feat(worklog): 新增工作證明自動記錄 skill 與 Stop hook,升版 0.0.2 #5

Merged
admin merged 8 commits from develop into master 2026-07-27 04:00:52 +00:00
Member

變更摘要

為 generic plugin 新增 worklog(工作證明自動記錄) 功能:每輪工作結束時把本輪內容濃縮成精簡條目,追加到 Gitea wiki 的當週工作紀錄頁(Worklog-yyyy-MM-W<週>),工作內容全程不落地。

自動記錄由 Claude Code 的 Stop hook 觸發,不需人工介入;/jsc:worklog skill 負責自動路徑之外的人工操作(初始化、模型判定、診斷、補寫、回顧)。

影響範圍

  • generic plugin 的定位由「純共用規範」擴充為「共用規範 + 全域自動化」;可執行元件全部隔離在 scripts/worklog/,既有 skills/spec-* 完全未動。
  • 一律 opt-in:未設定 WORKLOG_ENABLED / WORKLOG_HOST / WORKLOG_REPO 環境變數時,hook 立即結束、完全不動作,因此其他人匯入 generic 為零影響。
  • hooks/hooks.json 只有 Claude Code 會讀;Codex / Antigravity / OpenCode 匯入時僅 skill 可用,自動記錄不會啟動。

重點檔案

檔案 職責
scripts/worklog/worklog.sh 主流程:遞迴 guard → 啟用檢查 → 抽本輪 → 模型決定 → 濃縮 → 遮蔽 → 追加 wiki;一律 exit 0
scripts/worklog/wiki_api.py Gitea wiki 讀寫、token fallback 鏈、append 讀改寫+寫後驗證重試、週頁命名
scripts/worklog/transcript.py 從 transcript JSONL 抽「本輪」(最後一筆使用者訊息之後,不需狀態檔)+機密遮蔽
skills/worklog/SKILL.md /jsc:worklog 五模式:--init / --tune / --diagnose / --append / --show
hooks/hooks.json Stop${CLAUDE_PLUGIN_ROOT}/scripts/worklog/worklog.sh,timeout 60

設計要點

  • 遞迴防護:濃縮用的子 claude 行程會再次觸發 Stop hook,靠 WORKLOG_CHILD guard + stop_hook_active 雙重阻斷。
  • 機密兩道防線:濃縮提示詞明令不得輸出憑證與個資;輸出後再過一次 transcript.py redact 正則遮蔽(URL 內嵌憑證、40 字元 hex token、gh?_ / sk- token、token= / password=Authorization:、Email、手機、身分證號)。
  • 模型決定WORKLOG_MODEL → 快取檔(--tune 產生,30 天過期)→ 保底 Haiku 4.5;hook 絕不自行呼叫 AI 判斷模型。
  • token 來源GITEA_TOKEN → 對目標 host 驗證失敗時退到 tea 設定檔該 host 的 token → ~/.git-credentials;全程不 echo、不落地。
  • 多 session 併發:append 採「讀取 → 合併 → 寫回 → 寫後讀取驗證 marker」,未落地則重讀最新內容重試,最多 3 次。

過程中解決的兩個環境問題

  1. Python 連不上內部 Gitea(curl 可以):Python 3.13+ 的 ssl 預設啟用 VERIFY_X509_STRICT,內部 CA 憑證缺 Subject Key Identifier 而被拒。只關閉該旗標,憑證鏈與主機名驗證仍完整保留。
  2. Gitea wiki 頁名轉義:title Worklog-2026-07-W4 的實際 sub_urlWorklog-2026-07-W4.-,直接用 title 讀取會 404。改為先 GET /wiki/pages 查表取 sub_url 再讀寫,不猜轉義規則。

驗證結果

wiki 初始化、頁面建立、append 寫後驗證、遞迴 guard、stop_hook_active 略過、端到端(真實 transcript → 摘要 → wiki 寫入)、wiki 頁面機密掃描、--tune smoke test、python/bash 語法、4 個 JSON 解析、三家 manifest 版本一致性 —— 全部通過。

風險與注意事項

  • Stop 是每個回應結束就觸發,長對話會產生多筆條目與多次 wiki commit;週頁會隨使用增長,每次寫入需先讀整頁。
  • 每個回應多一次 Haiku 摘要呼叫(成本與數秒延遲)。
  • 依設定不落地任何錯誤 log(僅 stderr);需要時可設 WORKLOG_ERRLOG 指定只記錯誤的檔案路徑。
  • 合併後需 claude plugin update 才會讓 Stop hook 生效。

版本

三家 manifest 同步升版 0.0.10.0.2


後續修正(跨助理適用性檢查)

對四家助理逐項檢查 README 與 skill 的適用性後修掉 8 項問題:

會實際壞掉

問題 修正
SKILL.md 以相對路徑呼叫腳本(skill 執行時的工作目錄是使用者專案目錄,四家都會 No such file 新增「腳本路徑解析」一節(Claude Code 用 ${CLAUDE_PLUGIN_ROOT};其他助理用 skill base directory 往上兩層),四處呼叫改為絕對路徑,並要求解析失敗即停止、不得改用相對路徑重試
OpenCode 以「複製 skills/」安裝,不會帶入 scripts/,worklog 所有模式都失效 在 skill description、支援矩陣、呼叫方式表與 README 安裝節明確標示 不支援 OpenCode
--tune 依賴 Claude Code 內建的 claude-api skill 與 claude CLI 標為 Claude Code 專屬,其他助理改以 WORKLOG_MODEL 手動指定

文件不準確 / 維護陷阱

問題 修正
原文稱其他三家「只有 skill 可用」,對 OpenCode 不成立;未說明 transcript 格式限制 README 新增「元件對各助理的適用範圍」矩陣,說明 worklog.sh 解析的是 Claude Code 專屬 transcript JSONL 結構
OpenCode 移除指令只清 spec-*,會殘留 worklog 及未來所有非 spec- 命名的 skill 改為逐一移除 skills/*/ 對應目錄(已 dry-run 驗證涵蓋全部 11 個 skill)
.gitignore 未忽略 __pycache__wiki_api.py 被 import 後容易誤 commit 加入 __pycache__/*.py[cod](已用 git check-ignore 驗證命中)
「新增一個 skill」流程未涵蓋含可執行元件的 skill 補四條注意:腳本放 scripts/、執行權限須入 git、禁相對路徑、標明支援範圍
Antigravity 更新指令用 ~/jsc-plugin,與安裝節的 ~/plugins/generic 不一致(既有問題) 統一為 ~/plugins/generic

AGENTS.md 也補一句指向適用範圍表 —— 它原本告訴助理「所有內容都在 skills/」,對讀該檔的 OpenCode 會誤導。

尚未驗證

Codex(codex plugin marketplace add)與 Antigravity(agy plugin install <本地路徑>)安裝後是否同樣保留 scripts/ 未實測;已在 README 標為 ⚠️--diagnose 也新增「scripts/worklog 目錄是否解析成功」檢查項,首次安裝跑一次即可定論。Claude Code 已確認 plugin cache 為完整 repo clone。

版本

本 PR 最終版本為 0.0.20.0.2 尚未合併到 master,這批修正與前批屬同一批變更,依 spec-plugin-version「同一 PR 只需最終一個版本」不再升版;期間誤 bump 的 0.0.3 已以 revert commit 還原(未改寫已推送歷史)。

## 變更摘要 為 generic plugin 新增 **worklog(工作證明自動記錄)** 功能:每輪工作結束時把本輪內容濃縮成精簡條目,追加到 Gitea wiki 的當週工作紀錄頁(`Worklog-yyyy-MM-W<週>`),工作內容全程不落地。 自動記錄由 Claude Code 的 `Stop` hook 觸發,不需人工介入;`/jsc:worklog` skill 負責自動路徑之外的人工操作(初始化、模型判定、診斷、補寫、回顧)。 ## 影響範圍 - generic plugin 的定位由「純共用規範」擴充為「**共用規範 + 全域自動化**」;可執行元件全部隔離在 `scripts/worklog/`,既有 `skills/spec-*` 完全未動。 - **一律 opt-in**:未設定 `WORKLOG_ENABLED` / `WORKLOG_HOST` / `WORKLOG_REPO` 環境變數時,hook 立即結束、完全不動作,因此其他人匯入 generic 為零影響。 - `hooks/hooks.json` **只有 Claude Code 會讀**;Codex / Antigravity / OpenCode 匯入時僅 skill 可用,自動記錄不會啟動。 ## 重點檔案 | 檔案 | 職責 | | --- | --- | | `scripts/worklog/worklog.sh` | 主流程:遞迴 guard → 啟用檢查 → 抽本輪 → 模型決定 → 濃縮 → 遮蔽 → 追加 wiki;一律 `exit 0` | | `scripts/worklog/wiki_api.py` | Gitea wiki 讀寫、token fallback 鏈、append 讀改寫+寫後驗證重試、週頁命名 | | `scripts/worklog/transcript.py` | 從 transcript JSONL 抽「本輪」(最後一筆使用者訊息之後,不需狀態檔)+機密遮蔽 | | `skills/worklog/SKILL.md` | `/jsc:worklog` 五模式:`--init` / `--tune` / `--diagnose` / `--append` / `--show` | | `hooks/hooks.json` | `Stop` → `${CLAUDE_PLUGIN_ROOT}/scripts/worklog/worklog.sh`,timeout 60 | ## 設計要點 - **遞迴防護**:濃縮用的子 `claude` 行程會再次觸發 `Stop` hook,靠 `WORKLOG_CHILD` guard + `stop_hook_active` 雙重阻斷。 - **機密兩道防線**:濃縮提示詞明令不得輸出憑證與個資;輸出後再過一次 `transcript.py redact` 正則遮蔽(URL 內嵌憑證、40 字元 hex token、`gh?_` / `sk-` token、`token=` / `password=`、`Authorization:`、Email、手機、身分證號)。 - **模型決定**:`WORKLOG_MODEL` → 快取檔(`--tune` 產生,30 天過期)→ 保底 Haiku 4.5;hook 絕不自行呼叫 AI 判斷模型。 - **token 來源**:`GITEA_TOKEN` → 對目標 host 驗證失敗時退到 `tea` 設定檔該 host 的 token → `~/.git-credentials`;全程不 echo、不落地。 - **多 session 併發**:append 採「讀取 → 合併 → 寫回 → 寫後讀取驗證 marker」,未落地則重讀最新內容重試,最多 3 次。 ## 過程中解決的兩個環境問題 1. **Python 連不上內部 Gitea(`curl` 可以)**:Python 3.13+ 的 `ssl` 預設啟用 `VERIFY_X509_STRICT`,內部 CA 憑證缺 Subject Key Identifier 而被拒。只關閉該旗標,憑證鏈與主機名驗證仍完整保留。 2. **Gitea wiki 頁名轉義**:title `Worklog-2026-07-W4` 的實際 `sub_url` 為 `Worklog-2026-07-W4.-`,直接用 title 讀取會 404。改為先 `GET /wiki/pages` 查表取 `sub_url` 再讀寫,不猜轉義規則。 ## 驗證結果 wiki 初始化、頁面建立、`append` 寫後驗證、遞迴 guard、`stop_hook_active` 略過、端到端(真實 transcript → 摘要 → wiki 寫入)、wiki 頁面機密掃描、`--tune` smoke test、python/bash 語法、4 個 JSON 解析、三家 manifest 版本一致性 —— 全部通過。 ## 風險與注意事項 - `Stop` 是每個回應結束就觸發,長對話會產生多筆條目與多次 wiki commit;週頁會隨使用增長,每次寫入需先讀整頁。 - 每個回應多一次 Haiku 摘要呼叫(成本與數秒延遲)。 - 依設定不落地任何錯誤 log(僅 stderr);需要時可設 `WORKLOG_ERRLOG` 指定只記錯誤的檔案路徑。 - 合併後需 `claude plugin update` 才會讓 `Stop` hook 生效。 ## 版本 三家 manifest 同步升版 `0.0.1` → `0.0.2`。 --- ## 後續修正(跨助理適用性檢查) 對四家助理逐項檢查 README 與 skill 的適用性後修掉 8 項問題: ### 會實際壞掉 | 問題 | 修正 | | --- | --- | | `SKILL.md` 以相對路徑呼叫腳本(skill 執行時的工作目錄是使用者專案目錄,四家都會 `No such file`) | 新增「腳本路徑解析」一節(Claude Code 用 `${CLAUDE_PLUGIN_ROOT}`;其他助理用 skill base directory 往上兩層),四處呼叫改為絕對路徑,並要求解析失敗即停止、不得改用相對路徑重試 | | OpenCode 以「複製 `skills/`」安裝,不會帶入 `scripts/`,worklog 所有模式都失效 | 在 skill `description`、支援矩陣、呼叫方式表與 README 安裝節明確標示 **不支援 OpenCode** | | `--tune` 依賴 Claude Code 內建的 `claude-api` skill 與 `claude` CLI | 標為 Claude Code 專屬,其他助理改以 `WORKLOG_MODEL` 手動指定 | ### 文件不準確 / 維護陷阱 | 問題 | 修正 | | --- | --- | | 原文稱其他三家「只有 skill 可用」,對 OpenCode 不成立;未說明 transcript 格式限制 | README 新增「元件對各助理的適用範圍」矩陣,說明 `worklog.sh` 解析的是 Claude Code 專屬 transcript JSONL 結構 | | OpenCode 移除指令只清 `spec-*`,會殘留 worklog 及未來所有非 `spec-` 命名的 skill | 改為逐一移除 `skills/*/` 對應目錄(已 dry-run 驗證涵蓋全部 11 個 skill) | | `.gitignore` 未忽略 `__pycache__`,`wiki_api.py` 被 import 後容易誤 commit | 加入 `__pycache__/`、`*.py[cod]`(已用 `git check-ignore` 驗證命中) | | 「新增一個 skill」流程未涵蓋含可執行元件的 skill | 補四條注意:腳本放 `scripts/`、執行權限須入 git、禁相對路徑、標明支援範圍 | | Antigravity 更新指令用 `~/jsc-plugin`,與安裝節的 `~/plugins/generic` 不一致(既有問題) | 統一為 `~/plugins/generic` | `AGENTS.md` 也補一句指向適用範圍表 —— 它原本告訴助理「所有內容都在 `skills/`」,對讀該檔的 OpenCode 會誤導。 ### 尚未驗證 Codex(`codex plugin marketplace add`)與 Antigravity(`agy plugin install <本地路徑>`)安裝後是否同樣保留 `scripts/` 未實測;已在 README 標為 ⚠️,`--diagnose` 也新增「`scripts/worklog` 目錄是否解析成功」檢查項,首次安裝跑一次即可定論。Claude Code 已確認 plugin cache 為完整 repo clone。 ### 版本 本 PR 最終版本為 **0.0.2**。`0.0.2` 尚未合併到 master,這批修正與前批屬同一批變更,依 `spec-plugin-version`「同一 PR 只需最終一個版本」不再升版;期間誤 bump 的 `0.0.3` 已以 revert commit 還原(未改寫已推送歷史)。
jiantw83 added 3 commits 2026-07-27 03:21:21 +00:00
jiantw83 added 4 commits 2026-07-27 03:51:59 +00:00
jiantw83 added 1 commit 2026-07-27 04:00:14 +00:00
0.0.2 尚未合併到 master,同一批變更只需最終一個版本。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
admin approved these changes 2026-07-27 04:00:47 +00:00
admin merged commit 32a94cb6df into master 2026-07-27 04:00:52 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: plugins/shared#5