feat(gitea): 新增 PR 盯場輪詢腳本與 pr-get、pr-edit 兩個子指令 #23

Merged
jiantw83 merged 5 commits from feat/sdlc-flow-rules/main into develop 2026-08-27 03:39:37 +00:00
Member

PR 描述

摘要

  • 需求描述:把功能主幹 feat/sdlc-flow-rules/main 累積的內容整批推上 develop。本存取庫負責使用者 15 條規則第一群「SDLC 執行流程」裡的兩條基礎設施:R10 等待 PR 合併要用輪詢盯場,不用睡死等待;R2 每次 commit 之後要校準既有 PR 的標題、描述與依賴。前者需要一支盯到底的輪詢腳本,後者需要能讀、能改既有 PR 的子指令,兩者都在這裡補齊,給 jsc-git、jsc-sdlc 呼叫。
  • 計畫名稱:無
  • 計畫頁:無
  • 分析頁:無

本 PR 併入 5 個 commit,來自已合併的子功能 PR plugins/gitea#22。

變更內容

檔案 為什麼改
tools/pr-watch.sh 新增。盯著一支 PR 到合併或關閉為止,中途抓到新留言就停下來交給呼叫端跑決策樹。R10 要的就是這支,先前只能靠模型自己重複查詢,行為不可預期
tools/gitea.sh 新增 pr-get、pr-edit 兩個子指令。R2 的校準要先讀得到既有 PR 的標題與描述,才比得出差異、改得回去;原本只有開 PR 的子指令,沒有讀與改
README.md 補上盯 PR 與 PR 校準的用法,含 JSC_PR_WATCH_INTERVAL 與四個退出碼的意義
AGENTS.md 同步工具清單,新增的兩支入口要讓其他 domain 找得到
plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json 三份 manifest 版本同步升到 0.1.5,照技能準則的版本規則走

設計重點

  • 輪詢間隔預設 60 秒,JSC_PR_WATCH_INTERVAL 可覆寫,不自動逾時退場,盯到 PR 合併或關閉為止。決策紀錄見 wiki QUESTION_FB8DF0B5 的 2026-08-27 那一節 Q7。加逾時上限會讓「等久了就自己放棄」變成常態,反而要人回頭確認,所以不加。
  • 退出碼分四種,呼叫端據此分流:0 是 PR 已合併或關閉、10 是有新留言待跑決策樹、2 是參數錯誤或第一輪就連不上 Gitea、3 是查不到該 PR。10 這條是 R11 的接口——留言不自動修,交回呼叫端取得共識(Q1)。
  • 已回報過的留言不重複回報:最後處理過的留言時間戳寫進狀態檔,預設 $JSC_HOME/pr-watch/{owner}-{repo}-{index}.seen。狀態檔還不存在時,把既有留言整批當成新留言回報一次——寧可重複回報,也不要漏掉開始盯之前就留下的審查意見。
  • PR 收尾那一輪若還有沒回報的留言,照樣印出來再退出,退出碼仍是 0。留言不會因為 PR 剛好合併就消失。
  • 加了一道狀態白名單:gitea.sh pr-status 對不存在的 PR 會印「? none none」並且 exit 0,所以只認 open 與 closed、merged 只認 true 與 false,對不上就回 3。少了這道護欄,PR 編號打錯會變成永遠輪詢一支不存在的 PR。
  • 資料一律經同目錄的 gitea.sh,不自行拼 API,連線設定跟著 GITEA_HOST、GITEA_TOKEN 繼承。
  • 第一輪查詢失敗算環境沒接好,直接回 2;之後才失敗算連線抖動,警告一句繼續輪詢。

測試結果

  • 子功能 PR plugins/gitea#22 已完成該層的驗證並合併,本 PR 不再重跑一次。
  • 主幹整合後複驗:sh -n tools/pr-watch.sh、sh -n tools/gitea.sh 皆通過。
  • 主幹整合後複驗:jsc-meta/tools/ste100-lint.sh 掃整個存取庫全綠。
  • 未跑對真實 Gitea 站台的端對端輪詢:那需要一支活的、狀態會變的 PR,開一支只為測試的 PR 反而污染存取庫的 PR 清單。實際行為由後續使用 jsc-sdlc:implement 的流程驗證。

前置 Push Request

  • 無
# PR 描述 ## 摘要 - 需求描述:把功能主幹 `feat/sdlc-flow-rules/main` 累積的內容整批推上 `develop`。本存取庫負責使用者 15 條規則第一群「SDLC 執行流程」裡的兩條基礎設施:R10 等待 PR 合併要用輪詢盯場,不用睡死等待;R2 每次 commit 之後要校準既有 PR 的標題、描述與依賴。前者需要一支盯到底的輪詢腳本,後者需要能讀、能改既有 PR 的子指令,兩者都在這裡補齊,給 `jsc-git`、`jsc-sdlc` 呼叫。 - 計畫名稱:無 - 計畫頁:無 - 分析頁:無 本 PR 併入 5 個 commit,來自已合併的子功能 PR [plugins/gitea#22](https://gitea.jsc.idv.tw/plugins/gitea/pulls/22)。 ## 變更內容 | 檔案 | 為什麼改 | | --- | --- | | `tools/pr-watch.sh` | 新增。盯著一支 PR 到合併或關閉為止,中途抓到新留言就停下來交給呼叫端跑決策樹。R10 要的就是這支,先前只能靠模型自己重複查詢,行為不可預期 | | `tools/gitea.sh` | 新增 `pr-get`、`pr-edit` 兩個子指令。R2 的校準要先讀得到既有 PR 的標題與描述,才比得出差異、改得回去;原本只有開 PR 的子指令,沒有讀與改 | | `README.md` | 補上盯 PR 與 PR 校準的用法,含 `JSC_PR_WATCH_INTERVAL` 與四個退出碼的意義 | | `AGENTS.md` | 同步工具清單,新增的兩支入口要讓其他 domain 找得到 | | `plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` | 三份 manifest 版本同步升到 `0.1.5`,照技能準則的版本規則走 | ## 設計重點 - 輪詢間隔預設 60 秒,`JSC_PR_WATCH_INTERVAL` 可覆寫,**不自動逾時退場**,盯到 PR 合併或關閉為止。決策紀錄見 wiki [QUESTION_FB8DF0B5](https://gitea.jsc.idv.tw/knowledges/QUESTION/wiki/QUESTION_FB8DF0B5) 的 2026-08-27 那一節 Q7。加逾時上限會讓「等久了就自己放棄」變成常態,反而要人回頭確認,所以不加。 - 退出碼分四種,呼叫端據此分流:`0` 是 PR 已合併或關閉、`10` 是有新留言待跑決策樹、`2` 是參數錯誤或第一輪就連不上 Gitea、`3` 是查不到該 PR。`10` 這條是 R11 的接口——留言不自動修,交回呼叫端取得共識(Q1)。 - 已回報過的留言不重複回報:最後處理過的留言時間戳寫進狀態檔,預設 `$JSC_HOME/pr-watch/{owner}-{repo}-{index}.seen`。狀態檔還不存在時,把既有留言整批當成新留言回報一次——寧可重複回報,也不要漏掉開始盯之前就留下的審查意見。 - PR 收尾那一輪若還有沒回報的留言,照樣印出來再退出,退出碼仍是 `0`。留言不會因為 PR 剛好合併就消失。 - 加了一道狀態白名單:`gitea.sh pr-status` 對不存在的 PR 會印「? none none」並且 exit 0,所以只認 `open` 與 `closed`、`merged` 只認 `true` 與 `false`,對不上就回 `3`。少了這道護欄,PR 編號打錯會變成永遠輪詢一支不存在的 PR。 - 資料一律經同目錄的 `gitea.sh`,不自行拼 API,連線設定跟著 `GITEA_HOST`、`GITEA_TOKEN` 繼承。 - 第一輪查詢失敗算環境沒接好,直接回 `2`;之後才失敗算連線抖動,警告一句繼續輪詢。 ## 測試結果 - 子功能 PR [plugins/gitea#22](https://gitea.jsc.idv.tw/plugins/gitea/pulls/22) 已完成該層的驗證並合併,本 PR 不再重跑一次。 - 主幹整合後複驗:`sh -n tools/pr-watch.sh`、`sh -n tools/gitea.sh` 皆通過。 - 主幹整合後複驗:`jsc-meta/tools/ste100-lint.sh` 掃整個存取庫全綠。 - 未跑對真實 Gitea 站台的端對端輪詢:那需要一支活的、狀態會變的 PR,開一支只為測試的 PR 反而污染存取庫的 PR 清單。實際行為由後續使用 `jsc-sdlc:implement` 的流程驗證。 ## 前置 Push Request - 無
jiantw83 added 5 commits 2026-08-27 03:38:53 +00:00
What:`tools/gitea.sh` 新增 `pr-get` 與 `pr-edit`。`pr-get` 印出一支 PR 的標題、base 分支與描述,前三行固定 `title`、`base`、`body` 三個標記,第 4 行起是描述原文;`pr-edit` 從檔案讀描述,一次更新標題與描述。

Why:分支已經有 PR 時,每次認可之後都要比對標題、描述與前置 PR 依賴三項,有差才更新。原本只有 `pr-create` 與 `pr-status`,讀不到既有 PR 的標題與描述,比不了就只能重開一支 PR 或整支蓋掉,兩種都會把審查中的討論打斷。

How:`pr-get` 把唯一會多行的描述放在輸出最後一段,呼叫端用 `head -n1`、`sed -n 2p`、`tail -n +4` 就取得到三個欄位,全程不必解析 JSON。`pr-edit` 的描述走檔案而不走參數,多行內容與全形標點才裝得下;描述檔不存在回 `2`,API 呼叫失敗回 `4`,成功印 `OK {owner}/{repo}#{編號}`。

Who:`jsc-git:pr` 的既有 PR 校準步驟,以及任何要先比對 PR 現況再決定改不改的呼叫端。
What:新增 `tools/pr-watch.sh`,盯一支 PR 直到它合併或關閉。退出碼 `0` 是已合併或已關閉、`10` 是有新留言要呼叫端接手、`2` 是參數錯誤或第一輪就連不上 Gitea、`3` 是查不到該 PR。輪詢間隔預設 60 秒,`JSC_PR_WATCH_INTERVAL` 可覆寫。

Why:等 PR 合併原本靠各技能自己寫輪詢迴圈,間隔與退場條件每支都不一樣,還常常自動逾時退場,PR 明明還開著就被當成收尾。改用一支共用腳本之後,等待行為只有一種,而且盯到 PR 收尾為止。

How:資料一律經同目錄的 `gitea.sh`(`pr-status`、`pr-comments`),不自行拼 API。已回報過的留言把最後一筆時間戳寫進狀態檔,預設 `$JSC_HOME/pr-watch/{owner}-{repo}-{編號}.seen`,同一則不重複回報;狀態檔還不存在時把既有留言整批回報一次,寧可重複也不漏掉開始盯之前的審查意見。PR 收尾那一輪若還有沒回報的留言,照樣印出來再退出,退出碼仍是 `0`。`pr-status` 對不存在的 PR 會印「? none none」並正常結束,所以 state 只認 `open` 與 `closed`、merged 只認 `true` 與 `false`,對不上就回 `3`,PR 編號打錯不會變成永遠輪詢一支不存在的 PR。

Who:`jsc-sdlc:implement` 開完工作包 PR 之後的等待合併,以及任何要盯 PR 的技能。
What:README 的指令清單補上 `pr-get`、`pr-edit` 與 `pr-watch.sh` 三項與各自的退出碼,環境變數表補 `JSC_HOME` 與 `JSC_PR_WATCH_INTERVAL`;AGENTS.md 新增一條規則,盯 PR 等合併一律用 `tools/pr-watch.sh`,不要自己寫輪詢迴圈。

Why:新指令沒寫進 README,呼叫端就只能翻腳本原始碼。`pr-watch.sh` 的退出碼 `10` 更要講清楚:它不是錯誤,是「有新留言,換你處理」的交棒訊號,看成錯誤就會把留言吞掉。

How:README 依既有版面把三項排進指令區塊,另補一段說明退出碼 `10` 的設計意圖。AGENTS.md 把新規則插進第 5 條,原第 5 條順延為第 6 條。

Who:讀 `jsc-gitea` 說明的人,以及依 AGENTS.md 行事的代理。
What:`plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` 的 `version` 由 0.1.4 改為 0.1.5。

Why:本次新增 `pr-get`、`pr-edit` 與 `pr-watch.sh`,屬於行為變更,版本要跟著往上走,各 CLI 才知道要更新。

How:三份只改 `version` 一個欄位,其餘內容不動,三份保持同一版號。

Who:`jsc-gitea` 外掛的套件描述檔。
Reviewed-on: #22
jiantw83 merged commit 8738f54b9d into develop 2026-08-27 03:39:37 +00:00
jiantw83 deleted branch feat/sdlc-flow-rules/main 2026-08-27 03:39:37 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: plugins/gitea#23