Spectra 2.0
credit: Nano Banana

Spectra 2.0

約 7,021 字

不久之前,我為了讓 OpenSpec 用來起更順手,我做了一款名為 Spectra 的 GUI 工具,詳情可參閱「Spectra:給 OpenSpec 的圖形介面」。同時如果你還不太熟悉什麼是 SDD 以及這東西有什麼好處,也可以先看看我之前另一篇文章「SDD 規格驅動開發」的介紹。

在好幾個 SDD 框架裡,OpenSpec 的簡單設計最合我的胃口,不過用一陣子之後,我發現它的流程跟我自己的開發習慣不太一樣,有些指令也顯得有點囉嗦。原本想就是 fork 之後來改一下 Skills/Commands 的內容,但發現光改 Skills 這些文件可能不太足以能夠完全發揮 SDD 的價值,最後還是得改整個流程才行。再加上我想做一些除了原本 OpenSpec 以外的功能(看完本文你就會知道我在說什麼),所以我就開始動手把整個 OpenSpec 的 binary 重新寫過,Skills 跟 Commands 的 template 也是,簡單的說,就是基於 OpenSpec 原本的設計,但整個重寫一次。感謝 AI,讓我在短時間內就能搞定這樣的改寫工作。

自己的工具自己做

第一個改的就是 CLI。之前要使用 OpenSpec 得先安裝 Node.js,再按照說明安裝官方的 CLI 工具。對工程師來說這可能不算什麼,但對終端機介面、要敲打指令的人來說,這就是一道門檻。

其實我從 Spectra 1.x 版就有默默在做這件事,但發現這樣下去會跟 OpenSpec 的 binary 混在一起,使用者可能會不知道自己到底在用的是什麼。所以從 2.0 開始我把原本做半套的 CLI 整個包進來了。什麼意思?就是以後只要安裝 Spectra 這個 app 就行了,其它像是 Node.js 或 npm 什麼指令的都不需要,連 Git 也不需要,我把有用到的東西都包進 Spectra 了,安裝 Spectra 就會在你的 Agent 裡看到相對應的 Skills 跟 Command。

當然如果你還是想要使用終端機指令,我也留了 spectra 這個終端機指令,例如在專案目錄下輸入 spectra . 就會用 Spectra app 來開啟專案。不想碰終端機的人就用 GUI,覺得終端機指令比較快就用 CLI,我兩邊都有做,兩邊都會通。

雖然整個改寫,資料格式還是相容 OpenSpec 的。如果之前是用 OpenSpec 建立的 openspec/ 目錄都還是可以用,就算之後不用 Spectra 的功能,也能單純把它當成 OpenSpec 的 GUI 版 Viewer 來用。

建立規格的時候幫你多看一眼

以前用 OpenSpec 建立新提案,它只管把 proposal、spec、design、tasks 這些檔案生出來。至於專案裡已經有哪些既有規格?新寫的東西跟舊的規格有沒有打架好像沒特別處理。

Spectra 2.0 在建立規格的時候會先花一點時間掃描專案裡相關的既有規格,把這些資訊當參考丟給 AI,同時分析檢查 proposal、spec、design、task 之間有沒有矛盾或遺漏。例如在 proposal 裡說要改某個功能,但 spec 裡面沒有對應的場景描述,AI 會把這個缺口指出來,能修的就修,修不了的提醒你,這是 OpenSpec 沒有的功能。

規格越寫越多之後,人腦真的很難記住每一份 Spec 寫了什麼,讓工具幫忙掃描與比對,不只比較輕鬆,也更可靠。

指令的改變

OpenSpec 1.0 多了幾個新指令,例如 /opsx:new/opsx:ff/opsx:continue,各有它的用途,不過對我來說不太需要分這麼細,所以我在 Spectra 2.0 版做了幾件事:

首先,我把所有指令統一改成 /spectra 開頭,例如 /spectra:new 或是 /spectra:ff,Skills 的名字也是相對應的改成 /spectra-new/spectra-ff,讓名稱跟工具一致,不只比較好記之外,也不會讓它跟原本的 OpenSpec 的指令 /opsx:* 搞混。

我可以理解為什麼 OpenSpec 在 1.0 版的時候把流程拆解成 /opsx:ff/opsx:continue,不過我用一陣子就發現我沒那個耐心用 /opsx:continue 一步一步往下執行,用到最後幾乎都只有用 /opsx:ff 而已。所以我後來就乾脆把 /spectra:new/spectra:ff/spectra:continue 都拿掉,功能統一由 /spectra:propose/spectra:ingest 涵蓋。

/spectra:propose 負責建立所需要的檔案,一個指令就能把 proposal、spec、design、tasks 等相關全部建好。而 /spectra:ingest 負責恢復進行中的工作上下文,而且如果你是使用 Claude Code 的 Plan Mode 的話,這兩個指令除了能從對話的上、下文整理出 Spec 外,也能直接從 Plan 檔案把東西拿來用,這也是我取名為 ingest 的原因,它可以進行攝取或吸收的操作。

所以,整個 Spectra 用起來流程大概會像這樣:

  1. 先跟 AI 討論需求,這時候還沒有真的動工,所以不用使用任何 /spectra:* 的指令,這個階段只要討論、閒聊就好。
  2. 經過幾輪跟 AI 的討論之後,需求差不多定義清楚了,這時候就可以使用 /spectra:propose 指令來建立規格文件。使用的方法也很簡單,就直接跟 AI 說 /spectra:propose 就好,不用特別加什麼參數,AI 會根據剛剛的討論的上下文來建立規格。如果你是使用 Claude Code 的 Plan mode,也可以選擇讀取 Plan 檔案,AI 會根據 Plan 裡面的內容來建立規格。
  3. 規格建立之後,巡一下看看有沒有問題,沒問題就是執行 /spectra:apply,開工!
  4. 在做的過程或是做完之後,很有可能會發現當時討論缺了一些東西或是方向不太對,沒關係,我們就再接著繼續跟 AI 討論需求,跟 AI 說不用急著改,等討論到差不多了之後可以執行 /spectra:ingest 指令,AI 會先根據新的討論內容來更新規格文件,或是 AI 也可能認為這應該另開新規格,就會問要不要開新的規格文件,不管是更新或新開規格,完成之後繼續執行 /spectra:apply。如果還有問題,就繼續這個循環。
  5. 如果任務都完成了,驗收成果也都沒問題,就可以執行 /spectra:archive 把這個專案的規格文件進行歸檔。這一些我會建議使用 Spectra 圖形介面來操作,不只比較簡單、清楚,而且還能趁這個時候檢視一下這個專案裡的規格文件,看看有沒有什麼需要修正或補充的地方,確定都沒問題就歸檔吧!

基本上以上這些指令就涵蓋了我日常八成以上的操作。

話說回來,上面步驟 1 跟步驟 4 都提到「跟 AI 討論」,但如果就這麼直接聊,聊著聊著很容易發散。所以我把原本 OpenSpec 裡的 /opsx:explore 改成了 /spectra:discuss,這不只是換個名字而已,行為邏輯也有改寫。/spectra:discuss 是一個有目的地的對話,我們可以丟一個主題給它,像是「搜尋太慢了怎麼辦」或「這邊該用 SQLite 還是 PostgreSQL」,它會去讀相關的程式碼,提出兩三個方案的評估,一次問我們一個問題,最後會收斂到一個結論。不管是設計決定、方向共識、還是「我們還需要更多資料才能決定」都行,但不會讓你聊完什麼都沒留下。如果討論到最後決定要動手做,它會建議你接著用 /spectra:propose 把剛剛的結論變成規格,然後進入上述的循環。

另外,在開發方面我有加了兩個新的指令,分別是 /spectra:tdd/spectra:debug

/spectra:tdd 就是 TDD(Test-Driven Development)的流程指引,先寫失敗的測試、再寫剛好讓測試通過的程式碼、最後重構,就是標準的 Red-Green-Refactor。這個功能可以在設定頁打開,如果有打開,/spectra:apply 在執行任務的時候就會自動套用 TDD 流程,不用每次都自己手動提醒 AI「喂,記得先寫測試」。

/spectra:debug 則是系統化的除錯流程:重現問題、隔離範圍、找到根因、修復。我設定了三次嘗試的上限,如果同一個方向試了三次還是修不好,就得停下來換個角度想,不要硬幹。修好之後它會引導你用 /spectra:tdd 寫一個回歸測試,確保這個 bug 不會再回來。

這兩個指令我是從 Superpowers 這套 Skills 參考來的,細節可參閱「給 AI 超能力?Superpowers 的設計與取捨」文章說明

介面改善

除了底層架構的翻修,還有一些我自己日常使用上比較順手的調整。

首先要介紹的就是「精簡模式(Compact Mode)」,在 Spectra 按 ⌘D 可以在完整視窗跟迷你視窗之間切換。迷你視窗是一個小浮動面板,適合寫程式的時候擺在螢幕角落監看進度。我自己的用法是開發時把 Spectra 切到精簡模式放在右下角,AI 每完成一個任務、打一個勾,餘光就能看到進度在動,不用一直切視窗。精簡模式下也可以直接切換專案、查看待辦事項,小小一個面板但該有的都有。

Markdown 預覽在網友的敲碗下也支援 Mermaid 圖表渲染,如果文件裡有用 Mermaid 語法畫的流程圖或架構圖,會自動轉成 SVG,這應該比看一堆文字描述直覺很多。側邊欄也支援收合跟展開(⌘\),視窗寬度不夠的時候會自動收合,小螢幕上比較沒那麼擠。

然後,有次跟朋友聊天講到是不是可以有「團隊共享」的功能,讓同一個專案裡的成員都能看到同一份規格文件,甚至可以在裡面留言討論。我覺得這好像不太對,因為規格文件原本就是專案裡的「共用資源」,相關的檔案都應該會進版本控制,不需要特別共享。不過如果還沒進版控之前,或是我只想給某個朋友看一下規格,這時候好像就需要一個簡單的分享功能了。所以我在 Spectra 裡加了一個「分享」功能,在規格上按右鍵選擇「分享」就能產生一組代碼,收到代碼的人就能在 24 小時內取得這份 Spec 的相關檔案。

其它改動:

  • 所有 Skills 跟 Commands 全面從 OpenSpec 改成 Spectra,設定檔用獨立的 SPECTRA:START/END 標記跟上游的 OpenSpec 區塊分開,兩邊各自演進互不干擾。
  • 產出的文件可以選中文、日文或英文版本,團隊裡有不同國家的成員不用再手動翻譯。
  • 設定頁新增了 Claude Code 專區,可以切換是否產出 Slash Commands,避免跟 Claude Code 內建的指令重複
  • Git Worktree 功能移到進階工程區,預設不顯示,想用的人去設定頁打開就好。

最後有個實驗功能,任務可以標記為「平行處理」,如果 AI Agent 支援的話就能同時跑多個任務,不用一個做完再做下一個。目前還在實驗中,有興趣可以在設定頁開啟。

暫存與 Worktree 功能

再回來說說這個暫存跟 Worktree 功能。用 SDD 一陣子之後,手邊同時有好幾個規格是很正常的事。有的做到一半被插件更急的事,有的是等別人回覆才能繼續,結果列表越來越長,活著的跟暫停的全部混在一起。還沒執行的加入版控裡有點怪,但放著工作區域又有點亂,要搬去別的目錄放還得要記得搬回來,對我這個有 Git 版控潔癖的人來說就覺得有點煩。

所以我加了一個「暫存(Park)」的設計。概念很簡單,就是把暫時不想處理的先收起來。在 Spectra 裡面點一下就能暫存,收起來的檔案們會先搬去某個地方放著,所以也不會污染 Git 的工作區,等有空了再把它叫回來繼續做。如果喜歡用終端機,spectra park my-hello-changespectra unpark my-hello-change 也能搞定,spectra list --parked 可以看目前有哪些被收起來的規格。

暫存不是刪除,只是從 openspec/changes/ 搬到 .git/spectra-app/changes/ 裡面藏起來而已。如果你執行 /spectra:apply 的時候不小心選到一個被暫存的項目,Spectra 會很貼心的跳出提醒「這目前是暫存狀態喔,要先還原嗎?」,不會讓你在搞不清楚狀況的情況下就開始動工。

另一個比較進階的功能是 Git Worktree 整合。如果你同時在做好幾個功能,而且這些功能有可能會改到同一個專案裡的檔案,在同一個工作目錄底下切來切去其實蠻容易搞混的。Worktree 的做法是幫每個 change 開一個獨立的工作目錄,branch 會自動建成 spx/<change-name>,目錄則放在專案旁邊的 {project-name}-worktrees/<change-name>/ 裡面。每個 change 都有自己的沙盒,互不干擾。

開了 worktree 之後,Spectra 的 CLI 指令像 statuslistarchive 都會自動偵測規格是在主目錄還是在 Worktree 目錄裡。如果你用 Claude Code 之類的 AI Agent 來 /spectra:apply,agent 也會先自動執行 cd 指令切到正確的 Worktree 目錄再開始做事。

不過因為 Worktree 對大部分人來說可能用不太到,所以我把它放在設定頁的「進階工程區」裡面,預設是關的,有需要的人自己去打開就好。

問答功能

另一個新指令 /spectra:ask 可以讓我們用自然語言對專案的規格文件進行「詢問」。我認為 Spec 並不只是給 AI 看的,也是給人看的,可能是三個月後的自己或是下一個接手的人。這些規格文件不應該只是堆在那裡,而是應該可以被詢問的「活文件」,例如我想知道「這個功能是什麼用途?什麼時候加進來的?」,不用自己翻所有的 Spec,直接透過 /spectra:ask 問 AI 就好。背後我做了一個輕量的向量比對、搜尋的功能,也就是大家常在講的 RAG(Retrieval-Augmented Generation)的概念。當文件在歸檔的時候都轉成向量並存在專案裡,不需要額外安裝向量資料庫,中文、英文、日文都能搜尋。不過這個功能目前只有支援 Apple M 系列以及 Windows 平台,尚不支援 Apple Intel 平台(所以這也是為什麼 Intel 版的安裝檔比較小的原因)。

實驗性功能:平行任務

用 SDD 建出來的 tasks.md 裡面,任務預設是一條一條照順序執行的。有時候你看那個任務列表就知道這些任務根本不相干,像是「改前端的表單驗證」跟「加後端的 API endpoint」,這兩個同時做也不會打架,何必等一個做完才做下一個?

這個想法其實是從另一套 SDD 工具 Speckit 參考來的,而且現在 Claude Code 可以同時開多個 Subagent 平行做事,我想也許可以試著把一些任務標記成「可平行處理」然後交給 AI 大軍處理就好。不過因為並不是所有的 AI Agent 都有這功能,所以我把這個功能放在設定頁的「實驗功能」區,有需要的可自己打開試試看。打開之後 /spectra:propose/spectra:ingest 在產出任務的時候會自動判斷哪些任務可以同時進行,符合條件的會在前面加上 [P] 標記,看起來大概像這樣:

- [ ] [P] 建立使用者 API endpoint
- [ ] [P] 實作前端表單元件
- [ ] 串接前後端並撰寫整合測試

前兩個任務改的檔案不同、彼此也沒有依賴關係,所以被標成 [P]。第三個需要等前兩個都完成才能做,就維持一般的循序執行。判斷標準也不複雜,如果改的是不同的檔案,而且沒有依賴其他未完成的任務,就可以加上 [P] 標記。在 Spectra 的介面上,標了 [P] 的任務旁邊會多一個小圖示,一眼就看得出哪些是可以平行跑的。

執行的時候,如果你用的 AI Agent 有支援平行處理(像 Claude Code 可以派 subagent 同時做事),/spectra:apply 就會把連續的 [P] 任務打包丟出去同時執行。如果你的 Agent 不支援也沒關係,[P] 標記會被忽略,任務照舊一個一個來,不影響結果。至於是不是有標記的了 [P] 就會平行處理,這還是得看 AI 自己的心情。

這功能目前還在實驗階段,預設是關的。有興趣的話可以去設定頁打開試試看,反正最糟就是跟以前一樣循序執行而已。

檔案下載: https://github.com/kaochenlong/spectra-app/releases/tag/v2.1.0

有任何問題,歡迎在 GitHub 上提出 issue 或是在這裡留言都行 :)

Happy Vibing!

合作夥伴

留言討論