現行紀錄只記「被叫用」,欄位是 ts、cli、session、skill,沒有成敗也沒有 結束碼。跑完整輪的技能與開場就中止的技能,在紀錄裡長得一模一樣。hook 成功時更是完全不留紀錄,只有錯誤路徑會寫 wiki,而那條路徑刻意不自動觸發。 事件流走本機檔案,不直接寫 wiki。hook 每次提示都跑,網路寫入會拖垮宿主 CLI;失敗的 hook 自我回報還會疊出迴圈,既有的錯誤回報因此不接在失敗的 hook 上,這裡沿用同一條線。助理巡檢時排空、彙整、寫頁。 hook 端用 EXIT trap 接,一支只加一行。這幾支的 exit 點很多,階段閘門一支 就有五十幾個;逐點改要動到每一條判定路徑,而那些路徑正是閘門的判準,為了 加一行紀錄去動閘門,風險遠大於收益。trap 涵蓋每一條離開路徑,含中途失敗。 狀態預設由結束碼推,推不出來的由 hook 自己覆寫。相依版本檢查與兩道閘門有 這種情形:antigravity 走 deny JSON、kiro 只印警告,兩者擋下時結束碼都是 0, 單看結束碼會把擋下記成放行。 技能的 start 由既有的技能用量 hook 順手發,不必改任何技能文件。end 只能由 技能自己在收尾步驟寫——hook 觸發時技能的實際工作還在後面的模型輪次,看不到 成敗。有 start 沒有配對的 end,就是那一輪中止了。
36 lines
1.9 KiB
Bash
Executable File
36 lines
1.9 KiB
Bash
Executable File
#!/usr/bin/env sh
|
||
# skill-usage.sh — 記錄技能使用與呼叫鏈(供 jsc-log:stats 統計)。
|
||
# Claude: PostToolUse(matcher=Skill) 接線;其他 CLI 由 wrapper 以
|
||
# JSC_SKILL=<name> skill-usage.sh 呼叫。
|
||
# 產出:
|
||
# $JSC_HOME/usage/skills.jsonl {ts,cli,session,skill}
|
||
# $JSC_HOME/usage/chains.jsonl {ts,cli,session,from,to}(同 session 內前一技能 → 本技能)
|
||
#
|
||
# 結束碼:0=一律成功,只有這一種正常碼。取不到技能名(JSC_SKILL 與 stdin JSON 都沒有)就
|
||
# 安靜降級,不寫任何紀錄直接 exit 0;寫得成紀錄也是 exit 0。這支接在 PostToolUse,
|
||
# 技能已經跑完了,結束碼擋不掉任何事,所以連寫檔失敗都不回報。
|
||
# 唯一的非零來源同 session-timer.sh:本檔以 `. "$HERE/lib.sh"` 載入,沒有接 `|| true`,
|
||
# lib.sh 讀不到時 sh 會就地結束並回 2。
|
||
HERE=$(dirname "$0"); . "$HERE/lib.sh"
|
||
hook_trace "skill-usage ${1:-}"
|
||
read_stdin
|
||
skill="${JSC_SKILL:-$(json_str skill)}"
|
||
[ -n "$skill" ] || exit 0
|
||
sid=$(session_id); cli=$(cli_name); ts=$(now_iso)
|
||
printf '{"ts":"%s","cli":"%s","session":"%s","skill":"%s"}\n' \
|
||
"$ts" "$cli" "$sid" "$skill" >> "$JSC_HOME/usage/skills.jsonl"
|
||
last_f="$JSC_HOME/sessions/$sid.lastskill"
|
||
last=$(cat "$last_f" 2>/dev/null || echo "")
|
||
if [ -n "$last" ]; then
|
||
printf '{"ts":"%s","cli":"%s","session":"%s","from":"%s","to":"%s"}\n' \
|
||
"$ts" "$cli" "$sid" "$last" "$skill" >> "$JSC_HOME/usage/chains.jsonl"
|
||
fi
|
||
printf '%s' "$skill" > "$last_f"
|
||
|
||
# 技能的 start 事件在這裡發,不必改任何 SKILL.md:這支接在技能指示載入之後,那一刻
|
||
# 就是「技能開始跑」。end 只能由技能自己在收尾步驟寫——本 hook 觸發時,技能的實際工作
|
||
# 還在後面的模型輪次,看不到成敗。有 start 沒有配對的 end,就是那一輪中止了。
|
||
emit_event skill "$skill" start ok 0
|
||
|
||
exit 0
|