Files
doc/skills/worklog/SKILL.md
T
JefferyandClaude Opus 5 67106b22c3 refactor(plugin 命名空間): plugin 更名 jsc-doc、hooks 只註冊自己擁有的 worklog
- 五份 manifest 的 name 由 jsc 改為 jsc-doc
- skill 目錄去掉重複的 doc- 前綴共 5 個(doc-funcs → funcs 等),worklog 名稱不變,frontmatter name 同步
- hooks/hooks.json 由合併超集改為只註冊 Stop(worklog):role 的 hook 交還 jsc-generic,避免改名後重複執行
- hook 腳本搜尋路徑與文件內 cache 路徑改指 jsc-doc
- 指令引用改為 /jsc-doc: 前綴;跨 plugin 引用指向 /jsc-code:、/jsc-generic:
- 保留 .docs/doc-funcs-index.md 等產物檔名不變(非 skill 識別名)
- 版號 0.2.6 → 0.2.7

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 17:07:14 +08:00

176 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: worklog
description: 工作證明自動記錄(worklog)的操作與維護 skill。搭配相容的 Stop hook,把每輪工作內容透過 README 定義的 headless CLIclaude/codex/agy/opencode/copilot)濃縮成精簡條目並追加到 Gitea wiki 的當週工作紀錄頁(Worklog-yyyy-MM-W<週>),工作內容全程不落地。提供 --init(初始化週頁與環境變數指引)、--tune(判定並快取最適合的 Claude 摘要模型)、--diagnose(診斷 hook 為何沒動作)、--append(手動補寫一筆)、--show(讀當週頁回顧)五個模式。當使用者說工作證明、工作紀錄、worklog、週報自動化、把工作內容寫到 wiki、記錄到 Gitea wiki、hook 沒有寫入 wiki、補寫工作紀錄、看本週做了什麼、重新判定摘要模型,或提到 WORKLOG_ENABLEDWORKLOG_HOSTWORKLOG_REPOWORKLOG_MODELWORKLOG_CLIWORKLOG_SCOPE 時觸發。不適用於:Gitea 議題操作(用 issues-syncissues)、專案文件化(用 funcs)。
---
# worklog — 工作證明自動記錄
把「每輪做了什麼」濃縮成一則條目,追加到 Gitea wiki 的當週工作紀錄頁。**自動記錄由相容的 `Stop` hook 完成,不需使用者同意、不需人工觸發**;本 skill 負責自動路徑之外的人工操作:初始化、模型判定、診斷、補寫、回顧。
| 元件 | 觸發者 | 職責 |
| --- | --- | --- |
| `hooks/hooks.json``Stop` hook | harness 自動 | 每輪結束抽本輪內容 → 濃縮 → 遮蔽 → 追加到當週頁 |
| 本 skill `/jsc-doc:worklog` | 使用者/助理手動 | `--init``--tune``--diagnose``--append``--show` |
| `scripts/worklog/worklog.sh` | 上述兩者共用 | 主流程(單一實作,避免漂移):依 `WORKLOG_CLI` 呼叫 headless CLI,每筆整理成六個固定欄位 |
| `scripts/worklog/wiki_api.py` | 上述兩者共用 | token 解析、wiki 讀寫、append 重試、週頁命名 |
| `scripts/worklog/transcript.py` | 上述兩者共用 | 抽本輪片段、估算花費時間、機密遮蔽 |
### 各助理支援範圍
| 功能 | Claude Code | Codex | Antigravity | OpenCode | GitHub Copilot |
| --- | --- | --- | --- | --- | --- |
| `Stop` hook 自動記錄 | ✅ | ✅ 需可讀 Codex session JSONL | ❌ | ❌ | ❌ |
| `--init``--diagnose``--append``--show` | ✅ | ⚠️ 需 plugin 目錄保留 `scripts/`(安裝後請實測一次) | ⚠️ 同左 | ⚠️ 需完整 plugin 目錄 | ⚠️ 需 plugin 目錄保留 `scripts/` |
| 摘要 CLI | `claude -p` | `codex exec` | `agy -p` | `opencode run` | `copilot -p` |
| `--tune` | ✅ | ❌ 無 `claude-api` skill 可載入 | ❌ 同左 | ❌ | ❌ |
兩個限制的來源:
- **`Stop` hook 只有相容 hook 環境實際執行**Claude Code 會用 `CLAUDE_PLUGIN_ROOT` 定位腳本,Codex 會從 `~/.codex/plugins/cache/doc/jsc-doc` 找已安裝的 worklog 腳本。`transcript.py` 目前支援 Claude Code transcript JSONL`type` / `message.content` blocks)與 Codex session JSONL`payload` events / response items),其他助理若提供等效 hook,必須先補對應 transcript 解析器。
- **OpenCode 以「複製 `skills/` 目錄」安裝**時不會帶入 `scripts/`,本 skill 的所有模式都無法執行;若以完整 plugin 目錄執行並能解析 `scripts/worklog`,可用 `WORKLOG_CLI=opencode` 作為摘要 CLI。
- 其他助理若要用 `--append``--show` 等純 wiki 操作,只需 `python3`;摘要路徑需要 README 定義的任一 headless CLI。`--tune` 仍是 Claude Code 專屬,其他 CLI 使用各自預設模型或手動設定其 CLI 行為。
### 腳本路徑解析(重要)
skill 執行時的工作目錄是**使用者的專案目錄**,不是 plugin 根目錄,因此**絕不可用相對路徑呼叫腳本**。先解析出 plugin 根目錄再組絕對路徑:
| 環境 | plugin 根目錄 |
| --- | --- |
| Claude Code | `${CLAUDE_PLUGIN_ROOT}` |
| 其他助理 | 本 skill 載入時提示的 base directory`.../skills/worklog`)往上兩層 |
```bash
# Claude Code
WORKLOG_DIR="${CLAUDE_PLUGIN_ROOT}/scripts/worklog"
# 其他助理:以 skill base directory 推導(<base>/../.. 即 plugin 根)
WORKLOG_DIR="<skill base directory>/../../scripts/worklog"
```
以下各模式的指令一律以 `${WORKLOG_DIR}` 表示該目錄。若解析不到或該目錄不存在,回報「plugin 目錄未包含 scripts/worklog,本 skill 在此環境不可用」並停止,不要改用相對路徑重試。
---
## 共用規範(必要前置)
執行本 skill 前,先以 Skill 工具載入下列共用規範並全程遵守;**任一載入不到時先詢問使用者是否安裝 generic plugin`https://gitea.jsc.idv.tw/plugins/generic.git`),不安裝則中斷**
- `/jsc-generic:spec-output`:繁體中文(台灣用語)、UTF-8 無 BOM、表格與 Mermaid 優先、**寫入外部系統不得洩漏 PII**。
- `/jsc-generic:spec-execution`:自動執行原則(必要決策才中斷)、不臆測。
- `/jsc-generic:spec-gitea`:token 機密保護(不 echo、遮蔽、不落地)、API 分頁、host 決定順序。
- `/jsc-generic:spec-time-log`:時間戳固定 Asia/Taipei `yyyy/MM/dd HH:mm:ss`;訊息格式 `[時間][階段][等級]: 訊息`、一行一則。
本 skill 特有補充:
- **工作內容不落地**:transcript 片段只在程序記憶體與 stdin/stdout 間傳遞、wiki 走 API 不 clone,全程不產生暫存檔。唯一允許落地的是**模型快取檔** `~/.claude/worklog/model`(僅含模型 id 與判定時間,不含任何工作內容)。
- **絕不阻斷**:hook 路徑任何失敗都以 exit 0 結束,只在 stderr 留訊息。
---
## 環境變數
| 變數 | 必要 | 說明 | 未設定 |
| --- | --- | --- | --- |
| `WORKLOG_ENABLED` | ✅ | 總開關,設為 `1` 才啟用 | hook 立即結束,完全不動作 |
| `WORKLOG_HOST` | ✅ | Gitea 主機,如 `gitea.housefun.com.tw` | 不啟用 |
| `WORKLOG_REPO` | ✅ | wiki 所在 repo,如 `H3285/WorkLog` | 不啟用 |
| `WORKLOG_MODEL` | | 強制指定摘要模型 | 讀快取檔 → 保底 `claude-haiku-4-5-20251001` |
| `WORKLOG_CLI` | | 摘要執行器:`auto``claude``codex``agy``opencode``copilot` | `auto`,先依目前 hook/session 環境判斷正在使用的 CLI,判斷不到或該 CLI 不可執行時才 fallback 到已安裝工具 |
| `WORKLOG_SCOPE` | | 冒號分隔的路徑前綴,僅這些路徑下的 session 才記 | 全部 session 都記 |
| `WORKLOG_ERRLOG` | | 錯誤訊息額外寫入的檔案路徑(只記錯誤、不含工作內容) | 只走 stderr |
**token 不需另設變數**,依固定優先序自動解析並實際驗證:
```
GITEA_TOKEN →(對目標 host 驗證失敗時)→ tea 設定檔中該 host 的 token → ~/.git-credentials
```
---
## 模式
### `--init`
1. 執行 `python3 "${WORKLOG_DIR}/wiki_api.py" probe`,回報 token 來源、Gitea 版本、當週頁狀態。
2. 當週頁不存在 → 執行 `python3 "${WORKLOG_DIR}/wiki_api.py" init` 建立(wiki 尚未初始化時一併初始化)。
3. 以表格印出應寫入 `~/.bashrc``WORKLOG_*` 變數清單;**不自動改使用者的 shell profile**(需人工確認的狀態變更)。
### `--tune`Claude Code 專屬)
決定「目前最適合的摘要模型」並快取,`Stop` hook 只讀快取、**絕不自行呼叫 AI 判斷**(否則就變成雞生蛋,還會拖慢使用者的等待路徑)。
本模式需要 Claude Code 內建的 `claude-api` skill 與 `claude` CLI,**其他助理無法執行**:請改為手動設定 `WORKLOG_MODEL` 環境變數指定模型,或沿用保底模型。
| 步驟 | 動作 |
| --- | --- |
| 1 | 以 Skill 工具載入 `claude-api` 取當下模型清單與定價,**不憑記憶** |
| 2 | 依本任務條件評分:延遲敏感(在使用者等待路徑上)、輸出短篇六欄工作紀錄、需嚴守機密過濾指令、每輪都跑一次故成本敏感 |
| 3 | Smoke test`WORKLOG_CHILD=1 claude -p "回 OK" --model <選定 id>` 確認該模型在此帳號可用 |
| 4 | 寫入 `~/.claude/worklog/model``model=<id>``tuned_at=<時間>``reason=<一行理由>`),並回報選擇與理由 |
快取超過 **30 天** 視為過期:hook 改用保底模型,並在條目標記 `(model: fallback)``--diagnose` 會提醒重跑 `--tune`
### `--diagnose`
逐項檢查並以表格回報,用於「hook 沒有寫入 wiki」時定位:
| 檢查項 | 判準 |
| --- | --- |
| `python3`/摘要 CLI | `python3``WORKLOG_CLI` 指定或 auto 選到的 CLI 是否找得到 |
| `WORKLOG_*` 變數 | 必要三項是否齊全、`WORKLOG_SCOPE` 是否把當前路徑排除 |
| `scripts/worklog` 目錄 | `${WORKLOG_DIR}` 是否解析成功且三支腳本存在(不存在=此助理不支援) |
| token | `python3 "${WORKLOG_DIR}/wiki_api.py" probe` 的 token 來源與驗證結果 |
| wiki API | Gitea 版本、`repos/<repo>` 與當週頁狀態 |
| 摘要設定 | `WORKLOG_CLI`、選到的 CLI、Claude 模型快取是否存在與是否過期 |
| hook 註冊 | `hooks/hooks.json` 是否存在且 plugin 已啟用 |
### `--append "<內容>"`
手動補寫一筆(hook 漏記、離線工作、或事後補充)。條目格式與自動路徑一致:
```
## <時間> — <專案> <!-- worklog:<時間戳>-manual -->
- 專案/任務名稱:<專案或任務>
- 執行細節與產出:<做了什麼、動到什麼、產出為何>
- 花費時間:<實際耗時或未判定>
- 任務狀態:<完成/進行中/待確認/受阻>
- 遇到的困難:<困難或未遇到明確困難>
- 解決方式:<處理方式或不需額外處理>
```
專案取當前工作目錄的 `<owner>/<repo>`;內容仍會過 `python3 "${WORKLOG_DIR}/transcript.py" redact` 遮蔽後才寫入。
### `--show`
讀當週頁(`python3 "${WORKLOG_DIR}/wiki_api.py" show`)並以表格摘要本週工作,用於回顧與週報。
---
## 條目與頁面格式
- 週頁名稱:`Worklog-<yyyy>-<MM>-W<該月第幾週>`,第幾週 `ceil(日/7)`(例:`2026/07/27``Worklog-2026-07-W4`)。
- 頁首標題:`# <yyyy> 年 <MM> 月 第 <週> 週工作紀錄`
- 每筆條目:`## <時間> — <專案>` +六個固定 bullet(專案/任務名稱、執行細節與產出、花費時間、任務狀態、遇到的困難、解決方式);標題行尾帶 HTML 註解 marker`<!-- worklog:… -->`)供寫後驗證與去重,wiki 渲染時不顯示。
- 多 session 同時寫入:`append_entry` 採「讀取 → 合併 → 寫回 → 寫後讀取驗證 marker」,未落地則重讀最新內容重試,最多 3 次。
---
## 機密與 PII(兩道防線)
| 防線 | 位置 | 內容 |
| --- | --- | --- |
| 1 | 濃縮提示詞 | 明令不得輸出 token/密碼/API key/連線字串/Email/電話/姓名/身分證號 |
| 2 | `transcript.py``redact` | 正則遮蔽:URL 內嵌憑證、40 字元 hex token、`gh?_``sk-` token、`token=``password=``Authorization:`、Email、台灣手機、身分證號 |
第二道防線不可移除 —— 模型有可能沒遵守指令,而 wiki 一旦寫入就留在 git 歷史裡。
---
## 呼叫方式
| 助理 | 呼叫 |
| --- | --- |
| Claude Code / Antigravity | `/jsc-doc:worklog --init``/jsc-doc:worklog --tune``/jsc-doc:worklog --diagnose``/jsc-doc:worklog --append "修正 X 的 Y 問題"``/jsc-doc:worklog --show` |
| Codex | `$worklog --diagnose`,或用 `/skills` 選單;可設 `WORKLOG_CLI=codex` |
| OpenCode / GitHub Copilot | 需完整 plugin 目錄保留 `scripts/`;可設 `WORKLOG_CLI=opencode``WORKLOG_CLI=copilot` |