@seanmars/tospec 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +17 -3
  3. package/assets/claude-mod/tospec-dashboard/.claude-plugin/plugin.json +7 -0
  4. package/assets/claude-mod/tospec-dashboard/hooks/hooks.json +1 -0
  5. package/assets/claude-mod/tospec-dashboard/hooks/register.ts +695 -0
  6. package/assets/claude-mod/tospec-dashboard/tests/register.test.ts +448 -0
  7. package/assets/claude-mod/tospec-dashboard/types/index.d.ts +8 -0
  8. package/assets/dashboard/app.js +218 -1180
  9. package/assets/dashboard/index.html +31 -22
  10. package/assets/dashboard/lib/charts.js +355 -0
  11. package/assets/dashboard/lib/derive.js +369 -0
  12. package/assets/dashboard/lib/dom.js +121 -0
  13. package/assets/dashboard/lib/routes.js +52 -0
  14. package/assets/dashboard/lib/store.js +324 -0
  15. package/assets/dashboard/style.css +3103 -664
  16. package/assets/dashboard/views/alerts.js +170 -0
  17. package/assets/dashboard/views/change.js +232 -0
  18. package/assets/dashboard/views/docs.js +214 -0
  19. package/assets/dashboard/views/home.js +357 -0
  20. package/assets/dashboard/views/project.js +168 -0
  21. package/assets/dashboard/views/session.js +270 -0
  22. package/assets/dashboard/views/sidebar.js +131 -0
  23. package/dist/cli/index.d.ts.map +1 -1
  24. package/dist/cli/index.js +74 -95
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/commands/dashboard-relay.d.ts +11 -0
  27. package/dist/commands/dashboard-relay.d.ts.map +1 -0
  28. package/dist/commands/dashboard-relay.js +88 -0
  29. package/dist/commands/dashboard-relay.js.map +1 -0
  30. package/dist/commands/dashboard.d.ts +62 -102
  31. package/dist/commands/dashboard.d.ts.map +1 -1
  32. package/dist/commands/dashboard.js +375 -609
  33. package/dist/commands/dashboard.js.map +1 -1
  34. package/dist/core/dashboard-hub.d.ts +258 -0
  35. package/dist/core/dashboard-hub.d.ts.map +1 -0
  36. package/dist/core/dashboard-hub.js +643 -0
  37. package/dist/core/dashboard-hub.js.map +1 -0
  38. package/dist/core/dashboard-routes.d.ts +56 -0
  39. package/dist/core/dashboard-routes.d.ts.map +1 -0
  40. package/dist/core/dashboard-routes.js +329 -0
  41. package/dist/core/dashboard-routes.js.map +1 -0
  42. package/dist/core/init.d.ts.map +1 -1
  43. package/dist/core/init.js +4 -1
  44. package/dist/core/init.js.map +1 -1
  45. package/dist/core/local-server.d.ts +1 -1
  46. package/dist/core/local-server.js +1 -1
  47. package/dist/core/shared/dashboard-mod.d.ts +24 -0
  48. package/dist/core/shared/dashboard-mod.d.ts.map +1 -0
  49. package/dist/core/shared/dashboard-mod.js +44 -0
  50. package/dist/core/shared/dashboard-mod.js.map +1 -0
  51. package/dist/core/shared/index.d.ts +1 -0
  52. package/dist/core/shared/index.d.ts.map +1 -1
  53. package/dist/core/shared/index.js +1 -0
  54. package/dist/core/shared/index.js.map +1 -1
  55. package/dist/core/update.d.ts.map +1 -1
  56. package/dist/core/update.js +4 -1
  57. package/dist/core/update.js.map +1 -1
  58. package/package.json +3 -2
  59. package/assets/dashboard/chart.umd.js +0 -14
package/CHANGELOG.md CHANGED
@@ -6,6 +6,45 @@
6
6
 
7
7
  tospec 是一套 spec-driven development CLI: 以 schema 定義文件結構與工作流程, 進度由檔案系統狀態推算, 開發方法則封裝於 Skill 之中, 使 AI 工具 (Claude Code / Codex) 得以循序完成需求釐清、規格撰寫、設計、任務拆解、實作到歸檔的完整流程.
8
8
 
9
+ ## [0.24.0] - 2026-10-07
10
+
11
+ 本版本的主題是**把 dashboard 從「每個專案一個 server」改成「所有專案共用一個 hub」**. 原本同時在多個專案驅動 agent 的人, 要為每個專案各開一個 server 與一個瀏覽器分頁, 而頁面只看得到檔案, 看不到 session 正在做什麼. 現在 hub 不讀任何專案檔案, 改由 Claude Code 的 `tospec-dashboard` mod 推送 snapshot 與 session 活動. 頁面重畫成跨專案的路線圖, 並可以回答 session 提出的問題. 命令介面隨之改成 `dashboard start|stop|status`.
12
+
13
+ ### 新增
14
+
15
+ - **dashboard hub 與 `tospec-dashboard` Claude Code mod**: 原本 `tospec dashboard` 在專案內啟動, 讀取該專案的檔案, 遇到被占用的連接埠就換下一個, 再登記到 registry 讓 `--stop` / `--list` 挑選. 現在只有一個 hub, 可以從任何目錄啟動, 固定綁定 5620, 本身不讀專案檔案. `tospec init` / `update` 把 mod 寫進 `.claude/skills/tospec-dashboard/`, mod 在專案內執行 `tospec dashboard snapshot` 並推送結果, 同一個專案以最新一次推送為準. mod 無法監聽連接埠, 所以 snapshot 沒有預先回答的讀取 (render 後的 markdown) 與唯一的寫入 (勾選 task) 會在 hub 依專案排隊, 等 session 以 long-poll 取走, 執行 `tospec dashboard query` 後回覆. 沒有 live session 的專案顯示最後一份 snapshot, 其餘請求回 503. hub 遇到 EADDRINUSE 不會換連接埠, 因為 mod 靠固定位址找到它 (可用 `TOSPEC_DASHBOARD_URL` 改). 沒有採用讓 hub 直接讀各專案檔案的做法: 那樣 hub 必須知道並信任每個專案的路徑, 路徑限制也要在 hub 端再做一次.
16
+ - mod 只寫入 Claude Code 的 skill 目錄. `.agents/skills/` 的讀者會看到一個沒有 `SKILL.md` 的目錄, 其他工具也不執行 function hook. 因此只使用 Codex 的專案在 dashboard 上沒有資料.
17
+ - profile 沒有選任何 workflow 時, init / update 會移除 mod, 避免它成為唯一還在載入的 tospec 檔案.
18
+ - mod 的 manifest 寫入產生它的 tospec 版本, 作用與 skill 的 `generatedBy` 相同. mod 與 hub 的 `DASHBOARD_PROTOCOL` 不符時, hub 以 409 拒絕推送; 升級 tospec 後要重跑 `tospec update`.
19
+ - mod 在 prompt footer 右側顯示 hub 狀態, 並註冊 `/tospec-dashboard [status|register|unregister]`.
20
+ - 新增 `pnpm test:mod`, 以 `claude plugin validate` / `claude plugin test` 驗證 mod. mod 在 Claude Code 內執行, 沒有 Node, vitest 無法載入它.
21
+ - **session 活動與從頁面回答問題**: mod 回報 session 狀態 (從 `turn.start` 到主迴圈的 `turn.complete` 為工作中)、正在執行的 tool, 以及 log (使用者 prompt 與 model 回覆截到 500 字元). 回報每 250ms 合併送出一次, session 未註冊時直接丟棄. hub 在記憶體中為每個 session 保留最近 200 筆事件, 並以 `activity` 事件連同 session 摘要推給頁面, 狀態改變不需要重新讀取.
22
+ - AskUserQuestion 與權限請求同時送到 dashboard 與終端機, 先回答的一方生效. dashboard 先答時, 回答直接成為 tool result, 終端機的對話框隨之關閉. 終端機先答時, dashboard 上的那份問題必須撤回, 否則頁面會提供第二次回答. 撤回有三層: hook 的 `next.signal` abort、問題所屬的 tool call 結束、session 回報 idle 時 hub 關閉它所有未答的問題. 會做三層, 是因為 `classic.PermissionRequest` 實測與權限對話框同時執行 (文件說它先執行), 這裡沒有任何 timeout, 而文件也沒有保證 `next.signal` 一定會 abort; tool call 結束則一定會發生.
23
+ - 頁面刻意沒有輸入 prompt 的路徑, 指示一律來自 session 的終端機.
24
+ - **跨專案路線圖頁面**: 原本的頁面一次只顯示一個專案, 以數字卡與圓餅圖開場, 並把 `blocked` artifact 標為警告. 但 `blocked` 只表示相依的文件還沒寫, 每個新 change 都是這個狀態, 所以唯一用來表示「卡住」的訊號一直在正常的 change 上觸發, 畫面上也沒有任何地方寫出 change 的下一步. 現在首頁把每個專案畫成一條路線, 共用 plan → apply → sync → archive 的站點格線. 每個 change 停在它的檔案決定的站點, 並標出讓它停在那裡的缺口 (可撰寫的 artifact、task 7/12、等待 sync 或 archive). 位置全部在 `assets/dashboard/lib/derive.js` 由既有 snapshot 推算, 不需要改 snapshot 的形狀. 紅色只用於 metadata 無法解析的 change, 狀態另以標記形狀表示, 不依賴顏色辨識.
25
+ - 側欄列出所有專案與各自的 session 數和狀態, 可展開到各個 change; 寬度不足 960px 時改為抽屜. 側欄會占用頁面寬度, 所以路線圖的斷點改用頁面的 container query, 而不是視窗的 media query.
26
+ - 每個 session 以一個點表示工作中 (閃動並顯示目前的 tool)、等待使用者或閒置. session 的 log 在側面板開啟; 面板只建立一次, 之後就地更新, live push 不會清掉選到一半的回答.
27
+ - session 開始等待或一個 turn 結束時顯示 toast; 使用者開啟通知後, 頁面不在前景時也會送出瀏覽器通知. 第一次載入的專案清單只用來建立基準, 開啟頁面時已在等待的 session 不會被當成新事件通知.
28
+ - 專案頁新增四張 SVG 圖表 (change 停留時間、每週 archive 數、ADR 時間軸、spec 大小), 樣式取自主題變數, 套件不再附帶 Chart.js.
29
+ - 頁面先以 overview 畫出路線圖, 其餘資料陸續補上. task 寫入後 hub 會清空該專案的快取直到下一次推送, 每個讀取都變成一次轉送的 CLI 執行, 等全部完成才畫圖會讓頁面停住數秒.
30
+ - 事件串流在 `pagehide` 時關閉. 停在 back/forward cache 的頁面會占住瀏覽器對同一 host 的 6 條連線之一, 累積多個之後新頁面的讀取就取不到連線.
31
+ - 介面文字為台灣正體中文, 狀態使用 tospec 的詞彙 (進行中、待處理、閒置、無法解析、離線), 階段沿用 CLI 的名稱.
32
+
33
+ ### 安全
34
+
35
+ - **dashboard 的信任邊界留在專案端**: 路徑限制、拒絕已歸檔或已通過 sync 的 change、只認 schema 追蹤的 task 檔, 這些檢查全部在 `src/core/dashboard-routes.ts`, 由專案端的 `tospec dashboard query` 執行. hub 只負責轉送, 所以無法放寬一個請求能碰到的範圍.
36
+ - **hub 的所有 POST 都要求 `application/json`**: snapshot 推送、poll、task 寫入與回答共用這道 CSRF 防護. 跨站表單無法送出這個 content type, 跨站 `fetch` 帶上它則必須先通過 CORS preflight.
37
+ - **只有綁定 loopback 的 hub 能回答問題**: 回答問題會讓 session 執行 tool, 所以 `DashboardHub.interactive` 只在綁定 loopback 時為 true. 使用 `--allow-remote` 時頁面是唯讀的.
38
+
39
+ ### 變更
40
+
41
+ - **`tospec dashboard --detach` / `--stop` / `--list` 改為 `dashboard start` / `stop` / `status` (breaking change)**: hub 已經服務所有專案, 命令卻還是每個專案一個 server 時的形狀: `tospec dashboard` 在前景執行, 最常用的「在背景啟動」反而要多加旗標. 現在 `start` 在背景啟動 hub (子程序是隱藏的 `dashboard serve`), `stop` 停止它, `status` 回報 hub 是否在執行、服務幾個 session、屬於哪些專案. `status` 透過 `/api/projects` 詢問 hub, 而不是只讀 registry: session 只存在 hub 的記憶體中, pid 存活也不代表它在服務誰 (pid 可能已被重用), 所以 hub 沒有回應時回報錯誤, 而不是「執行中」. `dashboard [path]` 的 path 參數一併移除, hub 不屬於任何專案. `snapshot` 與 `query` 由 mod 執行, 設為隱藏命令.
42
+
43
+ ### 其他
44
+
45
+ - **文件**: README 與 skills guide 改寫 dashboard 的段落: `start|stop|status` 命令、session 面板、從頁面回答問題 (以及不能送出 prompt)、loopback 限制、toast 與瀏覽器通知. 新增 `PRODUCT.md` 記錄網頁介面的服務對象與限制 (嚴格 CSP、完全離線、不需 build、經過色覺辨識驗證的圖表配色、台灣正體中文介面), `DESIGN.md` 與 `.impeccable/design.json` 記錄路線圖的設計系統.
46
+ - **CSP 註解**: `commands/dashboard.ts` 不再把 `'unsafe-inline'` 歸給已移除的 Chart.js. 是否拿掉 `'unsafe-inline'` 留待另一個決策.
47
+
9
48
  ## [0.23.0] - 2026-09-30
10
49
 
11
50
  本版本修正 code review 找到的**文件與 prompt 跟實際行為不一致**的地方: schema 交給 apply 的指示和預設 apply skill 對測試的要求互相矛盾, README 與 `docs/custom-schema.md` 列出的 artifact 狀態和原始碼不符, decision schema 註解寫的 ADR 檔名格式也和 CLI 實際寫出的不同.
@@ -484,6 +523,7 @@ Dashboard 進化為可背景常駐、多專案並存的服務, 並補上 TDD 導
484
523
 
485
524
  - 新增 `prepack` script 與 npm publish 的準備設定, 完備套件發行流程.
486
525
 
526
+ [0.24.0]: https://github.com/seanmars/tospec/compare/v0.23.0...v0.24.0
487
527
  [0.23.0]: https://github.com/seanmars/tospec/compare/v0.22.0...v0.23.0
488
528
  [0.22.0]: https://github.com/seanmars/tospec/compare/v0.21.0...v0.22.0
489
529
  [0.21.0]: https://github.com/seanmars/tospec/compare/v0.20.0...v0.21.0
package/README.md CHANGED
@@ -133,12 +133,26 @@ requirement 內文慣例上要有 SHALL 或 MUST, 缺了是 WARNING; `--strict`
133
133
  ### Dashboard
134
134
 
135
135
  ```bash
136
- tospec dashboard [path]
136
+ tospec dashboard start # 在背景啟動 hub
137
+ tospec dashboard status # 是否在執行, session 數量, 各 session 所屬的 project
138
+ tospec dashboard stop # 停止 hub
137
139
  ```
138
140
 
139
- 本機 web dashboard, 看 change 與 specs 進度. 唯一的寫入是勾 task checkbox, 已歸檔或 sync 通過的 change 不能勾.
141
+ 本機 web dashboard hub, 一個 service 服務所有 project, 在任何目錄都能啟動. Hub 不讀專案檔案:
140
142
 
141
- 選項: `-p, --port <n>` (預設 5620), `--host <addr>` (預設 127.0.0.1), `-o, --open`, `-d, --detach`, `--stop`, `-l, --list`, `--allow-remote` (綁非 loopback 位址, 會對外網開放).
143
+ 1. `tospec init` / `tospec update` 把 Claude Code mod 寫到 `.claude/skills/tospec-dashboard/`.
144
+ 2. Session 啟動後, mod 自動向 hub 註冊, 並推送 project 快照. 同一個 project 的多個 session 都可以註冊, 以最後推送的快照為準. Dashboard 的 Sessions 區塊會列出目前連線的 session 數量和 session id, 並標出提供目前快照的 session.
145
+ 3. Mod 在編輯 `tospec/` 檔案後和每個 turn 結束時推送新快照. Hub 沒有啟動時, mod 會靜默略過並定期重試.
146
+ 4. Claude Code 只在你對**這個專案資料夾本身**接受信任對話框之後, 才會載入 `.claude/skills/` 下的 plugin. 只信任上層資料夾不夠. 如果上層資料夾已被信任, 對話框不會出現, mod 也不會載入. 這時 `claude plugin list` 會顯示 "skipped because this workspace was not trusted".
147
+ 5. Claude Code 介面右下角顯示 hub 狀態 (`tospec hub: connected` / `offline` / `unregistered` / `error`). 用 `/tospec-dashboard register`, `/tospec-dashboard unregister` 手動註冊或取消註冊, 不帶參數則顯示目前狀態.
148
+ 6. Mod 也回報每個 session 的狀態 (工作中 / 等你回覆 / 閒置) 與即時 log (prompt, Claude 的回覆, tool 呼叫). 點 session 會在右側開啟面板, 可以看 log, 回答 `AskUserQuestion`, 以及允許或拒絕權限請求. Dashboard 只能回答 session 提出的問題, 不能送出其他輸入; 指示一律在 terminal 輸入.
149
+ 7. Session 開始等你回覆, 或一個回合結束而閒置時, 頁面右下角會跳出 Toast; 點一下就開啟該 project 與這個 session 的面板. 在上方工具列開啟「通知」後, 頁面不在前景時也會跳出瀏覽器通知.
150
+
151
+ 勾 task checkbox 由 hub 轉給該 project 的 session 執行, 已歸檔或 sync 通過的 change 不能勾. 沒有 session 的 project 只能瀏覽最後一次快照.
152
+
153
+ 從 dashboard 回答問題或允許權限, 等於讓 session 執行 tool, 所以只有 hub 綁在 loopback 時才開放; 加上 `--allow-remote` 時 dashboard 只能檢視. 權限請求與 `AskUserQuestion` 會同時出現在 terminal 與 dashboard, 先回答的一方有效; 在 terminal 回答後, dashboard 會自動撤回這個問題, 不會重複回應.
154
+
155
+ `start` 的選項: `-p, --port <n>` (預設 5620; mod 預設連 `http://127.0.0.1:5620`, 可用環境變數 `TOSPEC_DASHBOARD_URL` 改變), `--host <addr>` (預設 127.0.0.1), `-o, --open`, `--allow-remote` (綁非 loopback 位址, 會對外網開放).
142
156
 
143
157
  ## 文件
144
158
 
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "tospec-dashboard",
3
+ "version": "0.0.0",
4
+ "author": { "name": "tospec" },
5
+ "types": "./types/index.d.ts",
6
+ "description": "Registers this tospec project with the tospec dashboard hub (tospec dashboard) and keeps its snapshot current."
7
+ }
@@ -0,0 +1 @@
1
+ { "modules": ["./register.ts"] }