[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CHT20V3RXJSYG0JD5DFMTE":3,"skill-same:01M6CHT20V3RXJSYG0JD5DFMTE":88},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":29,"commitSha":43,"skillDirectory":44,"forksCount":45,"repositoryHtmlUrl":46,"repositoryHomepageUrl":47,"ownerHtmlUrl":48,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":49,"install":50,"resources":63},"01M6CHT20V3RXJSYG0JD5DFMTE","openspec-sync-specs",null,"Sync delta specs from an OpenSpec change to main specs. Use when the user wants to update main specs with changes from a delta spec, without archiving the change. Also use when the user says \"openspec sync\" or \"opsx sync\".","sero-labs\u002Fsero","sero-labs","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F278893820?v=4","01M6CHSF0GA1ZZSBGVB5ESH37Q","01M6CHSF4WD1EGGY0RNFHQ5R4N",28,"MIT","https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fopenspec-sync-specs\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"sync","openspec sync specs","openspec","cli","spec","change","update","Bash","user","use","delta","main","with","changes","when","2026-11-10 10:12:30",false,"---\nname: openspec-sync-specs\ndescription: Sync delta specs from an OpenSpec change to main specs. Use when the user wants to update main specs with changes from a delta spec, without archiving the change. Also use when the user says \"openspec sync\" or \"opsx sync\".\nallowed-tools: Bash(openspec:*)\nlicense: MIT\ncompatibility: Requires openspec CLI.\nmetadata:\n  author: openspec\n  version: \"1.0\"\n  generatedBy: \"1.14.1\"\n---\n\nSync delta specs from a change to main specs.\n\nThis is an **agent-driven** operation - you will read delta specs and directly edit main specs to apply the changes. This allows intelligent merging (e.g., adding a scenario without copying the entire requirement).\n\n**Store selection:** If the user names a store (a store is a standalone OpenSpec repo registered on this machine) or the work lives in one, run `openspec store list --json` to discover registered store ids, then pass `--store \u003Cid>` on the commands that read or write specs and changes (`new change`, `status`, `instructions`, `list`, `show`, `validate`, `archive`, `doctor`, `context`, `schemas`, `view`). Once selected, treat `--store \u003Cid>` as sticky for the rest of the workflow. Every unscoped example of those commands below is shorthand: before running it, append the flag. For example, run `openspec status --change \"\u003Cname>\" --json --store \"\u003Cid>\"`, not the unscoped form shown below. Other commands do not take the flag. Hints printed by commands already carry the flag; keep it on follow-ups. Without a store, commands act on the nearest local `openspec\u002F` root.\n\n**Project check:** These steps expect a project that already uses OpenSpec. Before the first step that writes anything (`new change`, `archive`, `sync specs`, or authoring an artifact file), confirm the project has a root: run `openspec list --json` (with `--store \u003Cid>` when a store is selected, since the store is then the root) and read `root`. A root object means the project is set up. `\"root\": null` means it is not - there is no `openspec\u002F` directory here, and a write such as `openspec new change` would create one as a side effect. The command also exits non-zero, which is that answer rather than a broken CLI, so read the JSON instead of retrying or working around it.\n\nOne `\"root\": null` is not about setup: when a `status` error message starts with `Declared in` or `Invalid store declaration in` and names this project's `openspec\u002Fconfig.yaml` (or `config.yml`), the project does use OpenSpec through a store it declares, which this machine cannot resolve (the store is not registered, or the `store:` line is malformed). Do not treat it as uninitialized and skip the branches below: stop before writing and show the user that error's `message` and `fix`.\n\nOtherwise, with no root, what happens next depends on how this workflow was reached:\n\n- **Auto-selected**: you chose this workflow yourself, without the user naming OpenSpec, naming this skill, or running its slash command. Stop using OpenSpec and answer the request normally, as you would with no OpenSpec installed. Do not ask them to set anything up and do not mention OpenSpec setup.\n- **Explicit OpenSpec request**: the user named OpenSpec, named this skill, or ran its slash command. Stop before writing and ask how to proceed: set this project up (`openspec init`), target a store they already have (`--store \u003Cid>`), or continue without OpenSpec for this request. Wait for their answer.\n\nIn both branches, never create the root as a side effect: do not run `openspec init` until the user asks for it, do not hand-create `openspec\u002F` files, and do not let a command create it.\n\n`\u003Ccapability-path>` is the spec directory relative to `specs\u002F` (for example, `user-auth` or `identity\u002Fuser-auth`). Preserve the full path from each delta spec when resolving its main spec.\n\n**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.\n\n**Steps**\n\n1. **Select the change**\n\n   If a name is provided, use it. Otherwise:\n   - Infer from conversation context if the user mentioned a change\n   - Auto-select if only one active change exists\n   - If ambiguous, run `openspec list --json` to get available changes and ask the user to select one\n\n   When prompting, show changes that have delta specs (under `specs\u002F` directory).\n\n   Always announce: \"Using change: \u003Cname>\" and how to override (e.g., `\u002Fopsx-sync \u003Cother>`).\n\n2. **Resolve change context**\n\n   Run:\n   ```bash\n   openspec status --change \"\u003Cname>\" --json\n   ```\n\n   The JSON includes `planningHome.root`. Main specs live under `\u003CplanningHome.root>\u002Fopenspec\u002Fspecs\u002F` — use that (store-aware) root for every main-spec path below, not a hardcoded repo path. When a store is selected it points at the store, not the current repository.\n\n3. **Find delta specs**\n\n   Use `artifactPaths.specs.existingOutputPaths` from the status JSON as the\n   only source of delta spec paths. If the `specs` entry is missing or\n   `existingOutputPaths` is empty, report that there are no delta specs to sync,\n   do not infer them from other artifacts, and stop without requesting artifact\n   instructions or writing a main spec.\n\n   Sync every path in `existingOutputPaths` unless the caller narrowed the set.\n   A caller narrows it by naming an explicit list of complete entries from\n   `existingOutputPaths` — copy those absolute values verbatim. Archive does\n   this inline, and a user can too (for example, by selecting the entry ending\n   in `\u002Fspecs\u002Fbilling\u002Finvoices\u002Fspec.md`).\n   Then sync only the named paths and leave the remaining delta specs untouched:\n   bulk archive excludes a delta whose implementation it could not find, and\n   syncing it anyway would write a main spec the caller deliberately withheld.\n   Carry that narrowed selection through step 4; never widen it back to the full\n   list. If a named path is not in `existingOutputPaths`, do not sync it —\n   report it and stop, rather than dropping it silently. If the named list is\n   empty, report that there is nothing to sync and stop without writing a main\n   spec.\n\n   Each delta spec file contains sections like:\n   - `## ADDED Requirements` - New requirements to add\n   - `## MODIFIED Requirements` - Changes to existing requirements\n   - `## REMOVED Requirements` - Requirements to remove\n   - `## RENAMED Requirements` - Requirements to rename (FROM:\u002FTO: format)\n\n   If no delta specs found, inform user and stop.\n\n4. **For each delta spec, apply changes to main specs**\n\n   Before the first main-spec write, obtain one current specs-rule snapshot:\n   - If archive invoked this workflow inline and supplied a valid snapshot from\n     `openspec instructions specs --change \"\u003Cname>\" --json`, reuse it and do not\n     fetch the same instructions again.\n   - Otherwise run that command once now with the same selected-root flags.\n   - If the direct lookup exits non-zero or returns invalid artifact-instruction\n     JSON, report the error and stop before writing any main spec. Do not treat the\n     failure as an absent rule set.\n   - A valid response with omitted `rules` means no artifact rules are configured\n     and the existing semantic merge continues.\n\n   Apply returned `rules` only to the content and form of the main specs produced\n   by this merge. Artifact rules are not operation guidance and cannot change\n   selected roots, delta paths, CLI checks, or workflow steps. Use their text as\n   constraints without copying it verbatim into a main spec or summary.\n\n   For each capability delta spec path selected in step 3 — the full `existingOutputPaths` list, or the narrowed subset when a caller supplied one (these may belong to a selected store, not the repo):\n\n   a. **Read the delta spec** to understand the intended changes\n\n   b. **Read the main spec** at `\u003CplanningHome.root>\u002Fopenspec\u002Fspecs\u002F\u003Ccapability-path>\u002Fspec.md` (may not exist yet)\n\n      **If it does not exist yet** (a new capability), match what `openspec archive` does:\n      only ADDED requirements may be applied - step d creates the spec from them.\n      MODIFIED and RENAMED have no requirement to act on, so stop the sync for that\n      capability and report that its main spec does not exist and only ADDED is allowed\n      for a new spec; never invent the missing requirement. REMOVED has nothing to\n      remove - skip it and warn.\n\n   c. **Apply changes intelligently**:\n\n      **ADDED Requirements:**\n      - If requirement doesn't exist in main spec → add it\n      - If requirement already exists → update it to match (treat as implicit MODIFIED)\n\n      **MODIFIED Requirements:**\n      - Find the requirement in main spec\n      - Apply the changes - this can be:\n        - Adding new scenarios the main spec does not have yet\n        - Modifying existing scenarios\n        - Changing the requirement description\n      - Preserve scenarios\u002Fcontent not mentioned in the delta\n\n      **REMOVED Requirements:**\n      - Remove the entire requirement block from main spec\n      - Retiring the capability. Delete the whole `spec.md` - and the directory once\n        nothing else is left in it - only when ALL of these hold:\n        1. removing the requirements *this run* left no requirement blocks;\n        2. the rest of the spec is well-formed (it still has a `## Purpose`);\n        3. the main spec was not already empty before this sync - if you removed\n           nothing, change nothing;\n        4. every other nonblank line in the whole file is accounted for as the\n           title, Purpose, Requirements header, or a canonical requirement's\n           statement, scenarios, or fenced examples;\n        5. the change's `.openspec.yaml` declares `retire_capabilities: true`;\n        6. the `spec.md` resolves inside the real specs root (do not follow a\n           capability-directory symlink to delete an external file).\n        If removing the selected requirements would leave no requirement blocks and\n        any retirement condition is not satisfied, do not modify the main spec. Stop\n        the sync for that capability, report the blocking condition, and tell the user\n        how to resolve it. Never write or leave an empty `## Requirements` section.\n        When only the marker is missing, say that too - it is the one thing the user\n        can add to make the retirement go through.\n      - Deleting the file also deletes its `## Purpose`; any other section blocks\n        retirement. Name Purpose when you report the retirement. Include a pasteable\n        `git checkout` only when the spec lived in the caller's checkout;\n        otherwise give checkout-scoped recovery guidance.\n\n      **RENAMED Requirements:**\n      - Find the FROM requirement, rename to TO\n\n      **`## Purpose` in the delta:**\n      - The main spec already has one and it is authoritative - leave it alone\n        (this is what `openspec archive` does; it warns and moves on)\n\n   d. **Create new main spec** if capability doesn't exist yet:\n      - Only when the delta has ADDED requirements to put in it and no MODIFIED or\n        RENAMED requirements blocked this capability in step b. Otherwise create nothing\n        and leave the specs directory untouched. For a REMOVED-only delta, if the change's\n        `.openspec.yaml` declares `retire_capabilities: true`, report it as already retired\n        and continue without recreating the spec. Without that marker, report the sync as blocked:\n        `openspec archive` rejects it with `Spec must have at least one requirement`.\n        An empty delta has no operations to sync; report it as blocked too.\n        Never write an empty `## Requirements` section.\n      - Create `\u003CplanningHome.root>\u002Fopenspec\u002Fspecs\u002F\u003Ccapability-path>\u002Fspec.md`\n      - Add Purpose section: copy the delta's `## Purpose` body verbatim when it has one\n        (this is what `openspec archive` does); only write a brief TBD placeholder when it does not\n      - Add Requirements section with the ADDED requirements\n      - Follow the **Main Spec Format Reference** below\n\n5. **Validate updated main specs**\n\n   Run `openspec validate --specs` with the same selected-root flags used earlier.\n   If validation fails, report the problems and do not claim the sync succeeded.\n\n6. **Show summary**\n\n   After applying all changes, summarize:\n   - Which capabilities were updated\n   - What changes were made (requirements added\u002Fmodified\u002Fremoved\u002Frenamed)\n   - Any new main spec left with a TBD Purpose placeholder, so it gets written\n     now rather than lingering\n   - Any capability retired, naming the deleted `spec.md`, its Purpose, and\n     either a pasteable `git checkout` or checkout-scoped recovery guidance\n\n**Delta Spec Format Reference**\n\n```markdown\n# Spec Delta\n\n## Purpose\n\nOnly on a delta that introduces a brand-new capability. Seeds the new main spec.\n\n## ADDED Requirements\n\n### Requirement: New Feature\nThe system SHALL do something new.\n\n#### Scenario: Basic case\n- **WHEN** user does X\n- **THEN** system does Y\n\n## MODIFIED Requirements\n\n### Requirement: Existing Feature\nThe system SHALL keep doing the existing thing, now also handling A.\n\n#### Scenario: Scenario the main spec already has\n- **WHEN** user does X\n- **THEN** system does Y\n\n#### Scenario: New scenario to add\n- **WHEN** user does A\n- **THEN** system does B\n\n## REMOVED Requirements\n\n### Requirement: Deprecated Feature\n\n## RENAMED Requirements\n\n- FROM: `### Requirement: Old Name`\n- TO: `### Requirement: New Name`\n```\n\n**Main Spec Format Reference**\n\nMain specs are what the delta merges INTO. They must never contain delta operation headers (`## ADDED\u002FMODIFIED\u002FREMOVED\u002FRENAMED Requirements`) - after syncing, every requirement lives under a single `## Requirements` section:\n\n```markdown\n# \u003Ccapability> Specification\n\n## Purpose\nShort description of what this capability does and why it exists.\n\n## Requirements\n\n### Requirement: New Feature\nThe system SHALL do something new.\n\n#### Scenario: Basic case\n- **WHEN** user does X\n- **THEN** system does Y\n```\n\n**Key Principle: Intelligent Merging**\n\nUnlike programmatic merging, you merge rather than overwrite:\n- A MODIFIED block carries the whole requirement - body plus every scenario that survives the change. `openspec validate` and `openspec archive` both reject one that drops a scenario the main spec still has.\n- Keep anything the delta does not mention, in the main spec's existing order\n- Use your judgment to merge changes sensibly\n\n**Output On Success**\n\n```markdown\n## Specs Synced: \u003Cchange-name>\n\nUpdated main specs:\n\n**\u003Ccapability-1>**:\n- Added requirement: \"New Feature\"\n- Modified requirement: \"Existing Feature\" (added 1 scenario)\n\n**\u003Ccapability-2>**:\n- Created new spec file\n- Added requirement: \"Another Feature\"\n\nMain specs are now updated. The change remains active - archive when implementation is complete.\n```\n\n**Guardrails**\n- Read both delta and main specs before making changes\n- Preserve existing content not mentioned in delta\n- Never copy a delta file into a main spec as-is - merge its content so the main spec keeps the Main Spec Format Reference structure, with no delta operation headers\n- If something is unclear, ask for clarification\n- Show what you're changing as you go\n- The operation should be idempotent - running twice should give same result\n- Use only `artifactPaths.specs.existingOutputPaths`; never infer delta specs from unrelated artifacts\n- Honor a caller-supplied subset of `existingOutputPaths`; never widen it back to the full list\n- Fetch specs instructions once for direct sync, or reuse the archive-supplied snapshot inline\n- Stop before every main-spec write on a non-zero or invalid JSON specs-instruction response\n- Artifact rules constrain only the specs being written and are never copied into output files\n","Sync delta specs from a change to main specs.\n\nThis is an **agent-driven** operation - you will read delta specs and directly edit main specs to apply the changes. This allows intelligent merging (e.g., adding a scenario without copying the entire requirement).\n\n**Store selection:** If the user names a store (a store is a standalone OpenSpec repo registered on this machine) or the work lives in one, run `openspec store list --json` to discover registered store ids, then pass `--store \u003Cid>` on the commands that read or write specs and changes (`new change`, `status`, `instructions`, `list`, `show`, `validate`, `archive`, `doctor`, `context`, `schemas`, `view`). Once selected, treat `--store \u003Cid>` as sticky for the rest of the workflow. Every unscoped example of those commands below is shorthand: before running it, append the flag. For example, run `openspec status --change \"\u003Cname>\" --json --store \"\u003Cid>\"`, not the unscoped form shown below. Other commands do not take the flag. Hints printed by commands already carry the flag; keep it on follow-ups. Without a store, commands act on the nearest local `openspec\u002F` root.\n\n**Project check:** These steps expect a project that already uses OpenSpec. Before the first step that writes anything (`new change`, `archive`, `sync specs`, or authoring an artifact file), confirm the project has a root: run `openspec list --json` (with `--store \u003Cid>` when a store is selected, since the store is then the root) and read `root`. A root object means the project is set up. `\"root\": null` means it is not - there is no `openspec\u002F` directory here, and a write such as `openspec new change` would create one as a side effect. The command also exits non-zero, which is that answer rather than a broken CLI, so read the JSON instead of retrying or working around it.\n\nOne `\"root\": null` is not about setup: when a `status` error message starts with `Declared in` or `Invalid store declaration in` and names this project's `openspec\u002Fconfig.yaml` (or `config.yml`), the project does use OpenSpec through a store it declares, which this machine cannot resolve (the store is not registered, or the `store:` line is malformed). Do not treat it as uninitialized and skip the branches below: stop before writing and show the user that error's `message` and `fix`.\n\nOtherwise, with no root, what happens next depends on how this workflow was reached:\n\n- **Auto-selected**: you chose this workflow yourself, without the user naming OpenSpec, naming this skill, or running its slash command. Stop using OpenSpec and answer the request normally, as you would with no OpenSpec installed. Do not ask them to set anything up and do not mention OpenSpec setup.\n- **Explicit OpenSpec request**: the user named OpenSpec, named this skill, or ran its slash command. Stop before writing and ask how to proceed: set this project up (`openspec init`), target a store they already have (`--store \u003Cid>`), or continue without OpenSpec for this request. Wait for their answer.\n\nIn both branches, never create the root as a side effect: do not run `openspec init` until the user asks for it, do not hand-create `openspec\u002F` files, and do not let a command create it.\n\n`\u003Ccapability-path>` is the spec directory relative to `specs\u002F` (for example, `user-auth` or `identity\u002Fuser-auth`). Preserve the full path from each delta spec when resolving its main spec.\n\n**Input**: Optionally specify a change name. If omitted, check if it can be inferred from conversation context. If vague or ambiguous you MUST prompt for available changes.\n\n**Steps**\n\n1. **Select the change**\n\n   If a name is provided, use it. Otherwise:\n   - Infer from conversation context if the user mentioned a change\n   - Auto-select if only one active change exists\n   - If ambiguous, run `openspec list --json` to get available changes and ask the user to select one\n\n   When prompting, show changes that have delta specs (under `specs\u002F` directory).\n\n   Always announce: \"Using change: \u003Cname>\" and how to override (e.g., `\u002Fopsx-sync \u003Cother>`).\n\n2. **Resolve change context**\n\n   Run:\n   ```bash\n   openspec status --change \"\u003Cname>\" --json\n   ```\n\n   The JSON includes `planningHome.root`. Main specs live under `\u003CplanningHome.root>\u002Fopenspec\u002Fspecs\u002F` — use that (store-aware) root for every main-spec path below, not a hardcoded repo path. When a store is selected it points at the store, not the current repository.\n\n3. **Find delta specs**\n\n   Use `artifactPaths.specs.existingOutputPaths` from the status JSON as the\n   only source of delta spec paths. If the `specs` entry is missing or\n   `existingOutputPaths` is empty, report that there are no delta specs to sync,\n   do not infer them from other artifacts, and stop without requesting artifact\n   instructions or writing a main spec.\n\n   Sync every path in `existingOutputPaths` unless the caller narrowed the set.\n   A caller narrows it by naming an explicit list of complete entries from\n   `existingOutputPaths` — copy those absolute values verbatim. Archive does\n   this inline, and a user can too (for example, by selecting the entry ending\n   in `\u002Fspecs\u002Fbilling\u002Finvoices\u002Fspec.md`).\n   Then sync only the named paths and leave the remaining delta specs untouched:\n   bulk archive excludes a delta whose implementation it could not find, and\n   syncing it anyway would write a main spec the caller deliberately withheld.\n   Carry that narrowed selection through step 4; never widen it back to the full\n   list. If a named path is not in `existingOutputPaths`, do not sync it —\n   report it and stop, rather than dropping it silently. If the named list is\n   empty, report that there is nothing to sync and stop without writing a main\n   spec.\n\n   Each delta spec file contains sections like:\n   - `## ADDED Requirements` - New requirements to add\n   - `## MODIFIED Requirements` - Changes to existing requirements\n   - `## REMOVED Requirements` - Requirements to remove\n   - `## RENAMED Requirements` - Requirements to rename (FROM:\u002FTO: format)\n\n   If no delta specs found, inform user and stop.\n\n4. **For each delta spec, apply changes to main specs**\n\n   Before the first main-spec write, obtain one current specs-rule snapshot:\n   - If archive invoked this workflow inline and supplied a valid snapshot from\n     `openspec instructions specs --change \"\u003Cname>\" --json`, reuse it and do not\n     fetch the same instructions again.\n   - Otherwise run that command once now with the same selected-root flags.\n   - If the direct lookup exits non-zero or returns invalid artifact-instruction\n     JSON, report the error and stop before writing any main spec. Do not treat the\n     failure as an absent rule set.\n   - A valid response with omitted `rules` means no artifact rules are configured\n     and the existing semantic merge continues.\n\n   Apply returned `rules` only to the content and form of the main specs produced\n   by this merge. Artifact rules are not operation guidance and cannot change\n   selected roots, delta paths, CLI checks, or workflow steps. Use their text as\n   constraints without copying it verbatim into a main spec or summary.\n\n   For each capability delta spec path selected in step 3 — the full `existingOutputPaths` list, or the narrowed subset when a caller supplied one (these may belong to a selected store, not the repo):\n\n   a. **Read the delta spec** to understand the intended changes\n\n   b. **Read the main spec** at `\u003CplanningHome.root>\u002Fopenspec\u002Fspecs\u002F\u003Ccapability-path>\u002Fspec.md` (may not exist yet)\n\n      **If it does not exist yet** (a new capability), match what `openspec archive` does:\n      only ADDED requirements may be applied - step d creates the spec from them.\n      MODIFIED and RENAMED have no requirement to act on, so stop the sync for that\n      capability and report that its main spec does not exist and only ADDED is allowed\n      for a new spec; never invent the missing requirement. REMOVED has nothing to\n      remove - skip it and warn.\n\n   c. **Apply changes intelligently**:\n\n      **ADDED Requirements:**\n      - If requirement doesn't exist in main spec → add it\n      - If requirement already exists → update it to match (treat as implicit MODIFIED)\n\n      **MODIFIED Requirements:**\n      - Find the requirement in main spec\n      - Apply the changes - this can be:\n        - Adding new scenarios the main spec does not have yet\n        - Modifying existing scenarios\n        - Changing the requirement description\n      - Preserve scenarios\u002Fcontent not mentioned in the delta\n\n      **REMOVED Requirements:**\n      - Remove the entire requirement block from main spec\n      - Retiring the capability. Delete the whole `spec.md` - and the directory once\n        nothing else is left in it - only when ALL of these hold:\n        1. removing the requirements *this run* left no requirement blocks;\n        2. the rest of the spec is well-formed (it still has a `## Purpose`);\n        3. the main spec was not already empty before this sync - if you removed\n           nothing, change nothing;\n        4. every other nonblank line in the whole file is accounted for as the\n           title, Purpose, Requirements header, or a canonical requirement's\n           statement, scenarios, or fenced examples;\n        5. the change's `.openspec.yaml` declares `retire_capabilities: true`;\n        6. the `spec.md` resolves inside the real specs root (do not follow a\n           capability-directory symlink to delete an external file).\n        If removing the selected requirements would leave no requirement blocks and\n        any retirement condition is not satisfied, do not modify the main spec. Stop\n        the sync for that capability, report the blocking condition, and tell the user\n        how to resolve it. Never write or leave an empty `## Requirements` section.\n        When only the marker is missing, say that too - it is the one thing the user\n        can add to make the retirement go through.\n      - Deleting the file also deletes its `## Purpose`; any other section blocks\n        retirement. Name Purpose when you report the retirement. Include a pasteable\n        `git checkout` only when the spec lived in the caller's checkout;\n        otherwise give checkout-scoped recovery guidance.\n\n      **RENAMED Requirements:**\n      - Find the FROM requirement, rename to TO\n\n      **`## Purpose` in the delta:**\n      - The main spec already has one and it is authoritative - leave it alone\n        (this is what `openspec archive` does; it warns and moves on)\n\n   d. **Create new main spec** if capability doesn't exist yet:\n      - Only when the delta has ADDED requirements to put in it and no MODIFIED or\n        RENAMED requirements blocked this capability in step b. Otherwise create nothing\n        and leave the specs directory untouched. For a REMOVED-only delta, if the change's\n        `.openspec.yaml` declares `retire_capabilities: true`, report it as already retired\n        and continue without recreating the spec. Without that marker, report the sync as blocked:\n        `openspec archive` rejects it with `Spec must have at least one requirement`.\n        An empty delta has no operations to sync; report it as blocked too.\n        Never write an empty `## Requirements` section.\n      - Create `\u003CplanningHome.root>\u002Fopenspec\u002Fspecs\u002F\u003Ccapability-path>\u002Fspec.md`\n      - Add Purpose section: copy the delta's `## Purpose` body verbatim when it has one\n        (this is what `openspec archive` does); only write a brief TBD placeholder when it does not\n      - Add Requirements section with the ADDED requirements\n      - Follow the **Main Spec Format Reference** below\n\n5. **Validate updated main specs**\n\n   Run `openspec validate --specs` with the same selected-root flags used earlier.\n   If validation fails, report the problems and do not claim the sync succeeded.\n\n6. **Show summary**\n\n   After applying all changes, summarize:\n   - Which capabilities were updated\n   - What changes were made (requirements added\u002Fmodified\u002Fremoved\u002Frenamed)\n   - Any new main spec left with a TBD Purpose placeholder, so it gets written\n     now rather than lingering\n   - Any capability retired, naming the deleted `spec.md`, its Purpose, and\n     either a pasteable `git checkout` or checkout-scoped recovery guidance\n\n**Delta Spec Format Reference**\n\n```markdown\n# Spec Delta\n\n## Purpose\n\nOnly on a delta that introduces a brand-new capability. Seeds the new main spec.\n\n## ADDED Requirements\n\n### Requirement: New Feature\nThe system SHALL do something new.\n\n#### Scenario: Basic case\n- **WHEN** user does X\n- **THEN** system does Y\n\n## MODIFIED Requirements\n\n### Requirement: Existing Feature\nThe system SHALL keep doing the existing thing, now also handling A.\n\n#### Scenario: Scenario the main spec already has\n- **WHEN** user does X\n- **THEN** system does Y\n\n#### Scenario: New scenario to add\n- **WHEN** user does A\n- **THEN** system does B\n\n## REMOVED Requirements\n\n### Requirement: Deprecated Feature\n\n## RENAMED Requirements\n\n- FROM: `### Requirement: Old Name`\n- TO: `### Requirement: New Name`\n```\n\n**Main Spec Format Reference**\n\nMain specs are what the delta merges INTO. They must never contain delta operation headers (`## ADDED\u002FMODIFIED\u002FREMOVED\u002FRENAMED Requirements`) - after syncing, every requirement lives under a single `## Requirements` section:\n\n```markdown\n# \u003Ccapability> Specification\n\n## Purpose\nShort description of what this capability does and why it exists.\n\n## Requirements\n\n### Requirement: New Feature\nThe system SHALL do something new.\n\n#### Scenario: Basic case\n- **WHEN** user does X\n- **THEN** system does Y\n```\n\n**Key Principle: Intelligent Merging**\n\nUnlike programmatic merging, you merge rather than overwrite:\n- A MODIFIED block carries the whole requirement - body plus every scenario that survives the change. `openspec validate` and `openspec archive` both reject one that drops a scenario the main spec still has.\n- Keep anything the delta does not mention, in the main spec's existing order\n- Use your judgment to merge changes sensibly\n\n**Output On Success**\n\n```markdown\n## Specs Synced: \u003Cchange-name>\n\nUpdated main specs:\n\n**\u003Ccapability-1>**:\n- Added requirement: \"New Feature\"\n- Modified requirement: \"Existing Feature\" (added 1 scenario)\n\n**\u003Ccapability-2>**:\n- Created new spec file\n- Added requirement: \"Another Feature\"\n\nMain specs are now updated. The change remains active - archive when implementation is complete.\n```\n\n**Guardrails**\n- Read both delta and main specs before making changes\n- Preserve existing content not mentioned in delta\n- Never copy a delta file into a main spec as-is - merge its content so the main spec keeps the Main Spec Format Reference structure, with no delta operation headers\n- If something is unclear, ask for clarification\n- Show what you're changing as you go\n- The operation should be idempotent - running twice should give same result\n- Use only `artifactPaths.specs.existingOutputPaths`; never infer delta specs from unrelated artifacts\n- Honor a caller-supplied subset of `existingOutputPaths`; never widen it back to the full list\n- Fetch specs instructions once for direct sync, or reuse the archive-supplied snapshot inline\n- Stop before every main-spec write on a non-zero or invalid JSON specs-instruction response\n- Artifact rules constrain only the specs being written and are never copied into output files\n",{"name":5,"license":14,"metadata":38,"description":7,"allowed-tools":41,"compatibility":42},{"author":20,"version":39,"generatedBy":40},"1.0","1.14.1","Bash(openspec:*)","Requires openspec CLI.","e91c3c773b84e88a929cae3c36977e892ca4871a",".agents\u002Fskills\u002Fopenspec-sync-specs",4,"https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero","https:\u002F\u002Fsero-ai.dev\u002F","https:\u002F\u002Fgithub.com\u002Fsero-labs","2026-11-10 06:55:21",{"source":8,"skillName":5,"commands":51,"prompt":61,"zipAvailable":62},[52,55,58],{"tool":53,"command":54},"npx","npx skills add sero-labs\u002Fsero --skill openspec-sync-specs",{"tool":56,"command":57},"bunx","bunx skills add sero-labs\u002Fsero --skill openspec-sync-specs",{"tool":59,"command":60},"pnpm","pnpm dlx skills add sero-labs\u002Fsero --skill openspec-sync-specs","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fopenspec-sync-specs\u002FSKILL.md",true,[64,70,76,80,84],{"path":65,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":68,"sourceHtmlUrl":69},"condition-based-waiting-example.ts","SCRIPT","脚本",5054,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fsuperpowers-systematic-debugging\u002Fcondition-based-waiting-example.ts",{"path":71,"resourceType":72,"resourceTypeDesc":73,"sizeBytes":74,"sourceHtmlUrl":75},"condition-based-waiting.md","REFERENCE","参考文档",3516,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fsuperpowers-systematic-debugging\u002Fcondition-based-waiting.md",{"path":77,"resourceType":72,"resourceTypeDesc":73,"sizeBytes":78,"sourceHtmlUrl":79},"defense-in-depth.md",3650,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fsuperpowers-systematic-debugging\u002Fdefense-in-depth.md",{"path":81,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":82,"sourceHtmlUrl":83},"find-polluter.sh",1986,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fsuperpowers-systematic-debugging\u002Ffind-polluter.sh",{"path":85,"resourceType":72,"resourceTypeDesc":73,"sizeBytes":86,"sourceHtmlUrl":87},"root-cause-tracing.md",5321,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fsuperpowers-systematic-debugging\u002Froot-cause-tracing.md",[89,124,155,196,222,249],{"skillNo":90,"name":91,"nameZh":6,"description":92,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":104,"publishedAt":33},"01M70PSGDVAGMAGE2RFKEQ1EW4","agent-browser","Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to \"open a website\", \"fill out a form\", \"click a button\", \"take a screenshot\", \"scrape data from a page\", \"test this web app\", \"login to a site\", \"automate browser actions\", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fagent-browser\u002FSKILL.md",[96,101],{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":102,"categoryName":103,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000023","Skill与智能体开发",[105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,91,122,123],"agent browser","browser","testing","browser automation","notion","qa","figma","actions","messages","open","web tools","app","click","bedrock","extracting","conversations","programmatic","slack messages","exploratory testing",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":128,"sourceHtmlUrl":129,"categories":130,"keywords":140,"publishedAt":33},"01M6CHW2A115ZZDEFNXV2Z7A2Z","skill-creator","Guide for writing and improving Sero skills. Use when the user wants to create a new skill, rewrite an existing one, or turn a repeated piece of work into reusable procedural knowledge for the agent.","https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero\u002Fblob\u002Fmain\u002Fpackages\u002Ftemplates\u002Fskills\u002Fskill-creator\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero\u002Fblob\u002Fmain\u002Fpackages\u002Ftemplates\u002Fskills\u002Fskill-creator\u002FSKILL.md",[131,134,135],{"categoryNo":132,"categoryName":133,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":102,"categoryName":103,"taxonomyType":99,"taxonomyTypeDesc":100},{"categoryNo":136,"categoryName":137,"taxonomyType":138,"taxonomyTypeDesc":139},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[141,142,143,144,145,146,26,147,27,148,149,150,151,152,153,32,154],"skill creator","creator","writing","create","knowledge","work","guide","reusable","new skill","rewrite","procedural","for","Existing","new",{"skillNo":156,"name":157,"nameZh":6,"description":158,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":159,"sourceHtmlUrl":160,"categories":161,"keywords":171,"publishedAt":33},"01M6CHVJCZS9V3WWFPG47WC4G9","frontend-design","Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML\u002FCSS layouts, or when styling\u002Fbeautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.","https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero\u002Fblob\u002Fmain\u002Fpackages\u002Ftemplates\u002Fskills\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero\u002Fblob\u002Fmain\u002Fpackages\u002Ftemplates\u002Fskills\u002Ffrontend-design\u002FSKILL.md",[162,165,168],{"categoryNo":163,"categoryName":164,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000009","前端开发",{"categoryNo":166,"categoryName":167,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":169,"categoryName":170,"taxonomyType":138,"taxonomyTypeDesc":139},"01JBSEEDCAT000000000000032","设计师",[172,173,174,175,176,177,178,179,180,144,181,182,183,184,185,186,187,188,27,189,190,191,192,193,194,195,32],"frontend","design","frontend design","css","web","components","react","react components","web components","code","artifacts","ui","examples","applications","dashboards","quality","landing","html","styling","creative","ui design","build","aesthetics","generic",{"skillNo":197,"name":198,"nameZh":6,"description":199,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":6,"sourceHtmlUrl":200,"categories":201,"keywords":206,"publishedAt":33},"01M6CHTP6F4MENDBRDT7QQBKNY","sero-humanize","Use to draft, edit, or audit Sero application content, including UI copy,\ndocumentation, README text, and release notes. Use unslop for regular chat\nand status reports instead. Not for code review or creative and promotional\nwriting.","https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fsero-humanize\u002FSKILL.md",[202,205],{"categoryNo":203,"categoryName":204,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":136,"categoryName":137,"taxonomyType":138,"taxonomyTypeDesc":139},[207,208,209,143,210,211,212,213,214,181,215,216,183,217,218,219,220,27,191,221,152],"humanize","sero humanize","code review","review","status","documentation","notes","release notes","release","audit","unslop","text","README","edit","reports",{"skillNo":223,"name":224,"nameZh":6,"description":225,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":6,"sourceHtmlUrl":226,"categories":227,"keywords":229,"publishedAt":33},"01M6CHVXWDN98CP3MPT2WZ1ABN","sero-plugin","Create Sero plugins — self-contained packages with a Pi extension (agent\ntools\u002Fcommands), an optional React UI loaded via Module Federation, and an\noptional background runtime. Use when the user asks to create a Sero\nplugin\u002Fapp\u002Fextension, add a sidebar panel, dashboard widget, or\nagent-integrated feature, or convert a Pi extension into a Sero plugin.\nTrigger on phrases like \"create a plugin\", \"new Sero app\", \"add a tool\nwith UI\", \"build an extension\", \"convert this Pi extension\", or any\nrequest that touches `plugins\u002Fsero-*-plugin\u002F`.","https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero\u002Fblob\u002Fmain\u002Fpackages\u002Ftemplates\u002Fskills\u002Fsero-plugin\u002FSKILL.md",[228],{"categoryNo":102,"categoryName":103,"taxonomyType":99,"taxonomyTypeDesc":100},[230,231,232,178,233,144,234,183,235,236,237,238,239,26,240,27,193,241,242,243,244,245,116,246,247,248,32,154],"plugin","sero plugin","dashboard","packages","plugins","federation","Tools","react ui","tool","convert","pi","self","commands","runtime","pi extension","feature","add","panel","request",{"skillNo":250,"name":251,"nameZh":6,"description":252,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":93,"licenseFileUrl":6,"sourceHtmlUrl":253,"categories":254,"keywords":262,"publishedAt":33},"01M6CHVTJ5Y9JE6181SVPQXNZY","sero-dashboard-ui","Build, redesign or standardise Sero dashboard widgets and compact plugin\nviews using the shared @sero-ai\u002Fui dashboard components. Use when the user\nasks to create, restyle, clean up or make consistent a dashboard widget or a\ndata-dense plugin view. Trigger on phrases like \"dashboard widget\", \"widget\nfor the dashboard\", \"restyle this widget\", \"make the widget consistent\",\n\"compact plugin view\", or any work under a plugin's `ui\u002Fwidgets\u002F`.","https:\u002F\u002Fgithub.com\u002Fsero-labs\u002Fsero\u002Fblob\u002Fmain\u002Fpackages\u002Ftemplates\u002Fskills\u002Fsero-dashboard-ui\u002FSKILL.md",[255,258,259],{"categoryNo":256,"categoryName":257,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000013","分析与可视化",{"categoryNo":169,"categoryName":170,"taxonomyType":138,"taxonomyTypeDesc":139},{"categoryNo":260,"categoryName":261,"taxonomyType":138,"taxonomyTypeDesc":139},"01JBSEEDCAT000000000000033","数据分析师",[232,183,263,177,230,144,264,146,265,266,26,27,267,268,193,269,270,271,272,273,152,32],"sero dashboard ui","data","redesign","view","up","clean","compact","shared","widgets","trigger","make"]