Skip to content

المتاجر (تجريبي) ​

خطط للتغييرات التي تمتد عبر مستودعات متعددة: متجر واحد، عدة مستودعات.

عادة ما يقع 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)

يمكن أن يكون لديك أكثر من متجر، رغم أننا نوصي بإبقاء العدد منخفضاً.

إعداد متجر ​

يقوم شخص واحد بإنشاء المتجر، ثم ينضم إليه الجميع.

  1. إنشاء المتجر (شخص واحد، مرة واحدة لكل فريق). شغّل openspec store setup وأجب على المطالبات:

    bash
    # run from anywhere; it asks what to create and where
    openspec store setup

    يسألك ثلاثة أسئلة:

    • اسم المتجر: team-plans
    • أين يجب أن يقع هذا المتجر؟: معبأ مسبقاً بـ ~/openspec/<name>، اضغط Enter للقبول أو اكتب مساراً آخر
    • إنشاء هذا المتجر؟: يعرض ما سيتم إنشاؤه، أجب بـ Yes

    ثم يُقرر بما أنشأه:

    yaml
    Store 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.
  2. ادفعه إلى مستضيف 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
  3. الانضمام إلى المتجر (كل زميل في الفريق، مرة واحدة لكل جهاز):

    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-plans
    yaml
    Store registered: team-plans
    Location: /Users/you/openspec/team-plans
    OpenSpec root: ready
    Registry: registered

    التسجيل يخبر جهازك بمكان وجود هذا المتجر. اسم المتجر مرتبط بداخله بالفعل، في .openspec-store/store.yaml. الإعداد سجّل نسخة المُنشئ، لذا النسخ المستنسخة فقط تحتاج هذه الخطوة.

  4. تأكد من أنه يعمل، من أي مجلد:

    bash
    # any OpenSpec command reaches the store by name
    openspec status --store team-plans
    yaml
    Using 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 else

OpenSpec في مستودعك وفي متجر (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/ الخاص بمشروعك، أو المتجر. يختار بالترتيب التالي، ويفوز الخيار الأول الذي ينطبق:

  1. --store <id> على أمر. يفوز دائماً، من أي مجلد.
  2. مجلد openspec/ الخاص بمشروعك. إذا كان لدى مشروعك مجلدات specs/ أو changes/ خاصة به، يستخدمها OpenSpec.
  3. سطر store: في مشروعك. كيف يسجل مشروع store-only متجره.
  4. defaultStore على جهازك. البديل عندما لا ينطبق أي مما سبق.

إذا لم ينطبق أي من هذه الخيارات ولديك متاجر مسجلة، يفشل الأمر ويسردها. عندما يتطابق معرّف متجر مع اسم مستودعك في ريموت origin الخاص به، يذكر الخطأ ذلك المتجر وسطر store: الذي يختاره. لا يختار OpenSpec متجراً بالاسم من تلقاء نفسه أبداً، لأن المستودعات في مؤسسات مختلفة يمكن أن تشترك في الاسم.

عندما يختار OpenSpec متجراً، يطبع Using OpenSpec root: ... قبل مخرجات الأمر.

سطر store: (مشاريع store-only) ​

أضف سطراً واحداً إلى openspec/config.yaml الخاص بمشروعك:

yaml
# web-app/openspec/config.yaml
store: team-plans

كل ما تشغّله أنت أو الوكيل الخاص بك داخل مشروعك يستخدم الآن المتجر، دون أي علامة للكتابة:

bash
# inside web-app, connected
openspec status
yaml
Using 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 من جذر مستودع الكود لتثبيت ملفات تكامل أدوات الذكاء الاصطناعي دون نقل التخطيط مرة أخرى إلى ذلك المستودع:

bash
# 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::

bash
# 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:

  1. انقل كل شيء في openspec/specs/ و openspec/changes/ الخاصة بالمستودع إلى المجلدات نفسها في المتجر.
  2. احذف المجلدات الفارغة الآن، بحيث لا يحتفظ مجلد openspec/ الخاص بالمستودع إلا بـ config.yaml.
  3. أضف سطر store: إلى ذلك config.yaml.

openspec status داخل المستودع يبدأ الآن بـ Using OpenSpec root: team-plans.

العمل في المتجر ​

لا تتغير سير العمل، لك أو للوكيل الخاص بك. الاقتراح والتطبيق والأرشفة تعمل كما تفعل دائماً. الفرق الوحيد هو مكان إنشاء المصنوعات، والقسم أعلاه يغطي ذلك.

أنشئ تغييراً من داخل مستودع store-only وسيهبط في المتجر:

bash
# inside web-app; the store: line routes this to team-plans
openspec new change add-login
yaml
Using 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 إعدادك دون تغيير أي شيء ويطبع حلاً لكل اكتشاف:

bash
# check the current root and its stores
openspec doctor
yaml
Doctor

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 الخاص بالمستودع:

yaml
# api-server/openspec/config.yaml
references:
  - team-plans

المراجع للقراءة فقط. يبقى عملك في مستودعك، ولا يغيّر المرجع إلا ما يُقال لوكيلك.

عندما تنشئ مهمة ما مصنّفًا، تُضاف إلى تعليماتها فهرسة بمواصفات المخزن المشار إليه، كل منها مع ملخص من سطر واحد والأمر الدقيق لجلبه:

xml
<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) للمخزن، للأجهزة التي لا تحتوي على هذا المخزن بعد:

yaml
references:
  - team-plans
  - { id: design-system, remote: "git@github.com:acme/design-system.git" }

مع الإعلان عن العنوان، يحوّل الأمر openspec doctor المخزن المفقود إلى حل قابل للصق:

yaml
# 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 أولاً.