diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 92a0737..4a56efe 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,12 +1,21 @@ { "name": "jsc-doc", - "version": "0.0.4", - "description": "JSC 文件化 skills(Claude Code / Codex / Antigravity / OpenCode / GitHub Copilot):docker 會整理 docker-compose.yaml 的行內註解與標題日期;funcs 會為專案 functions 建立 .docs 草稿、補齊 XML 文件註解並重建 README 功能列表與使用範例;issues-analyze-to-file 會讀取 Gitea issue、彙整需求、拆成多階段 issue 並產生實作草稿與交付留言;issues-analyze 會把專案/議題/文件來源(議題連同留言與附件一起讀取)拆成小功能議題(母議題須待所有子議題關閉後才可關閉)、分析完成後把屬於專案看板的議題移到「待處理」欄位並依到期日實作;issues-sync 會讀取 Gitea 專案或議題、依工作目錄檔案勾稽並同步議題的 TODO 進度、標籤與專案看板進度欄位並產生進度留言(指定關閉專案/專案完成時改為批次把專案所有議題搬到「已完成」並關閉);notifications 會讀取 Gitea 通知、依通知類型分組並照 REVIEW.md 流程處理,沒有流程時詢問使用者並把缺少流程的類別附加到 REVIEW.md;worklog 會以 README 定義的 headless CLI 將每輪工作整理成六欄工作紀錄並追加到 Gitea wiki。所有 skills 以 SKILL.md 為共通標準,於 Claude Code 以 /jsc-doc: 前綴呼叫。", + "version": "0.1.0", + "description": "JSC 文件化 skills(Claude Code / Codex / Antigravity / OpenCode / GitHub Copilot CLI):docker 會整理 docker-compose.yaml 的行內註解與標題日期;funcs 會為專案 functions 建立 .docs 草稿、補齊 XML 文件註解並重建 README 功能列表與使用範例;issues-analyze-to-file 會讀取 Gitea issue、彙整需求、拆成多階段 issue 並產生實作草稿與交付留言;issues-analyze 會把專案/議題/文件來源(議題連同留言與附件一起讀取)拆成小功能議題(母議題須待所有子議題關閉後才可關閉)、分析完成後把屬於專案看板的議題移到「待處理」欄位並依到期日實作;issues-sync 會讀取 Gitea 專案或議題、依工作目錄檔案勾稽並同步議題的 TODO 進度、標籤與專案看板進度欄位並產生進度留言(指定關閉專案/專案完成時改為批次把專案所有議題搬到「已完成」並關閉);notifications 會讀取 Gitea 通知、依通知類型分組並照 REVIEW.md 流程處理,沒有流程時詢問使用者並把缺少流程的類別附加到 REVIEW.md;worklog 會以 README 定義的 headless CLI 將每輪工作整理成六欄工作紀錄並追加到 Gitea wiki。所有 skills 以 SKILL.md 為共通標準;於 Claude Code 以 /jsc-doc: 前綴呼叫。", "skills": "./skills", "author": { "name": "JSC" }, "homepage": "https://gitea.jsc.idv.tw/plugins/doc", "repository": "https://gitea.jsc.idv.tw/plugins/doc.git", - "keywords": ["doc", "documentation", "docker-compose", "xml-doc", "worklog", "skills", "cross-tool", "jsc"] + "keywords": [ + "doc", + "documentation", + "docker-compose", + "xml-doc", + "worklog", + "skills", + "cross-tool", + "jsc" + ] } diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index e592327..497c4dd 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-doc", - "version": "0.0.4", + "version": "0.1.0", "description": "JSC 文件化 skills:docker 會整理 docker-compose.yaml 的行內註解與標題日期;funcs 會為專案 functions 建立 .docs 草稿、補齊 XML 文件註解並重建 README 功能列表與使用範例;issues-analyze-to-file 會讀取 Gitea issue、彙整需求、拆成多階段 issue 並產生實作草稿與交付留言;issues-analyze 會把專案/議題/文件來源(議題連同留言與附件一起讀取)拆成小功能議題(母議題須待所有子議題關閉後才可關閉)、分析完成後把屬於專案看板的議題移到「待處理」欄位並依到期日實作;issues-sync 會讀取 Gitea 專案或議題、依工作目錄檔案勾稽並同步議題的 TODO 進度、標籤與專案看板進度欄位並產生進度留言(指定關閉專案/專案完成時改為批次把專案所有議題搬到「已完成」並關閉);notifications 會讀取 Gitea 通知、依通知類型分組並照 REVIEW.md 流程處理,沒有流程時詢問使用者並把缺少流程的類別附加到 REVIEW.md;worklog 會以 README 定義的 headless CLI 將每輪工作整理成六欄工作紀錄並追加到 Gitea wiki(自動 Stop hook 僅相容 hook 環境支援)。所有 skills 以 SKILL.md 為共通標準。", "skills": "./skills" } diff --git a/README.md b/README.md index 7143763..efcf35b 100644 --- a/README.md +++ b/README.md @@ -73,120 +73,16 @@ doc/ ## 安裝 / 更新 / 移除(各助理) -> 指令中的 repo 網址:`https://gitea.jsc.idv.tw/plugins/doc.git` +> 完整的安裝/更新/移除指令(Claude Code、Codex、Antigravity、OpenCode、GitHub Copilot CLI 五種助理),一律以 [`/jsc-shared:spec-plugin-cli`](https://gitea.jsc.idv.tw/plugins/shared/src/branch/master/skills/spec-plugin-cli/SKILL.md) 為唯一權威版本,套用時代入下列佔位符: > -> **Claude / Codex 從 git URL 安裝(會 clone 遠端),請先把本 repo `push` 到 gitea。** -> **Antigravity 的 `agy plugin install ` 目前只支援 github.com**;gitea 請改用「clone + 本地路徑」(見 Antigravity 節)。 -> 本機/離線:Claude 可用本地路徑加 marketplace;Antigravity 用本地路徑安裝。 - -### Claude Code - -```bash -# 安裝 -claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/doc.git -claude plugin install jsc-doc@doc - -# 更新 -claude plugin marketplace update doc -claude plugin update jsc-doc@doc - -# 移除 -claude plugin uninstall jsc-doc@doc -claude plugin marketplace remove doc -``` - -- 工作階段內 slash 版(等價):把 `claude plugin` 換成 `/plugin`。 -- 本機開發(免 push):`claude plugin marketplace add C:\Users\h3285\source\repos.plugins\doc`(本地路徑)後再 install。 -- **呼叫**:`/jsc-doc:`(例 `/jsc-doc:docker`)。 - -### Codex - -```bash -# 安裝 -codex plugin marketplace add https://gitea.jsc.idv.tw/plugins/doc.git -codex plugin add jsc-doc@doc - -# 更新(重新抓取 marketplace 的 git 快照) -codex plugin marketplace upgrade doc - -# 移除 -codex plugin remove jsc-doc@doc -codex plugin marketplace remove doc -``` - -- 安裝 token `jsc-doc@doc` = plugin 名(`.codex-plugin/plugin.json` 的 `name`)@ marketplace 名(`.agents/plugins/marketplace.json` 的 `name`)。 -- 本 repo 的 Codex marketplace 以 `url` 來源指向自己,故 Codex **一律從 gitea 安裝**(需先 push);安裝後重啟 Codex。 -- **呼叫**:`$`(例 `$docker`),或用 `/skills` 選單。 - -### Antigravity(`agy`) - -> `agy plugin install ` 目前**只支援 github.com**;gitea 等自架 git 不支援 URL 安裝,請先 `git clone` 再用**本地路徑**安裝。 - -```bash -# 安裝:clone 後用本地路徑 -git clone https://gitea.jsc.idv.tw/plugins/doc.git ~/plugins/doc -agy plugin install ~/plugins/doc - -# 更新(agy 無 update 子指令 → git pull 後重裝) -git -C ~/plugins/doc pull -agy plugin uninstall jsc-doc -agy plugin install ~/plugins/doc - -# 移除 -agy plugin uninstall jsc-doc -``` - -- 若把 skills 放到 GitHub,則可直接 `agy plugin install https://github.com//`。 -- 其他:`agy plugin list`、`agy plugin enable jsc-doc` / `disable jsc-doc`、`agy plugin validate `。安裝後重啟工作階段。 -- **呼叫**:`/jsc-doc:`(例 `/jsc-doc:docker`)或依描述自動觸發。 - -### OpenCode - -OpenCode 的「plugin」是 TypeScript/npm 套件,不適用於 skill 包;skills 改用**目錄安裝**。 -OpenCode 會讀 `~/.config/opencode/skills/`(也會讀 `~/.claude/skills/`、`~/.agents/skills/`)。 - -```bash -# 安裝 -git clone https://gitea.jsc.idv.tw/plugins/doc.git ~/plugins/doc -mkdir -p ~/.config/opencode/skills -cp -r ~/plugins/doc/skills/* ~/.config/opencode/skills/ - -# 更新 -git -C ~/plugins/doc pull -cp -r ~/plugins/doc/skills/* ~/.config/opencode/skills/ - -# 移除 -rm -rf ~/.config/opencode/skills/docker ~/.config/opencode/skills/funcs ~/.config/opencode/skills/issues-analyze-to-file ~/.config/opencode/skills/issues-analyze ~/.config/opencode/skills/issues-sync ~/.config/opencode/skills/worklog -``` - -> **worklog 在 OpenCode 的 skills 目錄安裝不可用**:上面的複製只帶 `skills/`,不含 `scripts/` 與 `hooks/`,worklog 的所有模式都會失敗;若以完整 plugin 目錄執行並能解析 `scripts/worklog`,可用 `WORKLOG_CLI=opencode` 作為摘要 CLI。 - -> **Windows PowerShell**:`cp -r A B` → `Copy-Item A B -Recurse -Force`、`rm -rf X` → `Remove-Item X -Recurse -Force`、`~` → `$HOME`。 - -- **呼叫**:直接描述需求,模型會依 skill 描述自動透過 skill 工具呼叫。 - -### GitHub Copilot CLI - -Copilot CLI 支援與 Claude Code 類似的原生 plugin / marketplace 指令,可直接從 marketplace 安裝、更新與移除本 plugin。 - -```bash -# 安裝 -copilot plugin marketplace add https://gitea.jsc.idv.tw/plugins/doc.git -copilot plugin install jsc-doc@doc - -# 更新 -copilot plugin marketplace update doc -copilot plugin update jsc-doc@doc - -# 移除 -copilot plugin uninstall jsc-doc@doc -copilot plugin marketplace remove doc -``` - -- 安裝 token `jsc-doc@doc` = plugin 名(plugin manifest 的 `name`)@ marketplace 名。 -- `copilot plugin marketplace add` 支援 GitHub `owner/repo`、git URL 與本地路徑;Gitea repo 可用上方 HTTPS URL。 -- **呼叫**:在 Copilot CLI 中用自然語言描述需求,例如 `copilot -i "請使用 docker 整理 docker-compose 註解"`。 -- `worklog` 的 `Stop` hook 自動記錄仍只有相容 hook 環境會實際執行;Copilot CLI 可作為 `WORKLOG_CLI=copilot` 摘要執行器,但不會執行 Claude Code hook。 +> | 佔位符 | 值 | +> | --- | --- | +> | `` | `gitea.jsc.idv.tw` | +> | `` | `doc` | +> | `` | `jsc-doc` | +> | `` | `doc` | +> | ``(= `@`) | `jsc-doc@doc` | +> | `` | `https://gitea.jsc.idv.tw/plugins/doc.git` | --- @@ -291,3 +187,4 @@ copilot plugin marketplace remove doc - Antigravity:`git -C ~/plugins/doc pull && agy plugin uninstall jsc-doc && agy plugin install ~/plugins/doc` - OpenCode:`git pull` 後重新複製 `skills/` - Copilot:`copilot plugin marketplace update doc && copilot plugin update jsc-doc@doc` + diff --git a/plugin.json b/plugin.json index 54b5a19..6201f2b 100644 --- a/plugin.json +++ b/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-doc", - "version": "0.0.4", + "version": "0.1.0", "description": "JSC 文件化 skills:docker 會整理 docker-compose.yaml 的行內註解與標題日期;funcs 會為專案 functions 建立 .docs 草稿、補齊 XML 文件註解並重建 README 功能列表與使用範例;issues-analyze-to-file 會讀取 Gitea issue、彙整需求、拆成多階段 issue 並產生實作草稿與交付留言;issues-analyze 會把專案/議題/文件來源(議題連同留言與附件一起讀取)拆成小功能議題(母議題須待所有子議題關閉後才可關閉)、分析完成後把屬於專案看板的議題移到「待處理」欄位並依到期日實作;issues-sync 會讀取 Gitea 專案或議題、依工作目錄檔案勾稽並同步議題的 TODO 進度、標籤與專案看板進度欄位並產生進度留言(指定關閉專案/專案完成時改為批次把專案所有議題搬到「已完成」並關閉);notifications 會讀取 Gitea 通知、依通知類型分組並照 REVIEW.md 流程處理,沒有流程時詢問使用者並把缺少流程的類別附加到 REVIEW.md;worklog 會以 README 定義的 headless CLI 將每輪工作整理成六欄工作紀錄並追加到 Gitea wiki。所有 skills 以 SKILL.md 為共通標準;於 Antigravity 以 /jsc-doc: 前綴呼叫。", - "skills": "./skills/" + "skills": "./skills" } diff --git a/plugin.meta.json b/plugin.meta.json new file mode 100644 index 0000000..04ac96a --- /dev/null +++ b/plugin.meta.json @@ -0,0 +1,31 @@ +{ + "name": "jsc-doc", + "shortName": "doc", + "version": "0.1.0", + "descriptionCore": "JSC 文件化 skills:docker 會整理 docker-compose.yaml 的行內註解與標題日期;funcs 會為專案 functions 建立 .docs 草稿、補齊 XML 文件註解並重建 README 功能列表與使用範例;issues-analyze-to-file 會讀取 Gitea issue、彙整需求、拆成多階段 issue 並產生實作草稿與交付留言;issues-analyze 會把專案/議題/文件來源(議題連同留言與附件一起讀取)拆成小功能議題(母議題須待所有子議題關閉後才可關閉)、分析完成後把屬於專案看板的議題移到「待處理」欄位並依到期日實作;issues-sync 會讀取 Gitea 專案或議題、依工作目錄檔案勾稽並同步議題的 TODO 進度、標籤與專案看板進度欄位並產生進度留言(指定關閉專案/專案完成時改為批次把專案所有議題搬到「已完成」並關閉);notifications 會讀取 Gitea 通知、依通知類型分組並照 REVIEW.md 流程處理,沒有流程時詢問使用者並把缺少流程的類別附加到 REVIEW.md;worklog 會以 README 定義的 headless CLI 將每輪工作整理成六欄工作紀錄並追加到 Gitea wiki。所有 skills 以 SKILL.md 為共通標準。", + "assistants": ["Claude Code", "Codex", "Antigravity", "OpenCode", "GitHub Copilot CLI"], + "cliPrefix": "/jsc-doc:", + "callPrefixAssistants": { + "root": "Antigravity", + "claudePlugin": "Claude Code" + }, + "codexNote": "(自動 Stop hook 僅相容 hook 環境支援)", + "codexNoteInsertion": "接在 descriptionCore 的「...並追加到 Gitea wiki」之後、「。所有 skills 以 SKILL.md 為共通標準。」之前插入本句", + "codexNoteAnchor": "並追加到 Gitea wiki", + "skillsPath": "./skills", + "author": { "name": "JSC" }, + "homepage": "https://gitea.jsc.idv.tw/plugins/doc", + "repository": "https://gitea.jsc.idv.tw/plugins/doc.git", + "keywords": ["doc", "documentation", "docker-compose", "xml-doc", "worklog", "skills", "cross-tool", "jsc"], + "marketplace": { + "repoDescription": "JSC 文件化 skills 的 Claude Code marketplace,提供 docker-compose 註解整理、function XML 文件補齊、Gitea issue 文件流程、Gitea 通知處理與 worklog 工作紀錄。", + "pluginSummary": "JSC 文件化 skills:整理 docker-compose 註解、補齊 function XML 文件、同步 Gitea issue 文件流程、處理 Gitea 通知,並透過 worklog 記錄工作。" + }, + "_driftDecisions": [ + "決議1:skills 欄位統一為不帶尾斜線的 './skills'。現況:root plugin.json 為 './skills/'(帶尾斜線),.claude-plugin 與 .codex-plugin 已是 './skills';skillsPath 已定為統一值,root 需修正。", + "決議2:root plugin.json 已有「於 Antigravity 以 /jsc-doc: 前綴呼叫」句尾,符合決議,不需調整(此點是 shared 缺漏,doc 本身無此問題)。", + "決議3:.claude-plugin/plugin.json 助理括號清單現況為「(Claude Code / Codex / Antigravity / OpenCode / GitHub Copilot)」,順序已與統一決議相同,僅需把最後一項名稱由「GitHub Copilot」改為「GitHub Copilot CLI」。", + "決議4對應:.codex-plugin/plugin.json 專屬補充資訊「(自動 Stop hook 僅相容 hook 環境支援)」為真實資訊差異,已保留於 codexNote,不可被格式統一誤刪。", + "額外發現(非既知四點,次要):.claude-plugin/plugin.json 結尾使用「,於 Claude Code 以 /jsc-doc: 前綴呼叫」(逗號),而 root 用「;於 Antigravity 以 /jsc-doc: 前綴呼叫」(分號)——標點符號不一致,屬低優先級格式細節,建議下階段產生器統一標點但不影響語意。" + ] +} diff --git a/scripts/worklog/transcript.py b/scripts/worklog/transcript.py index b456d0a..1b27750 100755 --- a/scripts/worklog/transcript.py +++ b/scripts/worklog/transcript.py @@ -3,7 +3,9 @@ # 用途:worklog 的 transcript 處理工具。負責 (1) 從 Claude Code/Codex # JSONL 抽出「本輪」對話片段(最後一筆使用者訊息之後的全部內容), # (2) 估算本輪花費時間,(3) 對文字做機密遮蔽(token/密碼/PII), -# 作為寫入 wiki 前的第二道防線。 +# 作為寫入 wiki 前的第二道防線。本檔 REDACT_PATTERNS 現為 +# /jsc-shared:spec-gitea『機密遮蔽實作』章節的來源依據(其他工具的 +# 機密遮蔽規則以該章節為準)。 # 更新時間:2026/07/27 22:16:00 # 相依:Python 3 標準庫。全程僅走 stdin/stdout,不寫任何檔案。 # ============================================================================== @@ -21,6 +23,7 @@ TOTAL_LIMIT = 24000 # ------------------------------------------------------------------------------ # 機密遮蔽規則:命中一律換成 *** # ------------------------------------------------------------------------------ +# 本檔遮蔽規則對應 shared/scripts/lib/redact-patterns.json(經 /jsc-shared:spec-gitea 收斂) REDACT_PATTERNS = [ (r"[A-Za-z0-9_\-]*:[A-Za-z0-9_\-]{16,}@", "***@"), # URL 內嵌憑證 user:token@ (r"\b[0-9a-f]{40}\b", "***"), # Gitea 40 字元 token diff --git a/scripts/worklog/wiki_api.py b/scripts/worklog/wiki_api.py index 98a020b..037a188 100755 --- a/scripts/worklog/wiki_api.py +++ b/scripts/worklog/wiki_api.py @@ -3,6 +3,8 @@ # 用途:Gitea Wiki 讀寫工具(worklog 專用)。提供 token 解析、頁面讀取、 # 建立、append 追加(read-modify-write + 寫後驗證重試),供 worklog.sh # 與 /jsc-doc:worklog skill 共用,避免兩份實作漂移。 +# resolve_token() 的優先序實作對應 /jsc-shared:spec-gitea『token 解析 +# 優先序』章節。 # 更新時間:2026/07/29 19:03:29 # 相依:Python 3 標準庫(urllib、base64、json、re)。不需 requests、不需 jq。 # 機密:token 一律從環境變數或本機憑證檔讀取,絕不輸出、絕不寫入任何檔案。 @@ -18,8 +20,9 @@ import urllib.error import urllib.parse import urllib.request from datetime import datetime, timedelta, timezone +from zoneinfo import ZoneInfo -TAIPEI = timezone(timedelta(hours=8)) +TAIPEI = ZoneInfo("Asia/Taipei") def _ssl_context(): @@ -128,7 +131,12 @@ def resolve_token(host, repo): # ------------------------------------------------------------------------------ def _request(method, url, token, payload): - """發出 Gitea API 請求,回傳 (HTTP 狀態碼, 回應內文字串)。網路層錯誤以 0 表示。""" + """ + 發出 Gitea API 請求,回傳 (HTTP 狀態碼, 回應內文字串)。網路層錯誤以 0 表示。 + + 本函式實作 /jsc-shared:spec-gitea 的『API 呼叫慣例』章節: + Authorization 標頭帶 `token `、payload 以 UTF-8 JSON 編碼。 + """ data = json.dumps(payload, ensure_ascii=False).encode("utf-8") if payload is not None else None req = urllib.request.Request(url, data=data, method=method) req.add_header("Authorization", f"token {token}") @@ -145,7 +153,12 @@ def _request(method, url, token, payload): def _api_base(host, repo): - """組出 repo 層級的 wiki API base URL。""" + """ + 組出 repo 層級的 wiki API base URL。 + + 本函式實作 /jsc-shared:spec-gitea 的『API 呼叫慣例』章節:base 為 + `https:///api/v1/repos//` 之下的 wiki 路徑。 + """ return f"https://{host}/api/v1/repos/{repo}/wiki" @@ -188,6 +201,9 @@ def resolve_sub_url(host, repo, token, title): Gitea wiki 會對 title 做轉義(`-` 代表空格,實際 dash 另有轉義形式,例如 title `Worklog-2026-07-W4` 的 sub_url 為 `Worklog-2026-07-W4.-`),因此讀寫 一律以查表得到的 sub_url 為準,不自行猜測轉義規則。 + + 本函式實作 /jsc-shared:spec-gitea 的『Wiki 頁名轉義規則』第 2 點: + 以 `GET /wiki/pages` 查表找 sub_url,不用字串取代規則反推。 找不到回 None。 """ status, pages = list_pages(host, repo, token) diff --git a/skills/docker/SKILL.md b/skills/docker/SKILL.md index 2a3c2a8..fc764f2 100644 --- a/skills/docker/SKILL.md +++ b/skills/docker/SKILL.md @@ -5,6 +5,12 @@ description: 整理並對齊 docker-compose.yaml 的行內註解與標題區塊 # 對齊 docker-compose 註解 +## 共用規範(必要前置) + +先載入 `/jsc-shared:spec-preflight` 並依其流程處理;載入不到即代表 shared plugin 未安裝, +依該 spec 詢問使用者是否安裝 `https://gitea.jsc.idv.tw/plugins/shared.git`,不安裝則中斷本 skill。 +本 skill 需要的規範:`spec-output`、`spec-execution`、`spec-time-log` + 整理並對齊 `docker-compose.yaml` 的行內註解與標題。請優先使用自動化腳本執行。 以下範例中的 `skill_dir` 是本 skill 所在目錄,也就是包含此 `SKILL.md` 與 `scripts/` 的資料夾。不要假設目標專案內存在 `plugins/skills/docker/`。 diff --git a/skills/funcs/SKILL.md b/skills/funcs/SKILL.md index 288e370..b44a54c 100644 --- a/skills/funcs/SKILL.md +++ b/skills/funcs/SKILL.md @@ -7,13 +7,11 @@ description: 先判斷專案語言,再為每個 function 與每個指令檔( 你要替目前工作區內的專案補齊 function 文件、指令檔註解與 workflow README。所有草稿一律由 subagent 產生,草稿全部完成後再詢問使用者如何實作,實作完成後保守優化被文件化原始碼的效能(排版依原本方式維持原樣,僅修正有誤處),最後重建 README。請依下列階段依序完成。 -## 共用規範(shared plugin,必要前置) +## 共用規範(必要前置) -執行本 skill 前,先以 Skill 工具載入下列共用規範並全程遵守;**任一載入不到(shared plugin 未安裝)時,先詢問使用者是否安裝 shared plugin(`https://gitea.jsc.idv.tw/plugins/shared.git`),使用者不安裝則直接中斷本 skill**,不得只憑下方一行摘要繼續執行: - -- `/jsc-shared:spec-output`:繁體中文為主英文為輔、UTF-8(不含 BOM)無亂碼、subagent 提示需帶入本規範。 -- `/jsc-shared:spec-execution`:不臆測/需人工確認、不擴及無關檔案(generated/bin/obj/.git/.docs 與第三方依賴)。 -- `/jsc-shared:spec-time-log`:更新時間 Asia/Taipei `yyyy/MM/dd HH:mm:ss`、輸出訊息格式 `[時間][階段][等級]: 訊息`、一行一則。 +先載入 `/jsc-shared:spec-preflight` 並依其流程處理;載入不到即代表 shared plugin 未安裝, +依該 spec 詢問使用者是否安裝 `https://gitea.jsc.idv.tw/plugins/shared.git`,不安裝則中斷本 skill。 +本 skill 需要的規範:`spec-output`、`spec-execution`、`spec-subagent`、`spec-time-log`、`spec-ask-user`、`spec-git-safety` ## 第 0 步:先判斷語言與生態 @@ -47,7 +45,7 @@ description: 先判斷專案語言,再為每個 function 與每個指令檔( ## 第 3 步:派 Sub Agent 產生草稿(三類,全部由 subagent 產生) -針對每一個 function 與每一個指令檔各派一個 subagent。subagent 只分析指定目標與必要上下文,**不直接改原始碼或原始指令檔**,只在 .docs/ 底下建立草稿。 +依 `/jsc-shared:spec-subagent` 派工:針對每一個 function 與每一個指令檔各派一個 subagent,一個明確目標對應一個 subagent。本 skill 明確授權的例外寫入範圍僅限在 `.docs/` 底下建立草稿;subagent 只分析指定目標與必要上下文,不直接改原始碼或原始指令檔,其餘讀寫與回傳規則依該 spec。 ### 3-1 function 註解草稿 @@ -65,7 +63,7 @@ description: 先判斷專案語言,再為每個 function 與每個指令檔( 對每個指令檔,subagent 要**複製原始指令檔的完整內容**到草稿,並補上註解,作為實作時直接覆蓋原檔的版本。草稿檔放在 `.docs/doc-funcs/commands/{relative-path}` (保留原副檔名,便於語法檢查)。草稿內容規則: -- 檔案開頭必須有一段註解區塊,且「該份指令檔的用途」與「更新日期」必須包在同一個區塊內,不得拆成兩個分開的註解區塊。更新日期使用台灣時區(Asia/Taipei)並固定輸出為 `yyyy/MM/dd HH:mm:ss`(可用 `TZ='Asia/Taipei' date +'%Y/%m/%d %H:%M:%S'` 取得)。標頭格式必須依本 skill 的範本 `templates/command-header.md` 產生:依檔案類型選用 `#` 或 `::`/`REM` 變體,並遵守範本的佔位符與放置規則(shebang/`@echo off` 之後、外框成對)。派 subagent 產生指令檔草稿時,必須把該範本內容一併提供給 subagent。 +- 檔案開頭必須有一段註解區塊,且「該份指令檔的用途」與「更新日期」必須包在同一個區塊內,不得拆成兩個分開的註解區塊。更新日期格式依 `/jsc-shared:spec-time-log`。標頭格式必須依本 skill 的範本 `templates/command-header.md` 產生:依檔案類型選用 `#` 或 `::`/`REM` 變體,並遵守範本的佔位符與放置規則(shebang/`@echo off` 之後、外框成對)。派 subagent 產生指令檔草稿時,必須把該範本內容一併提供給 subagent。 - 原指令檔的每一行有效指令之間必須換行,且每行都要有對應的註解說明,解釋這行在做什麼、為何需要、重要參數或副作用。 - 註解符號必須符合該檔案類型:`*.sh`/`*.bash`/`*.ps1`/Makefile/yaml/Dockerfile 用 `#`;`*.bat`/`*.cmd` 用 `REM` 或 `::`。若該行語法不允許行尾註解(例如某些 yaml 值),改用該行上方獨立一行註解。 - 必須保留原始指令的實際行為與順序,只新增註解與開頭用途/日期區塊,不得變更指令邏輯;若發現原指令可能有問題,於草稿中以註解標註「需人工確認」,不要逕自修改。 @@ -91,7 +89,7 @@ description: 先判斷專案語言,再為每個 function 與每個指令檔( ## 第 5 步:詢問使用者要如何實作 -所有草稿完成且通過檢查後,主 agent 必須詢問使用者要如何實作(使用 AskUserQuestion),提供以下選項: +所有草稿完成且通過檢查後,主 agent 必須依 `/jsc-shared:spec-ask-user` 詢問使用者要如何實作(單選,已含「其他」選項),提供以下選項: 1. 全部一起實作。 2. 逐個草稿實作(每實作完一個草稿就回報,並讓使用者確認後再做下一個)。 @@ -105,11 +103,11 @@ description: 先判斷專案語言,再為每個 function 與每個指令檔( - function 草稿:依第 0 步判斷的語言把建議文件寫入原始碼(C# 用 XML documentation comments)。註解盡量使用繁體中文;保留既有正確文件,僅補齊缺漏或明顯不足處;此步驟不得為了文件改變 runtime 行為。 - 指令檔草稿:用草稿內容**覆蓋原始指令檔**(草稿已是含用途/日期/逐行註解的完整版本)。 -- Dockerfile 檔名正規化:覆蓋 Dockerfile 類指令檔時,若實際檔名大小寫與第 0 步判斷的專案多數命名慣例不符(例如專案多數為全小寫但檔名為 `Dockerfile`,或反之),用 `git mv` 把檔名調整為慣例風格;在大小寫不敏感的檔案系統上需兩段式改名(先 `git mv Dockerfile Dockerfile.tmp` 再 `git mv Dockerfile.tmp dockerfile`)。改名後必須同步更新專案內引用該檔名的位置(例如 docker-compose 的 `dockerfile:`、CI workflow 的 build 參數、文件內連結),確保建置行為不變;此檔名與引用調整不視為變更指令邏輯。第 0 步判斷為「無明顯多數」時保留原檔名,不做改名。 +- Dockerfile 檔名正規化:覆蓋 Dockerfile 類指令檔時,若實際檔名大小寫與第 0 步判斷的專案多數命名慣例不符(例如專案多數為全小寫但檔名為 `Dockerfile`,或反之),改名方式依 `/jsc-shared:spec-git-safety`(`git mv` 保留歷史、大小寫不敏感檔案系統的兩段式改名)。改名後必須同步更新專案內引用該檔名的位置(例如 docker-compose 的 `dockerfile:`、CI workflow 的 build 參數、文件內連結),確保建置行為不變;此檔名與引用調整不視為變更指令邏輯。第 0 步判斷為「無明顯多數」時保留原檔名,不做改名。 - workflow README 草稿:用草稿內容**覆蓋 `.gitea/workflows/readme.md`**,保留 workflow 實際設定不變,僅整理成說明文件。 - 若選「逐個草稿實作」,每完成一個就回報並等待使用者確認。 - 若遇到大量目標,仍要分批持續處理,不要只做示範。若 token 或時間不足,先完成已列入 index 的批次,並在 `.docs/doc-funcs-index.md` 標記 pending。 -- 輸出訊息格式:依 `/jsc-shared:spec-time-log` — 若該 function 或指令檔有輸出訊息,統一為 `[yyyy/MM/dd HH:mm:ss][階段][等級]: 訊息`(`階段` 選填、沿用所屬區塊原始名稱不翻譯;`等級` 限 `INF`/`WRN`/`ERR`/`TRC`/`DBG`;時間 Asia/Taipei);區塊階段命名(`#region`/橫幅段落名稱作為 `階段` 前綴並移除包裹/橫幅本身、僅移除標記保留指令與行為)、檔案標頭保留例外、一行一則規則皆依該 spec。調整僅限本次被文件化的原始碼或被覆蓋的指令檔,且不得改變訊息所反映的實際行為或判斷邏輯。 +- 輸出訊息格式:若該 function 或指令檔有輸出訊息,訊息格式、區塊階段命名、檔案標頭保留例外與一行一則規則一律依 `/jsc-shared:spec-time-log`。調整範圍僅限本次被文件化的原始碼或被覆蓋的指令檔,且不得改變訊息所反映的實際行為或判斷邏輯。 ## 第 7 步:實作註解後,保守優化效能並僅修正有誤的排版 @@ -121,7 +119,7 @@ description: 先判斷專案語言,再為每個 function 與每個指令檔( ## 第 8 步:重建 README -補齊後,重建專案根目錄的 README。README 檔名依第 0 步判斷的專案多數命名慣例決定(例如多數全大寫用 `README.md`、多數全小寫用 `readme.md`);第 0 步判斷為「無明顯多數」或無法判斷時,沿用既有 README 檔名,完全沒有既有 README 時預設 `README.md`。若根目錄已有 README(不論大小寫),先刪除既有檔案,再以慣例檔名產生新的 README;不要保留或合併舊內容,也不得同時留下兩種大小寫的 README。若檔名大小寫因此改變,需同步更新專案內引用舊 README 檔名的位置(例如文件連結、CI、套件描述檔)。README 必須包含更新時間,更新時間必須使用台灣時區(Asia/Taipei)並固定輸出為 `yyyy/MM/dd HH:mm:ss` 格式,例如 `2026/06/22 18:30:05`;README 必須在功能列表前加入專案列表,並只列出所有專案內的公開方法(public method、public constructor、public extension method、public operator),但不得列出單元測試方法;若方法位於測試專案、測試檔案、測試型別,或帶有測試框架屬性/命名(例如 `Test`、`Fact`、`Theory`、`TestMethod`、`TestCase`、`SetUp`、`TearDown`、`Initialize`、`Cleanup`),即使是 public 也要排除。產生 README 前,必須先為每個公開方法決定「最終功能名稱」: +補齊後,重建專案根目錄的 README。README 檔名依第 0 步判斷的專案多數命名慣例決定(例如多數全大寫用 `README.md`、多數全小寫用 `readme.md`);第 0 步判斷為「無明顯多數」或無法判斷時,沿用既有 README 檔名,完全沒有既有 README 時預設 `README.md`。若根目錄已有 README(不論大小寫),先刪除既有檔案,再以慣例檔名產生新的 README;不要保留或合併舊內容,也不得同時留下兩種大小寫的 README。若檔名大小寫因此改變,需同步更新專案內引用舊 README 檔名的位置(例如文件連結、CI、套件描述檔)。README 必須包含更新時間,格式依 `/jsc-shared:spec-time-log`;README 必須在功能列表前加入專案列表,並只列出所有專案內的公開方法(public method、public constructor、public extension method、public operator),但不得列出單元測試方法;若方法位於測試專案、測試檔案、測試型別,或帶有測試框架屬性/命名(例如 `Test`、`Fact`、`Theory`、`TestMethod`、`TestCase`、`SetUp`、`TearDown`、`Initialize`、`Cleanup`),即使是 public 也要排除。產生 README 前,必須先為每個公開方法決定「最終功能名稱」: - 預設功能名稱為 `Type.Method`。 - 若公開方法所在的型別簡名在不同專案或不同命名空間中重複,最終功能名稱不得只使用 `Type.Method`,必須在型別前加入可辨識的專案或模組前綴,格式為 `Module.Type.Method`。例如 `Hangfire.ServiceCollectionExtension.AddHangfireOptions`、`Hangfire.SqlServer.ServiceCollectionExtension.AddSqlServerHangfire`、`Swagger.ServiceCollectionExtension.AddSwagger`、`Swagger.ApplicationBuilderExtension.UseSwaggerUI`。 @@ -171,7 +169,7 @@ README 錨點檢查通過後,刪除本次產生的所有草稿與索引:`.do - 草稿是實作依據,不能跳過;所有草稿一律由 subagent 產生。 - function 註解步驟不得為了文件改變 runtime 行為;效能優化僅限第 7 步、僅限本次被文件化原始碼,且必須保持對外行為等價並驗證。 - 排版一律依照檔案原本的排版方式;只有排版確實有誤(縮排錯亂、tab/空白混用致錯、對齊錯誤造成誤讀、編碼/行尾異常)才修正該處,不得全檔重排、不得套用 formatter 改變原有風格。 -- 指令檔草稿只新增註解與開頭用途/日期區塊,不得變更指令邏輯;唯一例外是第 6 步的輸出訊息格式正規化(可移除區塊橫幅、把區塊名稱併入每行前綴、統一訊息格式),但不得改變訊息反映的實際行為,且開頭用途/更新日期標頭必須保留。指令檔開頭的用途與更新日期必須包在同一個註解區塊內,且格式依本 skill 的 `templates/command-header.md` 範本。 -- function 或指令檔若有輸出訊息,訊息格式、區塊階段命名、檔案標頭保留與一行一則規則一律依 `/jsc-shared:spec-time-log`,且不得藉此改變訊息反映的實際行為。 +- 指令檔草稿只新增註解與開頭用途/日期區塊,不得變更指令邏輯;唯一例外是輸出訊息格式正規化(同上,見前置區塊 spec-time-log),且開頭用途/更新日期標頭必須保留,格式依本 skill 的 `templates/command-header.md` 範本。指令檔開頭的用途與更新日期必須包在同一個註解區塊內。 +- function 或指令檔若有輸出訊息,其格式規則同上(見前置區塊 spec-time-log),且不得藉此改變訊息反映的實際行為。 - 若 function 或指令行為無法可靠推論,文件中要保守描述並標註不確定點,不要編造。 - 原始碼註解與 README 的語言依 `/jsc-shared:spec-output`(繁體中文為主;專有名詞、API 名稱、型別名稱與程式碼範例可保留英文)。 diff --git a/skills/issues-analyze-to-file/SKILL.md b/skills/issues-analyze-to-file/SKILL.md index 18d25d0..07ab023 100644 --- a/skills/issues-analyze-to-file/SKILL.md +++ b/skills/issues-analyze-to-file/SKILL.md @@ -7,21 +7,16 @@ description: 讀取一或多筆 Gitea issue URL(優先用 tea,否則用 Gite 你要讀取使用者提供的一或多筆 Gitea issue,彙整成完整需求文件,依功能拆成多個實作階段(每階段建立一個 issue),配合指定的 repositories 產生實作草稿,最後產出交付文件並依 issues 分組留言。**建立 issue 與留言屬於對外且不易復原的動作,必須先讓使用者確認過草稿再執行**。所有需求彙整、階段拆分與實作草稿一律先產生草稿檔,再詢問使用者是否實際建立 issue / 留言。請依下列階段依序完成。 -## 共用規範(shared plugin,必要前置) +## 共用規範(必要前置) -執行本 skill 前,先以 Skill 工具載入下列共用規範並全程遵守;**任一載入不到(shared plugin 未安裝)時,先詢問使用者是否安裝 shared plugin(`https://gitea.jsc.idv.tw/plugins/shared.git`),使用者不安裝則直接中斷本 skill**,不得只憑下方一行摘要繼續執行: - -- `/jsc-shared:spec-output`:繁體中文為主英文為輔、UTF-8(不含 BOM)無亂碼、Mermaid 呈現、個資(PII)去識別化。 -- `/jsc-shared:spec-execution`:不臆測/需人工確認、不擴及無關檔案。 -- `/jsc-shared:spec-gitea`:`GITEA_TOKEN` 機密保護、不依賴 `jq`、API 呼叫慣例(`Authorization: token`、分頁完整讀取)。 +先載入 `/jsc-shared:spec-preflight` 並依其流程處理;載入不到即代表 shared plugin 未安裝, +依該 spec 詢問使用者是否安裝 `https://gitea.jsc.idv.tw/plugins/shared.git`,不安裝則中斷本 skill。 +本 skill 需要的規範:`spec-output`、`spec-execution`、`spec-gitea`、`spec-issue-read`、`spec-ask-user`、`spec-subagent` ## 前置:輸入與工具 - **輸入**:至少一筆 issue URL(可多筆)。可另外指定「repositories 位置」(本機含多個專案的資料夾);若未指定,實作草稿以各 issue 所在的 repository 為準。 -- **工具優先序**: - 1. 若該 issue host 在 `tea login list` 中有對應 login,優先用 `tea`(`tea issues`、`tea comment` 等),並以 `--login --repo /` 指定目標。 - 2. 否則改用 Gitea REST API + `curl`,帶標頭 `Authorization: token $GITEA_TOKEN`(環境變數 `GITEA_TOKEN` 已設定)。 -- **不要依賴 `jq`**:依 `/jsc-shared:spec-gitea`(JSON 用 tea 結構化輸出或交給 subagent 解析,不 pipe 到 `jq`)。 +- **Gitea 工具選擇與呼叫慣例**:依 `/jsc-shared:spec-gitea` 執行(`tea` 與 API 的選擇與可用性檢查、不依賴 `jq`、分頁完整讀取、`Authorization: token` 等呼叫慣例),各 issue 的目標 `--login --repo /` 或 API base 依第 0 步解析出的 host/owner/repo 帶入。 - **工作目錄**:所有草稿與文件放在 `.docs/doc-issues-analyze-to-file/`。 - **議題描述流程圖**:依 `/jsc-shared:spec-output` — 產生要寫進 issue 的描述(尤其各階段 issue 的 body)時,有助理解就加入 Mermaid 流程圖(處理流程、狀態轉移、階段相依關係),忠實反映需求與拆分結果、不得杜撰。 @@ -36,12 +31,10 @@ description: 讀取一或多筆 Gitea issue URL(優先用 tea,否則用 Gite ## 第 1 步:讀取 issues 內容 -對每一筆 issue,讀取完整內容:`title`、`body`、`state`、`labels`、`milestone`、`assignees`、以及**所有 comments**;若 Gitea 版本支援,另讀該 issue 所屬 `project`。 +依 `/jsc-shared:spec-issue-read` 完整讀取每一筆 issue(描述、所有留言、所有附件,不得只讀描述、不得臆測缺漏部分),並補讀 `labels`、`milestone`、`assignees`;若 Gitea 版本支援,另讀該 issue 所屬 `project`。 - tea:`tea issues --repo / --login --comments`,或用 `tea issues list --fields index,title,body,labels,milestone,comments,url --output csv` 過濾。 -- API: - - issue 本體:`GET {base}/issues/{index}` - - 留言:`GET {base}/issues/{index}/comments` +- API:issue 本體 `GET {base}/issues/{index}`;留言與附件依 spec-issue-read 指定的端點分頁完整讀取。 - 同時盤點該 repo 既有的分類資源,供後續階段沿用: - 標籤:`GET {base}/labels`(tea:`tea labels list`) - 里程碑:`GET {base}/milestones`(tea:`tea milestones list`) @@ -71,7 +64,7 @@ description: 讀取一或多筆 Gitea issue URL(優先用 tea,否則用 Gite ## 第 4 步:確定 target repositories 並產生實作草稿(派 subagent) -決定要對照的 target repositories:使用者指定位置底下的所有專案,或各 issue 所在的 repository。對**每一個實作階段各派一個 subagent**,研究相關專案程式碼後產生實作草稿 `.docs/doc-issues-analyze-to-file/drafts/phase-{N}.md`。subagent 只讀程式碼與必要上下文、**不修改任何原始碼、不建立 issue、不留言**,只在 `.docs/` 底下寫草稿。每份草稿包含: +決定要對照的 target repositories:使用者指定位置底下的所有專案,或各 issue 所在的 repository。依 `/jsc-shared:spec-subagent` 對**每一個實作階段各派一個 subagent**,研究相關專案程式碼;本 skill 明確授權的例外寫入範圍僅限各自的草稿檔 `.docs/doc-issues-analyze-to-file/drafts/phase-{N}.md`,不得建立 issue、不得留言、不得修改任何原始碼。每份草稿包含: - 對應階段與對應(將建立的)issue 標題。 - 涉及的專案/檔案清單與定位(以 `path:line` 形式標出關鍵位置)。 @@ -88,9 +81,9 @@ description: 讀取一或多筆 Gitea issue URL(優先用 tea,否則用 Gite - 里程碑/專案/標籤的沿用決定,與第 1 步盤點到的既有資源一致(id/名稱對得上)。 - 若發現問題,先修正草稿並重新檢查,通過後才進入下一步。 -## 第 6 步:詢問使用者要如何執行(AskUserQuestion) +## 第 6 步:詢問使用者要如何執行 -草稿完成並通過檢查後,主 agent 必須用 AskUserQuestion 讓使用者確認要如何執行對外動作,至少提供: +草稿完成並通過檢查後,主 agent 依 `/jsc-shared:spec-ask-user` 詢問使用者要如何執行對外動作。本 skill 固定的 4 個情境選項,加上規範要求必附的「其他」共 5 項,超過 `AskUserQuestion` 的選項上限,故改用文字列出(附編號)供使用者回覆: 1. 全部執行:建立所有階段 issue,並產生交付文件、依 issues 分組留言。 2. 只建立 issue:建立階段 issue,但先不留言交付內容。 @@ -98,7 +91,7 @@ description: 讀取一或多筆 Gitea issue URL(優先用 tea,否則用 Gite 4. 逐階段確認:每建立一個 issue(及其留言)就回報,待使用者確認後再做下一個。 5. 其他(由使用者輸入自訂方式)。 -依使用者選擇進行後續步驟;未獲確認前不得建立 issue 或留言。 +依使用者選擇進行後續步驟;此為破壞性且不易復原的決策,未獲確認前不得建立 issue 或留言,且不得被任何自動確認旗標略過。 ## 第 7 步:依階段建立 issues @@ -129,6 +122,6 @@ description: 讀取一或多筆 Gitea issue URL(優先用 tea,否則用 Gite - 建立 issue 與留言是對外且不易復原的動作,**必須先經第 6 步使用者確認**;未確認前只產生本機草稿。 - 新 issue 一律沿用來源 issue 的里程碑與專案;標籤只從既有標籤中依需求性質挑選,不自行新建(除非使用者要求)。 -- subagent 與各步驟只讀程式碼與 issue、只寫 `.docs/` 草稿,**不得修改任何原始碼**;本 skill 的產出是需求文件、階段 issue、實作草稿與交付留言,不含改動程式邏輯。 -- JSON 解析(不依賴 `jq`)依 `/jsc-shared:spec-gitea`;個資保護(PII)與語言規範依 `/jsc-shared:spec-output`。 +- subagent 派工依 `/jsc-shared:spec-subagent`:只讀程式碼與 issue,僅授權寫入各自的草稿檔,**不得修改任何原始碼、不得建立 issue、不得留言**;本 skill 的產出是需求文件、階段 issue、實作草稿與交付留言,不含改動程式邏輯。 +- 議題讀取依 `/jsc-shared:spec-issue-read`;Gitea 工具與 JSON 解析(不依賴 `jq`)依 `/jsc-shared:spec-gitea`;個資保護(PII)與語言規範依 `/jsc-shared:spec-output`。 - 需求、階段與實作草稿若無法可靠推論,一律保守描述並標註「需人工確認」,不得編造 issue 未提及的內容。 diff --git a/skills/issues-analyze/SKILL.md b/skills/issues-analyze/SKILL.md index 67d4146..20782ec 100644 --- a/skills/issues-analyze/SKILL.md +++ b/skills/issues-analyze/SKILL.md @@ -7,18 +7,16 @@ description: 讀取使用者選擇的一或多種來源(專案編號、議題 你要先做工具可用性檢查並選擇工具;第二步詢問使用者要讀取哪些來源:專案編號、議題編號、檔案文件,至少選一種,接著讀取選定來源,並在產生保存議題前完整釐清需求——只要有任何不清楚的部分都必須詢問使用者,絕對不可以幻想——確認清楚後才彙整成保存議題內容。第三步必須把上個步驟產生的議題內容拆分成多個小功能議題,並為每個小功能議題產生標題、描述、阻擋關閉規則與依複雜度評估的到期日;若形成子母議題(保存議題為母、小功能議題為子),母議題必須所有子議題都關閉後才可關閉(優先以 issue dependency 阻擋);分析完成後,若議題屬於專案看板且欄位可對應進度語意(例如分析中/待處理/進行中/待測試/已完成),把議題移到「待處理」欄位。第四步必須將小功能議題依到期日與相依關係排序,並把排序結果留言到保存議題;**本 skill 不實作程式碼**——不修改原始碼、不 commit、不 push、不開 PR,後續實作交由 `/jsc-code:issues` 或使用者另行處理。所有中間成果都不准落地成草稿檔,必須一律使用 `tea` 或 Gitea API 保存到議題描述或留言。 -## 共用規範(shared plugin,必要前置) +## 共用規範(必要前置) -執行本 skill 前,先以 Skill 工具載入下列共用規範並全程遵守;**任一載入不到(shared plugin 未安裝)時,先詢問使用者是否安裝 shared plugin(`https://gitea.jsc.idv.tw/plugins/shared.git`),使用者不安裝則直接中斷本 skill**,不得只憑下方一行摘要繼續執行: - -- `/jsc-shared:spec-output`:繁體中文為主英文為輔、UTF-8(不含 BOM)無亂碼、表格/Mermaid 呈現、個資(PII)去識別化。 -- `/jsc-shared:spec-execution`:不臆測/需人工確認、已知資訊跳過詢問。 -- `/jsc-shared:spec-gitea`:tea/API 工具選擇與檢查、`GITEA_TOKEN` 機密保護、不依賴 `jq`、API 分頁完整讀取。 -- `/jsc-shared:spec-project-board`:看板欄位語意對應、GET 探測(404/501 不支援)、不往回移、不得新建欄位。 +先載入 `/jsc-shared:spec-preflight` 並依其流程處理;載入不到即代表 shared plugin 未安裝, +依該 spec 詢問使用者是否安裝 `https://gitea.jsc.idv.tw/plugins/shared.git`,不安裝則中斷本 skill。 +本 skill 需要的規範:`spec-output`、`spec-execution`、`spec-gitea`、`spec-issue-read`、`spec-no-scratch-files`、`spec-subagent`、`spec-todo-list`、`spec-project-board` ## 絕對準則(不可違反) -- **全程不得在磁碟落地任何檔案**:不建立 `.docs/`、不寫草稿檔、不寫暫存檔、不用檔案傳遞中間結果。所有中間成果(需求彙整、保存議題內容、小功能拆分、到期日排序、交付摘要)一律留在**對話內容**與 **subagent 的回傳值**,並透過 `tea` 或 Gitea API **保存到議題描述或留言**。例外只有一個:為了讀取議題附件(圖片等二進位檔)而**唯讀暫存下載到系統暫存目錄**,讀取完畢後立即刪除,不得下載到工作目錄或任何 repo 內、不得用暫存檔傳遞其他中間成果。除此之外不產生任何本機檔案。 +- **不落地**:依 `/jsc-shared:spec-no-scratch-files` 執行——全程不建立任何草稿檔/暫存檔,所有中間成果(需求彙整、保存議題內容、小功能拆分、到期日排序、交付摘要)一律留在對話內容、議題描述或留言;唯一例外是讀取議題附件時的唯讀暫存,讀取完畢立即刪除。 +- **派 subagent(例如研究 target repositories 程式碼以補充議題描述)**:依 `/jsc-shared:spec-subagent` 執行——一個明確目標派一個 subagent、只讀不寫、回傳結構化結果供本 skill 判讀後再寫回議題,不得直接寫外部系統。 ## 前置:輸入與工具 @@ -28,19 +26,14 @@ description: 讀取使用者選擇的一或多種來源(專案編號、議題 - **檔案文件**:本機文件路徑,可多筆;支援 Markdown、純文字與其他可直接讀取的需求文件。 - **保存目標**:合併整理後必須在指定專案建立一張議題保存;若輸入來源未包含可作為保存目標的專案編號,必須詢問使用者提供專案編號,不得自行臆測。 - **repositories 位置**:可另外指定本機含多個專案的資料夾;若未指定,程式碼分析參考(僅供研究、補充議題描述,不修改)以來源議題所在 repo、保存目標 repo 或使用者指定 repo 為準。 -- **工具選擇**:依 `/jsc-shared:spec-gitea` 的工具選擇流程(檢查 `tea`/`tea login list`/`GITEA_TOKEN` 後詢問使用者用 `tea` 或 `api`;已明確指定工具時才可跳過詢問;不依賴 `jq`,JSON 改用 tea 結構化輸出或交給 subagent 解析)。 -- **議題必須連同留言與附件一起讀取**:處理任何議題(含專案底下展開的議題)時,除了 `title`/`body` 等欄位,必須一併讀取**所有留言(comments)**與**所有附件(attachments/assets,含議題本身與各留言的附件)**,其內容都是需求分析的依據: - - 附件清單:`tea` 目前沒有附件指令,一律走 API — 議題附件 `GET {base}/repos/{owner}/{repo}/issues/{index}/assets`、留言附件 `GET {base}/repos/{owner}/{repo}/issues/comments/{id}/assets`,取得每個附件的檔名、類型與下載 URL。 - - 文字類附件(Markdown、純文字、CSV、JSON 等):以 `curl` 直接取得內容到對話中分析,不落地。 - - 圖片或其他二進位附件:依絕對準則的例外**唯讀暫存下載到系統暫存目錄**讀取(例如圖片以視覺方式讀取內容),讀取完畢後立即刪除暫存檔。 - - 無法讀取的格式(或僅有 `tea` 而無 token 可下載附件):在保存議題內容中列出附件檔名與 URL 並標註「附件無法讀取,需人工確認」,不得忽略附件的存在,也不得臆測其內容。 -- **禁止草稿落地**:所有流程都不准建立 `.docs/` 或其他本機草稿檔;需求整理、小功能拆分、排序、進度與交付資訊一律使用 `tea` 或 Gitea API 保存到對應議題描述或留言。 -- **TODO list**:所有建立或更新的議題描述最後都必須加上依該描述內容推導出的 `## TODO` 區塊,使用 Markdown checklist(`- [ ] ...`);TODO 必須可執行、可驗收,且不得加入描述未提及或無法合理推得的工作。 +- **工具選擇**:依 `/jsc-shared:spec-gitea` 執行(見第 1 步)。 +- **議題讀取**:依 `/jsc-shared:spec-issue-read` 執行——連同所有留言與附件一起讀取,附件依類型分流讀取,無法讀取的格式標註「附件無法讀取,需人工確認」。 +- **TODO list**:依 `/jsc-shared:spec-todo-list` 執行——所有建立或更新的議題描述最後都必須有 `## TODO` 區塊。 - **議題描述流程圖**:依 `/jsc-shared:spec-output` — 產生保存議題或小功能議題的描述時,有助理解就加入 Mermaid 流程圖(需求流程、狀態轉移、相依/阻擋關係),忠實反映需求與拆分結果、不得杜撰。 ## 第 1 步:工具可用性檢查與使用方式選擇 -依 `/jsc-shared:spec-gitea` 的工具選擇流程執行:檢查 `tea`(`command -v tea`、`tea login list`,失敗記錄原因不中止)與 `GITEA_TOKEN`(只輸出「已設定/未設定」)→ 詢問使用者要用 `tea` 或 `api`(除非使用者已明確指定,不得自行決定;選 `tea` 後續仍需確認來源 host 有對應 login)→ 兩種方式都不可用則停止並回報缺少 `tea login` 或 `GITEA_TOKEN`(不要要求使用者把 token 貼進對話)。 +依 `/jsc-shared:spec-gitea` 執行工具可用性檢查與使用方式選擇。 ## 第 2 步:選擇讀取來源、讀取內容並保存議題內容 @@ -83,8 +76,8 @@ description: 讀取使用者選擇的一或多種來源(專案編號、議題 - target repositories 來源:使用者指定的 repositories 位置,或「以來源議題所在 repo/保存目標 repo 為準」。 4. 若使用者指定了 repositories 位置,先確認該路徑存在並列出其中的專案;若未指定,記錄「以來源議題所在 repo/保存目標 repo 為準」,並確認本機是否已 clone 對應 repo(沒有就在保存議題留言中標註需人工提供或 clone)。 5. 依選定來源讀取內容: - - 專案:讀取 project 描述、欄位/卡片、project metadata,並只讀取該專案下**開啟中的議題**(若 API 有分頁必須完整分頁讀取;每筆議題都依「議題必須連同留言與附件一起讀取」完整讀取)。若 Gitea 版本不支援 project API 或無法由 project 取得開啟中的 issue 清單,標註「此 Gitea 版本不支援 project API,需人工處理」,並請使用者改提供議題編號或可匯出的 project 文件。 - - 議題:對每一筆 issue,讀取完整內容:`title`、`body`、`state`、`labels`、`milestone`、`assignees`、**所有 comments**、以及**議題與各留言的所有附件**(讀取方式見前置「議題必須連同留言與附件一起讀取」);若 Gitea 版本支援,另讀該 issue 所屬 `project`。 + - 專案:讀取 project 描述、欄位/卡片、project metadata,並只讀取該專案下**開啟中的議題**(若 API 有分頁必須完整分頁讀取;每筆議題都依 `/jsc-shared:spec-issue-read` 完整讀取)。若 Gitea 版本不支援 project API 或無法由 project 取得開啟中的 issue 清單,標註「此 Gitea 版本不支援 project API,需人工處理」,並請使用者改提供議題編號或可匯出的 project 文件。 + - 議題:對每一筆 issue,依 `/jsc-shared:spec-issue-read` 讀取完整內容(`title`、`body`、`state`、`labels`、`milestone`、`assignees`、所有 comments、議題與各留言的所有附件);若 Gitea 版本支援,另讀該 issue 所屬 `project`。 - 檔案文件:讀取文件全文;若格式無法直接讀取,標註需人工轉換或提供純文字/Markdown。 6. 同時盤點該 repo 既有的分類資源,供後續階段沿用: - 標籤:`GET {base}/labels`(tea:`tea labels list`) @@ -100,7 +93,7 @@ description: 讀取使用者選擇的一或多種來源(專案編號、議題 - 完整需求描述:整合專案、議題(含留言與附件內容)、檔案文件的內容,去除重複、補齊上下文,形成單一連貫的需求敘述。 - 驗收條件/預期結果:能從來源內容推得的,逐條列出;不能確定的標註「需人工確認」。 - 保存議題分類:labels/milestone/project 掛載方式。 - - `## TODO`:根據保存議題描述內容產生 Markdown checklist,放在描述最後。 + - `## TODO`:依 `/jsc-shared:spec-todo-list` 產生 Markdown checklist,放在描述最後。 需求彙整只做整理與歸納,不得編造來源內容未提及的需求;無法確定處必須依上方「需求釐清」關卡先詢問使用者,只有使用者明確指示保留的項目才可標註「需人工確認」後寫入。 @@ -109,7 +102,7 @@ description: 讀取使用者選擇的一或多種來源(專案編號、議題 將第 2 步保存到議題的內容拆分成多個小功能議題,使用 `tea` 或 Gitea API 建立/更新小功能議題或將小功能清單留言到保存議題;不得寫入本機草稿檔。每個小功能議題至少包含: - 標題:能清楚表示單一小功能交付範圍。 -- 描述:描述內容必須先詢問使用者想要包含哪些段落或資訊,至少提供可選項,例如需求背景、功能範圍、驗收條件、技術提示、測試方式、相依關係、風險與備註;依使用者選擇組成描述,不得自行固定格式。每個小功能議題建立或更新前,都必須逐一詢問使用者該議題描述是否有補充內容;使用者提供補充時,必須整合到該小功能議題描述中,若使用者明確表示沒有補充才可繼續建立或更新。描述最後必須加入 `## TODO` 區塊,根據該小功能描述內容產生 Markdown checklist。 +- 描述:描述內容必須先詢問使用者想要包含哪些段落或資訊,至少提供可選項,例如需求背景、功能範圍、驗收條件、技術提示、測試方式、相依關係、風險與備註;依使用者選擇組成描述,不得自行固定格式。每個小功能議題建立或更新前,都必須逐一詢問使用者該議題描述是否有補充內容;使用者提供補充時,必須整合到該小功能議題描述中,若使用者明確表示沒有補充才可繼續建立或更新。描述最後必須依 `/jsc-shared:spec-todo-list` 加入 `## TODO` 區塊。 - 阻擋關閉:小功能議題建立後必須以可追溯方式阻擋其被直接關閉,直到驗收條件完成。可用方式包含加上既有 blocking/blocked 類標籤、在 body 中加入「關閉前檢查清單」、建立與保存議題的追溯連結,或依 Gitea 支援能力設定 issue dependency;不得使用不存在的標籤或 API,找不到支援方式時標註需人工處理。若小功能有前後相依,較先完成的前置議題必須阻擋較後完成的後置議題(前置 issue blocks 後置 issue;後置 issue is blocked by 前置 issue),不得反向設定。 - 複雜度:依工作量、跨模組程度、風險、未知數與測試成本評估為 `S`/`M`/`L`/`XL`。 - 到期日:根據複雜度評估 due date,預設從建立日往後推算:`S` 3 個工作天、`M` 5 個工作天、`L` 10 個工作天、`XL` 15 個工作天;若遇週末順延到下一個工作天。若小功能有相依關係,必須先排定相依順序,後置功能的到期日不得早於其前置功能的到期日,且應從最後一個前置功能的到期日之後再依自身複雜度推算。若 Gitea API 不支援 due date,寫入 issue body 並回報需人工設定。 @@ -117,8 +110,8 @@ description: 讀取使用者選擇的一或多種來源(專案編號、議題 **子母議題關閉規則**:若本次拆分實際建立了子母關係(保存議題為**母議題**、拆出的小功能議題為**子議題**),母議題必須在**所有子議題都關閉後才可關閉**,建立子議題時就要把這個限制落實: -- 優先用 Gitea issue dependency 實作:把母議題設為 blocked by **每一個**子議題(API `POST {base}/issues/{母議題 index}/dependencies`,body 帶子議題資訊;先以 GET 探測該實例是否啟用 dependency 功能,404/501 視為不支援),讓 Gitea 在子議題尚未全部關閉前直接阻止關閉母議題。 -- dependency 不支援或未啟用時:在母議題描述加入「子議題清單」markdown 任務清單(每項連結一個子議題,例如 `- [ ] # <子議題標題>`)與「關閉前檢查:所有子議題皆已關閉」字樣,並在回報中標註此限制需人工遵守;不得對未確認存在的端點做寫入。 +- 優先用 Gitea issue dependency 實作:依 `/jsc-shared:spec-project-board` 的介面探測慣例(先 GET 探測、404/501 視為不支援、不寫入未確認端點)確認該實例是否啟用 dependency 功能後,把母議題設為 blocked by **每一個**子議題(API `POST {base}/issues/{母議題 index}/dependencies`,body 帶子議題資訊),讓 Gitea 在子議題尚未全部關閉前直接阻止關閉母議題。 +- dependency 不支援或未啟用時:在母議題描述加入「子議題清單」markdown 任務清單(每項連結一個子議題,例如 `- [ ] # <子議題標題>`)與「關閉前檢查:所有子議題皆已關閉」字樣,並在回報中標註此限制需人工遵守。 - 後續新增或補拆子議題時,必須同步補上對應的 dependency 或母議題子議題清單項目,不得遺漏。 決定要對照的 target repositories:使用者指定位置底下的所有專案、來源議題所在 repo,或使用者指定 repo。可研究相關專案程式碼以補充小功能議題描述,但所有分析結果必須直接保存到小功能議題描述或留言,不得建立本機草稿檔。 diff --git a/skills/issues-sync/SKILL.md b/skills/issues-sync/SKILL.md index 501f3b2..4d4def9 100644 --- a/skills/issues-sync/SKILL.md +++ b/skills/issues-sync/SKILL.md @@ -7,29 +7,23 @@ description: 讀取一個 Gitea 專案(project)或單一議題(優先用 t 你要讀取使用者提供的一個 Gitea **專案(project)**或**單一議題**,取得要同步的議題清單,然後一個議題派一個 subagent,**以目前工作目錄下的所有檔案為依據**,勾稽並更新每個議題的 TODO(markdown 任務清單)與標籤,最後把 TODO 的異動整理成留言。例外:輸入為專案且使用者指定「關閉專案/專案完成」時,進入**專案完成模式**(見第 1 步之後的專節),跳過標籤分組與逐議題勾稽,改為批次搬移至「已完成」並關閉議題。**修改議題正文、變更議題標籤、留言都是對外且不易復原的動作,subagent 只回傳同步計畫(不落地任何檔案),實際寫入 Gitea 前必須先讓使用者確認**。請依下列階段依序完成。 -## 共用規範(shared plugin,必要前置) +## 共用規範(必要前置) -執行本 skill 前,先以 Skill 工具載入下列共用規範並全程遵守;**任一載入不到(shared plugin 未安裝)時,先詢問使用者是否安裝 shared plugin(`https://gitea.jsc.idv.tw/plugins/shared.git`),使用者不安裝則直接中斷本 skill**,不得只憑下方一行摘要繼續執行: - -- `/jsc-shared:spec-output`:繁體中文為主英文為輔、UTF-8(不含 BOM)無亂碼、Mermaid 呈現、個資(PII)去識別化。 -- `/jsc-shared:spec-execution`:不臆測/需人工確認。 -- `/jsc-shared:spec-gitea`:`GITEA_TOKEN` 機密保護、不依賴 `jq`、API 呼叫慣例(分頁完整讀取、GET 探測版本相依端點)。 -- `/jsc-shared:spec-project-board`:看板欄位語意對應與建議欄位規則、404/501 視為不支援、不得新建欄位。 +先載入 `/jsc-shared:spec-preflight` 並依其流程處理;載入不到即代表 shared plugin 未安裝, +依該 spec 詢問使用者是否安裝 `https://gitea.jsc.idv.tw/plugins/shared.git`,不安裝則中斷本 skill。 +本 skill 需要的規範:`spec-output`、`spec-execution`、`spec-gitea`、`spec-project-board`、`spec-issue-read`、`spec-todo-list`、`spec-ask-user`、`spec-subagent`、`spec-no-scratch-files` ## 絕對準則(不可違反) -- **全程不得在磁碟落地任何檔案**:不建立 `.docs/`、不寫草稿檔、不寫暫存檔、不用檔案傳遞中間結果。所有中間成果(議題清單、需求分析、追加後的正文、標籤異動、勾稽結果、留言內容)一律留在**對話內容**與 **subagent 的回傳值**裡。最終產物只透過 `tea` 或 Gitea API **寫回議題正文/標籤/留言**,除此之外不產生任何本機檔案。 +依 `/jsc-shared:spec-no-scratch-files` 全程不落地任何檔案;本 skill 的中間成果(議題清單、需求分析、追加後的正文、標籤異動、勾稽結果、留言內容)一律留在**對話內容**與**subagent 的回傳值**裡,最終產物只透過 `tea` 或 Gitea API **寫回議題正文/標籤/留言**。 ## 前置:輸入與工具 - **輸入**:一個 Gitea 專案(project)或一筆議題的參照(URL 最佳,或 `owner/repo` + project id/issue index)。 - **依據來源**:所有「TODO 是否完成」「該補哪些 TODO」「該掛哪些標籤」的判斷,一律以**目前工作目錄下的檔案內容**為準(程式碼、設定、文件等),不得臆測。 -- **工具優先序**: - 1. 若該 host 在 `tea login list` 中有對應 login,優先用 `tea`(`tea issues`、`tea comment`、`tea labels` 等),並以 `--login --repo /` 指定目標。 - 2. 否則改用 Gitea REST API + `curl`,帶標頭 `Authorization: token $GITEA_TOKEN`(環境變數 `GITEA_TOKEN` 已設定;未設定則停下請使用者提供)。 -- **不要依賴 `jq`**:依 `/jsc-shared:spec-gitea`(JSON 用 tea 結構化輸出或交給 subagent 解析,不 pipe 到 `jq`)。 -- **TODO 的定義**:議題正文(body)中的 markdown 任務清單項目,`- [ ]`(未完成)與 `- [x]`(已完成)。本 skill 所有「TODO 追蹤/勾稽/新增」都在這種任務清單上操作。 -- **專案進度欄位(project column)**:依 `/jsc-shared:spec-project-board`(欄位語意以看板實際名稱為準、不得假設五欄都存在、對不上或介面不支援時不移動只回報建議);本 skill 會依議題描述、需求與 TODO 勾稽結果建議議題應在的欄位,並在使用者確認後調整,對應規則見第 3.5 步。 +- **工具選擇**:依 `/jsc-shared:spec-gitea`(`tea` 或 API + `GITEA_TOKEN` 的選擇、可用性檢查、不依賴 `jq`);本 skill 常用 `tea issues`、`tea comment`、`tea labels`,或對應 API 端點,一律以 `--login --repo /` 指定目標。 +- **TODO 的定義**:依 `/jsc-shared:spec-todo-list`(Markdown checklist `- [ ]`/`- [x]`);本 skill 所有「TODO 追蹤/勾稽/新增」都在議題正文的這種任務清單上操作。 +- **專案進度欄位(project column)**:依 `/jsc-shared:spec-project-board`;本 skill 依議題描述、需求與 TODO 勾稽結果建議欄位並在使用者確認後調整,規則見第 3.5 步。 - **議題描述流程圖**:依 `/jsc-shared:spec-output` — 補進議題正文或進度留言的內容有助理解時(需求流程、TODO 先後/相依),加入 Mermaid 流程圖,忠實反映議題需求與 TODO 現況、不得杜撰。 ## 第 0 步:解析輸入、判斷專案或議題、準備工具 @@ -56,13 +50,13 @@ description: 讀取一個 Gitea 專案(project)或單一議題(優先用 t 只在第 0 步標記為專案完成模式時進入本節。沿用第 1 步取得的「屬於此專案的議題清單」,之後**不做**標籤分組、不派 subagent、不勾稽 TODO、不更新標籤、不留言進度,改依下列流程把專案擁有的所有議題搬到「已完成」並關閉: 1. **列出將處理的議題清單**:每筆列出 `owner/repo`、編號、標題、目前狀態與所在看板欄位(可取得時),以及該議題是否還有未完成 TODO(僅從議題正文的任務清單計數,不做工作目錄勾稽)。 -2. **使用者確認(AskUserQuestion,必要,不可跳過)**:關閉議題是對外且不易復原的動作,未確認前不得寫入。至少提供選項: +2. **使用者確認(必要,不可跳過)**:依 `/jsc-shared:spec-ask-user`(破壞性決策不得被跳過),至少提供選項: - 全部搬到「已完成」並關閉。 - 逐議題確認(每關一筆回報,確認後再做下一筆)。 - 取消(不動任何議題)。 清單中若有議題仍有未完成 TODO,必須在詢問時明確標出這些議題與其未完成數量,讓使用者知道將照關。 3. **逐議題執行**(確認後): - - **搬到「已完成」欄位**:若議題屬於專案看板且看板有可對應「已完成」語意的欄位,依既有規則先探測 project/column API(404/501 視為不支援、不對未確認端點寫入),可用就把議題移到該欄位;不支援或欄位對不上就跳過搬移(議題關閉後看板通常會自行呈現完成狀態),於回報註明。 + - **搬到「已完成」欄位**:依 `/jsc-shared:spec-project-board` 判斷看板是否有可對應「已完成」語意的欄位並嘗試移動;不支援或欄位對不上就跳過搬移(議題關閉後看板通常會自行呈現完成狀態),於回報註明。 - **關閉議題**:tea:`tea issues close --repo / --login `;API:`PATCH {base}/repos/{owner}/{repo}/issues/{index}`,body `{"state":"closed"}`。 - 單筆失敗(權限不足、議題被鎖定等)不中斷整批:記錄失敗原因後繼續下一筆。 4. **回報**:搬移成功/跳過(含原因)筆數、關閉成功/失敗(含原因)清單、照關但仍有未完成 TODO 的議題清單(供追溯);專案看板本身的關閉/封存 Gitea 不一定支援 API 操作,如需關閉專案本身,提示使用者到 Gitea 介面手動處理。 @@ -73,27 +67,22 @@ description: 讀取一個 Gitea 專案(project)或單一議題(優先用 t 1. 讀取清單中每個議題的 `labels`。 2. **跳過條件**:若清單只有**一個議題**,或**所有議題都沒有標籤**,跳過本步、同步全部清單。 -3. 否則依標籤把議題分組(一個議題有多個標籤時,各組都出現),用 **AskUserQuestion(multiSelect)** 讓使用者挑選要同步「哪些標籤」的議題: - - 每個選項是一個標籤(附該標籤下的議題數量),讓使用者多選。 - - 標籤數量超過 AskUserQuestion 選項上限(4)時,改在訊息中列出全部標籤與各自議題數,請使用者回覆要同步哪些(可用「其他」自訂輸入)。 +3. 否則依標籤把議題分組(一個議題有多個標籤時,各組都出現),依 `/jsc-shared:spec-ask-user` 用 **AskUserQuestion(multiSelect)** 讓使用者挑選要同步「哪些標籤」的議題(每個選項為一個標籤並附議題數量;超過選項上限時改列文字清單並支援「其他」)。 4. 依選取的標籤過濾清單:保留**帶有任一選取標籤**的議題,作為後續要同步的最終清單。未被選取標籤涵蓋的議題不同步。 ## 第 3 步:逐議題派 subagent 產生同步計畫(每個議題一個 subagent) -對最終清單中的**每一個議題各派一個 subagent**。subagent **以目前工作目錄下的所有檔案為依據**,只讀檔案與議題、**把結果以結構化內容回傳給主 agent,不得在磁碟寫任何檔案**、**不得修改任何工作目錄的原始碼、不得直接改議題正文/標籤、不得直接留言**。每個 subagent 依序做: +對最終清單中的**每一個議題各派一個 subagent**,依 `/jsc-shared:spec-subagent`(一議題一 subagent、只讀不寫、回傳結構化結果、不得改動原始碼、不得直接寫外部系統)。subagent 以目前工作目錄下的所有檔案為依據,依序做: -1. **讀取議題**:`title`、`body`(含其中的 TODO 任務清單)、`labels`、以及既有 comments。 - - tea:`tea issues --repo / --login --comments`。 - - API:`GET {base}/repos/{owner}/{repo}/issues/{index}` 與 `.../comments`。 - - 一併盤點該 repo 既有標籤(供第 3.2 用):`GET {base}/repos/{owner}/{repo}/labels`(tea:`tea labels list`)。 -2. **3.1 判斷 TODO 是否足以追蹤議題描述的需求,不足就補**:分析議題描述的需求,逐項對照現有 TODO,判斷目前的 TODO 清單是否足以追蹤議題描述的需求。若不足,補上缺少的 TODO(以未完成 `- [ ]` 形式),規劃**追加到議題正文**(回傳內容中給出「追加後的正文」與「新增了哪些 TODO」)。補的 TODO 必須能對應到議題描述的需求,不得編造需求未涵蓋的項目。 +1. **讀取議題**:依 `/jsc-shared:spec-issue-read` 完整讀取議題(`title`/`body`,含其中的 TODO 任務清單/`labels`/所有 comments),並一併盤點該 repo 既有標籤(供第 3.2 用):`GET {base}/repos/{owner}/{repo}/labels`(tea:`tea labels list`)。 +2. **3.1 判斷 TODO 是否足以追蹤議題描述的需求,不足就補**:分析議題描述的需求,逐項對照現有 TODO,判斷目前的 TODO 清單是否足以追蹤議題描述的需求。若不足,依 `/jsc-shared:spec-todo-list` 補上缺少的 TODO,規劃**追加到議題正文**(回傳內容中給出「追加後的正文」與「新增了哪些 TODO」)。 3. **3.2 依需求更新可用標籤**:依議題需求性質,從該 repo **既有標籤**中挑選應掛上(或應移除)的標籤,回傳內容中列出「建議的標籤異動」(新增哪些、移除哪些、維持哪些)。**不自行新建標籤**,除非使用者要求;找不到合適標籤就維持原樣並標註。 -4. **3.3 逐條勾稽未完成 TODO 是否已完成**:對所有**未完成**的 TODO(含 3.1 新增的),逐條依工作目錄下的檔案內容判斷是否已完成。已完成者標記為 `- [x]` 並在回傳內容記下判斷依據(以 `path:line` 指出對應實作位置);無法從檔案可靠判斷者維持未完成並標註「需人工確認」。 +4. **3.3 逐條勾稽未完成 TODO 是否已完成**:對所有**未完成**的 TODO(含 3.1 新增的),依 `/jsc-shared:spec-todo-list` 的舉證規則,逐條依工作目錄下的檔案內容判斷是否已完成並標記為 `- [x]`(附 `path:line`);無法可靠判斷者維持未完成並標註「需人工確認」。 5. **3.4 整理 TODO 異動留言**:若本議題有任何 TODO 異動(**新增**的 TODO,或**狀態變更**——由未完成改為完成),整理成一則留言內容,包含:本次新增了哪些 TODO、哪些 TODO 判定為完成(附對應實作位置)、哪些仍未完成(含原因/需人工確認)。若沒有任何 TODO 異動,回傳標明「無異動、不需留言」。 6. **3.5 建議專案進度欄位**:若本議題屬於某個專案看板且能取得看板的欄位清單與議題目前所在欄位,依議題描述、需求與 3.1/3.3 的結果,從**看板實際存在的欄位**中建議議題應在的欄位;語意對應規則依 `/jsc-shared:spec-project-board` 的建議欄位表(分析中/待處理/進行中/待測試/已完成,欄位名稱以看板實際名稱為準、語意相近即可對應)。 回傳內容需含:目前欄位、建議欄位、判斷依據。建議欄位與目前欄位相同時標明「欄位無異動」;看板欄位語意對不上(或取不到欄位資訊)時標明「無法對應、維持原欄位」並列出實際欄位名稱,不得硬套。議題不屬於任何專案看板時跳過本項。 -每個 subagent **回傳**一份結構化同步計畫(**不落地成檔案**),至少包含:議題參照與標題、追加後的完整正文(標明新增與勾稽的變更)、建議的標籤異動、TODO 異動留言內容(或「無異動」)、專案進度欄位建議(目前欄位/建議欄位/判斷依據,或「不屬於專案看板」「無法對應」)、以及所有「需人工確認」項目。 +每個 subagent **回傳**一份結構化同步計畫(依 `/jsc-shared:spec-no-scratch-files`,不落地成檔案),至少包含:議題參照與標題、追加後的完整正文(標明新增與勾稽的變更)、建議的標籤異動、TODO 異動留言內容(或「無異動」)、專案進度欄位建議(目前欄位/建議欄位/判斷依據,或「不屬於專案看板」「無法對應」)、以及所有「需人工確認」項目。 ## 第 4 步:同步計畫品質檢查 @@ -102,13 +91,13 @@ description: 讀取一個 Gitea 專案(project)或單一議題(優先用 t - 內容以繁體中文為主、英文為輔,無亂碼或破損文字。 - 每個要同步的議題都有對應的同步計畫;正文的 TODO 變更(新增/勾稽)與留言內容的敘述一致。 - 標籤異動只用到該 repo 既有標籤(名稱/id 對得上第 3.1 盤點結果),未擅自新建標籤。 -- 「已完成」的勾稽都有工作目錄檔案的依據;無依據者標為未完成或「需人工確認」,未被誤判為完成。 +- 「已完成」的勾稽都依 `/jsc-shared:spec-todo-list` 附有工作目錄檔案依據;無依據者標為未完成或「需人工確認」,未被誤判為完成。 - 進度欄位建議只使用看板實際存在的欄位,且與 TODO 勾稽結果一致(例如仍有未完成 TODO 的議題不得建議「已完成」、仍有「需人工確認」項目的議題不得越過「待測試」)。 - 有問題先在對話中修正同步計畫並重新檢查,通過後才進入下一步。 ## 第 5 步:詢問使用者要如何執行(AskUserQuestion) -同步計畫通過檢查後,主 agent 用 AskUserQuestion 讓使用者確認要如何對 Gitea 執行寫入,至少提供: +同步計畫通過檢查後,主 agent 依 `/jsc-shared:spec-ask-user`(破壞性決策,未獲確認前不得寫入)用 AskUserQuestion 讓使用者確認要如何對 Gitea 執行寫入,至少提供: 1. 全部執行:追加/勾稽 TODO 到議題正文、套用標籤異動、調整專案進度欄位、對有異動的議題留言。 2. 只更新議題(正文+標籤+進度欄位),先不留言。 @@ -116,8 +105,6 @@ description: 讀取一個 Gitea 專案(project)或單一議題(優先用 t 4. 逐議題確認:每處理完一個議題就回報,待使用者確認後再做下一個。 5. 其他(由使用者輸入自訂方式)。 -未獲確認前不得對 Gitea 做任何寫入。 - ## 第 6 步:套用到 Gitea 依使用者選擇,對最終清單的每個議題執行(主 agent 執行,非 subagent): @@ -127,11 +114,11 @@ description: 讀取一個 Gitea 專案(project)或單一議題(優先用 t - 更新前先重新讀一次議題正文,若與 subagent 讀到的版本已不同(他人期間有改動),停下該議題並回報,避免覆蓋他人變更。 - **標籤異動**:套用建議的新增/移除。 - tea:`tea labels`/issue 編輯對應指令;API:`POST`/`DELETE {base}/repos/{owner}/{repo}/issues/{index}/labels`(用既有 label id)。 -- **調整專案進度欄位**:對「建議欄位與目前欄位不同」的議題,依 `/jsc-shared:spec-project-board` 把議題移到建議欄位(先 GET 探測端點、404/501 視為不支援且不得對未確認端點寫入;介面可用時一次一個議題並確認回應成功;不可用時不視為錯誤,改在第 7 步回報列「議題 → 建議欄位」清單請使用者手動拖曳;只在欄位確實存在且語意對應明確時移動,有疑慮就不動並回報)。「欄位無異動」「無法對應」「不屬於專案看板」的議題跳過。 +- **調整專案進度欄位**:對「建議欄位與目前欄位不同」的議題,依 `/jsc-shared:spec-project-board` 嘗試把議題移到建議欄位;不可用時不視為錯誤,改在第 7 步回報列「議題 → 建議欄位」清單請使用者手動拖曳。「欄位無異動」「無法對應」「不屬於專案看板」的議題跳過。 - **留言**:對有 TODO 異動的議題張貼留言。 - tea:`tea comment --repo / --login "<留言內容>"`;API:`POST {base}/repos/{owner}/{repo}/issues/{index}/comments`,body `{"body":"<留言內容>"}`。 - 無異動的議題不留言。 -- 若需要把 API body 帶入 `curl`,用管線/heredoc/變數帶入,**不要為此在磁碟落地暫存檔**。 +- 若需要把 API body 帶入 `curl`,依 `/jsc-shared:spec-no-scratch-files` 用管線/heredoc/變數帶入,不落地暫存檔。 - 若選「逐議題確認」,每處理完一個就回報並等待確認再繼續。 ## 第 7 步:回報 @@ -141,10 +128,10 @@ description: 讀取一個 Gitea 專案(project)或單一議題(優先用 t ## 重要限制 -- **全程不得在磁碟落地任何檔案**(見上方「絕對準則」):中間成果只留在對話與 subagent 回傳值,最終只寫回議題正文/標籤/留言。 +- 全程不落地任何檔案,依 `/jsc-shared:spec-no-scratch-files`(見上方「絕對準則」):中間成果只留在對話與 subagent 回傳值,最終只寫回議題正文/標籤/留言。 - 修改議題正文、變更標籤、留言都是對外且不易復原的動作,**必須先經第 5 步使用者確認**;未確認前不寫入 Gitea,成果只留在對話中。 - 「TODO 是否完成」「該補哪些 TODO」「該掛哪些標籤」一律以**工作目錄下的檔案**為依據;無法可靠判斷就標「需人工確認」,不得臆測或編造需求未涵蓋的內容。 -- subagent 與各步驟只讀檔案與議題、只回傳結構化內容,**不得在磁碟寫任何檔案、不得修改任何工作目錄原始碼**。 +- subagent 派工依 `/jsc-shared:spec-subagent`(只讀不寫、回傳結構化內容、不得改動原始碼)。 - 標籤只從既有標籤挑選,不自行新建(除非使用者要求)。 - 進度欄位調整依 `/jsc-shared:spec-project-board`,且必須經第 5 步使用者確認後執行。 - 專案完成模式只在輸入為專案且使用者**明確**指定關閉/完成時進入;語意不明就用 AskUserQuestion 確認,不得自行認定。批次關閉議題前必須經使用者確認;含未完成 TODO 的議題要在確認時明確標出。不得透過此模式關閉不屬於該專案的議題。 diff --git a/skills/notifications/SKILL.md b/skills/notifications/SKILL.md index e6b5bc2..c4324ce 100644 --- a/skills/notifications/SKILL.md +++ b/skills/notifications/SKILL.md @@ -3,6 +3,12 @@ name: notifications description: 讀取 Gitea 通知,依通知類型分組後逐組執行;若沒有通知就直接結束;先從目前工作區的 REVIEW.md 找對應流程,找不到就詢問使用者怎麼處理,並把缺少流程的通知類型附加回 REVIEW.md。當使用者要整理 Gitea 通知、依通知類型批次處理、照 REVIEW.md 執行通知流程、或補齊 REVIEW.md 的通知類型說明時使用此 skill。 --- +## 共用規範(必要前置) + +先載入 `/jsc-shared:spec-preflight` 並依其流程處理;載入不到即代表 shared plugin 未安裝, +依該 spec 詢問使用者是否安裝 `https://gitea.jsc.idv.tw/plugins/shared.git`,不安裝則中斷本 skill。 +本 skill 需要的規範:`spec-output`、`spec-execution`、`spec-gitea`、`spec-no-scratch-files` + # 依 REVIEW.md 處理 Gitea 通知 你要讀取目前使用者在目標 Gitea 主機上的通知,先依通知類型分組,再逐組套用 `REVIEW.md` 內定義的處理流程。若沒有通知,直接結束,不改任何檔案,也不寫回 Gitea。 @@ -10,7 +16,7 @@ description: 讀取 Gitea 通知,依通知類型分組後逐組執行;若沒 ## 第 0 步:先決條件 1. 先依 `/jsc-shared:spec-gitea` 確認工具可用性,並決定使用 `tea` 或 Gitea REST API + `GITEA_TOKEN`。 -2. 決定 Gitea host 時,優先使用目前工作區 repo 的 `origin`,再看 `$GITEA_HOST`,都沒有才詢問使用者。 +2. 依 `/jsc-shared:spec-gitea` 的「gitea 主機決定順序」決定 host,不自行定義順序。 3. 若 `tea` 可用且該 host 有對應 login,優先用 `tea`;否則用 API + `GITEA_TOKEN`。 ## 第 1 步:讀取通知 @@ -43,4 +49,4 @@ description: 讀取 Gitea 通知,依通知類型分組後逐組執行;若沒 1. 逐組完成後,回報本次讀到的通知總數、分組結果、已套用的流程,以及哪些通知類型沒有既有流程。 2. 若有新增到 `REVIEW.md`,明確回報更新位置。 -3. 全程不要把通知內容寫成草稿檔或暫存檔。 +3. 依 `/jsc-shared:spec-no-scratch-files` 執行,全程不把通知內容落地成草稿檔或暫存檔。 diff --git a/skills/worklog/SKILL.md b/skills/worklog/SKILL.md index 2c021bf..002003b 100644 --- a/skills/worklog/SKILL.md +++ b/skills/worklog/SKILL.md @@ -32,12 +32,7 @@ description: 工作證明自動記錄(worklog)的操作與維護 skill。搭 ### 腳本路徑解析(重要) -skill 執行時的工作目錄是**使用者的專案目錄**,不是 plugin 根目錄,因此**絕不可用相對路徑呼叫腳本**。先解析出 plugin 根目錄再組絕對路徑: - -| 環境 | plugin 根目錄 | -| --- | --- | -| Claude Code | `${CLAUDE_PLUGIN_ROOT}` | -| 其他助理 | 本 skill 載入時提示的 base directory(`.../skills/worklog`)往上兩層 | +依 `/jsc-shared:spec-script-path`(寫法一:多行版)解析 plugin 根目錄,全文以 `${WORKLOG_DIR}` 表示該目錄: ```bash # Claude Code @@ -47,22 +42,19 @@ WORKLOG_DIR="${CLAUDE_PLUGIN_ROOT}/scripts/worklog" WORKLOG_DIR="/../../scripts/worklog" ``` -以下各模式的指令一律以 `${WORKLOG_DIR}` 表示該目錄。若解析不到或該目錄不存在,回報「plugin 目錄未包含 scripts/worklog,本 skill 在此環境不可用」並停止,不要改用相對路徑重試。 +若解析不到或該目錄不存在,依 spec-script-path 的標準錯誤處理回報並停止,不要改用相對路徑重試。 --- ## 共用規範(必要前置) -執行本 skill 前,先以 Skill 工具載入下列共用規範並全程遵守;**任一載入不到時先詢問使用者是否安裝 shared plugin(`https://gitea.jsc.idv.tw/plugins/shared.git`),不安裝則中斷**: - -- `/jsc-shared:spec-output`:繁體中文(台灣用語)、UTF-8 無 BOM、表格與 Mermaid 優先、**寫入外部系統不得洩漏 PII**。 -- `/jsc-shared:spec-execution`:自動執行原則(必要決策才中斷)、不臆測。 -- `/jsc-shared:spec-gitea`:token 機密保護(不 echo、遮蔽、不落地)、API 分頁、host 決定順序。 -- `/jsc-shared:spec-time-log`:時間戳固定 Asia/Taipei `yyyy/MM/dd HH:mm:ss`;訊息格式 `[時間][階段][等級]: 訊息`、一行一則。 +先載入 `/jsc-shared:spec-preflight` 並依其流程處理;載入不到即代表 shared plugin 未安裝, +依該 spec 詢問使用者是否安裝 `https://gitea.jsc.idv.tw/plugins/shared.git`,不安裝則中斷本 skill。 +本 skill 需要的規範:`spec-output`、`spec-execution`、`spec-gitea`、`spec-time-log`、`spec-no-scratch-files`、`spec-script-path`、`spec-skill-invocation`、`spec-model` 本 skill 特有補充: -- **工作內容不落地**:transcript 片段只在程序記憶體與 stdin/stdout 間傳遞、wiki 走 API 不 clone,全程不產生暫存檔。唯一允許落地的是**模型快取檔** `~/.claude/worklog/model`(僅含模型 id 與判定時間,不含任何工作內容)。 +- **工作內容不落地**:依 `/jsc-shared:spec-no-scratch-files` 執行(transcript 片段只在程序記憶體與 stdin/stdout 間傳遞、wiki 走 API 不 clone,全程不產生暫存檔)。**本 skill 特有例外**:唯一允許落地的是**模型快取檔** `~/.claude/worklog/model`(僅含模型 id 與判定時間,不含任何工作內容)。 - **絕不阻斷**:hook 路徑任何失敗都以 exit 0 結束,只在 stderr 留訊息。 --- @@ -79,11 +71,7 @@ WORKLOG_DIR="/../../scripts/worklog" | `WORKLOG_SCOPE` | | 冒號分隔的路徑前綴,僅這些路徑下的 session 才記 | 全部 session 都記 | | `WORKLOG_ERRLOG` | | 錯誤訊息額外寫入的檔案路徑(只記錯誤、不含工作內容) | 只走 stderr | -**token 不需另設變數**,依固定優先序自動解析並實際驗證: - -``` -GITEA_TOKEN →(對目標 host 驗證失敗時)→ tea 設定檔中該 host 的 token → ~/.git-credentials -``` +**token 不需另設變數**,依 /jsc-shared:spec-gitea 的『token 解析優先序』自動解析並實際驗證(worklog 沒有專用變數,直接從 GITEA_TOKEN 開始)。 --- @@ -103,12 +91,11 @@ GITEA_TOKEN →(對目標 host 驗證失敗時)→ tea 設定檔中該 host | 步驟 | 動作 | | --- | --- | -| 1 | 以 Skill 工具載入 `claude-api` 取當下模型清單與定價,**不憑記憶** | -| 2 | 依本任務條件評分:延遲敏感(在使用者等待路徑上)、輸出短篇六欄工作紀錄、需嚴守機密過濾指令、每輪都跑一次故成本敏感 | -| 3 | Smoke test:`WORKLOG_CHILD=1 claude -p "回 OK" --model <選定 id>` 確認該模型在此帳號可用 | -| 4 | 寫入 `~/.claude/worklog/model`(`model=`、`tuned_at=<時間>`、`reason=<一行理由>`),並回報選擇與理由 | +| 1 | 以 Skill 工具呼叫 `/jsc-shared:models --task summary` 取得推薦模型——探測、評分(延遲敏感、輕量摘要、低成本等 `spec-model` 對映表定義的必要標籤)、smoke test 全由該 skill 依 `/jsc-shared:spec-model` 完成,本模式不重寫這套邏輯、不自行載入 `claude-api` 或另跑 smoke test | +| 2 | 取推薦結果的模型 id 與一行理由,寫入 worklog 專屬快取檔 `~/.claude/worklog/model`(`model=`、`tuned_at=<時間>`、`reason=<一行理由>`)——此檔與 `models` skill 自身的 `~/.claude/jsc/models.json` 快取用途不同(前者是 worklog hook 專讀的精簡快取,後者是全模型清單快取),兩者不合併、不互相讀取、不共用格式 | +| 3 | 回報選擇與理由 | -快取超過 **30 天** 視為過期:hook 改用保底模型,並在條目標記 `(model: fallback)`,`--diagnose` 會提醒重跑 `--tune`。 +快取超過 **30 天** 視為過期:hook 改用保底模型 `claude-haiku-4-5-20251001`,並在條目標記 `(model: fallback)`,`--diagnose` 會提醒重跑 `--tune`。 ### `--diagnose` @@ -170,6 +157,8 @@ GITEA_TOKEN →(對目標 host 驗證失敗時)→ tea 設定檔中該 host ## 呼叫方式 +依 `/jsc-shared:spec-skill-invocation` 的統一呼叫方式,本 skill 的實際參數格式與範例: + | 助理 | 呼叫 | | --- | --- | | 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` |