Merge pull request 'sdlc 0.1.6 發佈:四階段收尾一律回報' (#22) from develop into master
Reviewed-on: #22 Reviewed-by: 系統管理員 <1+admin@noreply.localhost>
This commit was merged in pull request #22.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-sdlc",
|
"name": "jsc-sdlc",
|
||||||
"version": "0.1.5",
|
"version": "0.1.6",
|
||||||
"description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)",
|
"description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)",
|
||||||
"skills": "./skills",
|
"skills": "./skills",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-sdlc",
|
"name": "jsc-sdlc",
|
||||||
"version": "0.1.5",
|
"version": "0.1.6",
|
||||||
"description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)",
|
"description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)",
|
||||||
"skills": "./skills"
|
"skills": "./skills"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
|
|||||||
| 腳本 | 用途 |
|
| 腳本 | 用途 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `tools/wp-gate.sh` | 工作包 PR 閘門,把「PR 沒合併就不開下一包」從內文敘述變成程式判定,共兩個用法。`check {owner}/{repo} {index} [--since {ISO 時間}]` 查 PR:已合併就呼叫 `jsc-hooks` 的 `sdlc-gate.sh wp-unlock` 解鎖並印 `status=merged`;沒合併就印 `status=open` 或 `status=closed-unmerged`(被關掉但沒合併不算完成),接著把 issue 留言、審查評語、行內留言全部逐行印出(`--since` 只印更新的,值取上一輪的 `latest=`),最後一行印 `latest={最新一筆留言的時間戳}` 供寫回分析頁。`lock {owner}/{repo} {index}` 在 PR 開好後轉呼叫 `sdlc-gate.sh wp-lock` 記下未結清。第一行固定 `status=...` 供程式判讀,其後為繁中說明;結束碼 `0`=已合併或無阻擋、`1`=未合併(擋住,呼叫端必須停下來逐筆修留言)、`2`=用法錯誤、`3`=相依工具或 PR 查不到(**查不到就擋,不放行**)。狀態檔由 `jsc-hooks` 管(`$JSC_HOME/wp/{owner}-{repo}.pr`,不綁 session,開新對話照樣擋),本檔只負責查詢與結清 |
|
| `tools/wp-gate.sh` | 工作包 PR 閘門,把「PR 沒合併就不開下一包」從內文敘述變成程式判定,共兩個用法。`check {owner}/{repo} {index} [--since {ISO 時間}]` 查 PR:已合併就呼叫 `jsc-hooks` 的 `sdlc-gate.sh wp-unlock` 解鎖並印 `status=merged`;沒合併就印 `status=open` 或 `status=closed-unmerged`(被關掉但沒合併不算完成),接著把 issue 留言、審查評語、行內留言全部逐行印出(`--since` 只印更新的,值取上一輪的 `latest=`),最後一行印 `latest={最新一筆留言的時間戳}` 供寫回分析頁。`lock {owner}/{repo} {index}` 在 PR 開好後轉呼叫 `sdlc-gate.sh wp-lock` 記下未結清。第一行固定 `status=...` 供程式判讀,其後為繁中說明;結束碼 `0`=已合併或無阻擋、`1`=未合併(擋住,呼叫端必須停下來逐筆修留言)、`2`=用法錯誤、`3`=相依工具或 PR 查不到(**查不到就擋,不放行**)。狀態檔由 `jsc-hooks` 管(`$JSC_HOME/wp/{owner}-{repo}.pr`,不綁 session,開新對話照樣擋),本檔只負責查詢與結清 |
|
||||||
|
| `tools/stage-report.sh` | 階段收尾回報,四個階段共用。`stage-report.sh {plan\|analyze\|implement\|maintain}` 加 `--page TYPE:PAGE`(本階段寫過的每一頁,可重複)產出繁中回報:模型閘門判定(轉述 `sdlc-gate.sh report`,不自評)、工作日誌連結(`--worklog`、`--worklog-heading` 組出導向條目標題的錨點)、所有寫入的 wiki 絕對網址。實作階段再加 `--worktree`、`--source-branch`、`--work-branch`、`--target-branch`、`--pr`,來源分支在不在遠端、工作分支幾個 commit、推送了沒,都由腳本現查。沒有工作日誌時警告使用者檢查,並用 `--pending-file`、`--log-hash` 把內容交給 `jsc-log/tools/worklog-pending.sh` 暫存,下次寫日誌一併寫入。結束碼 `0`=完整、`1`=有警告(**警告不是阻擋**)、`2`=用法錯誤、`3`=相依工具找不到 |
|
||||||
|
|
||||||
## Skills 目錄
|
## Skills 目錄
|
||||||
|
|
||||||
@@ -32,19 +33,19 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
|
|||||||
|
|
||||||
### `plan`
|
### `plan`
|
||||||
|
|
||||||
規劃:讀計畫目錄 → 補充或新建計畫 → 決策樹持續提問,補全目標、範圍、可行性到達成共識(判定規則見 `references/consensus.md`,一輪不算問完)→ 產生使用者故事 → 寫回 `PLAN_{HASH}`。純邏輯,禁止程式碼與修改檔案。
|
規劃:讀計畫目錄 → 補充或新建計畫 → 決策樹持續提問,補全目標、範圍、可行性到達成共識(判定規則見 `references/consensus.md`,一輪不算問完)→ 產生使用者故事 → 寫回 `PLAN_{HASH}` → 階段回報(`tools/stage-report.sh`)。純邏輯,禁止程式碼與修改檔案。
|
||||||
|
|
||||||
### `analyze`
|
### `analyze`
|
||||||
|
|
||||||
分析:先確認來源分支 → 持續提問到達成共識(`references/consensus.md`)→ 搭配現況(工作目錄與 `REPO_{HASH}` 盤點複用)分析使用者故事 → WBS 產生編號工作包,`WP-01` 固定是獨立的交付、交接工作包,實作工作包相依於它 → CPM 估工時與天數 → TDD 拆待辦 → 寫回 `ANALYZE_{HASH}`。純邏輯,禁止程式碼與修改檔案。
|
分析:先確認來源分支 → 持續提問到達成共識(`references/consensus.md`)→ 搭配現況(工作目錄與 `REPO_{HASH}` 盤點複用)分析使用者故事 → WBS 產生編號工作包,`WP-01` 固定是獨立的交付、交接工作包,實作工作包相依於它 → CPM 估工時與天數 → TDD 拆待辦 → 寫回 `ANALYZE_{HASH}` → 階段回報(`tools/stage-report.sh`)。純邏輯,禁止程式碼與修改檔案。
|
||||||
|
|
||||||
### `implement`
|
### `implement`
|
||||||
|
|
||||||
實作:先確認來源分支(同時是 PR 目標)→ 產生工作證鎖定「未完成、無相依、無工作證」的工作包(交付工作包優先)→ 交付工作包開工前先確認交付內容(API 文件、由使用者輸入,見 `references/deliver-formats.md`)→ **動程式碼前先從 `origin/{source-branch}` 建立 worktree**(`.worktree/{analysis-HASH}/{repo}`,分支處理依決策樹詢問)→ 在 worktree 內逐項 TDD 實作、每完成一項立即更新 wiki → 程式碼審查 → **每完成一個工作包就 commit、push、PR 回來源分支**(一包一 PR),接著 `tools/wp-gate.sh lock` 上鎖 → **PR 未合併就不開下一包,判定在程式層**:領工作包前先跑 `tools/wp-gate.sh check`,未合併就把全部留言逐筆印出並擋住,以 sub agent 回原 worktree 逐筆修正、推同一條工作分支(不開第二個 PR),修不動或純討論的留言忽略但要在回報裡列出,處理過的時間戳寫回分析頁的 PR 欄位當下一輪的 `--since`;合併後解鎖並移除 worktree → 詢問交付文件格式(`DELIVER_{HASH}` wiki 頁或 Gitea 議題留言)並產出 → 詢問是否加入維護目錄。
|
實作:先確認來源分支(同時是 PR 目標)→ 產生工作證鎖定「未完成、無相依、無工作證」的工作包(交付工作包優先)→ 交付工作包開工前先確認交付內容(API 文件、由使用者輸入,見 `references/deliver-formats.md`)→ **動程式碼前先從 `origin/{source-branch}` 建立 worktree**(`.worktree/{analysis-HASH}/{repo}`,分支處理依決策樹詢問)→ 在 worktree 內逐項 TDD 實作、每完成一項立即更新 wiki → 程式碼審查 → **每完成一個工作包就 commit、push、PR 回來源分支**(一包一 PR),接著 `tools/wp-gate.sh lock` 上鎖 → **PR 未合併就不開下一包,判定在程式層**:領工作包前先跑 `tools/wp-gate.sh check`,未合併就把全部留言逐筆印出並擋住,以 sub agent 回原 worktree 逐筆修正、推同一條工作分支(不開第二個 PR),修不動或純討論的留言忽略但要在回報裡列出,處理過的時間戳寫回分析頁的 PR 欄位當下一輪的 `--since`;合併後解鎖並移除 worktree → 詢問交付文件格式(`DELIVER_{HASH}` wiki 頁或 Gitea 議題留言)並產出 → 詢問是否加入維護目錄 → 階段回報(`tools/stage-report.sh`,多報工作目錄與來源、工作、目標三條分支)。
|
||||||
|
|
||||||
### `maintain`
|
### `maintain`
|
||||||
|
|
||||||
維護:讀取維護期內的專案,每個專案一個 sub agent:fetch 後切 develop、master 並對齊 `origin/{branch}` → 提出至少五種維護方法,依決策樹讓使用者挑要做哪些 → commit / push / PR → 更新前次維護時間。僅適用於維護期內已交付的專案;尚在實作中或未登記於 `MAINTAIN_CONTENTS` 的專案不適用。
|
維護:讀取維護期內的專案,每個專案一個 sub agent:fetch 後切 develop、master 並對齊 `origin/{branch}` → 提出至少五種維護方法,依決策樹讓使用者挑要做哪些 → commit / push / PR → 更新前次維護時間 → 階段回報(`tools/stage-report.sh`)。僅適用於維護期內已交付的專案;尚在實作中或未登記於 `MAINTAIN_CONTENTS` 的專案不適用。
|
||||||
|
|
||||||
<!-- JSC-SKILLS:END -->
|
<!-- JSC-SKILLS:END -->
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
|
|||||||
| `templates/repo-page.md`、`templates/repo-contents.md` | 存取庫盤點頁(功能與端點,附 commit sha)與盤點目錄 |
|
| `templates/repo-page.md`、`templates/repo-contents.md` | 存取庫盤點頁(功能與端點,附 commit sha)與盤點目錄 |
|
||||||
| `templates/deliver-page.md`、`templates/deliver-contents.md` | 交付頁(API 文件、新舊參數標示、驗證方式)與交付目錄 |
|
| `templates/deliver-page.md`、`templates/deliver-contents.md` | 交付頁(API 文件、新舊參數標示、驗證方式)與交付目錄 |
|
||||||
| `templates/maintain-contents.md` | 維護目錄(截止日 NULL = 永久維護) |
|
| `templates/maintain-contents.md` | 維護目錄(截止日 NULL = 永久維護) |
|
||||||
|
| `references/stage-report.md` | 階段回報:四階段都要交的三項(模型能力標籤、工作日誌連結、所有寫入的 wiki 連結)、實作階段多交的四項、沒寫日誌時的暫存規則、提前停止也要回報 |
|
||||||
| `references/model-gate.md` | 模型閘門:執行順序、各階段必要標籤、阻擋與回報的鐵則 |
|
| `references/model-gate.md` | 模型閘門:執行順序、各階段必要標籤、阻擋與回報的鐵則 |
|
||||||
| `references/tdd.md` | 接縫、紅綠循環規則、反模式 |
|
| `references/tdd.md` | 接縫、紅綠循環規則、反模式 |
|
||||||
| `references/branch.md` | 分支規則:**一律以遠端 `origin/{branch}` 為準、動作前先 fetch**、分析前確認來源分支、實作沿用同一條來源分支作為 PR 目標(一包一 PR、PR 未合併不開下一包,閘門分工見該檔)、實作一律在 `.worktree/{HASH}/{repo}` 內進行(建立前問分支、PR 合併後才移除)、判定遠端預設分支、不破壞未提交變更 |
|
| `references/branch.md` | 分支規則:**一律以遠端 `origin/{branch}` 為準、動作前先 fetch**、分析前確認來源分支、實作沿用同一條來源分支作為 PR 目標(一包一 PR、PR 未合併不開下一包,閘門分工見該檔)、實作一律在 `.worktree/{HASH}/{repo}` 內進行(建立前問分支、PR 合併後才移除)、判定遠端預設分支、不破壞未提交變更 |
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-sdlc",
|
"name": "jsc-sdlc",
|
||||||
"version": "0.1.5",
|
"version": "0.1.6",
|
||||||
"description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)",
|
"description": "開發生命週期:規劃、分析、實作、維護(wiki 追蹤)",
|
||||||
"skills": "./skills/"
|
"skills": "./skills/"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# 階段回報 — 四個階段收尾都要交的東西
|
||||||
|
|
||||||
|
規劃、分析、實作、維護跑完,最後一件事一定是階段回報。彙整由 `tools/stage-report.sh` 產出,
|
||||||
|
技能只負責把事實餵進去:寫過哪些 wiki 頁、有沒有寫工作日誌、實作階段的工作目錄與三條分支。
|
||||||
|
|
||||||
|
## 什麼時候回報
|
||||||
|
|
||||||
|
階段結束就回報,**提前停下來也算結束**:模型閘門擋下、工作包閘門擋下、沒有可選的計畫或工作包、
|
||||||
|
來源分支在遠端找不到——這些情況一樣要回報,而且更需要。停在半路卻沒有回報,看起來就跟沒跑過一樣。
|
||||||
|
|
||||||
|
## 每個階段都要回報的三項
|
||||||
|
|
||||||
|
| 項目 | 來源 | 沒有時怎麼辦 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 模型能力標籤 | `jsc-hooks/hooks/sdlc-gate.sh report`,腳本自己讀 | 回報「查不到閘門狀態」,並要求重跑 `lock {stage}` |
|
||||||
|
| 工作日誌連結 | `--worklog` 給頁名、`--worklog-heading` 給條目標題,組成導向該條目的錨點連結 | 警告使用者檢查,並把內容暫存(見下節) |
|
||||||
|
| 所有寫入的 wiki 連結 | 每寫一頁就記一筆,收尾時用 `--page TYPE:PAGE` 全部餵進去 | 沒寫任何頁就據實回報「本階段沒有寫入任何 wiki 頁」 |
|
||||||
|
|
||||||
|
`--page` 的 `TYPE` 是頁名前綴(`PLAN`、`ANALYZE`、`DELIVER`、`REPO`、`MAINTAIN`、`LOG`)。腳本用它解析
|
||||||
|
該類型的 wiki 存取庫,再換成絕對網址,所以跨存取庫的頁面也連得到。目錄頁(`*_CONTENTS`)也算寫入,要列。
|
||||||
|
|
||||||
|
## 實作階段多回報四項
|
||||||
|
|
||||||
|
| 項目 | 選項 | 腳本自己查的部分 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 工作目錄 | `--worktree PATH` | 無,原樣列出 |
|
||||||
|
| 來源分支 | `--source-branch NAME` | 遠端有沒有這一條。遠端找不到就標「只有本機」 |
|
||||||
|
| 工作分支 | `--work-branch NAME` | 相對來源分支的 commit 數、推送狀態(未 push、或還有幾個 commit 沒 push) |
|
||||||
|
| 目標分支 | `--target-branch NAME`、`--pr URL` | 省略目標分支時等同來源分支;沒有 PR 連結就列為警告 |
|
||||||
|
|
||||||
|
## 沒寫工作日誌就暫存
|
||||||
|
|
||||||
|
階段跑完卻沒有工作日誌,內容只留在對話裡,換一個工作階段就沒了。所以:
|
||||||
|
|
||||||
|
1. 把這個階段要記的日誌內容寫成一個檔案。
|
||||||
|
2. 收尾時一起餵進去:`--pending-file {檔案} --log-hash {LOG_{HASH} 的 HASH}`。
|
||||||
|
3. 腳本轉呼叫 `jsc-log/tools/worklog-pending.sh add`,把內容存進 `$JSC_HOME/worklog-pending/{HASH}/`,並在回報裡印出存放路徑。
|
||||||
|
4. 下次 `jsc-log:worklog` 寫入時,會先把暫存區的內容一併寫進日誌頁,寫成功才清掉暫存。
|
||||||
|
|
||||||
|
`{HASH}` 用 `jsc-gitea/tools/hash-id` 對程式碼存取庫的 `{owner}/{repo}` 算出來,和 `LOG_{HASH}` 同一個值。
|
||||||
|
|
||||||
|
## 結束碼
|
||||||
|
|
||||||
|
| 碼 | 意思 | 呼叫端要做的事 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 0 | 回報完整 | 把輸出原樣貼給使用者 |
|
||||||
|
| 1 | 有警告(缺工作日誌、或實作階段沒有 PR) | 一樣把輸出貼給使用者。**這是警告不是阻擋**,階段的工作已經做完了 |
|
||||||
|
| 2 | 用法錯誤 | 修正參數重跑 |
|
||||||
|
| 3 | 找不到 `gitea.sh` 或 `sdlc-gate.sh` | 修好相依關係再重跑 |
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: analyze
|
name: analyze
|
||||||
description: SDLC analysis stage. Gate on capability tags enforced in code by sdlc-gate (analyze requires reasoning-max), confirm the source branch, then pick a plan from PLAN_CONTENTS and question until consensus per references/consensus.md. Analyze its user stories against the current state (working directory plus REPO_{HASH} inventory for reuse), then run WBS with a standalone delivery/handover WP-01, CPM estimates and TDD todos. Write wiki page ANALYZE_{HASH} with real sample data; logic only - never write code or modify files. Use after planning and before implementation; not for writing code (that is implement), and not before a plan exists in PLAN_CONTENTS.
|
description: SDLC analysis stage. Gate on capability tags enforced in code by sdlc-gate (analyze requires reasoning-max), confirm the source branch, then pick a plan from PLAN_CONTENTS and question until consensus per references/consensus.md. Analyze its user stories against the current state (working directory plus REPO_{HASH} inventory for reuse), then run WBS with a standalone delivery/handover WP-01, CPM estimates and TDD todos. Write wiki page ANALYZE_{HASH} with real sample data, then close with tools/stage-report.sh - model tag verdict, worklog link, every wiki link written; logic only - never write code or modify files. Use after planning and before implementation; not for writing code (that is implement), and not before a plan exists in PLAN_CONTENTS.
|
||||||
---
|
---
|
||||||
|
|
||||||
# analyze
|
# analyze
|
||||||
@@ -35,6 +35,7 @@ All wiki reads and writes go through `jsc-gitea:wiki`.
|
|||||||
9. Split every work package into todos with **Test-Driven Development (TDD)**, formatted `[ ]` (open) / `[x]` (done). Each todo is one vertical slice: one seam, one test, one minimal implementation. Seams and anti-patterns: `references/tdd.md`. Completion condition: every work package carries at least one `[ ]` todo, and every todo names its seam and the behaviour its test asserts.
|
9. Split every work package into todos with **Test-Driven Development (TDD)**, formatted `[ ]` (open) / `[x]` (done). Each todo is one vertical slice: one seam, one test, one minimal implementation. Seams and anti-patterns: `references/tdd.md`. Completion condition: every work package carries at least one `[ ]` todo, and every todo names its seam and the behaviour its test asserts.
|
||||||
10. Apply `templates/analyze-page.md` to create or update the analysis page and write it back via `jsc-gitea:wiki`. The page content is Traditional Chinese, exactly as the template dictates. Completion condition: the page is saved on the wiki and carries every section the template dictates, including the source branch, the head sha and the 未決項 section (「無」 when there is none).
|
10. Apply `templates/analyze-page.md` to create or update the analysis page and write it back via `jsc-gitea:wiki`. The page content is Traditional Chinese, exactly as the template dictates. Completion condition: the page is saved on the wiki and carries every section the template dictates, including the source branch, the head sha and the 未決項 section (「無」 when there is none).
|
||||||
11. If the analysis page is new: add it to `ANALYZE_CONTENTS` per `templates/analyze-contents.md`, and flip the plan's status in `PLAN_CONTENTS` to the literal 「已分析」. Completion condition: `ANALYZE_CONTENTS` shows the new row and `PLAN_CONTENTS` shows the literal 「已分析」, both saved on the wiki.
|
11. If the analysis page is new: add it to `ANALYZE_CONTENTS` per `templates/analyze-contents.md`, and flip the plan's status in `PLAN_CONTENTS` to the literal 「已分析」. Completion condition: `ANALYZE_CONTENTS` shows the new row and `PLAN_CONTENTS` shows the literal 「已分析」, both saved on the wiki.
|
||||||
|
12. **Stage report — the last thing this stage does, including every early stop** (the model gate blocked, the working tree did not match `origin/{source-branch}`, no plan was selectable). Run `tools/stage-report.sh analyze` with one `--page TYPE:{page}` per wiki page this run wrote — `ANALYZE_{HASH}`, `ANALYZE_CONTENTS`, `PLAN_CONTENTS`, and `REPO_{HASH}` plus `REPO_CONTENTS` when a re-inventory happened — plus `--worklog` and `--worklog-heading` when a work log entry exists. No work log yet: write this stage's log content to a file and pass `--pending-file {file} --log-hash {HASH}` so it is held for the next `jsc-log:worklog` run. Rules and exit codes: `references/stage-report.md`. Exit 1 is a warning, never a block. Completion condition: the script's output is reported to the user verbatim, and every wiki page this run wrote appears in it.
|
||||||
|
|
||||||
## Delivery package is WP-01
|
## Delivery package is WP-01
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: implement
|
name: implement
|
||||||
description: SDLC implementation stage. Gate on capability tags enforced in code by sdlc-gate (implement requires coding), then confirm the analysis page's source branch - it is both the worktree base and the PR target. An unmerged work package PR is a hard gate enforced in code by tools/wp-gate.sh: it reads every PR comment, sub agents fix them in the original worktree, and no next package starts until that PR merges. Claim a ready work package from ANALYZE_CONTENTS with a work ticket, confirm a delivery package's content type, then complete its TDD todos one at a time inside a worktree built from origin/{source-branch}, updating the wiki after every item, closing with jsc-review code-review, one PR back to the source branch, the chosen delivery document and an optional MAINTAIN_CONTENTS entry. Use when analysis is done and code must be written; not for planning or analysis.
|
description: SDLC implementation stage. Gate on capability tags enforced in code by sdlc-gate (implement requires coding), then confirm the analysis page's source branch - it is both the worktree base and the PR target. An unmerged work package PR is a hard gate enforced in code by tools/wp-gate.sh: it reads every PR comment, sub agents fix them in the original worktree, and no next package starts until that PR merges. Claim a ready work package from ANALYZE_CONTENTS with a work ticket, confirm a delivery package's content type, then complete its TDD todos one at a time inside a worktree built from origin/{source-branch}, updating the wiki after every item, closing with jsc-review code-review, one PR back to the source branch, the chosen delivery document, an optional MAINTAIN_CONTENTS entry, and a tools/stage-report.sh report covering the model tag verdict, the worklog link, every wiki link written, the worktree and the three branches. Use when analysis is done and code must be written; not for planning or analysis.
|
||||||
---
|
---
|
||||||
|
|
||||||
# implement
|
# implement
|
||||||
@@ -49,6 +49,12 @@ All wiki reads and writes go through `jsc-gitea:wiki`.
|
|||||||
4. Issue comment: confirm the issue number with the user (propose the one referenced by the work package or the PR; never guess), then post via `jsc-gitea/tools/gitea.sh api POST /repos/{owner}/{repo}/issues/{n}/comments` with the body passed in as a UTF-8 file — real newlines, never a literal `\n`.
|
4. Issue comment: confirm the issue number with the user (propose the one referenced by the work package or the PR; never guess), then post via `jsc-gitea/tools/gitea.sh api POST /repos/{owner}/{repo}/issues/{n}/comments` with the body passed in as a UTF-8 file — real newlines, never a literal `\n`.
|
||||||
5. Completion condition: the chosen format has actually been produced, and you have reported where it landed (wiki page name, or the comment URL).
|
5. Completion condition: the chosen format has actually been produced, and you have reported where it landed (wiki page name, or the comment URL).
|
||||||
13. Ask per `jsc-ask:ask` rules whether to register this project for maintenance: append to `MAINTAIN_CONTENTS` with `templates/maintain-contents.md`. Required: repository `{owner}/{repo}`, maintenance method, start date. Optional: end date (NULL = maintain forever), last-maintained time. Completion condition: the user has answered, and a chosen registration is saved on the wiki.
|
13. Ask per `jsc-ask:ask` rules whether to register this project for maintenance: append to `MAINTAIN_CONTENTS` with `templates/maintain-contents.md`. Required: repository `{owner}/{repo}`, maintenance method, start date. Optional: end date (NULL = maintain forever), last-maintained time. Completion condition: the user has answered, and a chosen registration is saved on the wiki.
|
||||||
|
14. **Stage report — the last thing this stage does, including every early stop** (the work package gate blocked, no work package was selectable, the source branch was missing from the remote). Run `tools/stage-report.sh implement` with:
|
||||||
|
- one `--page TYPE:{page}` per wiki page this run wrote — `ANALYZE_{HASH}`, `DELIVER_{HASH}` and `DELIVER_CONTENTS`, `MAINTAIN_CONTENTS`;
|
||||||
|
- `--worklog` and `--worklog-heading` when a work log entry exists; otherwise write this stage's log content to a file and pass `--pending-file {file} --log-hash {HASH}`, which holds it for the next `jsc-log:worklog` run;
|
||||||
|
- `--worktree {path} --source-branch {name} --work-branch {name} --pr {url}` — the script reads the commit count, the push state and whether the source branch exists on the remote by itself, so pass the names, not your own count.
|
||||||
|
|
||||||
|
Rules and exit codes: `references/stage-report.md`. Exit 1 is a warning, never a block. Completion condition: the script's output is reported to the user verbatim, and it names the worktree, all three branches and every wiki page this run wrote.
|
||||||
|
|
||||||
## Rules
|
## Rules
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: maintain
|
name: maintain
|
||||||
description: SDLC maintenance stage. Gate on capability tags enforced in code by sdlc-gate (maintenance requires no specific tag, but the actual model id must be determinable from the transcript), read projects still inside their maintenance window from MAINTAIN_CONTENTS, then run one sub agent per project: switch to develop or master, propose at least five maintenance actions, commit to a new branch, push, and PR. Update the last-maintained timestamp afterward. Use for periodic upkeep of delivered projects inside their maintenance window; not for projects still mid-implementation or not yet registered in MAINTAIN_CONTENTS.
|
description: SDLC maintenance stage. Gate on capability tags enforced in code by sdlc-gate (maintenance requires no specific tag, but the actual model id must be determinable from the transcript), read projects still inside their maintenance window from MAINTAIN_CONTENTS, then run one sub agent per project: switch to develop or master, propose at least five maintenance actions, commit to a new branch, push, and PR. Update the last-maintained timestamp afterward, then close with tools/stage-report.sh - model tag verdict, worklog link, every wiki link written. Use for periodic upkeep of delivered projects inside their maintenance window; not for projects still mid-implementation or not yet registered in MAINTAIN_CONTENTS.
|
||||||
---
|
---
|
||||||
|
|
||||||
# maintain
|
# maintain
|
||||||
@@ -26,3 +26,4 @@ All wiki reads and writes go through `jsc-gitea:wiki`.
|
|||||||
3. Commit the changes to a new branch per `jsc-git:commit`, push, then open a PR per `jsc-git:pr` back to the branch of step 3.1, passing it explicitly as the base. Completion condition: the PR exists, and you have reported its URL and number.
|
3. Commit the changes to a new branch per `jsc-git:commit`, push, then open a PR per `jsc-git:pr` back to the branch of step 3.1, passing it explicitly as the base. Completion condition: the PR exists, and you have reported its URL and number.
|
||||||
4. Update the project's last-maintained field (the zh-TW column 「前次維護時間」) in `MAINTAIN_CONTENTS` to today. Completion condition: `MAINTAIN_CONTENTS` shows today's date in 「前次維護時間」 for that project, saved on the wiki.
|
4. Update the project's last-maintained field (the zh-TW column 「前次維護時間」) in `MAINTAIN_CONTENTS` to today. Completion condition: `MAINTAIN_CONTENTS` shows today's date in 「前次維護時間」 for that project, saved on the wiki.
|
||||||
4. The main agent reports the summary: maintenance methods applied per project, PR links, and failure reasons. The report and all generated wiki content, commits, and PR descriptions stay Traditional Chinese per the STE100 rule. Completion condition: the summary names every project read in step 2, each with its applied methods and either a PR link or the reason it was skipped.
|
4. The main agent reports the summary: maintenance methods applied per project, PR links, and failure reasons. The report and all generated wiki content, commits, and PR descriptions stay Traditional Chinese per the STE100 rule. Completion condition: the summary names every project read in step 2, each with its applied methods and either a PR link or the reason it was skipped.
|
||||||
|
5. **Stage report — the last thing this stage does, including when no project was in window.** Run `tools/stage-report.sh maintain` with one `--page MAINTAIN:{page}` per wiki page this run wrote (`MAINTAIN_CONTENTS` counts), plus `--worklog` and `--worklog-heading` when a work log entry exists. No work log yet: write this stage's log content to a file and pass `--pending-file {file} --log-hash {HASH}` so it is held for the next `jsc-log:worklog` run. Rules and exit codes: `references/stage-report.md`. Exit 1 is a warning, never a block. Completion condition: the script's output is reported to the user verbatim, and every wiki page this run wrote appears in it.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: plan
|
name: plan
|
||||||
description: SDLC planning stage. Gate on capability tags enforced in code by sdlc-gate (plan requires reasoning-max, verified against the transcript's actual model id), pick or create a plan from PLAN_CONTENTS, then run a decision tree until goal, scope, and feasibility reach consensus. Produce user stories into wiki page PLAN_{HASH}. Logic only - never write code or modify files. Use when the user wants to start or refine a plan; not for analysis or implementation.
|
description: SDLC planning stage. Gate on capability tags enforced in code by sdlc-gate (plan requires reasoning-max, verified against the transcript's actual model id), pick or create a plan from PLAN_CONTENTS, then run a decision tree until goal, scope, and feasibility reach consensus. Produce user stories into wiki page PLAN_{HASH}, then close with tools/stage-report.sh - model tag verdict, worklog link, every wiki link written. Logic only - never write code or modify files. Use when the user wants to start or refine a plan; not for analysis or implementation.
|
||||||
---
|
---
|
||||||
|
|
||||||
# plan
|
# plan
|
||||||
@@ -27,6 +27,7 @@ All wiki reads and writes go through `jsc-gitea:wiki`.
|
|||||||
5. Turn the consensus into **user stories** (the zh-TW pattern 「身為⋯⋯我想要⋯⋯以便⋯⋯」), one per line. Completion condition: every consensus item is covered by at least one user story in that pattern, and no user story rests on an unanswered question.
|
5. Turn the consensus into **user stories** (the zh-TW pattern 「身為⋯⋯我想要⋯⋯以便⋯⋯」), one per line. Completion condition: every consensus item is covered by at least one user story in that pattern, and no user story rests on an unanswered question.
|
||||||
6. Apply `templates/plan-page.md` to create or update the plan page, and write it back via `jsc-gitea:wiki`. The page content is Traditional Chinese, exactly as the template dictates. Completion condition: the page is saved on the wiki and carries every section the template dictates — goal, scope, feasibility, user stories and the consensus summary — with no placeholder left unfilled.
|
6. Apply `templates/plan-page.md` to create or update the plan page, and write it back via `jsc-gitea:wiki`. The page content is Traditional Chinese, exactly as the template dictates. Completion condition: the page is saved on the wiki and carries every section the template dictates — goal, scope, feasibility, user stories and the consensus summary — with no placeholder left unfilled.
|
||||||
7. If the plan page is new, add it to `PLAN_CONTENTS` using the entry format of `templates/plan-contents.md`, with status set to the literal 「未分析」. Completion condition: `PLAN_CONTENTS` shows the plan's row with the literal 「未分析」, saved on the wiki.
|
7. If the plan page is new, add it to `PLAN_CONTENTS` using the entry format of `templates/plan-contents.md`, with status set to the literal 「未分析」. Completion condition: `PLAN_CONTENTS` shows the plan's row with the literal 「未分析」, saved on the wiki.
|
||||||
|
8. **Stage report — the last thing this stage does, including every early stop** (the model gate blocked, no plan was selectable). Run `tools/stage-report.sh plan` with one `--page PLAN:{page}` per wiki page this run wrote (`PLAN_{HASH}` and `PLAN_CONTENTS` both count), plus `--worklog` and `--worklog-heading` when a work log entry exists. No work log yet: write this stage's log content to a file and pass `--pending-file {file} --log-hash {HASH}` so it is held for the next `jsc-log:worklog` run. Rules and exit codes: `references/stage-report.md`. Exit 1 is a warning, never a block. Completion condition: the script's output is reported to the user verbatim, and every wiki page this run wrote appears in it.
|
||||||
|
|
||||||
## Hard limits
|
## Hard limits
|
||||||
|
|
||||||
|
|||||||
Executable
+279
@@ -0,0 +1,279 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# stage-report.sh — SDLC 階段收尾回報(規劃、分析、實作、維護共用)。
|
||||||
|
#
|
||||||
|
# 為什麼要有這支腳本:階段結束要回報的東西是固定的——模型閘門判定、工作日誌連結、所有寫入的
|
||||||
|
# wiki 連結,實作階段再加上工作目錄與三條分支。寫在技能內文裡靠模型自己記,少一項看不出來;
|
||||||
|
# 所以彙整搬到程式層:頁名換成絕對網址、commit 數與推送狀態由 git 現查、沒有工作日誌就當場
|
||||||
|
# 警告並把內容存進暫存區,全部由本檔產出,技能只負責把事實餵進來。
|
||||||
|
#
|
||||||
|
# 用法:
|
||||||
|
# stage-report.sh <stage> [選項]
|
||||||
|
# <stage> = plan | analyze | implement | maintain
|
||||||
|
#
|
||||||
|
# 共用選項:
|
||||||
|
# --page TYPE:PAGE 本階段寫入的 wiki 頁,可重複(例:--page ANALYZE:ANALYZE_D3F1A2B0)
|
||||||
|
# --worklog PAGE 已寫入的工作日誌頁名(例:LOG_D3F1A2B0)
|
||||||
|
# --worklog-heading TEXT 日誌條目標題,用來組出導向該條目的錨點連結
|
||||||
|
# --pending-file FILE 沒有工作日誌時,要暫存起來的日誌內容檔
|
||||||
|
# --log-hash HASH 暫存歸屬的工作日誌 hash(即 LOG_{HASH} 的 HASH)
|
||||||
|
#
|
||||||
|
# 實作階段選項:
|
||||||
|
# --worktree PATH 工作目錄(worktree 路徑)
|
||||||
|
# --source-branch NAME 來源分支(本檔自行判定遠端有沒有這一條)
|
||||||
|
# --work-branch NAME 工作分支(本檔自行算 commit 數與推送狀態)
|
||||||
|
# --pr URL 目標分支的 PR 連結
|
||||||
|
# --target-branch NAME 目標分支(省略時等同來源分支)
|
||||||
|
#
|
||||||
|
# 輸出: 繁體中文 markdown 階段回報,直接貼給使用者。
|
||||||
|
# 結束碼: 0=回報完整 1=有警告(缺工作日誌,內容已暫存) 2=用法錯誤 3=相依工具找不到
|
||||||
|
#
|
||||||
|
# 陷阱:
|
||||||
|
# - 結束碼 1 是警告,不是阻擋:階段的工作已經做完了,擋下去只會讓使用者拿不到回報。
|
||||||
|
# - 缺工作日誌時一定要給 --pending-file 與 --log-hash,否則內容留在對話裡,換一個工作階段就沒了。
|
||||||
|
# - 模型閘門那一列只轉述 sdlc-gate.sh report 的結果,不自己判定標籤。
|
||||||
|
set -u
|
||||||
|
|
||||||
|
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
plugin_root="${CLAUDE_PLUGIN_ROOT:-$script_dir/..}"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat >&2 <<'EOF'
|
||||||
|
用法:
|
||||||
|
stage-report.sh <plan|analyze|implement|maintain> [選項]
|
||||||
|
--page TYPE:PAGE 本階段寫入的 wiki 頁,可重複
|
||||||
|
--worklog PAGE 已寫入的工作日誌頁名
|
||||||
|
--worklog-heading TEXT 日誌條目標題(組錨點用)
|
||||||
|
--pending-file FILE 沒有工作日誌時要暫存的內容檔
|
||||||
|
--log-hash HASH 暫存歸屬的工作日誌 hash
|
||||||
|
--worktree PATH 實作:工作目錄
|
||||||
|
--source-branch NAME 實作:來源分支
|
||||||
|
--work-branch NAME 實作:工作分支
|
||||||
|
--target-branch NAME 實作:目標分支(省略時同來源分支)
|
||||||
|
--pr URL 實作:PR 連結
|
||||||
|
結束碼: 0=完整 1=缺工作日誌(已暫存,警告) 2=用法錯誤 3=相依工具找不到
|
||||||
|
EOF
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# 找相依腳本。兩種版面都要顧到:並排存取庫(開發用)與已安裝 plugin(各版本一個目錄)。
|
||||||
|
resolve_dep() { # $1=並排目錄名(gitea、hooks、log) $2=plugin 內的相對路徑
|
||||||
|
_name="$1"; _rel="$2"
|
||||||
|
for _c in "$plugin_root/../$_name/$_rel" "$plugin_root/../jsc-$_name/$_rel"; do
|
||||||
|
[ -f "$_c" ] && { printf '%s\n' "$_c"; return 0; }
|
||||||
|
done
|
||||||
|
_c=$(ls -d "$plugin_root"/../../"jsc-$_name"/*/"$_rel" \
|
||||||
|
"$plugin_root"/../../"$_name"/*/"$_rel" \
|
||||||
|
"$HOME"/.claude/plugins/cache/*/"jsc-$_name"/*/"$_rel" 2>/dev/null \
|
||||||
|
| sort | tail -n1)
|
||||||
|
[ -n "$_c" ] && [ -f "$_c" ] && { printf '%s\n' "$_c"; return 0; }
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
gitea_sh() {
|
||||||
|
if [ -n "${JSC_GITEA_TOOLS:-}" ] && [ -f "$JSC_GITEA_TOOLS/gitea.sh" ]; then
|
||||||
|
printf '%s\n' "$JSC_GITEA_TOOLS/gitea.sh"; return 0
|
||||||
|
fi
|
||||||
|
resolve_dep gitea tools/gitea.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
sdlc_gate_sh() {
|
||||||
|
if [ -n "${JSC_HOOKS_DIR:-}" ] && [ -f "$JSC_HOOKS_DIR/sdlc-gate.sh" ]; then
|
||||||
|
printf '%s\n' "$JSC_HOOKS_DIR/sdlc-gate.sh"; return 0
|
||||||
|
fi
|
||||||
|
resolve_dep hooks hooks/sdlc-gate.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
stage="${1:-}"
|
||||||
|
case "$stage" in
|
||||||
|
plan|analyze|implement|maintain) shift ;;
|
||||||
|
*) usage ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
pages=''
|
||||||
|
worklog=''
|
||||||
|
worklog_heading=''
|
||||||
|
pending_file=''
|
||||||
|
log_hash=''
|
||||||
|
worktree=''
|
||||||
|
source_branch=''
|
||||||
|
work_branch=''
|
||||||
|
target_branch=''
|
||||||
|
pr_url=''
|
||||||
|
|
||||||
|
while [ "$#" -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--page) [ "$#" -ge 2 ] || usage; pages="$pages$2
|
||||||
|
"; shift 2 ;;
|
||||||
|
--worklog) [ "$#" -ge 2 ] || usage; worklog="$2"; shift 2 ;;
|
||||||
|
--worklog-heading) [ "$#" -ge 2 ] || usage; worklog_heading="$2"; shift 2 ;;
|
||||||
|
--pending-file) [ "$#" -ge 2 ] || usage; pending_file="$2"; shift 2 ;;
|
||||||
|
--log-hash) [ "$#" -ge 2 ] || usage; log_hash="$2"; shift 2 ;;
|
||||||
|
--worktree) [ "$#" -ge 2 ] || usage; worktree="$2"; shift 2 ;;
|
||||||
|
--source-branch) [ "$#" -ge 2 ] || usage; source_branch="$2"; shift 2 ;;
|
||||||
|
--work-branch) [ "$#" -ge 2 ] || usage; work_branch="$2"; shift 2 ;;
|
||||||
|
--target-branch) [ "$#" -ge 2 ] || usage; target_branch="$2"; shift 2 ;;
|
||||||
|
--pr) [ "$#" -ge 2 ] || usage; pr_url="$2"; shift 2 ;;
|
||||||
|
*) echo "[jsc][階段回報][ERR]:不認得的選項「$1」。" >&2; usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
GITEA=$(gitea_sh) || { echo '[jsc][階段回報][ERR]:找不到 jsc-gitea/tools/gitea.sh,無法把頁名換成網址。' >&2; exit 3; }
|
||||||
|
GATE=$(sdlc_gate_sh) || { echo '[jsc][階段回報][ERR]:找不到 jsc-hooks/hooks/sdlc-gate.sh,無法轉述閘門判定。' >&2; exit 3; }
|
||||||
|
|
||||||
|
stage_zh() {
|
||||||
|
case "$1" in
|
||||||
|
plan) echo '規劃' ;;
|
||||||
|
analyze) echo '分析' ;;
|
||||||
|
implement) echo '實作' ;;
|
||||||
|
maintain) echo '維護' ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
required_tag() {
|
||||||
|
case "$1" in
|
||||||
|
plan|analyze) echo 'reasoning-max' ;;
|
||||||
|
implement) echo 'coding' ;;
|
||||||
|
maintain) echo '無(模型 id 可判定即通過)' ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# 錨點:Gitea wiki 的標題錨點比照 GitHub——轉小寫、空白換連字號、去掉標點;中文原樣保留。
|
||||||
|
anchor_of() {
|
||||||
|
printf '%s' "$1" \
|
||||||
|
| tr 'A-Z' 'a-z' \
|
||||||
|
| sed 's/[][()#。,、:;!?,.:;!?]//g; s/[[:space:]]\{1,\}/-/g'
|
||||||
|
}
|
||||||
|
|
||||||
|
page_url() { # TYPE PAGE -> 絕對網址;查不到就回空字串
|
||||||
|
_type="$1"; _page="$2"
|
||||||
|
_repo=$("$GITEA" wiki-repo "$_type" 2>/dev/null) || return 1
|
||||||
|
"$GITEA" wiki-url "$_repo" "$_page" 2>/dev/null || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---- 模型能力標籤 ----
|
||||||
|
gate_line=$("$GATE" report 2>/dev/null || true)
|
||||||
|
gate_stage=$(printf '%s' "$gate_line" | awk '{print $2}')
|
||||||
|
gate_tag=$(printf '%s' "$gate_line" | awk '{print $3}')
|
||||||
|
gate_model=$(printf '%s' "$gate_line" | awk '{print $4}')
|
||||||
|
if [ -z "$gate_line" ]; then
|
||||||
|
gate_result="查不到閘門狀態(未上鎖或狀態檔不在),請重跑 sdlc-gate.sh lock $stage"
|
||||||
|
elif [ "$gate_stage" != "$stage" ]; then
|
||||||
|
gate_result="不符:本階段為 $stage,鎖上的卻是 $gate_stage,請重跑 sdlc-gate.sh lock $stage"
|
||||||
|
else
|
||||||
|
gate_result="通過(必要標籤 $(required_tag "$stage"),實際模型 ${gate_model:-未知},鎖上時的標籤 ${gate_tag:-無})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- 工作日誌 ----
|
||||||
|
warn=0
|
||||||
|
worklog_cell=''
|
||||||
|
if [ -n "$worklog" ]; then
|
||||||
|
wl_url=$(page_url LOG "$worklog" || true)
|
||||||
|
if [ -n "$wl_url" ]; then
|
||||||
|
if [ -n "$worklog_heading" ]; then
|
||||||
|
worklog_cell="[$worklog_heading]($wl_url#$(anchor_of "$worklog_heading"))"
|
||||||
|
else
|
||||||
|
worklog_cell="[$worklog]($wl_url)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
worklog_cell="$worklog(取不到網址,請確認 LOG 的 wiki 存取庫設定)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn=1
|
||||||
|
worklog_cell='**尚未寫入**'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- 暫存 ----
|
||||||
|
pending_note=''
|
||||||
|
if [ "$warn" -eq 1 ]; then
|
||||||
|
if [ -n "$pending_file" ] && [ -n "$log_hash" ]; then
|
||||||
|
PENDING=$(resolve_dep log tools/worklog-pending.sh || true)
|
||||||
|
if [ -n "$PENDING" ]; then
|
||||||
|
if saved=$("$PENDING" add "$log_hash" "$pending_file" 2>&1); then
|
||||||
|
pending_note="已暫存到 $saved,下次 jsc-log:worklog 寫入時一併寫進去。"
|
||||||
|
else
|
||||||
|
pending_note="暫存失敗:$saved"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pending_note='找不到 jsc-log/tools/worklog-pending.sh,這次的內容沒有暫存起來。'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pending_note='沒有給 --pending-file 與 --log-hash,這次的內容沒有暫存起來。'
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- 分支資訊(實作階段) ----
|
||||||
|
branch_rows=''
|
||||||
|
if [ "$stage" = implement ]; then
|
||||||
|
wt="${worktree:-}"
|
||||||
|
git_in() { # 在工作目錄裡跑 git
|
||||||
|
if [ -n "$wt" ]; then git -C "$wt" "$@" 2>/dev/null; else git "$@" 2>/dev/null; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
src_cell='未提供'
|
||||||
|
if [ -n "$source_branch" ]; then
|
||||||
|
if git_in show-ref --verify --quiet "refs/remotes/origin/$source_branch"; then
|
||||||
|
src_cell="origin/$source_branch(遠端)"
|
||||||
|
else
|
||||||
|
src_cell="$source_branch(**遠端找不到**,只有本機)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
work_cell='未提供'
|
||||||
|
if [ -n "$work_branch" ]; then
|
||||||
|
base="origin/$source_branch"
|
||||||
|
git_in show-ref --verify --quiet "refs/remotes/origin/$source_branch" || base="$source_branch"
|
||||||
|
count=$(git_in rev-list --count "$base..$work_branch" || true)
|
||||||
|
[ -n "$count" ] || count='?'
|
||||||
|
if git_in show-ref --verify --quiet "refs/remotes/origin/$work_branch"; then
|
||||||
|
ahead=$(git_in rev-list --count "origin/$work_branch..$work_branch" || true)
|
||||||
|
if [ "${ahead:-0}" = 0 ]; then push_cell='已 push'; else push_cell="尚有 ${ahead} 個 commit 未 push"; fi
|
||||||
|
else
|
||||||
|
push_cell='**未 push**'
|
||||||
|
fi
|
||||||
|
work_cell="$work_branch($count commit、$push_cell)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
tgt="${target_branch:-$source_branch}"
|
||||||
|
if [ -n "$pr_url" ]; then
|
||||||
|
tgt_cell="${tgt:-未提供}(PR $pr_url)"
|
||||||
|
else
|
||||||
|
tgt_cell="${tgt:-未提供}(**尚無 PR**)"
|
||||||
|
warn=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
branch_rows=$(cat <<EOF
|
||||||
|
| 工作目錄 | ${worktree:-未提供} |
|
||||||
|
| 來源分支 | $src_cell |
|
||||||
|
| 工作分支 | $work_cell |
|
||||||
|
| 目標分支 | $tgt_cell |
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- 輸出 ----
|
||||||
|
printf '## 階段回報:%s\n\n' "$(stage_zh "$stage")"
|
||||||
|
printf '| 項目 | 內容 |\n| --- | --- |\n'
|
||||||
|
printf '| 模型能力標籤 | %s |\n' "$gate_result"
|
||||||
|
printf '| 工作日誌 | %s |\n' "$worklog_cell"
|
||||||
|
[ -n "$branch_rows" ] && printf '%s\n' "$branch_rows"
|
||||||
|
printf '\n### 寫入的 wiki 頁\n\n'
|
||||||
|
if [ -n "$pages" ]; then
|
||||||
|
printf '| 頁面 | 連結 |\n| --- | --- |\n'
|
||||||
|
printf '%s' "$pages" | while IFS= read -r item; do
|
||||||
|
[ -n "$item" ] || continue
|
||||||
|
type=${item%%:*}
|
||||||
|
page=${item#*:}
|
||||||
|
url=$(page_url "$type" "$page" || true)
|
||||||
|
printf '| %s | %s |\n' "$page" "${url:-(取不到網址)}"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
printf '本階段沒有寫入任何 wiki 頁。\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$warn" -eq 1 ]; then
|
||||||
|
printf '\n### 警告\n\n'
|
||||||
|
[ -n "$worklog" ] || printf -- '- 這個階段還沒有寫入工作日誌,請自行檢查是不是漏了。%s\n' "$pending_note"
|
||||||
|
[ "$stage" = implement ] && [ -z "$pr_url" ] && printf -- '- 目標分支還沒有 PR,工作尚未交出去。\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user