feat(log): 工作日誌支援待寫入暫存
What:新增 tools/worklog-pending.sh,worklog 技能改成寫入前先併入暫存內容、寫成功後才清除。
Why:SDLC 階段跑完沒寫工作日誌時,內容如果只留在對話裡,換一個工作階段就補不回來了。
How:暫存放在 $JSC_HOME/worklog-pending/{HASH}/,檔名帶 UTC 時間與 pid,同一秒的兩個工作階段不會互相覆蓋。jsc-sdlc 的階段回報負責存入,worklog 負責併入與清除;清除排在 wiki 寫入成功之後,先清再寫會兩邊都沒有。
Who:用 jsc-sdlc 跑階段、事後要靠工作日誌回頭查的人。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-log",
|
"name": "jsc-log",
|
||||||
"version": "0.0.8",
|
"version": "0.0.9",
|
||||||
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
|
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
|
||||||
"skills": "./skills",
|
"skills": "./skills",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-log",
|
"name": "jsc-log",
|
||||||
"version": "0.0.8",
|
"version": "0.0.9",
|
||||||
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
|
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
|
||||||
"skills": "./skills"
|
"skills": "./skills"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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/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-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 的取得方式寫在腳本開頭註解 |
|
| `tools/token-usage.sh` | 讀單一 CLI 這次工作的 token 用量,印出「input(tab)output」;來源讀不到就印「N/A(tab)N/A」並正常結束。第二個參數傳 session id,就只讀該階段的 transcript,數字才會跟花費時間對得上。各 CLI 的取得方式寫在腳本開頭註解 |
|
||||||
|
|
||||||
## Skills 目錄
|
## Skills 目錄
|
||||||
@@ -34,7 +35,7 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
|
|||||||
|
|
||||||
### `worklog`
|
### `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`
|
### `stats`
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-log",
|
"name": "jsc-log",
|
||||||
"version": "0.0.8",
|
"version": "0.0.9",
|
||||||
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
|
"description": "工作日誌(LOG_{HASH} wiki 頁)、技能使用統計與教訓紀錄(LEARN_{HASH} wiki 頁)",
|
||||||
"skills": "./skills/"
|
"skills": "./skills/"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: worklog
|
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
|
# 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.
|
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.
|
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.
|
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`.
|
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. 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.
|
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.
|
||||||
|
|||||||
Executable
+92
@@ -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
|
||||||
Reference in New Issue
Block a user