Files
doc/skills/issues-sync/SKILL.md
T
jiantw83andClaude Sonnet 5 ed7f29c10f refactor(doc): 接上 shared 共用規範,去除重抄段落並修正時區/機密遮蔽引用
依 todo.md 執行的規範治理專案:worklog/funcs/issues-analyze/
issues-analyze-to-file/issues-sync/notifications/docker 七個 skill 改為
引用 shared 新增的 14 個共用 spec(token 優先序、issue 讀取、TODO list、
ask-user、subagent、no-scratch-files、skill-invocation、script-path 等),
不再重抄內容;wiki_api.py 改用 zoneinfo 而非硬編 +8 offset,並補上與
shared/scripts/lib/redact-patterns.json 的對應註記;worklog 的 --tune 改為
呼叫 /jsc-shared:models --task summary。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-11 06:03:35 +00:00

139 lines
19 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: issues-sync
description: 讀取一個 Gitea 專案(project)或單一議題(優先用 tea,否則用 Gitea REST API + curl + GITEA_TOKEN,不依賴 jq);若給的是專案,因 tea/Gitea API 目前無法直接查詢專案,就先取得該 repo 底下所有開啟中的議題、再過濾掉與此專案無關的議題;若給的是議題就只同步該議題。議題若有標籤就依標籤分組並以 AskUserQuestion 讓使用者挑選要同步哪些標籤的議題(只有一個議題或全部無標籤則跳過)。接著一個議題派一個 subagent,基於工作目錄下的所有檔案:分析議題描述的需求並判斷議題內的 TODO(markdown 任務清單)是否足以追蹤議題描述的需求、不足就補上 TODO 追加到議題正文、依需求從既有標籤更新議題標籤、逐條判斷未完成 TODO(含新增)是否已完成、有異動就整理成一則留言;若議題屬於專案看板且看板欄位可對應進度語意(例如分析中/待處理/進行中/待測試/已完成),依議題描述與勾稽結果建議並調整議題所在欄位,介面不支援時改列建議清單請使用者手動調整。若輸入為專案且使用者指定「關閉專案」或「專案完成」,則進入專案完成模式:只執行到取得專案議題清單,跳過其後所有同步步驟,經使用者確認後把專案擁有的所有議題搬到「已完成」欄位並關閉。全程不落地任何檔案:所有中間成果一律留在對話/subagent 回傳內容,最終只透過 tea 或 Gitea API 寫回議題正文/標籤/留言,且寫入前先經使用者確認。當使用者要同步議題進度、依專案批次更新議題 TODO、依程式碼勾稽議題完成度、更新議題標籤與進度留言,或提到 issues-sync、issue sync、議題同步、TODO 勾稽、tea issues、Gitea 專案議題時使用此 skill。
---
# 依工作目錄同步 Gitea 專案/議題的 TODO 進度與標籤
你要讀取使用者提供的一個 Gitea **專案(project)**或**單一議題**,取得要同步的議題清單,然後一個議題派一個 subagent,**以目前工作目錄下的所有檔案為依據**,勾稽並更新每個議題的 TODO(markdown 任務清單)與標籤,最後把 TODO 的異動整理成留言。例外:輸入為專案且使用者指定「關閉專案/專案完成」時,進入**專案完成模式**(見第 1 步之後的專節),跳過標籤分組與逐議題勾稽,改為批次搬移至「已完成」並關閉議題。**修改議題正文、變更議題標籤、留言都是對外且不易復原的動作,subagent 只回傳同步計畫(不落地任何檔案),實際寫入 Gitea 前必須先讓使用者確認**。請依下列階段依序完成。
## 共用規範(必要前置)
先載入 `/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`
## 絕對準則(不可違反)
依 `/jsc-shared:spec-no-scratch-files` 全程不落地任何檔案;本 skill 的中間成果(議題清單、需求分析、追加後的正文、標籤異動、勾稽結果、留言內容)一律留在**對話內容**與**subagent 的回傳值**裡,最終產物只透過 `tea` 或 Gitea API **寫回議題正文/標籤/留言**。
## 前置:輸入與工具
- **輸入**:一個 Gitea 專案(project)或一筆議題的參照(URL 最佳,或 `owner/repo` + project id/issue index)。
- **依據來源**:所有「TODO 是否完成」「該補哪些 TODO」「該掛哪些標籤」的判斷,一律以**目前工作目錄下的檔案內容**為準(程式碼、設定、文件等),不得臆測。
- **工具選擇**:依 `/jsc-shared:spec-gitea`(`tea` 或 API + `GITEA_TOKEN` 的選擇、可用性檢查、不依賴 `jq`);本 skill 常用 `tea issues`、`tea comment`、`tea labels`,或對應 API 端點,一律以 `--login <name> --repo <owner>/<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 步:解析輸入、判斷專案或議題、準備工具
1. 從輸入解析出 `host`、`owner`、`repo`,並判斷這是**專案**還是**議題**:
- 議題 URL 形如 `https://<host>/<owner>/<repo>/issues/<index>` → 議題。
- 專案 URL 形如 `https://<host>/<owner>/<repo>/projects/<id>` 或組織層級 `https://<host>/<owner>/-/projects/<id>` → 專案。
2. 執行 `tea login list`,判斷該 host 走 tea 還是 API(API base 為 `https://<host>/api/v1`)。
3. **判斷是否進入專案完成模式**:若輸入是**專案**,且使用者明確指定「關閉專案」「專案完成」(或同義表述,例如「這個專案做完了,收尾」),標記為專案完成模式 — 第 1 步取得議題清單後,改走「專案完成模式」專節,不進入第 2 步之後的同步流程。輸入是單一議題時不適用此模式;使用者語意不明確(看不出是要同步還是要收尾關閉)時,用 AskUserQuestion 確認,不得自行認定要關閉。
4. **找不到就詢問使用者(AskUserQuestion)**:若無法從輸入判斷是專案還是議題、或依輸入查不到對應的專案/議題(例如 API 回 404、專案 id 不存在、repo 拼錯),必須用 AskUserQuestion 請使用者補齊或更正(host/owner/repo、專案 id 或議題 URL)。取得可解析的目標前,不進入下一步。
## 第 1 步:取得要同步的議題清單
- **若輸入是議題**:清單就是這一筆議題,**跳過本步的專案展開**,直接進入第 2 步。
- **若輸入是專案**:**`tea` 與 Gitea API 目前都無法直接查詢專案掛載的議題**,因此改用「先撈全部、再過濾」:
1. 先取得該 `owner/repo` 底下**所有開啟中(open)的議題**:
- tea:`tea issues list --repo <owner>/<repo> --login <name> --state open`(必要時加 `--fields index,title,labels` 等)。
- API:`GET {base}/repos/{owner}/{repo}/issues?state=open&type=issues`(注意分頁,逐頁取完)。
2. **過濾掉與此專案無關的議題**,只保留屬於目標專案的議題:依每個議題可取得的專案關聯資訊(issue 物件上的 project 欄位、或該議題所屬 project id/名稱)比對目標專案;比對得上才留下。彙整成議題清單(每筆記下 `owner/repo`、`index`、`title`、`labels`)。
3. 若逐議題都**無法可靠判斷是否屬於此專案**(tea/API 完全取不到議題的專案關聯),用 AskUserQuestion 告知此限制,請使用者選擇要如何處理(例如:把該 repo 全部 open 議題都視為要同步、由使用者提供屬於此專案的議題清單/編號、或改給單一議題 URL),不要自行臆測。
## 專案完成模式:指定關閉專案/專案完成時(跳過第 2 步之後的所有步驟)
只在第 0 步標記為專案完成模式時進入本節。沿用第 1 步取得的「屬於此專案的議題清單」,之後**不做**標籤分組、不派 subagent、不勾稽 TODO、不更新標籤、不留言進度,改依下列流程把專案擁有的所有議題搬到「已完成」並關閉:
1. **列出將處理的議題清單**:每筆列出 `owner/repo`、編號、標題、目前狀態與所在看板欄位(可取得時),以及該議題是否還有未完成 TODO(僅從議題正文的任務清單計數,不做工作目錄勾稽)。
2. **使用者確認(必要,不可跳過)**:依 `/jsc-shared:spec-ask-user`(破壞性決策不得被跳過),至少提供選項:
- 全部搬到「已完成」並關閉。
- 逐議題確認(每關一筆回報,確認後再做下一筆)。
- 取消(不動任何議題)。
清單中若有議題仍有未完成 TODO,必須在詢問時明確標出這些議題與其未完成數量,讓使用者知道將照關。
3. **逐議題執行**(確認後):
- **搬到「已完成」欄位**:依 `/jsc-shared:spec-project-board` 判斷看板是否有可對應「已完成」語意的欄位並嘗試移動;不支援或欄位對不上就跳過搬移(議題關閉後看板通常會自行呈現完成狀態),於回報註明。
- **關閉議題**:tea:`tea issues close --repo <owner>/<repo> --login <name> <index>`;API:`PATCH {base}/repos/{owner}/{repo}/issues/{index}`,body `{"state":"closed"}`。
- 單筆失敗(權限不足、議題被鎖定等)不中斷整批:記錄失敗原因後繼續下一筆。
4. **回報**:搬移成功/跳過(含原因)筆數、關閉成功/失敗(含原因)清單、照關但仍有未完成 TODO 的議題清單(供追溯);專案看板本身的關閉/封存 Gitea 不一定支援 API 操作,如需關閉專案本身,提示使用者到 Gitea 介面手動處理。
本模式全程仍遵守「不落地檔案」絕對準則;若第 1 步取得的清單為空(專案沒有 open 議題),直接回報並結束,不需確認。
## 第 2 步:依標籤分組並詢問要同步哪些(AskUserQuestion)
1. 讀取清單中每個議題的 `labels`。
2. **跳過條件**:若清單只有**一個議題**,或**所有議題都沒有標籤**,跳過本步、同步全部清單。
3. 否則依標籤把議題分組(一個議題有多個標籤時,各組都出現),依 `/jsc-shared:spec-ask-user` 用 **AskUserQuestion(multiSelect)** 讓使用者挑選要同步「哪些標籤」的議題(每個選項為一個標籤並附議題數量;超過選項上限時改列文字清單並支援「其他」)。
4. 依選取的標籤過濾清單:保留**帶有任一選取標籤**的議題,作為後續要同步的最終清單。未被選取標籤涵蓋的議題不同步。
## 第 3 步:逐議題派 subagent 產生同步計畫(每個議題一個 subagent)
對最終清單中的**每一個議題各派一個 subagent**,依 `/jsc-shared:spec-subagent`(一議題一 subagent、只讀不寫、回傳結構化結果、不得改動原始碼、不得直接寫外部系統)。subagent 以目前工作目錄下的所有檔案為依據,依序做:
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 新增的),依 `/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 **回傳**一份結構化同步計畫(依 `/jsc-shared:spec-no-scratch-files`,不落地成檔案),至少包含:議題參照與標題、追加後的完整正文(標明新增與勾稽的變更)、建議的標籤異動、TODO 異動留言內容(或「無異動」)、專案進度欄位建議(目前欄位/建議欄位/判斷依據,或「不屬於專案看板」「無法對應」)、以及所有「需人工確認」項目。
## 第 4 步:同步計畫品質檢查
實際寫入 Gitea 前,主 agent 必須檢查所有 subagent 回傳的同步計畫(僅在對話中檢查,不寫檔):
- 內容以繁體中文為主、英文為輔,無亂碼或破損文字。
- 每個要同步的議題都有對應的同步計畫;正文的 TODO 變更(新增/勾稽)與留言內容的敘述一致。
- 標籤異動只用到該 repo 既有標籤(名稱/id 對得上第 3.1 盤點結果),未擅自新建標籤。
- 「已完成」的勾稽都依 `/jsc-shared:spec-todo-list` 附有工作目錄檔案依據;無依據者標為未完成或「需人工確認」,未被誤判為完成。
- 進度欄位建議只使用看板實際存在的欄位,且與 TODO 勾稽結果一致(例如仍有未完成 TODO 的議題不得建議「已完成」、仍有「需人工確認」項目的議題不得越過「待測試」)。
- 有問題先在對話中修正同步計畫並重新檢查,通過後才進入下一步。
## 第 5 步:詢問使用者要如何執行(AskUserQuestion)
同步計畫通過檢查後,主 agent 依 `/jsc-shared:spec-ask-user`(破壞性決策,未獲確認前不得寫入)用 AskUserQuestion 讓使用者確認要如何對 Gitea 執行寫入,至少提供:
1. 全部執行:追加/勾稽 TODO 到議題正文、套用標籤異動、調整專案進度欄位、對有異動的議題留言。
2. 只更新議題(正文+標籤+進度欄位),先不留言。
3. 只呈現同步計畫、先不動 Gitea:僅在對話中列出計畫供檢視(不落地檔案、不寫入議題)。
4. 逐議題確認:每處理完一個議題就回報,待使用者確認後再做下一個。
5. 其他(由使用者輸入自訂方式)。
## 第 6 步:套用到 Gitea
依使用者選擇,對最終清單的每個議題執行(主 agent 執行,非 subagent):
- **更新正文(TODO 追加+勾稽)**:以同步計畫中「追加後的完整正文」更新議題 body。
- tea:對應的 issue 編輯指令;API:`PATCH {base}/repos/{owner}/{repo}/issues/{index}`,body `{"body":"<新正文>"}`。
- 更新前先重新讀一次議題正文,若與 subagent 讀到的版本已不同(他人期間有改動),停下該議題並回報,避免覆蓋他人變更。
- **標籤異動**:套用建議的新增/移除。
- tea:`tea labels`/issue 編輯對應指令;API:`POST`/`DELETE {base}/repos/{owner}/{repo}/issues/{index}/labels`(用既有 label id)。
- **調整專案進度欄位**:對「建議欄位與目前欄位不同」的議題,依 `/jsc-shared:spec-project-board` 嘗試把議題移到建議欄位;不可用時不視為錯誤,改在第 7 步回報列「議題 → 建議欄位」清單請使用者手動拖曳。「欄位無異動」「無法對應」「不屬於專案看板」的議題跳過。
- **留言**:對有 TODO 異動的議題張貼留言。
- tea:`tea comment --repo <owner>/<repo> --login <name> <index> "<留言內容>"`;API:`POST {base}/repos/{owner}/{repo}/issues/{index}/comments`,body `{"body":"<留言內容>"}`。
- 無異動的議題不留言。
- 若需要把 API body 帶入 `curl`,依 `/jsc-shared:spec-no-scratch-files` 用管線/heredoc/變數帶入,不落地暫存檔。
- 若選「逐議題確認」,每處理完一個就回報並等待確認再繼續。
## 第 7 步:回報
- 回報:輸入是專案或議題、(若為專案)該 repo open 議題數/過濾後屬於此專案的議題數與依標籤篩選後的最終清單、每個議題新增了哪些 TODO、勾稽為完成的 TODO(附實作位置)、標籤異動、進度欄位異動(目前欄位 → 新欄位;介面不支援時改列「議題 → 建議欄位」清單請使用者手動調整)、是否留言,以及所有「需人工確認」或「無法判斷是否屬於此專案」項目。
- 因全程不落地檔案,**沒有本機草稿需要清理**;成果都在對話與已寫回的議題正文/標籤/留言中。
## 重要限制
- 全程不落地任何檔案,依 `/jsc-shared:spec-no-scratch-files`(見上方「絕對準則」):中間成果只留在對話與 subagent 回傳值,最終只寫回議題正文/標籤/留言。
- 修改議題正文、變更標籤、留言都是對外且不易復原的動作,**必須先經第 5 步使用者確認**;未確認前不寫入 Gitea,成果只留在對話中。
- 「TODO 是否完成」「該補哪些 TODO」「該掛哪些標籤」一律以**工作目錄下的檔案**為依據;無法可靠判斷就標「需人工確認」,不得臆測或編造需求未涵蓋的內容。
- subagent 派工依 `/jsc-shared:spec-subagent`(只讀不寫、回傳結構化內容、不得改動原始碼)。
- 標籤只從既有標籤挑選,不自行新建(除非使用者要求)。
- 進度欄位調整依 `/jsc-shared:spec-project-board`,且必須經第 5 步使用者確認後執行。
- 專案完成模式只在輸入為專案且使用者**明確**指定關閉/完成時進入;語意不明就用 AskUserQuestion 確認,不得自行認定。批次關閉議題前必須經使用者確認;含未完成 TODO 的議題要在確認時明確標出。不得透過此模式關閉不屬於該專案的議題。
- JSON 解析(不依賴 `jq`)依 `/jsc-shared:spec-gitea`;個資保護(PII)與語言規範依 `/jsc-shared:spec-output`。