المتاجر (تجريبي)
خطط للتغييرات التي تمتد عبر مستودعات متعددة: متجر واحد، عدة مستودعات.
عادة ما يقع 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 على فروع و pull requests بنفس الطريقة التي يحصل بها الكود عليها.
متى تحتاج إلى متجر
سببان شائعان لاستخدام متجر:
الواجهة الأمامية والخلفية في مستودعات منفصلة: ميزة واحدة تمسّ كليهما، وتحتاج الخطة إلى موطن واحد بدلاً من نصفين.
shop-plans (store) └── openspec/changes/add-discounts/ one plan for the feature ▲ ┌─────────┴─────────┐ │ │ storefront api (frontend repo) (backend repo)منتج واحد، عدة مستودعات عميل: يُصدر أندرويد و iOS والويب من مستودعاتهم الخاصة لكنهم يشتركون في سلوك متوقع واحد. يصف 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)
يمكن أن يكون لديك أكثر من متجر، رغم أننا نوصي بإبقاء العدد منخفضاً.
إعداد متجر
يقوم شخص واحد بإنشاء المتجر، ثم ينضم إليه الجميع.
إنشاء المتجر (شخص واحد، مرة واحدة لكل فريق). شغّل
openspec store setupوأجب على المطالبات:bash# run from anywhere; it asks what to create and where openspec store setupيسألك ثلاثة أسئلة:
- اسم المتجر:
team-plans - أين يجب أن يقع هذا المتجر؟: معبأ مسبقاً بـ
~/openspec/<name>، اضغط Enter للقبول أو اكتب مساراً آخر - إنشاء هذا المتجر؟: يعرض ما سيتم إنشاؤه، أجب بـ
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.- اسم المتجر:
ادفعه إلى مستضيف git الخاص بك. أنشئ مستودعاً فارغاً باسم
team-plansعلى مستضيفك أولاً. الإعداد لا يضيف ريموت git، لذا اربط المتجر بذلك المستودع، ثم ادفع:bash# connect the store to the empty repo on your git host cd ~/openspec/team-plans git remote add origin git@github.com:acme/team-plans.git # publish it git push -u origin mainالانضمام إلى المتجر (كل زميل في الفريق، مرة واحدة لكل جهاز):
bash# get the store onto your machine git clone git@github.com:acme/team-plans.git ~/openspec/team-plans # tell OpenSpec where it lives openspec store register ~/openspec/team-plansyamlStore registered: team-plans Location: /Users/you/openspec/team-plans OpenSpec root: ready Registry: registeredالتسجيل يخبر جهازك بمكان وجود هذا المتجر. اسم المتجر مرتبط بداخله بالفعل، في
.openspec-store/store.yaml. الإعداد سجّل نسخة المُنشئ، لذا النسخ المستنسخة فقط تحتاج هذه الخطوة.تأكد من أنه يعمل، من أي مجلد:
bash# any OpenSpec command reaches the store by name 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-only: مستودعك لا يحتفظ بأي specs أو changes خاصة به. كل شيء يقع في المتجر.
- store-optional: مشروعك لديه مجلد
openspec/خاص به ويصل أيضاً إلى متجر عندما تطلب ذلك.
الافتراضي: OpenSpec داخل مستودعك (repo-local)
يضع openspec init مجلد openspec/ بجانب الكود الخاص بك، وتعيش specs و changes الخاصة بهذا المستودع هناك. لا يوجد متجر معني. هذا هو الإعداد الذي يعلمه إعداد مشروعك، ومعظم المشاريع لا تحتاج إلى غيره.
web-app (code repo)
└── openspec/
├── specs/
└── changes/OpenSpec خارج مستودعك، في متجر (store-only)
المستودع لا يحتفظ بأي specs أو changes خاصة به. كل ما يخطط له يقع في المتجر، وسطر واحد في إعدادات المستودع يربط بينهما.
شائع عندما يقوم فريق واحد ببناء جميع المستودعات والتخطيط في مكان واحد. الأمثلة أعلاه كلها تحمل هذا الشكل.
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-optional)
يبقى المستودع repo-local لأعماله الخاصة، بينما يحتفظ المتجر بالـ specs و changes المشتركة. داخل المستودع، يستخدم OpenSpec مجلد openspec/ الخاص بمشروعك، ويصل إلى المتجر فقط عندما تمرر --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 وينقل specs و changes الخاصة به إلى المتجر لاحقاً. نقل specs و changes مستودع إلى المتجر يوضح كيفية ذلك.
أين تُنشأ المصنوعات عند استخدام المتاجر
عند استخدام متجر، يجب على OpenSpec أيضاً تحديد مكان إنشاء المصنوعات. يعتمد ذلك على إعدادك:
- store-only (مشروعك يكتب فقط إلى المتجر): كل مصنوعة تُنشأ في المتجر. سطر
store:أدناه يسجل ذلك. - store-optional (مشروعك لديه مجلد
openspec/خاص به ويستخدم متجراً أيضاً): تُنشأ المصنوعات في مشروعك، ما لم تذكر اسم المتجر في طلبك أو تمرر--storeلذلك التغيير. عندئذٍ يحمل الوكيل الخاص بك العلامة عبر بقية سير العمل.
يكتب OpenSpec المصنوعات في مكانين اثنين: مجلد openspec/ الخاص بمشروعك، أو المتجر. يختار بالترتيب التالي، ويفوز الخيار الأول الذي ينطبق:
--store <id>على أمر. يفوز دائماً، من أي مجلد.- مجلد
openspec/الخاص بمشروعك. إذا كان لدى مشروعك مجلداتspecs/أوchanges/خاصة به، يستخدمها OpenSpec. - سطر
store:في مشروعك. كيف يسجل مشروع store-only متجره. defaultStoreعلى جهازك. البديل عندما لا ينطبق أي مما سبق.
إذا لم ينطبق أي من هذه الخيارات ولديك متاجر مسجلة، يفشل الأمر ويسردها. عندما يتطابق معرّف متجر مع اسم مستودعك في ريموت origin الخاص به، يذكر الخطأ ذلك المتجر وسطر store: الذي يختاره. لا يختار OpenSpec متجراً بالاسم من تلقاء نفسه أبداً، لأن المستودعات في مؤسسات مختلفة يمكن أن تشترك في الاسم.
عندما يختار OpenSpec متجراً، يطبع Using OpenSpec root: ... قبل مخرجات الأمر.
سطر store: (مشاريع store-only)
أضف سطراً واحداً إلى openspec/config.yaml الخاص بمشروعك:
# web-app/openspec/config.yaml
store: team-plansكل ما تشغّله أنت أو الوكيل الخاص بك داخل مشروعك يستخدم الآن المتجر، دون أي علامة للكتابة:
# inside web-app, connected
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 مع خطأ يسرد متاجرك المسجلة.
- اربطه: الزملاء الذين يستنسخون مشروعك يحصلون على السطر أيضاً. ما زالوا بحاجة إلى تسجيل المتجر على أجهزتهم (الخطوة 3 من إعداد متجر)، وإلا يُخطئ OpenSpec ويطلب منهم تسجيله.
- بجانب المجلدات الحقيقية: إذا كان لدى مشروعك أيضاً مجلدات
specs/أوchanges/، يستخدمها OpenSpec ويتجاهل السطر، مع تحذير.
تثبيت التكاملات في مستودع store-only
شغّل init من جذر مستودع الكود لتثبيت ملفات تكامل أدوات الذكاء الاصطناعي دون نقل التخطيط مرة أخرى إلى ذلك المستودع:
# inside web-app, at the repository root
openspec init --tools claude- ملفات التكامل: تُكتب في مستودع الكود.
openspec/config.yaml: يُحفظ حرفياً، بما في ذلك سطرstore:.openspec/specs/وopenspec/changes/: لا تُنشأ في مستودع الكود.
يرفض OpenSpec هذا الأمر من مجلد فرعي لمستودع الكود. شغّله من جذر المستودع.
يرفض OpenSpec أيضاً --language هنا لأن اللغة تنتمي إلى إعدادات المتجر الخارجي. شغّل init في جذر المتجر أو عدّل تلك الإعدادات مباشرة.
defaultStore على جهازك
عيّنه مرة واحدة إذا كان كل مشروع تعمل عليه يستخدم نفس المتجر. يعود OpenSpec إليه عندما لا يجد علامة، ولا مجلد openspec/ محلي، ولا سطر store::
# use team-plans whenever nothing else names a store
openspec config set defaultStore team-plans
# undo it
openspec config unset defaultStoreالأوامر التي تبقى محلية. init و update و templates و schemas والأوامر الفرعية openspec schema تعمل على المجلد الحالي فقط ولا تقبل --store.
نقل specs و changes مستودع إلى المتجر
لنقل مستودع من repo-local إلى store-only:
- انقل كل شيء في
openspec/specs/وopenspec/changes/الخاصة بالمستودع إلى المجلدات نفسها في المتجر. - احذف المجلدات الفارغة الآن، بحيث لا يحتفظ مجلد
openspec/الخاص بالمستودع إلا بـconfig.yaml. - أضف سطر
store:إلى ذلكconfig.yaml.
openspec status داخل المستودع يبدأ الآن بـ Using OpenSpec root: team-plans.
العمل في المتجر
لا تتغير سير العمل، لك أو للوكيل الخاص بك. الاقتراح والتطبيق والأرشفة تعمل كما تفعل دائماً. الفرق الوحيد هو مكان إنشاء المصنوعات، والقسم أعلاه يغطي ذلك.
أنشئ تغييراً من داخل مستودع store-only وسيهبط في المتجر:
# inside web-app; the store: line routes this to 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- أين ذهب: في مستودع المتجر، وليس بجانب الكود الخاص بك.
- مشاركته: التغيير موجود فقط في نسختك حتى تربط وتدفع مستودع المتجر. يراه الزملاء عندما يسحبون. ينطبق الشيء نفسه على كل مصنوعة تكتبها سير العمل.
- المسارات في الوثائق: في كل مكان تعرض فيه الوثائق مسار
openspec/، في إعداد المتجر يكون هذا المجلد هو المتجر.
عندما تُنشأ المصنوعات في مكان لم تتوقعه، يفحص openspec doctor إعدادك دون تغيير أي شيء ويطبع حلاً لكل اكتشاف:
# check the current root and its stores
openspec doctorDoctor
Root
Location: /Users/you/openspec/team-plans
OpenSpec root: ok
Store: team-plans (metadata ok)
References
(none declared)يسرد openspec context الجذر والمتاجر التي يعمل معها مجلدك الحالي، عندما تريد الصورة نفسها بدون الفحوصات.
لفتح المتجر ومستودع في نافذة محرر واحدة، حتى يتمكن الوكيل الخاص بك من قراءة كليهما، راجع مجموعات العمل (تجريبي).
قراءة المواصفات من مخزن آخر
يمكن لمستودعك الاحتفاظ بمجلد openspec/ خاص به مع إتاحة قراءة الوكيل لمواصفات مخزن آخر. قم بالإعلان عن ذلك المخزن تحت references: في ملف openspec/config.yaml الخاص بالمستودع:
# api-server/openspec/config.yaml
references:
- team-plansالمراجع للقراءة فقط. يبقى عملك في مستودعك، ولا يغيّر المرجع إلا ما يُقال لوكيلك.
عندما تنشئ مهمة ما مصنّفًا، تُضاف إلى تعليماتها فهرسة بمواصفات المخزن المشار إليه، كل منها مع ملخص من سطر واحد والأمر الدقيق لجلبه:
<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>يمكن للمرجع أيضًا أن يحمل عنوان الاستنساخ (clone URL) للمخزن، للأجهزة التي لا تحتوي على هذا المخزن بعد:
references:
- team-plans
- { id: design-system, remote: "git@github.com:acme/design-system.git" }مع الإعلان عن العنوان، يحوّل الأمر openspec doctor المخزن المفقود إلى حل قابل للصق:
# 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-systemقيود النسخة التجريبية
- قد يتغير الشكل: يمكن أن تتغير أسماء الأوامر والخيارات وصيغ الملفات بين الإصدارات. أعد قراءة هذه الصفحة بعد الترقية.
- لا مزامنة، بحكم التصميم: OpenSpec لا يستنسخ أو يسحب أو يدفع أبدًا. يظهر الخروج القديم (stale checkout) مواصفات قديمة حتى تقوم بالسحب، وتُقرأ المراجع من أي محتوى موجود على القرص.
- استنساخ واحد لكل اسم مخزن: تسجيل مجلد ثانٍ باسم مسجّل مسبقًا يفشل، مع تلميح لتشغيل
openspec store unregisterأولاً.