สโตร์ (เบต้า)
วางแผนการเปลี่ยนแปลงที่ครอบคลุมหลายที่เก็บข้อมูล: สโตร์หนึ่ง, หลายรีโพ
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 เช่นเดียวกับการแชร์โค้ด: commit, push, pull, และรีวิวด้วยตัวคุณเอง Specs และ changes จะได้รับ branches และ pull requests เช่นเดียวกับโค้ด
เมื่อคุณต้องการสโตร์หนึ่ง
เหตุผลทั่วไปสองประการในการใช้สโตร์:
ฟรอนต์เอนด์และแบ็กเอนด์อยู่ในรีโพแยกกัน: ฟีเจอร์หนึ่งสัมผัสทั้งสอง และแผนต้องการที่อยู่ที่เดียวแทนที่จะเป็นสองส่วน
shop-plans (store) └── openspec/changes/add-discounts/ one plan for the feature ▲ ┌─────────┴─────────┐ │ │ storefront api (frontend repo) (backend repo)ผลิตภัณฑ์หนึ่ง, รีโพไคลเอนต์หลายอัน: Android, iOS, และ web ปล่อยจากรีโพของตัวเอง แต่แชร์พฤติกรรมที่คาดหวังเดียวกัน spec อธิบายพฤติกรรม ไม่ใช่การใช้งาน ดังนั้น spec หนึ่งจึงทำงานให้ทั้งสามได้
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:
Push ไปยัง git host ของคุณ สร้าง repo
team-plansแบบว่างบน host ของคุณก่อน การตั้งค่าไม่ได้เพิ่ม git remote ดังนั้นเชื่อม store กับ repo นั้น แล้ว push:bash# เชื่อม store กับ repo ว่างบน git host ของคุณ 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 ว่า store อยู่ที่ไหน openspec store register ~/openspec/team-plansyamlStore registered: team-plans Location: /Users/you/openspec/team-plans OpenSpec root: ready Registry: registeredการลงทะเบียนจะบอกเครื่องของคุณว่า store นี้อยู่ที่ใด ชื่อของ store ถูก commit ไว้ภายในแล้วใน
.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 อยู่ภายใน repo ของคุณ ไม่มี store เป็นค่าเริ่มต้น
- store-only: repo ของคุณไม่มี specs หรือ changes เป็นของตัวเอง ทุกอย่างอยู่ใน store
- store-optional: โปรเจกต์ของคุณมีโฟลเดอร์
openspec/ของตัวเอง และยังเข้าถึง store เมื่อคุณร้องขอ
ค่าเริ่มต้น: OpenSpec ภายใน repo ของคุณ (repo-local)
openspec init วางโฟลเดอร์ openspec/ ไว้ข้างโค้ดของคุณ และ specs กับ changes ของ repo นั้นจะอยู่ที่นั่น ไม่มีการใช้ store นี่คือการตั้งค่าที่ ตั้งค่าโปรเจกต์ของคุณ สอน และโปรเจกต์ส่วนใหญ่ไม่จำเป็นต้องใช้แบบอื่นเลย
web-app (code repo)
└── openspec/
├── specs/
└── changes/OpenSpec นอก repo ของคุณ ใน store (store-only)
repo ไม่มี specs หรือ changes เป็นของตัวเอง ทุกสิ่งที่วางแผนไว้อยู่ใน store และบรรทัดหนึ่งใน config ของ repo เชื่อมทั้งสองเข้าด้วยกัน
พบบ่อยเมื่อทีมเดียวสร้าง repo ทั้งหมดและวางแผนในที่เดียว ตัวอย่างด้านบน ทั้งหมดมีรูปแบบนี้
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 ใน repo ของคุณและใน store (store-optional)
repo ยังคงเป็น repo-local สำหรับงานของตัวเอง ขณะที่ store เก็บ specs และ changes ที่ใช้ร่วมกัน ภายใน repo OpenSpec ใช้โฟลเดอร์ openspec/ ของโปรเจกต์คุณ และจะเข้าถึง store เฉพาะเมื่อคุณส่ง --store เท่านั้น
พบบ่อยเมื่อ repo ใช้ OpenSpec อยู่ก่อนที่ store จะมีขึ้น หรือเมื่อ repo ที่เป็นอิสระเป็นส่วนใหญ่เพียงบางครั้งเท่านั้นที่แตะงานที่ใช้ร่วมกัน
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 สามารถเริ่มแบบ repo-local และย้าย specs กับ changes ไปยัง store ภายหลังได้ ย้าย specs และ changes ของ repo ไปยัง store แสดงวิธีการ
artifacts ถูกสร้างที่ใดเมื่อใช้ store
เมื่อคุณใช้ store OpenSpec ยังต้องตัดสินใจว่า artifacts จะถูกสร้างที่ใด ซึ่งขึ้นอยู่กับการตั้งค่าของคุณ:
- store-only (โปรเจกต์ของคุณเขียนลง store เท่านั้น): artifacts ทุกชิ้นถูกสร้างใน store บรรทัด
store:ด้านล่างบันทึกสิ่งนั้นไว้ - store-optional (โปรเจกต์ของคุณมีโฟลเดอร์
openspec/ของตัวเองและใช้ store ด้วย): artifacts จะถูกสร้างในโปรเจกต์ของคุณ เว้นแต่คุณจะระบุชื่อ store ในคำขอหรือส่ง--storeสำหรับ change นั้น จากนั้น agent ของคุณจะพา flag นี้ต่อไปตลอดส่วนที่เหลือของ workflow
OpenSpec เขียน artifacts ไปยังหนึ่งในสองที่: โฟลเดอร์ openspec/ ของโปรเจกต์คุณ หรือของ store โดยเลือกตามลำดับนี้ และตัวเลือกแรกที่ใช้ได้จะชนะ:
--store <id>บนคำสั่ง ชนะเสมอ จากไดเรกทอรีใดก็ได้- โฟลเดอร์
openspec/ของโปรเจกต์คุณ หากโปรเจกต์ของคุณมีโฟลเดอร์specs/หรือchanges/ของตัวเอง OpenSpec จะใช้โฟลเดอร์เหล่านั้น - บรรทัด
store:ในโปรเจกต์ของคุณ วิธีที่โปรเจกต์ store-only บันทึก store ของตน defaultStoreบนเครื่องของคุณ ตัวสำรองเมื่อไม่มีตัวเลือกข้างต้นใช้ได้
หากไม่มีตัวเลือกใดใช้ได้และคุณมี store ที่ลงทะเบียนไว้ คำสั่งจะล้มเหลวและแสดงรายการ store เหล่านั้น เมื่อ id ของ store หนึ่งตรงกับชื่อ repo ของคุณใน remote origin ข้อความ error จะระบุชื่อ store นั้นและบรรทัด store: ที่เลือก store นั้น OpenSpec ไม่เคยเลือก store ตามชื่อด้วยตัวเอง เพราะ repo ในองค์กรที่ต่างกันสามารถมีชื่อซ้ำกันได้
เมื่อ OpenSpec เลือก store ระบบจะพิมพ์ Using OpenSpec root: ... ก่อน output ของคำสั่ง
บรรทัด store: (โปรเจกต์ store-only)
เพิ่มหนึ่งบรรทัดใน openspec/config.yaml ของโปรเจกต์คุณ:
# web-app/openspec/config.yaml
store: team-plansทุกสิ่งที่คุณหรือ agent ของคุณรันภายในโปรเจกต์ตอนนี้จะใช้ store โดยไม่ต้องพิมพ์ flag:
# ภายใน 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 จะหยุดพร้อม error ที่แสดงรายการ store ที่คุณลงทะเบียนไว้
- Commit บรรทัดนี้: สมาชิกในทีมที่ clone โปรเจกต์ของคุณจะได้บรรทัดนี้ไปด้วย พวกเขายังต้องลงทะเบียน store บนเครื่องของตน (ขั้นตอนที่ 3 ของการตั้งค่า store) มิฉะนั้น OpenSpec จะ error และแจ้งให้ลงทะเบียน
- เมื่อมีโฟลเดอร์จริงอยู่ด้วย: หากโปรเจกต์ของคุณมีโฟลเดอร์
specs/หรือchanges/ด้วย OpenSpec จะใช้โฟลเดอร์เหล่านั้นและเพิกเฉยต่อบรรทัดนี้ พร้อมคำเตือน
ติดตั้ง integrations ใน repo แบบ store-only
รัน init จาก root ของ code repo เพื่อติดตั้งไฟล์ integration ของเครื่องมือ AI โดยไม่ย้ายการวางแผนกลับเข้า repo นั้น:
# ภายใน web-app ที่ root ของ repository
openspec init --tools claude- ไฟล์ integration: ถูกเขียนใน code repo
openspec/config.yaml: ถูกเก็บรักษาแบบ byte-for-byte รวมถึงบรรทัดstore:openspec/specs/และopenspec/changes/: ไม่ถูกสร้างใน code repo
OpenSpec จะปฏิเสธคำสั่งนี้หากรันจากไดเรกทอรีย่อยของ code repo ให้รันจาก root ของ repository
OpenSpec ยังปฏิเสธ --language ที่นี่ด้วย เพราะภาษาเป็นส่วนหนึ่งของ config ของ store ภายนอก ให้รัน init ใน root ของ store หรือแก้ไข config นั้นโดยตรง
defaultStore บนเครื่องของคุณ
ตั้งค่าเพียงครั้งเดียวหากทุกโปรเจกต์ที่คุณทำงานด้วยใช้ store เดียวกัน OpenSpec จะใช้ค่านี้เป็นตัวสำรองเมื่อไม่พบ flag ไม่พบโฟลเดอร์ openspec/ ในเครื่อง และไม่พบบรรทัด store::
# ใช้ team-plans เมื่อไม่มีสิ่งอื่นระบุชื่อ store
openspec config set defaultStore team-plans
# ยกเลิก
openspec config unset defaultStoreคำสั่งที่ทำงานเฉพาะเครื่อง init, update, templates, schemas และคำสั่งย่อย openspec schema ทำงานกับไดเรกทอรีปัจจุบันเท่านั้นและไม่รับ --store
ย้าย specs และ changes ของ repo ไปยัง store
หากต้องการเปลี่ยน repo จาก repo-local เป็น store-only:
- ย้ายทุกอย่างใน
openspec/specs/และopenspec/changes/ของ repo ไปยังโฟลเดอร์เดียวกันใน store - ลบโฟลเดอร์ที่ว่างแล้ว เพื่อให้โฟลเดอร์
openspec/ของ repo เหลือเพียงconfig.yaml - เพิ่มบรรทัด
store:ลงในconfig.yamlนั้น
openspec status ภายใน repo ตอนนี้จะขึ้นต้นด้วย Using OpenSpec root: team-plans
ทำงานใน store
workflows ไม่เปลี่ยนแปลง ทั้งสำหรับคุณและ agent ของคุณ Propose, apply และ archive ทำงานเหมือนที่เคยทำเสมอ ความแตกต่างเดียวคือตำแหน่งที่ artifacts ถูกสร้าง และหัวข้อด้านบนครอบคลุมเรื่องนั้น
สร้าง change จากภายใน repo แบบ 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 repo ไม่ใช่ข้างโค้ดของคุณ
- การแชร์: change จะมีอยู่เฉพาะใน checkout ของคุณจนกว่าคุณจะ commit และ push store repo สมาชิกในทีมจะเห็นเมื่อพวกเขา pull เช่นเดียวกับ artifacts ทุกชิ้นที่ workflows เขียน
- พาธในเอกสาร: ทุกที่ที่เอกสารแสดงพาธ
openspec/ในการตั้งค่าแบบ store โฟลเดอร์นั้นคือของ store
เมื่อ artifacts ถูกสร้างในที่ที่คุณไม่ได้คาดไว้ openspec doctor จะตรวจสอบการตั้งค่าของคุณโดยไม่เปลี่ยนแปลงสิ่งใด และพิมพ์วิธีแก้สำหรับแต่ละสิ่งที่พบ:
# ตรวจสอบ root ปัจจุบันและ store ของมัน
openspec doctorDoctor
Root
Location: /Users/you/openspec/team-plans
OpenSpec root: ok
Store: team-plans (metadata ok)
References
(none declared)openspec context แสดงรายการ root และ store ที่ไดเรกทอรีปัจจุบันทำงานด้วย เมื่อคุณต้องการภาพเดียวกันโดยไม่มีการตรวจสอบ
หากต้องการเปิด store และ repo ในหน้าต่าง editor เดียว เพื่อให้ agent ของคุณอ่านทั้งสองอย่างได้ ดู Worksets (beta)
อ่านสเปกจาก store อื่น
รีโปของคุณสามารถเก็บโฟลเดอร์ openspec/ ของตัวเองไว้ได้ และยังให้เอเจนต์อ่านสเปกของ store อื่นได้ด้วย ประกาศ store นั้นภายใต้ references: ใน openspec/config.yaml ของรีโป:
# api-server/openspec/config.yaml
references:
- team-plansการอ้างอิงเป็นแบบอ่านอย่างเดียว งานของคุณยังคงอยู่ในรีโปของคุณ และการอ้างอิงมีผลเพียงเปลี่ยนข้อมูลที่บอกกับเอเจนต์ของคุณเท่านั้น
เมื่อเวิร์กโฟลว์สร้างอาร์ติแฟกต์ คำแนะนำของเวิร์กโฟลว์จะมีดัชนีของสเปกใน store ที่อ้างอิง โดยแต่ละรายการมีสรุปหนึ่งบรรทัดและคำสั่งที่แน่นอนสำหรับดึงสเปกนั้น:
<referenced_stores>
<!-- บริบทต้นทางแบบอ่านอย่างเดียว ดึงข้อมูลที่คุณต้องการ แล้วอ้างอิงสิ่งที่คุณใช้ -->
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>การอ้างอิงยังสามารถระบุ URL สำหรับโคลนของ store ได้ สำหรับเครื่องที่ยังไม่มี store นั้น:
references:
- team-plans
- { id: design-system, remote: "git@github.com:acme/design-system.git" }เมื่อประกาศ URL ไว้แล้ว openspec doctor จะเปลี่ยน store ที่หายไปให้เป็นวิธีแก้ไขที่คัดลอกไปวางได้:
# เอาต์พุตขึ้นบรรทัดใหม่เพื่อให้แสดงผลพอดี
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-systemข้อจำกัดของเบต้า
- โครงสร้างอาจเปลี่ยนแปลงได้: ชื่อคำสั่ง แฟล็ก และรูปแบบไฟล์อาจเปลี่ยนได้ระหว่างรีลีส โปรดอ่านหน้านี้อีกครั้งหลังจากอัปเกรด
- ไม่มีการซิงก์โดยการออกแบบ: OpenSpec จะไม่โคลน ดึง หรือพุชเลย เช็กเอาต์ที่ล้าสมัยจะแสดงสเปกที่ล้าสมัยจนกว่าคุณจะดึงข้อมูล และการอ้างอิงจะอ่านจากสิ่งที่อยู่บนดิสก์ ณ ขณะนั้น
- หนึ่งเช็กเอาต์ต่อหนึ่งชื่อ store: การลงทะเบียนโฟลเดอร์ที่สองภายใต้ชื่อที่ลงทะเบียนไว้แล้วจะล้มเหลว พร้อมคำแนะนำให้รัน
openspec store unregisterก่อน