dev-playbooks-cn 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,6 +46,7 @@ AI 编码助手很强大,但往往**不可预测**:
46
46
  | **Claude Code** | 完整 Skills | `CLAUDE.md` |
47
47
  | **Codex CLI** | 完整 Skills | `AGENTS.md` |
48
48
  | **Qoder** | 完整 Skills | `AGENTS.md` |
49
+ | **OpenCode(oh-my-opencode)** | 完整 Skills | `AGENTS.md` |
49
50
  | **Cursor** | Rules 系统 | `.cursor/rules/` |
50
51
  | **Windsurf** | Rules 系统 | `.windsurf/rules/` |
51
52
  | **Gemini CLI** | Rules 系统 | `GEMINI.md` |
@@ -83,6 +84,7 @@ npx dev-playbooks-cn@latest init
83
84
  初始化后:
84
85
  - Claude Code:`~/.claude/skills/devbooks-*`
85
86
  - Codex CLI:`~/.codex/skills/devbooks-*`
87
+ - OpenCode:`~/.config/opencode/skill/devbooks-*`
86
88
 
87
89
  ### 快速集成
88
90
 
package/bin/devbooks.js CHANGED
@@ -32,6 +32,7 @@ const __filename = fileURLToPath(import.meta.url);
32
32
  const __dirname = path.dirname(__filename);
33
33
 
34
34
  const CLI_COMMAND = 'dev-playbooks-cn';
35
+ const XDG_CONFIG_HOME = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
35
36
 
36
37
  // ============================================================================
37
38
  // Skills 支持级别定义
@@ -71,6 +72,18 @@ const AI_TOOLS = [
71
72
  instructionFile: 'AGENTS.md',
72
73
  available: true
73
74
  },
75
+ {
76
+ id: 'opencode',
77
+ name: 'OpenCode',
78
+ description: 'OpenCode AI CLI (compatible with oh-my-opencode)',
79
+ skillsSupport: SKILLS_SUPPORT.FULL,
80
+ slashDir: '.opencode/command',
81
+ agentsDir: '.opencode/agent',
82
+ skillsDir: path.join(XDG_CONFIG_HOME, 'opencode', 'skill'),
83
+ globalDir: path.join(XDG_CONFIG_HOME, 'opencode'),
84
+ instructionFile: 'AGENTS.md',
85
+ available: true
86
+ },
74
87
 
75
88
  // === Rules 类似系统 ===
76
89
  {
@@ -115,17 +128,6 @@ const AI_TOOLS = [
115
128
  instructionFile: 'GEMINI.md',
116
129
  available: true
117
130
  },
118
- {
119
- id: 'opencode',
120
- name: 'OpenCode',
121
- description: 'OpenCode AI CLI',
122
- skillsSupport: SKILLS_SUPPORT.RULES,
123
- slashDir: '.opencode/commands/devbooks',
124
- agentsDir: '.opencode/agent',
125
- globalDir: path.join(os.homedir(), '.config', 'opencode'),
126
- instructionFile: 'AGENTS.md',
127
- available: true
128
- },
129
131
 
130
132
  // === Agents/自定义指令 ===
131
133
  {
@@ -473,11 +475,11 @@ function printSkillsSupportInfo() {
473
475
  console.log(chalk.gray('─'.repeat(50)));
474
476
  console.log();
475
477
 
476
- console.log(chalk.green('★ 完整 Skills') + chalk.gray(' - Claude Code, Codex CLI, Qoder'));
478
+ console.log(chalk.green('★ 完整 Skills') + chalk.gray(' - Claude Code, Codex CLI, OpenCode, Qoder'));
477
479
  console.log(chalk.gray(' └ 独立的 Skills/Agents 系统,可按需调用,有独立上下文'));
478
480
  console.log();
479
481
 
480
- console.log(chalk.blue('◆ Rules 系统') + chalk.gray(' - Cursor, Windsurf, Gemini, Antigravity, OpenCode, Continue'));
482
+ console.log(chalk.blue('◆ Rules 系统') + chalk.gray(' - Cursor, Windsurf, Gemini, Antigravity, Continue'));
481
483
  console.log(chalk.gray(' └ 规则自动应用于匹配的文件/场景,功能接近 Skills'));
482
484
  console.log();
483
485
 
@@ -550,8 +552,8 @@ function installSkills(toolIds, update = false) {
550
552
  const tool = AI_TOOLS.find(t => t.id === toolId);
551
553
  if (!tool || tool.skillsSupport !== SKILLS_SUPPORT.FULL) continue;
552
554
 
553
- // Claude Code Codex CLI 都支持相同格式的 Skills
554
- if ((toolId === 'claude' || toolId === 'codex') && tool.skillsDir) {
555
+ // Claude Code / Codex CLI / OpenCode(含 oh-my-opencode)支持相同格式的 Skills
556
+ if ((toolId === 'claude' || toolId === 'codex' || toolId === 'opencode') && tool.skillsDir) {
555
557
  const skillsSrcDir = path.join(__dirname, '..', 'skills');
556
558
  const skillsDestDir = tool.skillsDir;
557
559
 
@@ -612,6 +614,72 @@ function installSkills(toolIds, update = false) {
612
614
  return results;
613
615
  }
614
616
 
617
+ // ============================================================================
618
+ // OpenCode:安装项目级命令入口(.opencode/command/devbooks.md)
619
+ // ============================================================================
620
+
621
+ function generateOpenCodeDevbooksCommand() {
622
+ return `---
623
+ description: DevBooks 工作流入口(OpenCode / oh-my-opencode)
624
+ ---
625
+
626
+ ${DEVBOOKS_MARKERS.start}
627
+ # DevBooks(OpenCode / oh-my-opencode)
628
+
629
+ 本项目使用 DevBooks 工作流进行规格驱动开发。
630
+
631
+ ## 快速开始
632
+
633
+ 1. **推荐入口(Router)**:在对话中输入:\`/devbooks-router\`
634
+ 2. 或使用自然语言:\`请运行 devbooks-router skill,分析需求:<你的需求>\`
635
+
636
+ > 说明:在 oh-my-opencode 中,Skills 会作为可用的 Slash Commands 被加载,因此可以直接用 \`/<skill-name>\` 调用。
637
+
638
+ ## 常用命令(直接用 /<skill-name>)
639
+
640
+ - \`/devbooks-router\`:入口路由(自动判断下一步)
641
+ - \`/devbooks-impact-analysis\`:影响分析(跨模块/对外契约)
642
+ - \`/devbooks-proposal-author\`:创建提案(禁止编码)
643
+ - \`/devbooks-design-doc\`:设计文档(What/Constraints + AC)
644
+ - \`/devbooks-implementation-plan\`:编码计划(tasks.md)
645
+ - \`/devbooks-test-owner\`:验收测试与追溯(独立对话)
646
+ - \`/devbooks-coder\`:按 tasks 实现(禁止改 tests/)
647
+ - \`/devbooks-spec-gardener\`:归档前规格修剪
648
+
649
+ ## 核心约束(必须遵守)
650
+
651
+ - 在回答任何问题或写任何代码前:先做配置发现并阅读规则文档(\`.devbooks/config.yaml\` → \`dev-playbooks/project.md\` → \`project.md\`)
652
+ - 新功能/破坏性变更/架构改动:必须先创建 \`dev-playbooks/changes/<id>/\` 并产出 proposal/design/tasks/verification
653
+ - Test Owner 与 Coder 必须在独立对话/独立实例中执行;Coder 禁止修改 \`tests/**\`
654
+
655
+ ${DEVBOOKS_MARKERS.end}
656
+ `;
657
+ }
658
+
659
+ function installOpenCodeCommands(toolIds, projectDir, update = false) {
660
+ const results = [];
661
+
662
+ if (!toolIds.includes('opencode')) return results;
663
+
664
+ const destDir = path.join(projectDir, '.opencode', 'command');
665
+ fs.mkdirSync(destDir, { recursive: true });
666
+
667
+ const destPath = path.join(destDir, 'devbooks.md');
668
+ const content = generateOpenCodeDevbooksCommand();
669
+
670
+ if (!fs.existsSync(destPath)) {
671
+ fs.writeFileSync(destPath, content);
672
+ results.push({ tool: 'OpenCode', type: 'command', path: destPath, action: 'created' });
673
+ } else if (update) {
674
+ const updated = updateManagedContent(destPath, content);
675
+ if (updated) {
676
+ results.push({ tool: 'OpenCode', type: 'command', path: destPath, action: 'updated' });
677
+ }
678
+ }
679
+
680
+ return results;
681
+ }
682
+
615
683
  // ============================================================================
616
684
  // 安装 Claude Code 自定义子代理(解决内置子代理无法访问 Skills 的问题)
617
685
  // ============================================================================
@@ -1088,6 +1156,12 @@ async function initCommand(projectDir, options) {
1088
1156
  console.log(chalk.gray(` └ ${result.tool}: ${path.relative(projectDir, result.path)}`));
1089
1157
  }
1090
1158
 
1159
+ // OpenCode:安装项目级命令入口(.opencode/command/devbooks.md)
1160
+ const openCodeCmdResults = installOpenCodeCommands(selectedTools, projectDir);
1161
+ for (const result of openCodeCmdResults) {
1162
+ console.log(chalk.gray(` └ ${result.tool}: ${path.relative(projectDir, result.path)}`));
1163
+ }
1164
+
1091
1165
  // 设置 ignore 文件
1092
1166
  const ignoreSpinner = ora('配置 ignore 文件...').start();
1093
1167
  const ignoreResults = setupIgnoreFiles(selectedTools, projectDir);
@@ -1197,6 +1271,14 @@ async function updateCommand(projectDir) {
1197
1271
  }
1198
1272
  }
1199
1273
 
1274
+ // OpenCode:更新项目级命令入口(.opencode/command/devbooks.md)
1275
+ const openCodeCmdResults = installOpenCodeCommands(configuredTools, projectDir, true);
1276
+ for (const result of openCodeCmdResults) {
1277
+ if (result.action === 'updated') {
1278
+ console.log(chalk.green('✓') + ` ${result.tool}: 更新了命令入口 ${path.relative(projectDir, result.path)}`);
1279
+ }
1280
+ }
1281
+
1200
1282
  console.log();
1201
1283
  console.log(chalk.green('✓') + ' 更新完成!');
1202
1284
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-playbooks-cn",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "AI-driven spec-based development workflow",
5
5
  "keywords": [
6
6
  "devbooks",
@@ -148,6 +148,15 @@ override dispose() {
148
148
  | 无 spec deltas | 归档完成 | 无需其他 skill |
149
149
  | 发现重大问题 | 交回 `devbooks-coder` | 归档前修复问题 |
150
150
 
151
+ ### Reviewer 专属权限:设置 verification.md Status
152
+
153
+ **只有 Reviewer 可以将 `verification.md` 的 Status 设为 `Done`**。
154
+
155
+ Review 通过后,Reviewer 必须执行:
156
+ 1. 打开 `<change-root>/<change-id>/verification.md`
157
+ 2. 将 `- Status: Ready` 改为 `- Status: Done`
158
+ 3. 这是归档的前置条件(`change-check.sh --mode archive` 会检查)
159
+
151
160
  ### 输出模板
152
161
 
153
162
  完成 code-review 后,输出:
@@ -141,6 +141,7 @@ devbooks change-evidence <change-id> --label green-final -- npm test
141
141
  ### 角色边界约束
142
142
  - **禁止修改 `tests/**`**(需要改测试必须交还 Test Owner)
143
143
  - **禁止修改 `verification.md`**(由 Test Owner 维护)
144
+ - **禁止修改 `verification.md` 的 Status 字段**(只有 Reviewer 可以设为 Done)
144
145
  - **禁止修改 `.devbooks/`、`build/`、工程配置文件**(除非 proposal.md 明确声明)
145
146
 
146
147
  ### 代码质量约束
@@ -410,6 +410,25 @@ check_verification() {
410
410
  return 0
411
411
  fi
412
412
 
413
+ # ==========================================================================
414
+ # AC-010: Verification Status Check
415
+ # Status field controls change package lifecycle: Draft → Ready → Done → Archived
416
+ # Only Reviewer can set Status to "Done" (Coder/Test Owner prohibited)
417
+ # ==========================================================================
418
+ if [[ "$mode" == "archive" || "$mode" == "strict" ]]; then
419
+ local status_line
420
+ status_line=$(rg -n "^- Status[::] *(Draft|Ready|Done|Archived)\b" "$verification_file" -m 1 || true)
421
+ if [[ -z "$status_line" ]]; then
422
+ err "verification missing Status line (e.g., '- Status: Done'): ${verification_file}"
423
+ else
424
+ local status_value
425
+ status_value="$(echo "$status_line" | sed -E 's/^[0-9]+:- Status[::] *//')"
426
+ if [[ "$status_value" != "Done" && "$status_value" != "Archived" ]]; then
427
+ err "verification Status must be 'Done' or 'Archived' for ${mode} (current: '${status_value}'). Only Reviewer can set Status to Done: ${verification_file}"
428
+ fi
429
+ fi
430
+ fi
431
+
413
432
  for h in "A\) (Test Plan Directive Table|测试计划指令表)" "B\) (Traceability Matrix|追溯矩阵)" "C\) (Execution Anchors|执行锚点)" "D\) (MANUAL-\* Checklist|MANUAL-\* 清单)"; do
414
433
  if ! rg -n "${h}" "$verification_file" >/dev/null; then
415
434
  err "verification missing section '${h}': ${verification_file}"
@@ -263,7 +263,13 @@ cat <<'EOF' | render_template | write_file "${change_dir}/verification.md"
263
263
  ## Metadata
264
264
 
265
265
  - Change ID: `__CHANGE_ID__`
266
- - Status: Draft | Ready | Done | Archived
266
+ - Status: Draft
267
+ > Status lifecycle: Draft → Ready → Done → Archived
268
+ > - Draft: Initial state
269
+ > - Ready: Test plan ready (set by Test Owner)
270
+ > - Done: All tests passed + Review approved (set by **Reviewer only**)
271
+ > - Archived: Archived (set by Spec Gardener)
272
+ > **Constraint: Coder is prohibited from modifying Status field**
267
273
  - References:
268
274
  - Proposal: `__CHANGE_ROOT__/__CHANGE_ID__/proposal.md`
269
275
  - Design: `__CHANGE_ROOT__/__CHANGE_ID__/design.md`
@@ -40,6 +40,17 @@ allowed-tools:
40
40
 
41
41
  Test Owner 必须产出结构化的 `verification.md`,同时作为测试计划和追溯文档。
42
42
 
43
+ ### Status 字段权限
44
+
45
+ | 状态 | 含义 | 谁可以设置 |
46
+ |------|------|-----------|
47
+ | `Draft` | 初始状态 | 自动生成 |
48
+ | `Ready` | 测试计划就绪 | **Test Owner** |
49
+ | `Done` | Review 通过 | Reviewer(禁止 Test Owner/Coder) |
50
+ | `Archived` | 已归档 | Spec Gardener |
51
+
52
+ **约束**:Test Owner 完成测试计划后,应将 Status 设为 `Ready`。
53
+
43
54
  ```markdown
44
55
  # 验证计划:<change-id>
45
56
 
@@ -61,6 +61,7 @@ AI 编码助手很强大,但往往**不可预测**:
61
61
  | **Claude Code** | 完整 Skills | `CLAUDE.md` |
62
62
  | **Codex CLI** | 完整 Skills | `AGENTS.md` |
63
63
  | **Qoder** | 完整 Skills | `AGENTS.md` |
64
+ | **OpenCode(oh-my-opencode)** | 完整 Skills | `AGENTS.md` |
64
65
  | **Cursor** | Rules 系统 | `.cursor/rules/` |
65
66
  | **Windsurf** | Rules 系统 | `.windsurf/rules/` |
66
67
  | **Gemini CLI** | Rules 系统 | `GEMINI.md` |
@@ -98,6 +99,7 @@ npx dev-playbooks-cn@latest init
98
99
  初始化后:
99
100
  - Claude Code:`~/.claude/skills/devbooks-*`
100
101
  - Codex CLI:`~/.codex/skills/devbooks-*`
102
+ - OpenCode:`~/.config/opencode/skill/devbooks-*`
101
103
 
102
104
  ### 快速集成
103
105