實戰背景
範例 001 走的是 /opsx:propose 一步到位的自動產出流程,適合需求明確的小改動。當你想要親自逐步雕琢 proposal、design 與 tasks,不要 AI 一次幫你寫完,就要改用實驗性的 /opsx:new 漸進式工作流 (Incremental Workflow)。
本範例假設你有一支 30 行的 CLI 腳本 src/cli.js,會把命令列第一個參數當成使用者的名字並印出問候語:
// src/cli.js
export function greet(name) {
return `Hello, ${name}!`;
}
const input = process.argv[2] ?? 'world';
console.log(greet(input));
需求很單純:加上 --upper 旗標,指定時把問候語全部轉成大寫。改動雖小,但我們刻意走完整的漸進式流程,讓你親眼看到 OpenSpec 如何把一個簡單功能拆成四份規劃文件,再逐步被實作填滿。
規格定義
歸屬的 Capability 為 greeting-cli。本次的規格增量 (Spec Delta) 只動一條需求:
## ADDED Requirements
### Requirement: Uppercase output flag
The CLI SHALL accept a `--upper` flag that, when present, prints the greeting
in uppercase letters.
#### Scenario: Flag omitted
- **WHEN** user runs `node src/cli.js Alice`
- **THEN** the output SHALL be `Hello, Alice!`
#### Scenario: Flag present
- **WHEN** user runs `node src/cli.js Alice --upper`
- **THEN** the output SHALL be `HELLO, ALICE!`
兩個 Scenario 都很具體,後續 /opsx:verify 才有明確的對照標準。
端到端 5 輪漸進式協作紀錄
── 第 1 輪:用 /opsx:new 起頭 ──
- You:
/opsx:new "為 greet CLI 加上 --upper 大寫旗標" - AI:
好的,我已為您建立變更計畫
add-cli-upper-flag(使用預設spec-driven工作流)。目前的進度為:0/4 規劃檔案已完成。
依據依賴順序,第一個要撰寫的檔案是
proposal.md,範本如下:## Why <!-- 說明為什麼需要此變更 --> ## What Changes <!-- 說明要修改哪些部分 -->準備好開始撰寫了嗎?請執行
/opsx:continue,或直接告訴我這次變更的背景。
注意此時 OpenSpec 沒有 自動產出任何規格內容,只生骨架。這正是 /opsx:new 與 /opsx:propose 最大的差別。
── 第 2 輪:/opsx:continue 逐份完成規劃 ──
- You:
請幫我繼續。背景:CLI 目前只會原樣輸出問候語,我希望加上 --upper 旗標可以把輸出轉大寫。 - AI:
收到,我已透過
/opsx:continue完成下列規劃產物:- proposal.md:說明動機是讓 CLI 在 CI log 標題場景更容易辨識。
- specs/greeting-cli/spec.md:新增
Requirement: Uppercase output flag,含Flag omitted與Flag present兩個 Scenario。 - design.md:決議直接用 JavaScript 內建
String.prototype.toUpperCase(),不引入第三方函式庫。 - tasks.md:拆成 3 個任務:
- 1.1 在
src/cli.js解析process.argv中的--upper - 1.2 將
greet()結果在旗標成立時轉大寫 - 1.3 撰寫兩個 Scenario 對應的執行驗證
- 1.1 在
4/4 規劃檔案已完成,可以執行
/opsx:apply開始實作。
📌 教學精簡說明:依 /opsx:continue 的設計,每次呼叫只會產出一份檔案並隨即暫停(例如先 proposal.md,下次才 specs/.../spec.md)。為了讓範例聚焦在「漸進式流程的全貌」,本輪把四次的累積成果合併呈現;實際操作時進度會從 1/4 → 2/4 → 3/4 → 4/4 逐次推進。
── 第 3 輪:/opsx:apply 實作程式碼 ──
- You:
/opsx:apply - AI:
Implementing: add-cli-upper-flag (schema: spec-driven)
正在處理任務 1-3/3:本變更三項任務都集中在同一檔案,一併完成。
修改後的
src/cli.js:export function greet(name, { upper = false } = {}) { const message = `Hello, ${name}!`; return upper ? message.toUpperCase() : message; } const args = process.argv.slice(2); const upper = args.includes('--upper'); const name = args.find(a => !a.startsWith('--')) ?? 'world'; console.log(greet(name, { upper }));✓ 3/3 任務全數完成。
關鍵設計:把 upper 放進 greet() 的 options 物件,而不是直接讀 process.argv,這樣函式庫本身保持純粹、好測試。
── 第 4 輪:/opsx:verify 獨立驗收 ──
範例 001 把 verify 與 archive 串在一起跑,這次我們刻意把驗收單獨執行,看清報告內容。
- You:
/opsx:verify - AI:
Verification Report: add-cli-upper-flag
1. 完整性 (Completeness)
- 任務完成度:3/3 全數勾選 ✓
- 規格覆蓋度:
Uppercase output flag的兩個 Scenario 皆有對應實作 ✓
2. 正確性 (Correctness)
Flag omitted:node src/cli.js Alice印出Hello, Alice!✓Flag present:node src/cli.js Alice --upper印出HELLO, ALICE!✓
3. 一致性 (Coherence)
- 設計遵循度:採用內建
toUpperCase(),與 design.md 決議一致 ✓
結果:0 個 CRITICAL、0 個 WARNING、1 個 SUGGESTION(建議補一個針對
greet()的單元測試,非必要)。
verify 沒有發現任何阻擋問題,可以放心進入歸檔。
── 第 5 輪:/opsx:archive 結案 ──
- You:
/opsx:archive - AI:
Archive Complete
- 驗證成功:所有實作皆吻合規格。
- 智慧同步:已將暫存規格合併至
openspec/specs/greeting-cli/spec.md。 - 清理歸檔:已將計畫資料夾移動至
openspec/changes/archive/2026-08-13-add-cli-upper-flag/。
工作目錄回歸乾淨,主規格庫已記錄這個新能力。
程式碼與設計亮點
- 旗標解析不污染核心函式:
greet()只認 options 物件,process.argv的解析留在程式進入點,方便日後給greet()寫獨立單元測試。 - 預設值向後相容:未傳
--upper時行為與變更前完全一致,舊使用者不會被破壞。 - 零相依:用內建
String.prototype.toUpperCase()達成,不為了一個小功能引入 CLI 解析函式庫。
關鍵學習點
/opsx:new與/opsx:propose的核心差別在「自動產出規劃內容與否」:前者只建骨架並停下來等你,後者一口氣把 proposal/specs/design/tasks 全部寫完。- 漸進式流程適合需求想邊寫邊校的場合;當你很清楚要什麼時,直接用
/opsx:propose會更省事。 /opsx:verify與/opsx:archive刻意拆開執行,能讓你在結案前實際看到三維度報告(完整性 / 正確性 / 一致性),把關動作不再被壓縮成一行。- 規格裡的
Scenario寫得越具體(連輸入指令與預期輸出都寫出來),驗收階段能對照的證據就越明確,AI 也越難矇混過關。