[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C5FY61PVPJGSVY5NKAAJSZ":3,"skill-same:01M6C5FY61PVPJGSVY5NKAAJSZ":86},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":43,"linkOnly":44,"markdownContent":45,"markdownBody":46,"frontMatter":47,"refName":54,"commitSha":55,"skillDirectory":56,"forksCount":57,"repositoryHtmlUrl":58,"repositoryHomepageUrl":6,"ownerHtmlUrl":59,"ownerBlogUrl":6,"ownerDescription":60,"updatedAt":61,"install":62,"resources":75},"01M6C5FY61PVPJGSVY5NKAAJSZ","blueprint-sync-ids",null,"Scan blueprint docs and assign missing PRD\u002FADR\u002FPRP\u002FWO IDs. Use when assigning IDs to docs; --dry-run to preview, --link-issues to create GitHub issues for orphans.","laurigates\u002Fclaude-plugins","laurigates","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F13014001?v=4","01M6C59YHWS9C7KMXKSRX1YXNP","Lauri Gates","01M6C59YP2APG9YAM4DWYQYGFJ",60,"MIT","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fblueprint-plugin\u002Fskills\u002Fblueprint-sync-ids\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42],"blueprint sync ids","sync","ids","Blueprint","blueprint sync","sonnet","wed","2026","dry","preview","when","github issues","prd","docs","edit","write","read","run","github","create","Bash","use","issues","adr","2026-11-10 10:12:30",false,"---\ncreated: 2026-01-20\nmodified: 2026-11-13\nreviewed: 2026-06-10\ndescription: Scan blueprint docs and assign missing PRD\u002FADR\u002FPRP\u002FWO IDs. Use when assigning IDs to docs; --dry-run to preview, --link-issues to create GitHub issues for orphans.\nargs: \"[--dry-run] [--link-issues]\"\nargument-hint: \"--dry-run to preview changes, --link-issues to create GitHub issues for orphans\"\nallowed-tools: Read, Write, Edit, Glob, Bash, AskUserQuestion\nmodel: sonnet\nname: blueprint-sync-ids\n---\n\nScan all PRDs, ADRs, PRPs, and work-orders, assign IDs to documents missing them, and update the manifest registry.\n\n## When to Use This Skill\n\n| Use this skill when... | Use blueprint-sync instead when... |\n|---|---|\n| You're assigning PRD-NNN \u002F ADR-NNNN \u002F PRP-NNN \u002F WO-NNN to docs missing them | You want to detect modified or stale generated content (not IDs) |\n| You're previewing ID assignments with `--dry-run` | You're reconciling drift between `.claude\u002Frules\u002F` and the manifest |\n| You want to create GitHub issues for orphan docs via `--link-issues` | Use document-linking instead for runtime cross-doc traceability |\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--dry-run` | Preview changes without modifying files |\n| `--link-issues` | Also create GitHub issues for orphan documents |\n\n## Interaction Mode\n\nBefore any closing `AskUserQuestion` menu, resolve the automation config:\n\n```bash\nbash \"${CLAUDE_SKILL_DIR}\u002F..\u002F..\u002Fscripts\u002Fget-automation-config.sh\"\n```\n\nWhen `EFFECTIVE_INTERACTION_MODE=quiet` **and** this invocation was\nautomation-initiated (autopilot, session bookend, drift-nudge follow-up — not\na slash command the user typed), skip closing navigation menus (\"what next?\" \u002F\n\"create another?\" style): apply the safe default and end with a one-line\nreceipt instead. Quiet mode never skips confirmation gates that guard writes —\nonly navigation menus. A direct user invocation always behaves fully\ninteractively (explicit intent overrides quiet; see ADR-0020).\n\n## Prerequisites\n\n- Blueprint initialized (`docs\u002Fblueprint\u002Fmanifest.json` exists)\n- At least one document exists in `docs\u002Fprds\u002F`, `docs\u002Fadrs\u002F`, `docs\u002Fprps\u002F`, or `docs\u002Fblueprint\u002Fwork-orders\u002F`\n\n## Steps\n\n### Step 1: Initialize ID Registry\n\nCheck if `id_registry` exists in manifest:\n\n```bash\njq -e '.id_registry' docs\u002Fblueprint\u002Fmanifest.json >\u002Fdev\u002Fnull 2>&1\n```\n\nIf not, initialize it:\n\n```json\n{\n  \"id_registry\": {\n    \"last_prd\": 0,\n    \"last_prp\": 0,\n    \"documents\": {},\n    \"github_issues\": {}\n  }\n}\n```\n\n### Step 2: Run the read-only ID audit\n\nRun the helper. It owns the read-only scan: frontmatter `id:` extraction across\nPRDs\u002FADRs\u002FPRPs\u002Fwork-orders, deriving the expected ADR \u002F `WO-NNN` id from each\nfilename, flagging `NEEDS_ID` (no id) and `id_mismatch` (frontmatter id disagrees\nwith the filename-derived expectation), checking ids against the manifest\n`id_registry`, and building the reverse `github_issues` index from it. ADRs come\nfrom `docs\u002Fadrs\u002F`, else `docs\u002Fadr\u002F`, named `NNNN-title.md` or `ADR-NNN-title.md`\n(else the frontmatter `id:` alone):\n\n```bash\nbash \"${CLAUDE_SKILL_DIR}\u002Fscripts\u002Fblueprint-sync-ids.sh\" --home-dir \"$HOME\" --project-dir \"$(pwd)\"\n```\n\nParse `STATUS=` and `ISSUES:` from the output:\n\n- `PRD_NEEDS_ID` \u002F `ADR_NEEDS_ID` \u002F `PRP_NEEDS_ID` \u002F `WO_NEEDS_ID` and the\n  `needs_id` issues are the documents to assign IDs to in Step 7 (each carries\n  `DOC=` and, for ADRs\u002FWOs, the `EXPECTED=` filename-derived ID).\n- `ADR_MISMATCH` \u002F `WO_MISMATCH` and the `id_mismatch` issues (`HAS=` vs\n  `EXPECTED=`) are documents whose frontmatter id disagrees with their filename\n  — reconcile these in Step 7, never silently. `STATUS=ERROR` indicates at least\n  one mismatch, duplicate, or registry conflict.\n- `ADR_DIR` is the ADR directory scanned (`none` if absent);\n  `ADR_FRONTMATTER_ONLY` counts ADRs numbered only in frontmatter.\n- `DUPLICATE_IDS` \u002F `duplicate_id` (ERROR, `KIND=` `ID=` `DOCS=`): two documents\n  of one kind share a frontmatter id. Renumber one before assigning anything.\n- `REGISTRY_PRESENT` is `true` only when the manifest has `id_registry` with a\n  `documents` map; when `false`, every registry check is skipped (counts `0`).\n  - `REGISTRY_UNREGISTERED` \u002F `unregistered` (WARN): the id is not in\n    `documents`. Add it in Step 7.\n  - `REGISTRY_ID_PATH_MISMATCH` \u002F `id_path_mismatch` (ERROR): the registry holds\n    this path under another id (`REGISTRY=`) or this id under another path\n    (`REGISTRY_PATH=`). A swapped pair is two rows.\n  - `REGISTRY_PATH_MISSING` \u002F `registry_path_missing` (ERROR): a `documents`\n    `path` not on disk.\n  - `COUNTER_STALE` \u002F `counter_stale` (WARN): a `last_*` counter is below the\n    highest id of its kind on disk (`MAX_ON_DISK=`). Raise it before Step 7.\n- `GH_ISSUE_MAPPINGS` and `MANIFEST_PRESENT` summarise the reverse-index build\n  (Step 9 detail below).\n- On WARN\u002FERROR, `REASON=` names the first finding as `\u003Ctype>: \u003Cdetail>`.\n\nThe audit is read-only; it makes no edits. Surface its counts as the Step 6\nreport and proceed to the mutating steps.\n\n### Step 7: Assign IDs (unless `--dry-run`)\n\nFor each document needing an ID:\n\nPRD and PRP ids come from the shared helper, which prints max(`id_registry.last_\u003Ckind>`,\nhighest id of that kind on disk) + 1. The counter alone can repeat an id that a\npulled or merged document already carries (#3554). Call the helper once per\ndocument, after the previous document's `id:` is written, so each call sees it:\n\n```bash\nbash \"${CLAUDE_SKILL_DIR}\u002F..\u002F..\u002Fscripts\u002Fblueprint-next-id.sh\" --kind PRD\nbash \"${CLAUDE_SKILL_DIR}\u002F..\u002F..\u002Fscripts\u002Fblueprint-next-id.sh\" --kind PRP\n```\n\n**PRDs**:\n1. Get the next ID from `blueprint-next-id.sh --kind PRD` (prints `PRD-NNN`)\n2. Insert into frontmatter after first `---`:\n   ```yaml\n   id: PRD-001\n   ```\n3. Update manifest: set `last_prd` to the assigned number, add to `documents`\n\n**ADRs**:\n1. Derive ID from filename: `0003-title.md` → `ADR-0003`, `ADR-003-title.md` → `ADR-003`\n2. Insert into frontmatter\n3. Add to manifest `documents`\n\n**PRPs**:\n1. Get the next ID from `blueprint-next-id.sh --kind PRP` (prints `PRP-NNN`)\n2. Insert into frontmatter\n3. Update manifest: set `last_prp` to the assigned number, add to `documents`\n\n**Work-Orders**:\n1. Derive ID from filename: `003-task.md` → `WO-003`\n2. Insert into frontmatter\n3. Add to manifest `documents`\n\n### Step 8: Extract Titles and Links\n\nFor each document, also extract:\n- **Title**: First `# ` heading or frontmatter `name`\u002F`title` field\n- **Existing links**: `relates-to`, `implements`, `github-issues` from frontmatter\n- **Status**: From frontmatter\n\nStore in manifest registry:\n\n```json\n{\n  \"documents\": {\n    \"PRD-001\": {\n      \"path\": \"docs\u002Fprds\u002Fuser-auth.md\",\n      \"title\": \"User Authentication\",\n      \"status\": \"Active\",\n      \"relates_to\": [\"ADR-0003\"],\n      \"github_issues\": [42],\n      \"created\": \"2026-01-15\"\n    }\n  }\n}\n```\n\n### Step 9: Build GitHub Issue Index\n\nThe Step 2 audit already groups the manifest's per-document `github_issues`\narrays into the reverse index (`GH_ISSUE_MAPPINGS=` reports how many distinct\nissue numbers map to documents). Write that reverse index into the manifest:\n\n```json\n{\n  \"github_issues\": {\n    \"42\": [\"PRD-001\", \"PRP-002\"],\n    \"45\": [\"WO-003\"]\n  }\n}\n```\n\n### Step 10: Create Issues for Orphans (if `--link-issues`)\n\nFor each document without `github-issues`:\n\n```\nquestion: \"Create GitHub issue for {ID}: {title}?\"\noptions:\n  - label: \"Yes, create issue\"\n    description: \"Creates [{ID}] {title} issue\"\n  - label: \"Skip this one\"\n    description: \"Leave unlinked for now\"\n  - label: \"Skip all remaining\"\n    description: \"Don't prompt for more orphans\"\n```\n\nIf yes:\n```bash\ngh issue create \\\n  --title \"[{ID}] {title}\" \\\n  --body \"## {Document Type}\n\n**ID**: {ID}\n**Document**: \\`{path}\\`\n\n{Brief description from document}\n\n---\n*Auto-generated by \u002Fblueprint:sync-ids*\" \\\n  --label \"{type-label}\"\n```\n\nUpdate document frontmatter and manifest with new issue number.\n\n`sync-ids` is a deterministic task and keeps no run state in the tracked\nmanifest (ADR-0027, #3548): do not write `task_registry[\"sync-ids\"]`\n`last_completed_at`, `last_result` or `stats`. The only manifest changes are\nthe `id_registry` edits made in Steps 1–10.\n\n### Step 11: Final Report\n\n```\nID Sync Complete\n\nAssigned IDs:\n- PRD-003: docs\u002Fprds\u002Fpayment-flow.md\n- PRD-004: docs\u002Fprds\u002Fnotifications.md\n- PRP-005: docs\u002Fprps\u002Fstripe-integration.md\n\nUpdated Manifest:\n- last_prd: 4\n- last_prp: 5\n- documents: 22 entries\n- github_issues: 18 mappings\n\n{If --link-issues:}\nCreated GitHub Issues:\n- #52: [PRD-003] Payment Flow\n- #53: [PRP-005] Stripe Integration\n\nStill orphaned (no GitHub issues):\n- ADR-0004: Database Migration Strategy\n- WO-008: Add error handling\n\nRun `\u002Fblueprint:status` to see full traceability report.\n```\n\n## Error Handling\n\n| Condition | Action |\n|-----------|--------|\n| No manifest | Error: Run `\u002Fblueprint:init` first |\n| No documents found | Warning: No documents to scan |\n| Frontmatter parse error | Warning: Skip file, report for manual fix |\n| `gh` not available | Skip issue creation, warn user |\n| Write permission denied | Error: Check file permissions |\n\n## Manifest Schema\n\nAfter sync, manifest includes:\n\n```json\n{\n  \"id_registry\": {\n    \"last_prd\": 4,\n    \"last_prp\": 5,\n    \"documents\": {\n      \"PRD-001\": {\n        \"path\": \"docs\u002Fprds\u002Fuser-auth.md\",\n        \"title\": \"User Authentication\",\n        \"status\": \"Active\",\n        \"relates_to\": [\"ADR-0003\"],\n        \"implements\": [],\n        \"github_issues\": [42],\n        \"created\": \"2026-01-10\"\n      },\n      \"ADR-0003\": {\n        \"path\": \"docs\u002Fadrs\u002F0003-session-storage.md\",\n        \"title\": \"Session Storage Strategy\",\n        \"status\": \"Accepted\",\n        \"domain\": \"authentication\",\n        \"relates_to\": [\"PRD-001\"],\n        \"github_issues\": [],\n        \"created\": \"2026-01-12\"\n      }\n    },\n    \"github_issues\": {\n      \"42\": [\"PRD-001\", \"PRP-002\"],\n      \"45\": [\"WO-003\"]\n    }\n  }\n}\n```\n","Scan all PRDs, ADRs, PRPs, and work-orders, assign IDs to documents missing them, and update the manifest registry.\n\n## When to Use This Skill\n\n| Use this skill when... | Use blueprint-sync instead when... |\n|---|---|\n| You're assigning PRD-NNN \u002F ADR-NNNN \u002F PRP-NNN \u002F WO-NNN to docs missing them | You want to detect modified or stale generated content (not IDs) |\n| You're previewing ID assignments with `--dry-run` | You're reconciling drift between `.claude\u002Frules\u002F` and the manifest |\n| You want to create GitHub issues for orphan docs via `--link-issues` | Use document-linking instead for runtime cross-doc traceability |\n\n## Flags\n\n| Flag | Description |\n|------|-------------|\n| `--dry-run` | Preview changes without modifying files |\n| `--link-issues` | Also create GitHub issues for orphan documents |\n\n## Interaction Mode\n\nBefore any closing `AskUserQuestion` menu, resolve the automation config:\n\n```bash\nbash \"${CLAUDE_SKILL_DIR}\u002F..\u002F..\u002Fscripts\u002Fget-automation-config.sh\"\n```\n\nWhen `EFFECTIVE_INTERACTION_MODE=quiet` **and** this invocation was\nautomation-initiated (autopilot, session bookend, drift-nudge follow-up — not\na slash command the user typed), skip closing navigation menus (\"what next?\" \u002F\n\"create another?\" style): apply the safe default and end with a one-line\nreceipt instead. Quiet mode never skips confirmation gates that guard writes —\nonly navigation menus. A direct user invocation always behaves fully\ninteractively (explicit intent overrides quiet; see ADR-0020).\n\n## Prerequisites\n\n- Blueprint initialized (`docs\u002Fblueprint\u002Fmanifest.json` exists)\n- At least one document exists in `docs\u002Fprds\u002F`, `docs\u002Fadrs\u002F`, `docs\u002Fprps\u002F`, or `docs\u002Fblueprint\u002Fwork-orders\u002F`\n\n## Steps\n\n### Step 1: Initialize ID Registry\n\nCheck if `id_registry` exists in manifest:\n\n```bash\njq -e '.id_registry' docs\u002Fblueprint\u002Fmanifest.json >\u002Fdev\u002Fnull 2>&1\n```\n\nIf not, initialize it:\n\n```json\n{\n  \"id_registry\": {\n    \"last_prd\": 0,\n    \"last_prp\": 0,\n    \"documents\": {},\n    \"github_issues\": {}\n  }\n}\n```\n\n### Step 2: Run the read-only ID audit\n\nRun the helper. It owns the read-only scan: frontmatter `id:` extraction across\nPRDs\u002FADRs\u002FPRPs\u002Fwork-orders, deriving the expected ADR \u002F `WO-NNN` id from each\nfilename, flagging `NEEDS_ID` (no id) and `id_mismatch` (frontmatter id disagrees\nwith the filename-derived expectation), checking ids against the manifest\n`id_registry`, and building the reverse `github_issues` index from it. ADRs come\nfrom `docs\u002Fadrs\u002F`, else `docs\u002Fadr\u002F`, named `NNNN-title.md` or `ADR-NNN-title.md`\n(else the frontmatter `id:` alone):\n\n```bash\nbash \"${CLAUDE_SKILL_DIR}\u002Fscripts\u002Fblueprint-sync-ids.sh\" --home-dir \"$HOME\" --project-dir \"$(pwd)\"\n```\n\nParse `STATUS=` and `ISSUES:` from the output:\n\n- `PRD_NEEDS_ID` \u002F `ADR_NEEDS_ID` \u002F `PRP_NEEDS_ID` \u002F `WO_NEEDS_ID` and the\n  `needs_id` issues are the documents to assign IDs to in Step 7 (each carries\n  `DOC=` and, for ADRs\u002FWOs, the `EXPECTED=` filename-derived ID).\n- `ADR_MISMATCH` \u002F `WO_MISMATCH` and the `id_mismatch` issues (`HAS=` vs\n  `EXPECTED=`) are documents whose frontmatter id disagrees with their filename\n  — reconcile these in Step 7, never silently. `STATUS=ERROR` indicates at least\n  one mismatch, duplicate, or registry conflict.\n- `ADR_DIR` is the ADR directory scanned (`none` if absent);\n  `ADR_FRONTMATTER_ONLY` counts ADRs numbered only in frontmatter.\n- `DUPLICATE_IDS` \u002F `duplicate_id` (ERROR, `KIND=` `ID=` `DOCS=`): two documents\n  of one kind share a frontmatter id. Renumber one before assigning anything.\n- `REGISTRY_PRESENT` is `true` only when the manifest has `id_registry` with a\n  `documents` map; when `false`, every registry check is skipped (counts `0`).\n  - `REGISTRY_UNREGISTERED` \u002F `unregistered` (WARN): the id is not in\n    `documents`. Add it in Step 7.\n  - `REGISTRY_ID_PATH_MISMATCH` \u002F `id_path_mismatch` (ERROR): the registry holds\n    this path under another id (`REGISTRY=`) or this id under another path\n    (`REGISTRY_PATH=`). A swapped pair is two rows.\n  - `REGISTRY_PATH_MISSING` \u002F `registry_path_missing` (ERROR): a `documents`\n    `path` not on disk.\n  - `COUNTER_STALE` \u002F `counter_stale` (WARN): a `last_*` counter is below the\n    highest id of its kind on disk (`MAX_ON_DISK=`). Raise it before Step 7.\n- `GH_ISSUE_MAPPINGS` and `MANIFEST_PRESENT` summarise the reverse-index build\n  (Step 9 detail below).\n- On WARN\u002FERROR, `REASON=` names the first finding as `\u003Ctype>: \u003Cdetail>`.\n\nThe audit is read-only; it makes no edits. Surface its counts as the Step 6\nreport and proceed to the mutating steps.\n\n### Step 7: Assign IDs (unless `--dry-run`)\n\nFor each document needing an ID:\n\nPRD and PRP ids come from the shared helper, which prints max(`id_registry.last_\u003Ckind>`,\nhighest id of that kind on disk) + 1. The counter alone can repeat an id that a\npulled or merged document already carries (#3554). Call the helper once per\ndocument, after the previous document's `id:` is written, so each call sees it:\n\n```bash\nbash \"${CLAUDE_SKILL_DIR}\u002F..\u002F..\u002Fscripts\u002Fblueprint-next-id.sh\" --kind PRD\nbash \"${CLAUDE_SKILL_DIR}\u002F..\u002F..\u002Fscripts\u002Fblueprint-next-id.sh\" --kind PRP\n```\n\n**PRDs**:\n1. Get the next ID from `blueprint-next-id.sh --kind PRD` (prints `PRD-NNN`)\n2. Insert into frontmatter after first `---`:\n   ```yaml\n   id: PRD-001\n   ```\n3. Update manifest: set `last_prd` to the assigned number, add to `documents`\n\n**ADRs**:\n1. Derive ID from filename: `0003-title.md` → `ADR-0003`, `ADR-003-title.md` → `ADR-003`\n2. Insert into frontmatter\n3. Add to manifest `documents`\n\n**PRPs**:\n1. Get the next ID from `blueprint-next-id.sh --kind PRP` (prints `PRP-NNN`)\n2. Insert into frontmatter\n3. Update manifest: set `last_prp` to the assigned number, add to `documents`\n\n**Work-Orders**:\n1. Derive ID from filename: `003-task.md` → `WO-003`\n2. Insert into frontmatter\n3. Add to manifest `documents`\n\n### Step 8: Extract Titles and Links\n\nFor each document, also extract:\n- **Title**: First `# ` heading or frontmatter `name`\u002F`title` field\n- **Existing links**: `relates-to`, `implements`, `github-issues` from frontmatter\n- **Status**: From frontmatter\n\nStore in manifest registry:\n\n```json\n{\n  \"documents\": {\n    \"PRD-001\": {\n      \"path\": \"docs\u002Fprds\u002Fuser-auth.md\",\n      \"title\": \"User Authentication\",\n      \"status\": \"Active\",\n      \"relates_to\": [\"ADR-0003\"],\n      \"github_issues\": [42],\n      \"created\": \"2026-01-15\"\n    }\n  }\n}\n```\n\n### Step 9: Build GitHub Issue Index\n\nThe Step 2 audit already groups the manifest's per-document `github_issues`\narrays into the reverse index (`GH_ISSUE_MAPPINGS=` reports how many distinct\nissue numbers map to documents). Write that reverse index into the manifest:\n\n```json\n{\n  \"github_issues\": {\n    \"42\": [\"PRD-001\", \"PRP-002\"],\n    \"45\": [\"WO-003\"]\n  }\n}\n```\n\n### Step 10: Create Issues for Orphans (if `--link-issues`)\n\nFor each document without `github-issues`:\n\n```\nquestion: \"Create GitHub issue for {ID}: {title}?\"\noptions:\n  - label: \"Yes, create issue\"\n    description: \"Creates [{ID}] {title} issue\"\n  - label: \"Skip this one\"\n    description: \"Leave unlinked for now\"\n  - label: \"Skip all remaining\"\n    description: \"Don't prompt for more orphans\"\n```\n\nIf yes:\n```bash\ngh issue create \\\n  --title \"[{ID}] {title}\" \\\n  --body \"## {Document Type}\n\n**ID**: {ID}\n**Document**: \\`{path}\\`\n\n{Brief description from document}\n\n---\n*Auto-generated by \u002Fblueprint:sync-ids*\" \\\n  --label \"{type-label}\"\n```\n\nUpdate document frontmatter and manifest with new issue number.\n\n`sync-ids` is a deterministic task and keeps no run state in the tracked\nmanifest (ADR-0027, #3548): do not write `task_registry[\"sync-ids\"]`\n`last_completed_at`, `last_result` or `stats`. The only manifest changes are\nthe `id_registry` edits made in Steps 1–10.\n\n### Step 11: Final Report\n\n```\nID Sync Complete\n\nAssigned IDs:\n- PRD-003: docs\u002Fprds\u002Fpayment-flow.md\n- PRD-004: docs\u002Fprds\u002Fnotifications.md\n- PRP-005: docs\u002Fprps\u002Fstripe-integration.md\n\nUpdated Manifest:\n- last_prd: 4\n- last_prp: 5\n- documents: 22 entries\n- github_issues: 18 mappings\n\n{If --link-issues:}\nCreated GitHub Issues:\n- #52: [PRD-003] Payment Flow\n- #53: [PRP-005] Stripe Integration\n\nStill orphaned (no GitHub issues):\n- ADR-0004: Database Migration Strategy\n- WO-008: Add error handling\n\nRun `\u002Fblueprint:status` to see full traceability report.\n```\n\n## Error Handling\n\n| Condition | Action |\n|-----------|--------|\n| No manifest | Error: Run `\u002Fblueprint:init` first |\n| No documents found | Warning: No documents to scan |\n| Frontmatter parse error | Warning: Skip file, report for manual fix |\n| `gh` not available | Skip issue creation, warn user |\n| Write permission denied | Error: Check file permissions |\n\n## Manifest Schema\n\nAfter sync, manifest includes:\n\n```json\n{\n  \"id_registry\": {\n    \"last_prd\": 4,\n    \"last_prp\": 5,\n    \"documents\": {\n      \"PRD-001\": {\n        \"path\": \"docs\u002Fprds\u002Fuser-auth.md\",\n        \"title\": \"User Authentication\",\n        \"status\": \"Active\",\n        \"relates_to\": [\"ADR-0003\"],\n        \"implements\": [],\n        \"github_issues\": [42],\n        \"created\": \"2026-01-10\"\n      },\n      \"ADR-0003\": {\n        \"path\": \"docs\u002Fadrs\u002F0003-session-storage.md\",\n        \"title\": \"Session Storage Strategy\",\n        \"status\": \"Accepted\",\n        \"domain\": \"authentication\",\n        \"relates_to\": [\"PRD-001\"],\n        \"github_issues\": [],\n        \"created\": \"2026-01-12\"\n      }\n    },\n    \"github_issues\": {\n      \"42\": [\"PRD-001\", \"PRP-002\"],\n      \"45\": [\"WO-003\"]\n    }\n  }\n}\n```\n",{"args":48,"name":5,"model":24,"created":49,"modified":50,"reviewed":51,"description":7,"allowed-tools":52,"argument-hint":53},"[--dry-run] [--link-issues]",1768867200000,1794528000000,1781049600000,"Read, Write, Edit, Glob, Bash, AskUserQuestion","--dry-run to preview changes, --link-issues to create GitHub issues for orphans","main","b47840019d190aa9afa1fd8d6d42ddd584a45641","blueprint-plugin\u002Fskills\u002Fblueprint-sync-ids",6,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins","https:\u002F\u002Fgithub.com\u002Flaurigates","Linux enthusiast, cloud engineer, neovim addict, electronics hobbyist.","2026-11-15 03:36:11",{"source":8,"skillName":5,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add laurigates\u002Fclaude-plugins --skill blueprint-sync-ids",{"tool":68,"command":69},"bunx","bunx skills add laurigates\u002Fclaude-plugins --skill blueprint-sync-ids",{"tool":71,"command":72},"pnpm","pnpm dlx skills add laurigates\u002Fclaude-plugins --skill blueprint-sync-ids","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fblueprint-plugin\u002Fskills\u002Fblueprint-sync-ids\u002FSKILL.md",true,[76,82],{"path":77,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":80,"sourceHtmlUrl":81},"scripts\u002Fblueprint-sync-ids.sh","SCRIPT","脚本",15924,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fblueprint-plugin\u002Fskills\u002Fblueprint-sync-ids\u002Fscripts\u002Fblueprint-sync-ids.sh",{"path":83,"resourceType":78,"resourceTypeDesc":79,"sizeBytes":84,"sourceHtmlUrl":85},"scripts\u002Ftests\u002Ftest-blueprint-sync-ids.sh",14106,"https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fblueprint-plugin\u002Fskills\u002Fblueprint-sync-ids\u002Fscripts\u002Ftests\u002Ftest-blueprint-sync-ids.sh",[87,114,133,149,171,200],{"skillNo":88,"name":89,"nameZh":6,"description":90,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":91,"categories":92,"keywords":98,"publishedAt":43},"01M70PFHMH9ADY0CRE6047Y4B2","kitty-show-image","Show the user an image with a note on what to judge, via a file send or a labelled kitty tab. Use when the user must see an image, or icat fails with no \u002Fdev\u002Ftty.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fkitty-plugin\u002Fskills\u002Fkitty-show-image\u002FSKILL.md",[93],{"categoryNo":94,"categoryName":95,"taxonomyType":96,"taxonomyTypeDesc":97},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[99,100,101,102,103,104,105,106,107,108,40,29,39,109,110,111,112,113,26,35],"show","kitty show image","image","kitty","show image","ls","get","send","open","dev","file","text","with","xdg","via",{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":120,"publishedAt":43},"01M70PFEN18HKQ4RCQ1VPGMPTB","kitty-session-persistence","Snapshot and restore kitty terminal sessions on macOS. Use when surviving WindowServer hangs without losing tabs, configuring snapshots, or restoring after a force-reboot.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fkitty-plugin\u002Fskills\u002Fkitty-session-persistence\u002FSKILL.md",[],[102,121,122,123,124,125,29,39,126,127,128,26,35,34,33,129,130,131,132,40],"kitty session persistence","session","persistence","false","snapshots","uname","reboot","terminal","snapshot","macos","sessions","restore",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":139,"publishedAt":43},"01M70PFC77XGXCVQ1543VGZHYR","kitty-remote-control","Safe kitty remote control from an agent — read panes with kitty @ ls\u002Fget-text, notify, and never mutate the live terminal unasked. Use when running inside kitty.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fkitty-plugin\u002Fskills\u002Fkitty-remote-control\u002FSKILL.md",[],[140,141,102,142,143,104,144,145,105,146,147,40,29,148,39,110,111,128,26,35],"kitty remote control","remote","control","remote control","running","never","panes","notify","query",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":155,"publishedAt":43},"01M70P6WVMCT5JG4SACTM69AF9","docs-reference-check","Dangling doc-reference gate: flag markdown naming repo paths or relative links that no longer exist. Use when docs cite moved\u002Fdeleted files, or wiring a doc-drift lint.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fdocumentation-plugin\u002Fskills\u002Fdocs-reference-check\u002FSKILL.md",[],[156,157,158,159,32,160,161,162,163,164,40,29,39,165,109,166,167,168,169,170],"docs reference check","check","reference check","reference","links","python3","repo","files","auto","drift","lint","wiring","chezmoi","references","cp",{"skillNo":172,"name":173,"nameZh":6,"description":174,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":175,"categories":176,"keywords":186,"publishedAt":43},"01M6C6NDE7DAQGNWSF22J5CJ0Z","youtube-upload","Upload a video to YouTube via the Data API v3 and edit its title, description, tags or thumbnail afterwards. Use when publishing or retitling a YouTube video.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fyoutube-plugin\u002Fskills\u002Fyoutube-upload\u002FSKILL.md",[177,180,181],{"categoryNo":178,"categoryName":179,"taxonomyType":96,"taxonomyTypeDesc":97},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":94,"categoryName":95,"taxonomyType":96,"taxonomyTypeDesc":97},{"categoryNo":182,"categoryName":183,"taxonomyType":184,"taxonomyTypeDesc":185},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[187,188,189,190,161,36,35,191,33,192,193,194,40,39,109,195,196,29,197,198,199,113,26],"youtube upload","upload","youtube","Video","uv run","publishing","data","uv","api","v3","tags","id","title",{"skillNo":201,"name":202,"nameZh":6,"description":203,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":204,"categories":205,"keywords":209,"publishedAt":43},"01M6C6NABWW1X58KJJM4F6GQMQ","youtube-studio-share","Share a private YouTube video with a whole Google Workspace organization by scripting YouTube Studio in the browser. Use when a video must be org-only.","https:\u002F\u002Fgithub.com\u002Flaurigates\u002Fclaude-plugins\u002Fblob\u002Fmain\u002Fyoutube-plugin\u002Fskills\u002Fyoutube-studio-share\u002FSKILL.md",[206],{"categoryNo":207,"categoryName":208,"taxonomyType":96,"taxonomyTypeDesc":97},"01JBSEEDCAT000000000000023","Skill与智能体开发",[210,211,212,213,189,190,214,215,216,217,218,35,219,220,221,222,40,223,29,111,224,26],"youtube studio share","share","youtube studio","studio","browser","javascript","scripting","google workspace","workspace","tool","google","only","MCP","chrome","organization"]