存放庫 (測試版)
規劃跨越多個儲存庫的變更:一個存放庫,多個程式碼儲存庫。
OpenSpec 通常位於單一儲存庫中:一個與其所規劃程式碼相鄰的 openspec/ 資料夾。存放庫則是將該資料夾移至其自身的儲存庫,讓多個程式碼儲存庫可以共用。
每台機器完成一次性設定後,像 status、new change 和 archive 等指令就能在任何目錄中操作該存放庫。
team-plans (a store: OpenSpec in its own repo)
├── .openspec-store/store.yaml the store's name
└── openspec/
├── specs/
└── changes/
▲
│ set up once on each machine,
│ shared by pushing and cloning like any repo
┌─────────────┼─────────────┐
│ │ │
web-app api-server mobile-app
(code repo) (code repo) (code repo)您可以像共用程式碼一樣,透過 Git 共用存放庫:提交、推送、拉取並自行審查。規格與變更會像程式碼一樣,使用分支與拉取請求 (pull request) 進行管理。
何時需要使用存放庫
兩個常見的使用存放庫理由:
前後端位於不同儲存庫:一個功能會同時涉及兩者,該計劃需要一個統一的位置,而不是分成兩半。
shop-plans (store) └── openspec/changes/add-discounts/ one plan for the feature ▲ ┌─────────┴─────────┐ │ │ storefront api (frontend repo) (backend repo)一個產品,多個客戶端儲存庫:Android、iOS 和 Web 各自從自己的儲存庫發布,但共享相同的預期行為。規格描述的是行為而非實作,因此一份規格就能服務這三個平台。
product-specs (store) └── openspec/specs/checkout/spec.md the expected behavior ▲ ┌─────────────┼─────────────┐ │ │ │ android-app ios-app web-app (code repo) (code repo) (code repo)
您可以擁有不只一個存放庫,但我們建議維持較少的數量。
設定 store
由一個人建立 store,然後其他人再加入。
建立 store(由一個人執行,每個團隊一次)。執行
openspec store setup並回答提示:bash# 可從任何位置執行;它會詢問要建立什麼以及要建立到哪裡 openspec store setup它會詢問三個問題:
- store 名稱:
team-plans - 這個 store 應該放在哪裡?:預先填入
~/openspec/<name>,按 Enter 接受,或輸入其他路徑 - 要建立這個 store 嗎?:顯示即將建立的內容,回答
Yes
接著它會回報已建立的內容:
yamlStore ready: team-plans Location: ~/openspec/team-plans OpenSpec root: ready Registry: registered Next: run normal OpenSpec commands against this store, for example: openspec new change <change-id> --store team-plans Share this store by committing and pushing it like any Git repo.- store 名稱:
將它推送到你的 Git 主機。 先在你的主機上建立一個空的
team-plans儲存庫。設定流程不會加入 Git remote,因此請將 store 連接到該儲存庫,然後推送:bash# 將 store 連接到 Git 主機上的空儲存庫 cd ~/openspec/team-plans git remote add origin git@github.com:acme/team-plans.git # 發布它 git push -u origin main加入 store(每位隊友、每台機器一次):
bash# 將 store 放到你的機器上 git clone git@github.com:acme/team-plans.git ~/openspec/team-plans # 告訴 OpenSpec 它位於何處 openspec store register ~/openspec/team-plansyamlStore registered: team-plans Location: /Users/you/openspec/team-plans OpenSpec root: ready Registry: registered註冊會告訴你的機器這個 store 位於何處。store 的名稱已提交在其內部的
.openspec-store/store.yaml中。設定流程已註冊建立者的副本,因此只有 clone 出來的副本需要執行此步驟。確認設定成功,可從任何目錄執行:
bash# 任何 OpenSpec 命令都能依名稱找到該 store openspec status --store team-plansyamlUsing OpenSpec root: team-plans (/Users/you/openspec/team-plans) No active changes. Create one with: openspec new change <name> --store team-plans
設定類型
OpenSpec 有三種設定類型。本頁其餘部分會使用以下名稱:
- repo-local:OpenSpec 位於你的儲存庫內,不使用 store。這是預設。
- store-only:你的儲存庫不保留自己的規格或變更。所有內容都位於 store 中。
- store-optional:你的專案有自己的
openspec/資料夾,並且在你指定時也會連到 store。
預設:OpenSpec 位於你的儲存庫內(repo-local)
openspec init 會在你的程式碼旁放置一個 openspec/ 資料夾,該儲存庫的規格與變更就放在那裡。不會涉及 store。這是 設定你的專案 所教的設定方式,大多數專案不需要其他設定。
web-app (code repo)
└── openspec/
├── specs/
└── changes/OpenSpec 位於你的儲存庫之外,在 store 中(store-only)
儲存庫不保留自己的規格或變更。它規劃的所有內容都位於 store 中,並由儲存庫設定中的一行連接兩者。
當一個團隊建置所有儲存庫並在同一處規劃時,這很常見。上述範例 都是這種形式。
team-plans (store)
└── openspec/
├── specs/ the repo's specs live here
└── changes/ its changes too
▲
│ store: team-plans (the connecting line)
web-app (code repo)
└── openspec/
└── config.yaml nothing elseOpenSpec 同時位於你的儲存庫與 store 中(store-optional)
儲存庫自身的工作仍維持 repo-local,而 store 則保存共用的規格與變更。在儲存庫內,OpenSpec 會使用你專案的 openspec/ 資料夾,且只有在傳入 --store 時才會連到 store。
當儲存庫在 store 出現之前就已使用 OpenSpec,或當一個大致獨立的儲存庫偶爾才涉及共用工作時,這很常見。
team-plans (store)
└── openspec/ the shared specs and changes
▲
│ only when you pass --store team-plans
web-app (code repo)
└── openspec/ this repo's own
├── config.yaml
├── specs/
└── changes/儲存庫可以從 repo-local 開始,之後再將其規格與變更移入 store。將儲存庫的規格與變更移入 store 說明了做法。
使用 store 時,產出物會建立在哪裡
使用 store 時,OpenSpec 也必須決定產出物會建立在哪裡。這取決於你的設定:
- store-only(你的專案只寫入 store):每個產出物都會建立在 store 中。下方的
store:行會記錄這一點。 - store-optional(你的專案有自己的
openspec/資料夾,同時也使用 store):除非你在請求中指名該 store,或為該變更傳入--store,否則產出物會建立在你專案中。你的 agent 接著會在後續工作流程中沿用該旗標。
OpenSpec 會將產出物寫入兩個位置之一:你專案的 openspec/ 資料夾,或 store 的資料夾。它會依下列順序選擇,並以第一個適用者為準:
- 命令上的
--store <id>。 永遠優先,且可從任何目錄生效。 - 你專案的
openspec/資料夾。 如果你的專案有自己的specs/或changes/資料夾,OpenSpec 會使用它們。 - 你專案中的
store:行。 store-only 專案用來記錄其 store 的方式。 - 你機器上的
defaultStore。 上述皆不適用時的後備選項。
如果上述皆不適用,且你已有註冊的 store,命令會失敗並列出這些 store。當某個 store 的 id 與你的儲存庫在其 origin remote 中的名稱相符時,錯誤訊息會指出該 store,以及選取它的 store: 行。OpenSpec 絕不會自行依名稱挑選 store,因為不同組織的儲存庫可能同名。
當 OpenSpec 選取 store 時,會在命令輸出之前印出 Using OpenSpec root: ...。
store: 行(store-only 專案)
在你專案的 openspec/config.yaml 中加入一行:
# web-app/openspec/config.yaml
store: team-plans你或你的 agent 在專案內執行的所有操作,現在都會使用該 store,且不必輸入任何旗標:
# 在 web-app 內,已連接
openspec statusUsing OpenSpec root: team-plans (/Users/you/openspec/team-plans)
No active changes. Create one with: openspec new change <name> --store team-plans- 沒有這一行時:在 store-only 專案中執行一般命令,OpenSpec 會停止並顯示錯誤,列出你已註冊的 store。
- 提交它:clone 你專案的隊友也會取得這一行。他們仍需要在各自的機器上註冊該 store(設定 store 的步驟 3),否則 OpenSpec 會報錯並要求他們註冊。
- 與實際資料夾並存時:如果你的專案也有
specs/或changes/資料夾,OpenSpec 會使用這些資料夾、忽略該行,並顯示警告。
在 store-only 儲存庫中安裝整合
從程式碼儲存庫的根目錄執行 init,以安裝 AI 工具整合檔案,同時不把規劃移回該儲存庫:
# 在 web-app 內,於儲存庫根目錄
openspec init --tools claude- 整合檔案:寫入程式碼儲存庫。
openspec/config.yaml:逐位元組原樣保留,包括store:行。openspec/specs/與openspec/changes/:不會在程式碼儲存庫中建立。
OpenSpec 會拒絕從程式碼儲存庫的子目錄執行此命令。請從儲存庫根目錄執行。
OpenSpec 在此也會拒絕 --language,因為語言設定屬於外部 store 的設定。請在 store 根目錄執行 init,或直接編輯該設定。
你機器上的 defaultStore
如果你工作的每個專案都使用同一個 store,設定一次即可。當 OpenSpec 找不到旗標、本機 openspec/ 資料夾與 store: 行時,會改用它:
# 當其他設定未指定 store 時,使用 team-plans
openspec config set defaultStore team-plans
# 取消設定
openspec config unset defaultStore維持在本機執行的命令。 init、update、templates、schemas 以及 openspec schema 子命令只作用於目前目錄,且不接受 --store。
將儲存庫的規格與變更移入 store
若要將儲存庫從 repo-local 轉為 store-only:
- 將儲存庫
openspec/specs/與openspec/changes/中的所有內容,移入 store 中同名的資料夾。 - 刪除這些已清空的資料夾,讓儲存庫的
openspec/資料夾只保留config.yaml。 - 在該
config.yaml中加入store:行。
在儲存庫內執行 openspec status,現在會以 Using OpenSpec root: team-plans 開頭。
在 store 中工作
無論是你或你的 agent,工作流程都不變。Propose、apply 與 archive 的執行方式一如往常。唯一的差異是產出物建立的位置,上一節 已說明。
在 store-only 儲存庫內建立變更,該變更會落在 store 中:
# 在 web-app 內;store: 行會將其導向 team-plans
openspec new change add-loginUsing OpenSpec root: team-plans (/Users/you/openspec/team-plans)
Created change 'add-login' at /Users/you/openspec/team-plans/openspec/changes/add-login/
Schema: spec-driven
Next: openspec status --change add-login --store team-plans- 建立位置:位於 store 儲存庫中,而不是你的程式碼旁邊。
- 分享方式:在你提交並推送 store 儲存庫之前,這項變更只存在於你的 checkout。隊友會在拉取後看到它。工作流程寫入的每個產出物也是如此。
- 文件中的路徑:文件中只要出現
openspec/路徑,在 store 設定中,該資料夾就是 store 的資料夾。
當產出物建立在你意想不到的位置時,openspec doctor 會檢查你的設定而不做任何變更,並針對每項發現輸出修正方式:
# 檢查目前的根目錄及其 store
openspec doctorDoctor
Root
Location: /Users/you/openspec/team-plans
OpenSpec root: ok
Store: team-plans (metadata ok)
References
(none declared)openspec context 會列出目前目錄所使用的根目錄與 store,適合在你想要相同概況但不想執行檢查時使用。
若要在同一個編輯器視窗中開啟 store 與儲存庫,讓你的 agent 能同時讀取兩者,請參閱 Worksets(beta)。
從其他 store 讀取 specs
你的 repo 可以保有自己獨立的 openspec/ 資料夾,同時仍能讓你的 agent 讀取其他 store 的 specs。在 repo 的 openspec/config.yaml 中,於 references: 底下宣告該 store:
# api-server/openspec/config.yaml
references:
- team-plansReferences 是唯讀的。你的工作內容仍保存在你自己的 repo 中,而 reference 只會改變 agent 接收到的資訊。
當 workflow 建立一項產物時,其指令會附上一份所參考 store 的 specs 索引,每個項目都包含單行摘要,以及用來擷取該 spec 的確切指令:
<referenced_stores>
<!-- Read-only upstream context. Fetch what you need; cite what you use. -->
Store team-plans (/Users/you/openspec/team-plans):
- payments: Rules for charging and refunding customers.
Fetch: openspec show <spec-id> --type spec --store team-plans
</referenced_stores>Reference 也可以攜帶該 store 的 clone URL,方便尚未擁有該 store 的機器使用:
references:
- team-plans
- { id: design-system, remote: "git@github.com:acme/design-system.git" }一旦宣告 URL,openspec doctor 便會將遺失的 store 轉換為可直接貼上執行的修正指示:
# output wrapped to fit
References
- team-plans: ok (/Users/you/openspec/team-plans)
- design-system: Referenced store 'design-system' is not registered on this machine.
Fix: git clone -- git@github.com:acme/design-system.git '/Users/you/openspec/design-system' &&
openspec store register '/Users/you/openspec/design-system' --id design-systemBeta 版限制
- 形式可能變更:指令名稱、旗標和檔案格式可能在版本之間有所變動。升級後請重新閱讀本頁。
- 依設計不提供同步:OpenSpec 絕不執行 clone、pull 或 push。過期的 checkout 在執行 pull 之前都會顯示過期的 specs,而 references 則是直接從磁碟上的內容讀取。
- 每個 store 名稱僅限一個 checkout:以已註冊的名稱再註冊第二個資料夾會失敗,並附上先執行
openspec store unregister的提示。