Files
doc/skills/issues-sync/SKILL.md
T

152 lines
21 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 前必須先讓使用者確認**。請依下列階段依序完成。
## 共用規範(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 視為不支援、不得新建欄位。
## 絕對準則(不可違反)
- **全程不得在磁碟落地任何檔案**:不建立 `.docs/`、不寫草稿檔、不寫暫存檔、不用檔案傳遞中間結果。所有中間成果(議題清單、需求分析、追加後的正文、標籤異動、勾稽結果、留言內容)一律留在**對話內容**與 **subagent 的回傳值**裡。最終產物只透過 `tea` 或 Gitea API **寫回議題正文/標籤/留言**,除此之外不產生任何本機檔案。
## 前置:輸入與工具
- **輸入**:一個 Gitea 專案(project)或一筆議題的參照(URL 最佳,或 `owner/repo` + project idissue index)。
- **依據來源**:所有「TODO 是否完成」「該補哪些 TODO」「該掛哪些標籤」的判斷,一律以**目前工作目錄下的檔案內容**為準(程式碼、設定、文件等),不得臆測。
- **工具優先序**
1. 若該 host 在 `tea login list` 中有對應 login,優先用 `tea``tea issues``tea comment``tea labels` 等),並以 `--login <name> --repo <owner>/<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-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 還是 APIAPI base 為 `https://<host>/api/v1`)。
3. **判斷是否進入專案完成模式**:若輸入是**專案**,且使用者明確指定「關閉專案」「專案完成」(或同義表述,例如「這個專案做完了,收尾」),標記為專案完成模式 — 第 1 步取得議題清單後,改走「專案完成模式」專節,不進入第 2 步之後的同步流程。輸入是單一議題時不適用此模式;使用者語意不明確(看不出是要同步還是要收尾關閉)時,用 AskUserQuestion 確認,不得自行認定要關閉。
4. **找不到就詢問使用者(AskUserQuestion**:若無法從輸入判斷是專案還是議題、或依輸入查不到對應的專案/議題(例如 API 回 404、專案 id 不存在、repo 拼錯),必須用 AskUserQuestion 請使用者補齊或更正(hostowner/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. **使用者確認(AskUserQuestion,必要,不可跳過)**:關閉議題是對外且不易復原的動作,未確認前不得寫入。至少提供選項:
- 全部搬到「已完成」並關閉。
- 逐議題確認(每關一筆回報,確認後再做下一筆)。
- 取消(不動任何議題)。
清單中若有議題仍有未完成 TODO,必須在詢問時明確標出這些議題與其未完成數量,讓使用者知道將照關。
3. **逐議題執行**(確認後):
- **搬到「已完成」欄位**:若議題屬於專案看板且看板有可對應「已完成」語意的欄位,依既有規則先探測 projectcolumn API404501 視為不支援、不對未確認端點寫入),可用就把議題移到該欄位;不支援或欄位對不上就跳過搬移(議題關閉後看板通常會自行呈現完成狀態),於回報註明。
- **關閉議題**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. 否則依標籤把議題分組(一個議題有多個標籤時,各組都出現),用 **AskUserQuestionmultiSelect** 讓使用者挑選要同步「哪些標籤」的議題:
- 每個選項是一個標籤(附該標籤下的議題數量),讓使用者多選。
- 標籤數量超過 AskUserQuestion 選項上限(4)時,改在訊息中列出全部標籤與各自議題數,請使用者回覆要同步哪些(可用「其他」自訂輸入)。
4. 依選取的標籤過濾清單:保留**帶有任一選取標籤**的議題,作為後續要同步的最終清單。未被選取標籤涵蓋的議題不同步。
## 第 3 步:逐議題派 subagent 產生同步計畫(每個議題一個 subagent)
對最終清單中的**每一個議題各派一個 subagent**。subagent **以目前工作目錄下的所有檔案為依據**,只讀檔案與議題、**把結果以結構化內容回傳給主 agent,不得在磁碟寫任何檔案**、**不得修改任何工作目錄的原始碼、不得直接改議題正文/標籤、不得直接留言**。每個 subagent 依序做:
1. **讀取議題**`title``body`(含其中的 TODO 任務清單)、`labels`、以及既有 comments。
- tea`tea issues <index> --repo <owner>/<repo> --login <name> --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 必須能對應到議題描述的需求,不得編造需求未涵蓋的項目。
3. **3.2 依需求更新可用標籤**:依議題需求性質,從該 repo **既有標籤**中挑選應掛上(或應移除)的標籤,回傳內容中列出「建議的標籤異動」(新增哪些、移除哪些、維持哪些)。**不自行新建標籤**,除非使用者要求;找不到合適標籤就維持原樣並標註。
4. **3.3 逐條勾稽未完成 TODO 是否已完成**:對所有**未完成**的 TODO(含 3.1 新增的),逐條依工作目錄下的檔案內容判斷是否已完成。已完成者標記為 `- [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 異動留言內容(或「無異動」)、專案進度欄位建議(目前欄位/建議欄位/判斷依據,或「不屬於專案看板」「無法對應」)、以及所有「需人工確認」項目。
## 第 4 步:同步計畫品質檢查
實際寫入 Gitea 前,主 agent 必須檢查所有 subagent 回傳的同步計畫(僅在對話中檢查,不寫檔):
- 內容以繁體中文為主、英文為輔,無亂碼或破損文字。
- 每個要同步的議題都有對應的同步計畫;正文的 TODO 變更(新增/勾稽)與留言內容的敘述一致。
- 標籤異動只用到該 repo 既有標籤(名稱/id 對得上第 3.1 盤點結果),未擅自新建標籤。
- 「已完成」的勾稽都有工作目錄檔案的依據;無依據者標為未完成或「需人工確認」,未被誤判為完成。
- 進度欄位建議只使用看板實際存在的欄位,且與 TODO 勾稽結果一致(例如仍有未完成 TODO 的議題不得建議「已完成」、仍有「需人工確認」項目的議題不得越過「待測試」)。
- 有問題先在對話中修正同步計畫並重新檢查,通過後才進入下一步。
## 第 5 步:詢問使用者要如何執行(AskUserQuestion
同步計畫通過檢查後,主 agent 用 AskUserQuestion 讓使用者確認要如何對 Gitea 執行寫入,至少提供:
1. 全部執行:追加/勾稽 TODO 到議題正文、套用標籤異動、調整專案進度欄位、對有異動的議題留言。
2. 只更新議題(正文+標籤+進度欄位),先不留言。
3. 只呈現同步計畫、先不動 Gitea:僅在對話中列出計畫供檢視(不落地檔案、不寫入議題)。
4. 逐議題確認:每處理完一個議題就回報,待使用者確認後再做下一個。
5. 其他(由使用者輸入自訂方式)。
未獲確認前不得對 Gitea 做任何寫入。
## 第 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` 把議題移到建議欄位(先 GET 探測端點、404/501 視為不支援且不得對未確認端點寫入;介面可用時一次一個議題並確認回應成功;不可用時不視為錯誤,改在第 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`,用管線/heredoc/變數帶入,**不要為此在磁碟落地暫存檔**。
- 若選「逐議題確認」,每處理完一個就回報並等待確認再繼續。
## 第 7 步:回報
- 回報:輸入是專案或議題、(若為專案)該 repo open 議題數/過濾後屬於此專案的議題數與依標籤篩選後的最終清單、每個議題新增了哪些 TODO、勾稽為完成的 TODO(附實作位置)、標籤異動、進度欄位異動(目前欄位 → 新欄位;介面不支援時改列「議題 → 建議欄位」清單請使用者手動調整)、是否留言,以及所有「需人工確認」或「無法判斷是否屬於此專案」項目。
- 因全程不落地檔案,**沒有本機草稿需要清理**;成果都在對話與已寫回的議題正文/標籤/留言中。
## 重要限制
- **全程不得在磁碟落地任何檔案**(見上方「絕對準則」):中間成果只留在對話與 subagent 回傳值,最終只寫回議題正文/標籤/留言。
- 修改議題正文、變更標籤、留言都是對外且不易復原的動作,**必須先經第 5 步使用者確認**;未確認前不寫入 Gitea,成果只留在對話中。
- 「TODO 是否完成」「該補哪些 TODO」「該掛哪些標籤」一律以**工作目錄下的檔案**為依據;無法可靠判斷就標「需人工確認」,不得臆測或編造需求未涵蓋的內容。
- subagent 與各步驟只讀檔案與議題、只回傳結構化內容,**不得在磁碟寫任何檔案、不得修改任何工作目錄原始碼**。
- 標籤只從既有標籤挑選,不自行新建(除非使用者要求)。
- 進度欄位調整依 `/jsc-shared:spec-project-board`,且必須經第 5 步使用者確認後執行。
- 專案完成模式只在輸入為專案且使用者**明確**指定關閉/完成時進入;語意不明就用 AskUserQuestion 確認,不得自行認定。批次關閉議題前必須經使用者確認;含未完成 TODO 的議題要在確認時明確標出。不得透過此模式關閉不屬於該專案的議題。
- JSON 解析(不依賴 `jq`)依 `/jsc-shared:spec-gitea`;個資保護(PII)與語言規範依 `/jsc-shared:spec-output`