feat(log): 工作日誌支援待寫入暫存 #12

Merged
admin merged 1 commits from feat/worklog-pending into develop 2026-08-26 01:29:39 +00:00
6 changed files with 102 additions and 7 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-log",
"version": "0.0.8",
"version": "0.0.9",
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
"skills": "./skills",
"author": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-log",
"version": "0.0.8",
"version": "0.0.9",
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
"skills": "./skills"
}
+2 -1
View File
@@ -24,6 +24,7 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
| --- | --- |
| `tools/usage-stats.sh` | 聚合 `$JSC_HOME/usage/*.jsonl`:`skills` 列技能使用次數、`chains` 列呼叫鏈次數(皆降冪),`--cli <name>` 過濾 |
| `tools/worklog-target.sh` | 接收已由 `jsc-gitea/tools/hash-id` 算好的 `HASH`,組出 `LOG_{HASH}`、`LOG_CONTENTS`(本身不再計算 SHA-1) |
| `tools/worklog-pending.sh` | 待寫入日誌的暫存區,存放於 `$JSC_HOME/worklog-pending/{HASH}/`。`add {HASH} {檔案}` 存一段內容(`jsc-sdlc` 的階段回報發現沒寫日誌時會呼叫),`cat {HASH}` 依時間印出全部、`list` 列路徑、`clear` 清除。結束碼 `3` 代表沒有暫存內容。**寫進 wiki 成功之後才 clear**,先清再寫會兩邊都沒有 |
| `tools/token-usage.sh` | 讀單一 CLI 這次工作的 token 用量,印出「input(tab)output」;來源讀不到就印「N/A(tab)N/A」並正常結束。第二個參數傳 session id,就只讀該階段的 transcript,數字才會跟花費時間對得上。各 CLI 的取得方式寫在腳本開頭註解 |
## Skills 目錄
@@ -34,7 +35,7 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
### `worklog`
工作完成後蒐集十項資訊(存取庫、分支、計畫連結、工作包連結、花費時間、token 用量、任務狀態、執行細節、困難與解決、PR 目標分支),用 `tools/worklog-target.sh` 產生目標頁,再套範本附加到 `LOG_{HASH}` 與 `LOG_CONTENTS`。
工作完成後蒐集十項資訊(存取庫、分支、計畫連結、工作包連結、花費時間、token 用量、任務狀態、執行細節、困難與解決、PR 目標分支),用 `tools/worklog-target.sh` 產生目標頁,再套範本附加到 `LOG_{HASH}` 與 `LOG_CONTENTS`。寫入前先讀 `tools/worklog-pending.sh cat {HASH}`:之前有階段跑完沒寫日誌,內容會暫存在那裡,這次一併寫進去,**寫成功之後才清暫存**。
### `stats`
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-log",
"version": "0.0.8",
"version": "0.0.9",
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
"skills": "./skills/"
}
+5 -3
View File
@@ -1,6 +1,6 @@
---
name: worklog
description: After finishing a work package, collect ten facts (repo, branch, plan link, work package link, elapsed time from session-timer, token usage per CLI, status, details, difficulties, PR target) and append a templated entry to wiki LOG_{HASH} plus LOG_CONTENTS. HASH follows the shared 8-char rule with the H-prefix fallback, and the work-week Friday still drives the page content. Trigger at the end of implement or maintain; not for planning notes.
description: After finishing a work package, collect ten facts (repo, branch, plan link, work package link, elapsed time from session-timer, token usage per CLI, status, details, difficulties, PR target) and append a templated entry to wiki LOG_{HASH} plus LOG_CONTENTS. HASH follows the shared 8-char rule with the H-prefix fallback, and the work-week Friday still drives the page content. Merge whatever tools/worklog-pending.sh holds for that HASH into the same write, then clear the pending area once the wiki write succeeded. Trigger at the end of implement or maintain; not for planning notes.
---
# worklog — work log
@@ -30,5 +30,7 @@ The `{HASH}` in every page name above is computed with `jsc-gitea/tools/hash-id`
2. Compute `{HASH}` from the code repo's `{owner}/{repo}` with `jsc-gitea/tools/hash-id`. Done when the 8-character `{HASH}` is known.
3. Run `tools/worklog-target.sh "{HASH}" all`. Use `PAGE` for `LOG_{HASH}` and `CONTENTS` for `LOG_CONTENTS`. Done when both page names are known.
4. Fix the work week: the Friday of the current work week drives the page content and the row dates. Done when that Friday is fixed as a `yyyy-MM-dd` date.
5. Read `PAGE` via `jsc-gitea:wiki`. If it does not exist, create it with the structure described in `templates/log-entry.md`; otherwise APPEND the new entry at the end and never overwrite existing entries. Done when the new entry exists on `PAGE`.
6. Update `CONTENTS` in the same pass (apply `templates/log-contents.md`; add the row if missing, otherwise refresh its 條目數 and 最後更新). Done when the row for `PAGE` carries this week's Friday date.
5. Collect what the pending area holds for this `{HASH}`: run `tools/worklog-pending.sh cat {HASH}`. Exit 3 means nothing is pending — carry on with this run's entry alone. Anything it prints was written by an earlier SDLC stage that ended without a work log, so it goes into **this** write, ahead of this run's own entry, in the order printed. Done when the pending content is either merged into the entries about to be written, or confirmed empty.
6. Read `PAGE` via `jsc-gitea:wiki`. If it does not exist, create it with the structure described in `templates/log-entry.md`; otherwise APPEND the new entries at the end and never overwrite existing entries. Done when every entry from step 5 plus this run's own entry exists on `PAGE`.
7. Update `CONTENTS` in the same pass (apply `templates/log-contents.md`; add the row if missing, otherwise refresh its 條目數 and 最後更新). Done when the row for `PAGE` carries this week's Friday date.
8. Clear the pending area: run `tools/worklog-pending.sh clear {HASH}` **only after the wiki write of step 6 succeeded**. Clearing first and failing the write loses the content on both sides. Skip this when step 5 found nothing. Done when the script reports the cleared path, or step 5 was empty.
+92
View File
@@ -0,0 +1,92 @@
#!/usr/bin/env sh
# worklog-pending.sh — 待寫入工作日誌的暫存區(供 jsc-sdlc 階段回報與 jsc-log:worklog 使用)。
#
# 為什麼要有這支腳本:SDLC 每個階段結束都要回報工作日誌連結。階段跑完卻沒寫日誌時,
# 內容如果只留在對話裡,換一個工作階段就消失了,下次寫日誌也補不回來。所以暫存搬到檔案層:
# 階段回報發現沒有日誌,就把該階段的內容存進本區並警告使用者;下次 jsc-log:worklog 寫入時
# 先把本區的內容一併寫進去,寫完才清掉。
#
# 用法:
# worklog-pending.sh add <hash> <file> 把一段待寫入的日誌內容存起來,印出存放路徑
# worklog-pending.sh list <hash> 列出該 hash 的暫存檔路徑(一行一個,依時間排序)
# worklog-pending.sh cat <hash> 依時間順序印出全部暫存內容
# worklog-pending.sh clear <hash> 清掉該 hash 的暫存(寫入日誌成功後才做)
#
# <hash> 為 jsc-gitea/tools/hash-id 算出的 8 碼工作日誌 hash,也就是 LOG_{HASH} 的 HASH。
# 存放位置: $JSC_HOME/worklog-pending/{hash}/{UTC 時間}-{pid}.md(JSC_HOME 預設 ~/.jsc)
#
# 結束碼: 0=成功 1=讀寫失敗 2=用法錯誤 3=該 hash 沒有暫存內容
#
# 陷阱:
# - clear 只在日誌確實寫進 wiki 之後才呼叫。先清再寫,寫失敗就兩邊都沒有。
# - 檔名帶 UTC 時間與 pid,同一秒內兩個工作階段各存各的,不會互相覆蓋。
set -eu
JSC_HOME="${JSC_HOME:-$HOME/.jsc}"
ROOT="$JSC_HOME/worklog-pending"
usage() {
cat >&2 <<'EOF'
用法:
worklog-pending.sh add <hash> <file> 存一段待寫入的日誌內容
worklog-pending.sh list <hash> 列出暫存檔路徑
worklog-pending.sh cat <hash> 印出全部暫存內容
worklog-pending.sh clear <hash> 清掉暫存(寫入日誌成功後才做)
結束碼: 0=成功 1=讀寫失敗 2=用法錯誤 3=沒有暫存內容
EOF
exit 2
}
valid_hash() { # 只收 8 碼大寫英數,擋掉路徑穿越
case "$1" in
[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]) return 0 ;;
*) echo "[jsc][工作日誌暫存][ERR]:hash 須為 8 碼大寫英數,收到「${1:-空值}」。" >&2; exit 2 ;;
esac
}
cmd="${1:-}"; [ -n "$cmd" ] || usage
shift || true
hash="${1:-}"; [ -n "$hash" ] || usage
valid_hash "$hash"
dir="$ROOT/$hash"
case "$cmd" in
add)
src="${2:-}"
[ -n "$src" ] || usage
[ -f "$src" ] || { echo "[jsc][工作日誌暫存][ERR]:找不到內容檔「$src」。" >&2; exit 1; }
mkdir -p "$dir" || { echo "[jsc][工作日誌暫存][ERR]:建不出暫存目錄「$dir」。" >&2; exit 1; }
stamp=$(date -u +%Y%m%dT%H%M%SZ)
target="$dir/$stamp-$$.md"
cp "$src" "$target" || { echo "[jsc][工作日誌暫存][ERR]:寫不進「$target」。" >&2; exit 1; }
printf '%s\n' "$target"
;;
list)
[ -d "$dir" ] || exit 3
found=0
for f in "$dir"/*.md; do
[ -f "$f" ] || continue
printf '%s\n' "$f"
found=1
done
[ "$found" -eq 1 ] || exit 3
;;
cat)
[ -d "$dir" ] || exit 3
found=0
for f in "$dir"/*.md; do
[ -f "$f" ] || continue
cat "$f"
printf '\n'
found=1
done
[ "$found" -eq 1 ] || exit 3
;;
clear)
[ -d "$dir" ] || exit 3
rm -rf "$dir" || { echo "[jsc][工作日誌暫存][ERR]:清不掉「$dir」。" >&2; exit 1; }
printf '已清除暫存:%s\n' "$dir"
;;
*)
usage ;;
esac