Theme / v1.12.0

OpenSpec

規格驅動開發

實戰範例

實戰範例 011:以 opsx:new 漸進式新增 CLI --upper 旗標

第一次使用 /opsx:new 與 /opsx:continue 漸進式工作流,為 Node.js CLI 工具新增把輸出轉大寫的 --upper 旗標,再用 /opsx:verify 逐條驗收。

實戰背景

範例 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 omittedFlag 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 對應的執行驗證

    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 omittednode src/cli.js Alice 印出 Hello, Alice!
    • Flag presentnode 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

    1. 驗證成功:所有實作皆吻合規格。
    2. 智慧同步:已將暫存規格合併至 openspec/specs/greeting-cli/spec.md
    3. 清理歸檔:已將計畫資料夾移動至 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 也越難矇混過關。