Skip to content

結構描述(Schemas) ​

變更 OpenSpec 產出的內容:產出物、它們的順序,以及它們的範本。

結構描述定義了一份變更提案會產出什麼:哪些產出物、以什麼順序、來自哪些範本。例如 spec-driven,這個預設內建的結構描述,會大致依以下順序產出這四項,每一項都建立在前一項的基礎之上:

proposal → specs → design → tasks

當你希望這些是不同的文件時,就複製(fork)一份結構描述來修改,無論是減少文件數量、改變名稱,還是採用不同的結構。

結構描述存放的位置 ​

OpenSpec 會依序在三個地方尋找結構描述,並使用它找到的第一個:

  1. 你的專案:openspec/schemas/,隨儲存庫一起提交,讓整個團隊都能取得。
  2. 你的機器:macOS 與 Linux 上為 ~/.local/share/openspec/schemas(若你設定了 $XDG_DATA_HOME 則位於其下),Windows 上為 %LOCALAPPDATA%\openspec\schemas。放在這裡的結構描述在你工作的每個專案中都可用。
  3. 套件本身:內建的結構描述,例如 spec-driven,隨 openspec 本身一起發布。

相同的名稱可以存在於多個地方,而愈具體的位置優先。openspec schema which 會顯示目前使用的是哪一份:

$ openspec schema which spec-driven
Schema: spec-driven
Source: project
Path: /your-project/openspec/schemas/spec-driven

Shadows:
  package: .../openspec/schemas/spec-driven

結構描述裡有什麼 ​

結構描述由一個資料夾內的純檔案定義:一個宣告產出物的 schema.yaml,以及每個產出物各自的範本。以下是內建的 spec-driven:

spec-driven/
├── schema.yaml
└── templates/
    ├── proposal.md
    ├── spec.md
    ├── design.md
    └── tasks.md
  • schema.yaml:宣告每個產出物、它產生的檔案、它起始的範本、它需要哪些前置產出物,以及代理程式建立它時會收到的指示。每個欄位的契約都記載於 schema.yaml。
  • templates/:每個產出物一份 markdown 骨架,由代理程式填寫。

以下是 schema.yaml 中 tasks 產出物的條目(已精簡):

yaml
artifacts:
  - id: tasks
    generates: tasks.md
    description: Implementation checklist with trackable tasks
    template: tasks.md
    instruction: |
      ...what the agent is told when creating tasks.md...
    requires:
      - specs
      - design

內建結構描述隨 openspec 套件一起發布,因此你永遠不會就地編輯它們。你會透過複製(fork)取得自己的副本。

建立你自己的自訂結構描述 ​

取得自己的結構描述有兩種方式:

  1. 複製(fork)現有的結構描述並編輯你的副本。當某個現有結構描述已接近你想要的內容時,從這裡開始,因為其中的一切都已經可以運作。
  2. 從零開始,當沒有任何一個符合需求時,使用 openspec schema init 建立一個空的結構描述骨架。

複製現有的結構描述 ​

  1. 從你的專案根目錄執行,複製你想作為起點的結構描述:

    console
    $ openspec schema fork spec-driven
    
    Note: Schema commands are experimental and may change.
    ✔ Forked 'spec-driven' to 'spec-driven-custom'
    
    Source: .../openspec/schemas/spec-driven (package)
    Destination: /your-project/openspec/schemas/spec-driven-custom

    傳入第二個引數以指定名稱(openspec schema fork spec-driven team-flow)。名稱使用 kebab-case。

  2. 編輯副本:schema.yaml 與範本。編輯你的複本說明了要修改什麼。

  3. 驗證它:

    bash
    openspec schema validate spec-driven-custom

    這是唯一能在你進行變更的過程中之前,就抓出結構描述問題(缺少範本、YAML 錯誤、依賴循環)的指令。

  4. 在 openspec/config.yaml 中將你的專案指向它。這一步要你自己做,因為 fork 不會更動 config.yaml:

    yaml
    schema: spec-driven-custom
  5. 新的變更提案現在會遵循你的結構描述。較早建立的變更則保留它們起始時所用的結構描述。

若要在不更動 config.yaml 的情況下,在所有地方取代預設值,就複製成相同的名稱:openspec schema fork spec-driven spec-driven。你專案的副本便會覆蓋內建版本,如結構描述存放的位置所述。

從零開始 ​

openspec schema init 會建立一個新的結構描述骨架,而不是複製現有的:

console
$ openspec schema init lite --description "Lite flow" --artifacts proposal,tasks

✔ Created schema 'lite'
Schema created at: /your-project/openspec/schemas/lite
Artifacts: proposal, tasks

這個骨架是空白的。產出物只能來自內建的四個 id,且產生的範本不含任何指示,因此在你自己撰寫之前,代理程式得到的指引較少。之後複製流程的步驟照樣適用:先驗證,再將 config.yaml 指向它。

編輯你的複本 ​

一個複本有兩類檔案可以編輯:

  • templates/ 改變每份文件的骨架。在 tasks 範本中加入一個章節,之後每個新的 tasks.md 都會以它開頭。請保留第一行的 # 標題:產出物會繼承它,讓每個產生的檔案都以有標題的文件形式呈現。
  • schema.yaml 改變工作流程本身:存在哪些產出物、每個產出物需要哪些前置項,以及代理程式建立它時會收到什麼指示。

例如,若要移除 design 文件以獲得更精簡的流程:

  1. 從 schema.yaml 刪除 design 條目。

  2. 從 tasks 的 requires 清單中移除 design。

  3. 驗證:

    console
    $ openspec schema validate spec-driven-custom
    
    ✓ Schema 'spec-driven-custom' is valid

跳過步驟 2,驗證就會抓出問題:

console
✗ Schema 'spec-driven-custom' has errors:
  error: Invalid dependency reference in artifact 'tasks': 'design' does not exist

每次手動編輯後都要驗證。否則損壞的結構描述會在變更進行到一半時才浮現,也就是工作流程要求一個不存在的檔案時。與 config.yaml 一樣,結構描述的編輯會在下一次執行時對代理程式生效。

複本是一個快照 ​

openspec update 會更新已安裝的技能與指令,但它絕不會更動 openspec/schemas/。你的複本會完全依照你離開時的狀態繼續運作,這也代表當內建結構描述演進時,它不會再收到改進。若要在之後取得這些改進,請以新名稱再次複製內建版本,並將差異移植過來。

分享結構描述 ​

分享結構描述就是複製它的資料夾。

  • 與你的團隊:提交 openspec/schemas/,儲存庫上的每個人都能使用它。
  • 跨你的專案:將資料夾放到結構描述存放的位置中的使用者層級目錄。
  • 來自社群:社群目錄列出了共享的結構描述。將其中一個複製到 openspec/schemas/<name>,它就會像你自己的一樣運作。

我們正在開發一個結構描述登錄庫,包含公開與私有的,讓結構描述可以透過名稱安裝,而不必手動複製。

將 OpenSpec 與 Superpowers 搭配使用 ​

社群維護的 superpowers-bridge 結構描述將 OpenSpec 的產出物連結到 Superpowers 的執行技能。在將它複製到你的專案之前,請先閱讀該橋接的安裝與相容性說明。

該橋接是在 OpenSpec 之外發布的。OpenSpec 不會測試或為其 Superpowers 整合進行版本管理。