Stores (beta)
Lên kế hoạch cho những thay đổi trải rộng nhiều repository: một store, nhiều repo.
OpenSpec thường nằm trong một repo: một thư mục openspec/ đặt cạnh phần code mà nó lên kế hoạch. Store chuyển thư mục đó vào một repository riêng, và nhiều code repo có thể dùng chung nó.
Sau khi thiết lập một lần trên mỗi máy, các lệnh như status, new change và archive có thể hoạt động trong store từ bất kỳ thư mục nào.
team-plans (một store: OpenSpec trong repo riêng của nó)
├── .openspec-store/store.yaml tên của store
└── openspec/
├── specs/
└── changes/
▲
│ thiết lập một lần trên mỗi máy,
│ chia sẻ bằng push và clone như bất kỳ repo nào
┌─────────────┼─────────────┐
│ │ │
web-app api-server mobile-app
(code repo) (code repo) (code repo)Bạn chia sẻ store bằng git, giống như cách bạn chia sẻ code: tự commit, push, pull và review nó. Specs và changes cũng có branch và pull request giống như code.
Khi nào bạn cần dùng
Hai lý do phổ biến để dùng store:
Frontend và backend ở các repo riêng biệt: một feature động đến cả hai, và kế hoạch cần một nơi duy nhất thay vì hai nửa.
shop-plans (store) └── openspec/changes/add-discounts/ một kế hoạch cho feature ▲ ┌─────────┴─────────┐ │ │ storefront api (repo frontend) (repo backend)Một sản phẩm, nhiều client repo: Android, iOS và web phát hành từ repo riêng của chúng nhưng dùng chung một hành vi mong đợi. Một spec mô tả hành vi, không phải implementation, nên một spec phục vụ cả ba.
product-specs (store) └── openspec/specs/checkout/spec.md hành vi mong đợi ▲ ┌─────────────┼─────────────┐ │ │ │ android-app ios-app web-app (code repo) (code repo) (code repo)
Bạn có thể có nhiều hơn một store, tuy nhiên chúng tôi khuyến nghị giữ số lượng ở mức thấp.
Thiết lập một store
Một người tạo store, sau đó mọi người khác tham gia vào.
Tạo store (một người, một lần cho mỗi nhóm). Chạy
openspec store setupvà trả lời các câu hỏi:bash# chạy từ bất kỳ đâu; nó sẽ hỏi bạn muốn tạo gì và ở đâu openspec store setupNó đặt ba câu hỏi:
- Store name:
team-plans - Where should this store live?: đã điền sẵn
~/openspec/<name>, nhấn Enter để chấp nhận hoặc nhập một đường dẫn khác - Create this store?: hiển thị những gì nó sắp tạo, trả lời
Yes
Sau đó nó báo cáo những gì đã tạo:
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 name:
Đẩy nó lên git host của bạn. Tạo một repo
team-planstrống trên host của bạn trước. Setup không thêm git remote, vì vậy hãy kết nối store với repo đó, sau đó push:bash# kết nối store với repo trống trên git host của bạn cd ~/openspec/team-plans git remote add origin git@github.com:acme/team-plans.git # xuất bản nó git push -u origin mainTham gia store (mỗi đồng đội, một lần cho mỗi máy):
bash# lấy store về máy của bạn git clone git@github.com:acme/team-plans.git ~/openspec/team-plans # cho OpenSpec biết nó nằm ở đâu openspec store register ~/openspec/team-plansyamlStore registered: team-plans Location: /Users/you/openspec/team-plans OpenSpec root: ready Registry: registeredĐăng ký cho máy của bạn biết store nằm ở đâu. Tên của store đã được commit bên trong nó, trong
.openspec-store/store.yaml. Setup đã đăng ký bản sao của người tạo, vì vậy chỉ các bản sao được clone mới cần bước này.Xác nhận nó hoạt động, từ bất kỳ thư mục nào:
bash# bất kỳ lệnh OpenSpec nào cũng đến store bằng tên 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
Các loại thiết lập
OpenSpec có ba loại thiết lập. Phần còn lại của trang này sử dụng các tên này:
- repo-local: OpenSpec bên trong repo của bạn, không có store. Mặc định.
- store-only: repo của bạn không giữ specs hoặc changes riêng. Mọi thứ nằm trong store.
- store-optional: dự án của bạn có thư mục
openspec/riêng và cũng kết nối đến một store khi bạn yêu cầu.
Mặc định: OpenSpec bên trong repo của bạn (repo-local)
openspec init đặt một thư mục openspec/ bên cạnh code của bạn, và specs và changes của repo đó nằm ở đó. Không có store nào liên quan. Đây là thiết lập mà Thiết lập dự án của bạn hướng dẫn, và hầu hết các dự án không bao giờ cần thiết lập khác.
web-app (code repo)
└── openspec/
├── specs/
└── changes/OpenSpec bên ngoài repo của bạn, trong một store (store-only)
Repo không giữ specs hoặc changes riêng. Mọi thứ nó lên kế hoạch nằm trong store, và một dòng trong config của repo kết nối hai thứ này.
Phổ biến khi một nhóm xây dựng tất cả các repo và lên kế hoạch ở một nơi. Tất cả các ví dụ ở trên đều có hình dạng này.
team-plans (store)
└── openspec/
├── specs/ specs của repo nằm ở đây
└── changes/ changes của nó cũng vậy
▲
│ store: team-plans (đường kết nối)
web-app (code repo)
└── openspec/
└── config.yaml không có gì khácOpenSpec trong repo của bạn và trong một store (store-optional)
Repo vẫn là repo-local cho công việc riêng của nó, trong khi store chứa specs và changes dùng chung. Bên trong repo, OpenSpec sử dụng thư mục openspec/ của dự án bạn, và chỉ kết nối đến store khi bạn truyền --store.
Phổ biến khi một repo đã sử dụng OpenSpec trước khi store tồn tại, hoặc khi một repo độc lập chủ yếu chỉ thỉnh thoảng chạm vào công việc dùng chung.
team-plans (store)
└── openspec/ specs và changes dùng chung
▲
│ chỉ khi bạn truyền --store team-plans
web-app (code repo)
└── openspec/ của chính repo này
├── config.yaml
├── specs/
└── changes/Một repo có thể bắt đầu với repo-local và sau đó chuyển specs và changes của nó vào store. Chuyển specs và changes của repo vào store chỉ cách thực hiện.
Nơi các artifact được tạo khi sử dụng store
Khi bạn sử dụng store, OpenSpec cũng phải quyết định nơi các artifact được tạo. Nó phụ thuộc vào thiết lập của bạn:
- store-only (dự án của bạn chỉ ghi vào store): mọi artifact được tạo trong store. Dòng
store:bên dưới ghi lại điều đó. - store-optional (dự án của bạn có thư mục
openspec/riêng và cũng sử dụng store): artifact được tạo trong dự án của bạn, trừ khi bạn chỉ định store trong yêu cầu hoặc truyền--storecho change đó. Agent của bạn sau đó mang cờ đó xuyên suốt phần còn lại của quy trình.
OpenSpec ghi artifact vào một trong hai nơi: thư mục openspec/ của dự án bạn, hoặc của store. Nó chọn theo thứ tự này, và tùy chọn đầu tiên được áp dụng sẽ thắng:
--store <id>trên một lệnh. Luôn thắng, từ bất kỳ thư mục nào.- Thư mục
openspec/của dự án bạn. Nếu dự án của bạn có thư mụcspecs/hoặcchanges/riêng, OpenSpec sử dụng chúng. - Dòng
store:trong dự án bạn. Cách một dự án store-only ghi lại store của nó. defaultStoretrên máy bạn. Phương án dự phòng khi không có tùy chọn nào ở trên được áp dụng.
Nếu không có tùy chọn nào được áp dụng và bạn đã đăng ký store, lệnh sẽ thất bại và liệt kê chúng. Khi id của một store khớp với tên repo của bạn trong remote origin của nó, lỗi sẽ nêu tên store đó và dòng store: chọn nó. OpenSpec không bao giờ tự chọn store theo tên, vì các repo trong các tổ chức khác nhau có thể có cùng tên.
Khi OpenSpec chọn một store, nó in Using OpenSpec root: ... trước khi in kết quả lệnh.
Dòng store: (các dự án store-only)
Thêm một dòng vào openspec/config.yaml của dự án bạn:
# web-app/openspec/config.yaml
store: team-plansMọi thứ bạn hoặc agent của bạn chạy bên trong dự án bây giờ đều sử dụng store, không cần gõ cờ:
# bên trong web-app, đã kết nối
openspec statusUsing OpenSpec root: team-plans (/Users/you/openspec/team-plans)
No active changes. Create one with: openspec new change <name> --store team-plans- Không có dòng đó: chạy một lệnh đơn giản trong dự án store-only và OpenSpec dừng lại với lỗi liệt kê các store đã đăng ký của bạn.
- Commit nó: đồng đội clone dự án của bạn cũng nhận được dòng đó. Họ vẫn cần store được đăng ký trên máy của họ (bước 3 của Thiết lập một store), hoặc OpenSpec báo lỗi và yêu cầu họ đăng ký.
- Bên cạnh các thư mục thực: nếu dự án của bạn cũng có thư mục
specs/hoặcchanges/, OpenSpec sử dụng chúng và bỏ qua dòng đó, kèm theo cảnh báo.
Cài đặt tích hợp trong repo store-only
Chạy init từ thư mục gốc của code repo để cài đặt các tệp tích hợp công cụ AI mà không chuyển việc lập kế hoạch trở lại repo đó:
# bên trong web-app, ở thư mục gốc repo
openspec init --tools claude- Tệp tích hợp: được ghi trong code repo.
openspec/config.yaml: được giữ nguyên từng byte, bao gồm dòngstore:.openspec/specs/vàopenspec/changes/: không được tạo trong code repo.
OpenSpec từ chối lệnh này từ thư mục con của code repo. Chạy nó từ thư mục gốc repo.
OpenSpec cũng từ chối --language ở đây vì ngôn ngữ thuộc về config của store bên ngoài. Chạy init ở thư mục gốc store hoặc chỉnh sửa trực tiếp config đó.
defaultStore trên máy bạn
Đặt một lần nếu mọi dự án bạn làm việc đều sử dụng cùng một store. OpenSpec sử dụng nó làm phương án dự phòng khi không tìm thấy cờ, không có thư mục openspec/ cục bộ và không có dòng store::
# sử dụng team-plans bất cứ khi nào không có gì khác chỉ định store
openspec config set defaultStore team-plans
# hoàn tác
openspec config unset defaultStoreCác lệnh giữ cục bộ. init, update, templates, schemas và các lệnh con openspec schema chỉ tác động lên thư mục hiện tại và không nhận --store.
Chuyển specs và changes của repo vào store
Để chuyển một repo từ repo-local sang store-only:
- Chuyển mọi thứ trong
openspec/specs/vàopenspec/changes/của repo vào các thư mục tương tự trong store. - Xóa các thư mục giờ đã trống, để thư mục
openspec/của repo chỉ chứaconfig.yaml. - Thêm dòng
store:vàoconfig.yamlđó.
openspec status bên trong repo bây giờ bắt đầu bằng Using OpenSpec root: team-plans.
Làm việc trong store
Các quy trình không thay đổi, cho bạn hoặc cho agent của bạn. Propose, apply và archive chạy theo cách chúng luôn làm. Sự khác biệt duy nhất là nơi các artifact được tạo, và phần ở trên đề cập đến điều đó.
Tạo một change từ bên trong repo store-only và nó sẽ nằm trong store:
# bên trong web-app; dòng store: định tuyến điều này đến 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- Nơi nó đã đến: vào repo store, không phải bên cạnh code của bạn.
- Chia sẻ nó: change chỉ tồn tại trong checkout của bạn cho đến khi bạn commit và push repo store. Đồng đội nhìn thấy nó khi họ pull. Điều tương tự áp dụng cho mọi artifact mà các quy trình ghi.
- Đường dẫn trong tài liệu: ở bất kỳ đâu tài liệu hiển thị đường dẫn
openspec/, trong thiết lập store thì thư mục đó là của store.
Khi artifact được tạo ở nơi bạn không mong đợi, openspec doctor kiểm tra thiết lập của bạn mà không thay đổi gì và in ra cách khắc phục cho mỗi phát hiện:
# kiểm tra root hiện tại và các store của nó
openspec doctorDoctor
Root
Location: /Users/you/openspec/team-plans
OpenSpec root: ok
Store: team-plans (metadata ok)
References
(none declared)openspec context liệt kê root và các store mà thư mục hiện tại của bạn làm việc cùng, khi bạn muốn cùng một bức tranh mà không cần kiểm tra.
Để mở store và một repo trong cùng một cửa sổ trình soạn thảo, để agent của bạn có thể đọc cả hai, xem Worksets (beta).
Đọc specs từ store khác
Repository của bạn có thể giữ nguyên thư mục openspec/ của mình và vẫn cho phép agent của bạn đọc specs từ một store khác. Khai báo store đó dưới references: trong tệp openspec/config.yaml của repository:
# api-server/openspec/config.yaml
references:
- team-plansCác tham chiếu (references) là chỉ đọc. Công việc của bạn vẫn nằm trong repository của bạn, và tham chiếu chỉ thay đổi những gì agent của bạn được thông báo.
Khi một workflow tạo ra một artifact, hướng dẫn của nó sẽ được thêm chỉ mục specs của store được tham chiếu, mỗi spec kèm theo một dòng tóm tắt và lệnh chính xác để lấy nó:
<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>Một tham chiếu cũng có thể chứa URL clone của store, dành cho các máy chưa có store đó:
references:
- team-plans
- { id: design-system, remote: "git@github.com:acme/design-system.git" }Khi URL đã được khai báo, openspec doctor sẽ biến một store thiếu thành một cách khắc phục có thể dán (paste) trực tiếp:
# 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-systemGiới hạn của bản Beta
- Cấu trúc có thể thay đổi: tên lệnh, cờ (flags) và định dạng tệp có thể thay đổi giữa các phiên bản. Hãy đọc lại trang này sau khi nâng cấp.
- Không đồng bộ, theo thiết kế: OpenSpec không bao giờ clone, pull hoặc push. Một checkout cũ sẽ hiển thị các specs cũ cho đến khi bạn pull, và các tham chiếu được đọc từ những gì có trên ổ đĩa.
- Một checkout cho mỗi tên store: đăng ký thư mục thứ hai dưới tên đã được đăng ký trước đó sẽ thất bại, kèm theo gợi ý chạy
openspec store unregistertrước tiên.