mcpField
B
blueprint-sync-ids

blueprint-sync-ids

github.com/laurigates文档处理5951 次安装1 天前更新
代码仓库

关于 blueprint-sync-ids

用于 Blueprint 文档维护的技能,可扫描 PRD、ADR、PRP 和 work-order,为缺少 ID 的文档分配编号并更新清单注册表。

主要功能

  1. 01扫描指定类型文档
  2. 02为文档分配 ID
  3. 03更新清单注册表
  4. 04构建 GitHub issue 索引
  5. 05可预览变更
  6. 06可为孤立文档创建 GitHub issue

适用场景

  1. 01整理缺少编号的项目文档
  2. 02同步文档 ID 与 manifest
  3. 03查找文档关联的 GitHub issue
  4. 04为未关联 issue 的文档创建 issue

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/laurigates/claude-plugins --skill blueprint-sync-ids

安装后在 Claude Code 中输入/blueprint-sync-ids确认已加载。

详细介绍

扫描所有 PRD、ADR、PRP 和 work-order,为缺少 ID 的文档分配 ID,并更新清单注册表。

标志

标志说明
--dry-run预览更改,但不修改文件
--link-issues同时为孤立文档创建 GitHub issue

前置条件

  • 已初始化 Blueprint(docs/blueprint/manifest.json 存在)
  • docs/prds/、docs/adrs/、docs/prps/ 或 docs/blueprint/work-orders/ 中至少存在一个文档

步骤

步骤 1:初始化 ID 注册表

检查清单中是否存在 id_registry:

jq -e '.id_registry' docs/blueprint/manifest.json >/dev/null 2>&1

如果不存在,则进行初始化:

{
  "id_registry": {
    "last_prd": 0,
    "last_prp": 0,
    "documents": {},
    "github_issues": {}
  }
}
步骤 2:扫描 PRD
for prd in docs/prds/*.md; do
  [ -f "$prd" ] || continue

  # Check for existing ID in frontmatter
  existing_id=$(head -50 "$prd" | grep -m1 "^id:" | sed 's/^id:[[:space:]]*//')

  if [ -z "$existing_id" ]; then
    echo "NEEDS_ID: $prd"
  else
    echo "HAS_ID: $prd ($existing_id)"
  fi
done
步骤 3:扫描 ADR
for adr in docs/adrs/*.md; do
  [ -f "$adr" ] || continue

  # ADR ID derived from filename (0001-title.md → ADR-0001)
  filename=$(basename "$adr")
  num=$(echo "$filename" | grep -oE '^[0-9]{4}')

  if [ -n "$num" ]; then
    expected_id="ADR-$num"
    existing_id=$(head -50 "$adr" | grep -m1 "^id:" | sed 's/^id:[[:space:]]*//')

    if [ -z "$existing_id" ]; then
      echo "NEEDS_ID: $adr (should be $expected_id)"
    elif [ "$existing_id" != "$expected_id" ]; then
      echo "MISMATCH: $adr (has $existing_id, should be $expected_id)"
    else
      echo "HAS_ID: $adr ($existing_id)"
    fi
  fi
done
步骤 4:扫描 PRP
for prp in docs/prps/*.md; do
  [ -f "$prp" ] || continue

  existing_id=$(head -50 "$prp" | grep -m1 "^id:" | sed 's/^id:[[:space:]]*//')

  if [ -z "$existing_id" ]; then
    echo "NEEDS_ID: $prp"
  else
    echo "HAS_ID: $prp ($existing_id)"
  fi
done
步骤 5:扫描 Work-Order
for wo in docs/blueprint/work-orders/*.md; do
  [ -f "$wo" ] || continue

  # WO ID derived from filename (003-task.md → WO-003)
  filename=$(basename "$wo")
  num=$(echo "$filename" | grep -oE '^[0-9]{3}')

  if [ -n "$num" ]; then
    expected_id="WO-$num"
    existing_id=$(head -50 "$wo" | grep -m1 "^id:" | sed 's/^id:[[:space:]]*//')

    if [ -z "$existing_id" ]; then
      echo "NEEDS_ID: $wo (should be $expected_id)"
    else
      echo "HAS_ID: $wo ($existing_id)"
    fi
  fi
done
步骤 6:报告发现
Document ID Scan Results

PRDs:
- With IDs: X
- Missing IDs: Y
  - docs/prds/feature-a.md
  - docs/prds/feature-b.md

ADRs:
- With IDs: X
- Missing IDs: Y
- Mismatched IDs: Z

PRPs:
- With IDs: X
- Missing IDs: Y

Work-Orders:
- With IDs: X
- Missing IDs: Y

Total: X documents, Y need IDs
步骤 7:分配 ID(除非使用 --dry-run)

为每个需要 ID 的文档:

PRD:

  1. 获取下一个 PRD 编号:jq '.id_registry.last_prd' manifest.json + 1
  2. 生成 ID:PRD-NNN(补零)
  3. 在第一个 --- 后插入到 frontmatter 中:
    id: PRD-001
    
  4. 更新清单:递增 last_prd,并添加到 documents

ADR:

  1. 根据文件名推导 ID:0003-title.md → ADR-0003
  2. 插入到 frontmatter 中
  3. 添加到清单的 documents

PRP:

  1. 获取下一个 PRP 编号:jq '.id_registry.last_prp' manifest.json + 1
  2. 生成 ID:PRP-NNN
  3. 插入到 frontmatter 中
  4. 更新清单:递增 last_prp,并添加到 documents

Work-Order:

  1. 根据文件名推导 ID:003-task.md → WO-003
  2. 插入到 frontmatter 中
  3. 添加到清单的 documents
步骤 8:提取标题和链接

对于每个文档,还需提取:

  • 标题:第一个 # 标题或 frontmatter 中的 name/title 字段
  • 现有链接:frontmatter 中的 relates-to、implements、github-issues
  • 状态:来自 frontmatter

存储到清单注册表中:

{
  "documents": {
    "PRD-001": {
      "path": "docs/prds/user-auth.md",
      "title": "User Authentication",
      "status": "Active",
      "relates_to": ["ADR-0003"],
      "github_issues": [42],
      "created": "2026-01-15"
    }
  }
}
步骤 9:构建 GitHub Issue 索引

扫描所有文档中的 github-issues 字段,并构建反向索引:

{
  "github_issues": {
    "42": ["PRD-001", "PRP-002"],
    "45": ["WO-003"]
  }
}
步骤 10:为孤立文档创建 Issue(如果使用 --link-issues)

对于每个没有 github-issues 的文档:

question: "Create GitHub issue for {ID}: {title}?"
options:
  - label: "Yes, create issue"
    description: "Creates [{ID}] {title} issue"
  - label: "Skip this one"
    description: "Leave unlinked for now"
  - label: "Skip all remaining"
    description: "Don't prompt for more orphans"

如果是:

gh issue create \
  --title "[{ID}] {title}" \
  --body "## {Document Type}

**ID**: {ID}
**Document**: \`{path}\`

{Brief description from document}

---
*Auto-generated by /blueprint:sync-ids*" \
  --label "{type-label}"

使用新 issue 编号更新文档的 frontmatter 和清单。

步骤 11:更新任务注册表

更新 docs/blueprint/manifest.json 中的任务注册表条目:

jq --arg now "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
  --argjson processed "${DOCS_CHECKED:-0}" \
  --argjson created "${IDS_ASSIGNED:-0}" \
  '.task_registry["sync-ids"].last_completed_at = $now |
   .task_registry["sync-ids"].last_result = "success" |
   .task_registry["sync-ids"].stats.runs_total = ((.task_registry["sync-ids"].stats.runs_total // 0) + 1) |
   .task_registry["sync-ids"].stats.items_processed = $processed |
   .task_registry["sync-ids"].stats.items_created = $created' \
  docs/blueprint/manifest.json > tmp.json && mv tmp.json docs/blueprint/manifest.json
步骤 12:最终报告
ID Sync Complete

Assigned IDs:
- PRD-003: docs/prds/payment-flow.md
- PRD-004: docs/prds/notifications.md
- PRP-005: docs/prps/stripe-integration.md

Updated Manifest:
- last_prd: 4
- last_prp: 5
- documents: 22 entries
- github_issues: 18 mappings

{If --link-issues:}
Created GitHub Issues:
- #52: [PRD-003] Payment Flow
- #53: [PRP-005] Stripe Integration

Still orphaned (no GitHub issues):
- ADR-0004: Database Migration Strategy
- WO-008: Add error handling

Run `/blueprint:status` to see full traceability report.

错误处理

条件操作
没有清单错误:请先运行 /blueprint:init
未找到文档警告:没有可扫描的文档
frontmatter 解析错误警告:跳过文件,并报告以便手动修复
gh 不可用跳过创建 issue,并警告用户
写入权限被拒绝错误:检查文件权限

清单架构

同步后,清单包含:

{
  "id_registry": {
    "last_prd": 4,
    "last_prp": 5,
    "documents": {
      "PRD-001": {
        "path": "docs/prds/user-auth.md",
        "title": "User Authentication",
        "status": "Active",
        "relates_to": ["ADR-0003"],
        "implements": [],
        "github_issues": [42],
        "created": "2026-01-10"
      },
      "ADR-0003": {
        "path": "docs/adrs/0003-session-storage.md",
        "title": "Session Storage Strategy",
        "status": "Accepted",
        "domain": "authentication",
        "relates_to": ["PRD-001"],
        "github_issues": [],
        "created": "2026-01-12"
      }
    },
    "github_issues": {
      "42": ["PRD-001", "PRP-002"],
      "45": ["WO-003"]
    }
  }
}

评论

支持 Markdown