feat(overview-artifact): 產生可預覽總覽與截圖 fallback

This commit is contained in:
2026-09-18 15:59:34 +08:00
parent c545f11ec1
commit 867a23497f
16 changed files with 605 additions and 324 deletions
+46 -31
View File
@@ -216,32 +216,28 @@ node scripts/project-add.js --repo <owner/name> --index <編號> --project "<看
### 12. 產生分析版的圖解總覽 〔可委派〕
用同一份 `templates/overview-artifact.html` 再產一份,但這一份要多出**工作包全景**:
把工作包之間的相依與截止日畫成一張圖,讓開發者看得出自己這一項在整體中的位置。
全景圖用 `graph TD`,填進 `{{工作包全景}}`,連同段落標題一起:
排程完成後重新抽取需求與全部工作包,組成 `schemaVersion: 1` 的需求級 JSON。
工作包依賴與截止日必須來自重新抽取的實際資料,不使用模型記憶中的暫定值。
執行:
```
<section><h2>工作包全景</h2>
<figure><div class="mermaid">graph TD
A[建立共用函式庫<br/>09-25] --> B[建立抽取契約<br/>09-27]
</div></figure></section>
node scripts/overview-render.js --input <json> --output <html> --manifest <manifest>
```
節點寫工作包標題與截止日,箭頭方向是「先決 → 後續」。節點一樣以 12 個為上限,
超過就只畫相依鏈最長路徑上的那幾顆,其餘在頁尾列成文字。
委派的是**產出那份 HTML**;拿到網址之後寫回議題那一步**不委派**(判準第四條)。
網址一樣寫回需求議題:
HTML 內重新產生 SVG 與 HTML/CSS 視圖;不能直接搬用議題 Mermaid。預覽優先使用平台
能力,否則啟動短命 Node server 供瀏覽器截圖。產生 full-page 與局部圖 PNG 後執行:
```
node scripts/issue-update.js --repo <owner/name> --index <需求議題編號> --overview-url <網址>
node scripts/issue-assets.js --repo <owner/name> --index <需求議題編號> --manifest <manifest>
```
**重跑會就地更新同一行**,不會在議題上留下兩個連結。規劃階段產生的那一份會被這一份取代,
這是預期行為——同一顆需求議題只掛一個總覽網址。
截圖全部上傳成附件,需求議題正文只保留附件索引。只有真正可用的 preview URL 才使用
既有 `--overview-url`;不可把 `.tmp/` 或 `0.0.0.0` 寫回 Gitea。
產出 HTML 可委派;預覽截圖、附件上傳與任何 `issue-assets`/`issue-update` 寫回都不委派,
由主流程執行並處理錯誤。
若平台 preview 不可用,執行 `node scripts/overview-capture.js --backend auto`;
它依序嘗試 Firefox,再嘗試 `rsvg-convert`/`resvg`。所有 backend 都不可用時必須
停止並保留 `.tmp/` 的 HTML/SVG,不得宣稱截圖完成。
### 13. 停錶並回報
回報之前先停錶,這一段計時到此為止:
@@ -267,19 +263,9 @@ Gitea 1.27 的 API 沒有任何請求定義接受 `time_estimate`,該欄位只
## 架構圖的限制
依工作包的性質選圖:
- **`sequenceDiagram`** — 重點在「誰呼叫誰、順序為何」時用。
- **`flowchart`** — 重點在「條件分支與資料流向」時用。
- **`stateDiagram-v2`** — 重點在「狀態怎麼轉移」時用。
節點數上限 **12**,每個節點的文字上限 **8 字**。超過就拆成多張圖,或者乾脆不畫。
模板的 `{{架構圖}}` 要填入**完整的內容**,兩種形式擇一:
- 要畫:一個或多個完整的 ```mermaid 圍欄區塊。
- 不畫:**只在超過上限拆不開、或畫了不會比文字更清楚時**才選這個,填一行說明為什麼不畫,**不要加圍欄**。
圖表以抽象 `kind`、`direction`、`nodes`、`edges` 保存。renderer 產生議題 Mermaid
與 HTML SVG;不能讓模型直接維護兩套圖表語法。節點超過 12、文字超過 8 字或無法
安全轉換時,拆圖或記錄 `omitted` 原因。
## 邊界
- **共識摘要之前不對 Gitea 寫入任何內容**:不建議題、不改描述、不貼標籤、不留留言。
@@ -292,3 +278,32 @@ Gitea 1.27 的 API 沒有任何請求定義接受 `time_estimate`,該欄位只
- 計時只動這顆需求議題:在它上面起錶、在它上面停錶。**不停別顆議題上的錶**,
被別顆的錶擋下時交還給使用者決定,不繞過去。
- 不關閉或刪除任何既有議題。
# Artifact 交接與視圖
完成第三段排程後,依 `references/artifact-contract.md` 重新抽取需求與全部工作包,
組成一份 `schemaVersion: 1` 的 JSON 暫存檔。這份 JSON 是 HTML renderer 的輸入,
不是 Gitea 的第二份正本。
先執行:
```
node scripts/overview-render.js --input <json> --output <html> --manifest <manifest>
```
renderer 驗證失敗時,不截圖、不上傳、不更新議題,保留 `.tmp/` 的輸入與錯誤供修正。
HTML 必須自包含,不依賴 CDN;圖表由抽象節點/邊資料重新產生 SVG,不能直接搬用議題
Mermaid。公式是可選欄位,單一公式無法渲染時保留原文並標示未渲染。
預覽優先使用執行環境提供的預覽能力。沒有預覽能力時,使用 `0.0.0.0` 綁定的
ephemeral Node 靜態伺服器,只為瀏覽器截圖,完成後一定停止。產生 full-page 與所有
局部圖 PNG,為每張圖填入 manifest 的角色、固定檔名與 SHA-256。
截圖全部是需求議題附件,不嵌入圖片;執行:
```
node scripts/issue-assets.js --repo <owner/name> --index <需求議題編號> --manifest <manifest>
```
這支腳本負責 hash 重用、附件上傳與「圖解版總覽附件」索引的冪等更新。上傳或索引
更新失敗就是流程失敗。只有預覽平台提供真正可用的 URL 時,才另外使用既有的
`--overview-url`;不可把 `.tmp/` 或 `0.0.0.0` 寫回 Gitea。
+9
View File
@@ -364,3 +364,12 @@ node scripts/worktree-remove.js --repo <owner/name> --branch <分支名>
- 不替使用者決定來源分支。
- **不寫任何本機狀態檔。** 進度完全由 Gitea 上的 assignee、標籤、碼錶與 git 本身推導,
換一台機器或換一個 agent 都要能直接接手。
## 交接規格閘門
讀取工作包後,若它有介面契約,先完成第一個規格待辦:填妥介面、產出者、
消費者、形狀四欄,並附上該 `interfaceType` 的範例資料。四欄表格與範例資料
是同一待辦下的兩個驗收;兩者完成前不得進入後續程式實作。
資料、架構、排程工作包依其 `type` 先完成對應規格待辦;純內部小型實作可直接
進入下一個待辦。規格仍寫回工作包議題既有段落,不另建本機正本。
+19 -39
View File
@@ -134,32 +134,15 @@ node scripts/timer.js --repo <owner/name> --index <編號> --dry-run
### 8. 產生圖解版總覽 〔可委派〕
套用 `templates/overview-artifact.html`,把議題的總覽、目標與流程圖填成一份可以直接投影的
網頁。這一份是給**非技術的利害關係人**看的:他們不必讀完技術細節就知道這件事在做什麼。
依 `references/artifact-contract.md` 從需求議題抽取結果組成 `schemaVersion: 1` JSON,
執行 `node scripts/overview-render.js` 產生自包含 HTML 與 manifest。HTML 只給使用者檢視,
不取代需求議題的詳細內容。若平台有 preview 能力就使用它;否則以短命 Node server
服務 `.tmp/` 檔案供瀏覽器截圖。只有真正可用的 preview URL 才執行既有
`node scripts/issue-update.js --overview-url <網址>`。
產出 HTML 可委派;預覽截圖、附件上傳與任何 `issue-update` 寫回都不委派,由主流程
執行並處理錯誤。
模板的佔位對應如下,樣式不要動——版面與內容分開,改一邊不必碰另一邊:
- `{{標題}}` 需求議題標題
- `{{來源議題}}` 指回議題的連結
- `{{總覽}}` 一句話總覽
- `{{目標}}` 目標,逐條包成 `<li>`
- `{{流程圖}}` 流程圖的 Mermaid 原始碼(**不含**圍欄,圍欄是議題 markdown 用的)
- `{{工作包全景}}` 規劃階段還沒有工作包,**填空字串**;這一段由分析階段補上
- `{{頁尾}}` 產生時間與產生者
若執行環境能把 HTML 發佈成可分享的網址,就發佈;不能的話存成檔案,把路徑當成網址用。
委派的是**產出那份 HTML**;拿到網址之後寫回議題那一步**不委派**(判準第四條)。
拿到網址後寫回議題:
```
node scripts/issue-update.js --repo <owner/name> --index <編號> --overview-url <網址>
```
它把連結以固定前綴寫成總覽段落裡的一行,**重跑時就地更新同一行**,不會長出第二個連結;
議題原本的 markdown 白話總覽一字不動——網頁是補充,不是取代。連結旁會自動附上
「此連結預設為私有,組織外無法開啟」,因為讀到的人多半會想轉寄給組織外的人。
規劃階段沒有工作包,因此 `workPackages` 為空陣列,不產生工作包依賴圖。
### 9. 停錶並回報
@@ -173,22 +156,11 @@ node scripts/timer.js --repo <owner/name> --index <編號> --stop
說明),回報照樣做完。
把議題編號與網址告訴使用者。不要把整份議題內容再貼一次 —— 連結點進去就看得到。
## 流程圖的限制
用 Mermaid 的 `flowchart`。節點數上限 **12**,每個節點的文字上限 **8 字**。
超過就拆成多張圖,或者乾脆不畫 —— 一張塞了二十個節點的圖,比沒有圖更難懂。
節點文字寫該步驟在做什麼,不要寫成編號或代號。
模板的 `{{流程圖}}` 要填入**完整的內容**,兩種形式擇一:
- 要畫:一個或多個完整的 ```mermaid 圍欄區塊。
- 不畫:**只在超過上限拆不開、或畫了不會比文字更清楚時**才選這個,填一行說明為什麼不畫(例如「流程為單一直線,畫圖無助理解」),**不要加圍欄**。
圍欄寫在填入的內容裡而不是模板裡,否則不畫圖時會留下一個空的 mermaid 區塊,
在議題頁上是一塊渲染失敗的紅字。
流程圖的抽象節點與邊保存於 JSON,由 renderer 重新產生 SVG;議題若需要保存圖表,
由同一個 renderer 產生 Mermaid。節點數超過 12 或文字超過 8 字時拆圖或記錄
`omitted` 原因,不由模型任意壓縮語意。
## 邊界
@@ -198,3 +170,11 @@ node scripts/timer.js --repo <owner/name> --index <編號> --stop
- 規劃階段本身已含問題釐清,因此寫入 Gitea 前不再設額外的確認點;`--dry-run` 就是那道關卡。
- 計時只動這顆需求議題:在它上面起錶、在它上面停錶、把規劃時間補登在它上面。
**不停別顆議題上的錶**,被別顆的錶擋下時交還給使用者決定,不繞過去。
## Artifact 產物規則
圖解總覽不再套用 HTML 模板或依賴 Mermaid CDN。若此階段需要產生預覽,
先依 `references/artifact-contract.md` 組成需求級 JSON,再執行
`node scripts/overview-render.js`。HTML、SVG 與 manifest 只寫入 `.tmp/`;
只有真正可用的 preview URL 才能使用既有 `--overview-url` 回寫。規劃階段沒有
工作包時,`workPackages` 必須是空陣列,工作包全景不產生。