dev-playbooks 1.2.2 → 1.2.4
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 coding assistants are powerful, but often **unpredictable**:
|
|
|
46
46
|
| **Claude Code** | Full Skills | `CLAUDE.md` |
|
|
47
47
|
| **Codex CLI** | Full Skills | `AGENTS.md` |
|
|
48
48
|
| **Qoder** | Full Skills | `AGENTS.md` |
|
|
49
|
+
| **OpenCode (oh-my-opencode)** | Full Skills | `AGENTS.md` |
|
|
49
50
|
| **Cursor** | Rules | `.cursor/rules/` |
|
|
50
51
|
| **Windsurf** | Rules | `.windsurf/rules/` |
|
|
51
52
|
| **Gemini CLI** | Rules | `GEMINI.md` |
|
|
@@ -84,6 +85,7 @@ After initialization:
|
|
|
84
85
|
- Claude Code: `~/.claude/skills/devbooks-*`
|
|
85
86
|
- Codex CLI: `~/.codex/skills/devbooks-*`
|
|
86
87
|
- Qoder: `~/.qoder/` (manual setup required)
|
|
88
|
+
- OpenCode: `~/.config/opencode/skill/devbooks-*`
|
|
87
89
|
|
|
88
90
|
### Quick integration
|
|
89
91
|
|
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';
|
|
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,
|
|
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
|
|
554
|
-
if ((toolId === 'claude' || toolId === 'codex') && tool.skillsDir) {
|
|
555
|
+
// Claude Code / Codex CLI / OpenCode (incl. oh-my-opencode) share the same Skills format
|
|
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: project-level command entrypoint (.opencode/command/devbooks.md)
|
|
619
|
+
// ============================================================================
|
|
620
|
+
|
|
621
|
+
function generateOpenCodeDevbooksCommand() {
|
|
622
|
+
return `---
|
|
623
|
+
description: DevBooks workflow entrypoint (OpenCode / oh-my-opencode)
|
|
624
|
+
---
|
|
625
|
+
|
|
626
|
+
${DEVBOOKS_MARKERS.start}
|
|
627
|
+
# DevBooks (OpenCode / oh-my-opencode)
|
|
628
|
+
|
|
629
|
+
This project uses DevBooks for spec-driven development.
|
|
630
|
+
|
|
631
|
+
## Quick start
|
|
632
|
+
|
|
633
|
+
1. **Recommended entry (Router):** type \`/devbooks-router\` in chat
|
|
634
|
+
2. Or use natural language: \`Run devbooks-router skill: <your request>\`
|
|
635
|
+
|
|
636
|
+
> Note: In oh-my-opencode, installed Skills are also available as Slash Commands, so you can call them directly as \`/<skill-name>\`.
|
|
637
|
+
|
|
638
|
+
## Common commands (use /<skill-name>)
|
|
639
|
+
|
|
640
|
+
- \`/devbooks-router\`: workflow entry routing (recommends next step)
|
|
641
|
+
- \`/devbooks-impact-analysis\`: impact analysis (cross-module / external contracts)
|
|
642
|
+
- \`/devbooks-proposal-author\`: proposal stage (no coding)
|
|
643
|
+
- \`/devbooks-design-doc\`: design doc (What/Constraints + AC)
|
|
644
|
+
- \`/devbooks-implementation-plan\`: implementation plan (tasks.md)
|
|
645
|
+
- \`/devbooks-test-owner\`: acceptance tests + traceability (separate chat)
|
|
646
|
+
- \`/devbooks-coder\`: implement per tasks (do not modify tests/)
|
|
647
|
+
- \`/devbooks-spec-gardener\`: spec pruning before archive
|
|
648
|
+
|
|
649
|
+
## Hard constraints
|
|
650
|
+
|
|
651
|
+
- Before answering or writing code: run config discovery and read the rules doc (\`.devbooks/config.yaml\` → \`dev-playbooks/project.md\` → \`project.md\`)
|
|
652
|
+
- New features / breaking changes / architecture changes: create \`dev-playbooks/changes/<id>/\` and produce proposal/design/tasks/verification
|
|
653
|
+
- Test Owner and Coder must be in separate conversations; Coder must not modify \`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
|
// Install Claude Code Custom Subagents (solves built-in subagents cannot access Skills)
|
|
617
685
|
// ============================================================================
|
|
@@ -1084,6 +1152,12 @@ async function initCommand(projectDir, options) {
|
|
|
1084
1152
|
console.log(chalk.gray(` └ ${result.tool}: ${path.relative(projectDir, result.path)}`));
|
|
1085
1153
|
}
|
|
1086
1154
|
|
|
1155
|
+
// OpenCode: project-level command entrypoint (.opencode/command/devbooks.md)
|
|
1156
|
+
const openCodeCmdResults = installOpenCodeCommands(selectedTools, projectDir);
|
|
1157
|
+
for (const result of openCodeCmdResults) {
|
|
1158
|
+
console.log(chalk.gray(` └ ${result.tool}: ${path.relative(projectDir, result.path)}`));
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1087
1161
|
// Setup ignore files
|
|
1088
1162
|
const ignoreSpinner = ora('Configuring ignore files...').start();
|
|
1089
1163
|
const ignoreResults = setupIgnoreFiles(selectedTools, projectDir);
|
|
@@ -1193,6 +1267,14 @@ async function updateCommand(projectDir) {
|
|
|
1193
1267
|
}
|
|
1194
1268
|
}
|
|
1195
1269
|
|
|
1270
|
+
// OpenCode: update project-level command entrypoint (.opencode/command/devbooks.md)
|
|
1271
|
+
const openCodeCmdResults = installOpenCodeCommands(configuredTools, projectDir, true);
|
|
1272
|
+
for (const result of openCodeCmdResults) {
|
|
1273
|
+
if (result.action === 'updated') {
|
|
1274
|
+
console.log(chalk.green('✓') + ` ${result.tool}: updated command entrypoint ${path.relative(projectDir, result.path)}`);
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1196
1278
|
console.log();
|
|
1197
1279
|
console.log(chalk.green('✓') + ' Update complete!');
|
|
1198
1280
|
}
|
package/package.json
CHANGED
|
@@ -73,6 +73,16 @@ Main Plan Area writing rules (mandatory):
|
|
|
73
73
|
- Each task package must include: Purpose (Why), Deliverables, Impact Scope (Files/Modules), Acceptance Criteria, Dependencies, Risks.
|
|
74
74
|
- Subtasks should go up to interface/contract/behavior boundaries, not function bodies.
|
|
75
75
|
- Acceptance criteria must be observable and testable: specify which tests/acceptance checks to add/update and key metric thresholds.
|
|
76
|
+
- **Task checkbox format (required)**: each subtask must use Markdown task list format `- [ ]` to support Coder plan persistence.
|
|
77
|
+
- Initial state must be `- [ ]` (not done)
|
|
78
|
+
- Coder will update to `- [x]` (done) immediately after completing the subtask
|
|
79
|
+
- The subtask title must be on the checkbox line (do not replace it with `#### MPx.y:` headings)
|
|
80
|
+
- Example:
|
|
81
|
+
```markdown
|
|
82
|
+
### MP1: Task Package Name
|
|
83
|
+
- [ ] MP1.1 Subtask description
|
|
84
|
+
- [ ] MP1.2 Subtask description
|
|
85
|
+
```
|
|
76
86
|
|
|
77
87
|
Temporary Plan Area rules (mandatory):
|
|
78
88
|
- Only for off-plan high-priority tasks; include trigger reason, impact scope, minimal fix scope, regression test requirements.
|
|
@@ -46,6 +46,7 @@ AI coding assistants are powerful, but often **unpredictable**:
|
|
|
46
46
|
| **Claude Code** | Full Skills | `CLAUDE.md` |
|
|
47
47
|
| **Codex CLI** | Full Skills | `AGENTS.md` |
|
|
48
48
|
| **Qoder** | Full Skills | `AGENTS.md` |
|
|
49
|
+
| **OpenCode (oh-my-opencode)** | Full Skills | `AGENTS.md` |
|
|
49
50
|
| **Cursor** | Rules | `.cursor/rules/` |
|
|
50
51
|
| **Windsurf** | Rules | `.windsurf/rules/` |
|
|
51
52
|
| **Gemini CLI** | Rules | `GEMINI.md` |
|
|
@@ -84,6 +85,7 @@ After initialization:
|
|
|
84
85
|
- Claude Code: `~/.claude/skills/devbooks-*`
|
|
85
86
|
- Codex CLI: `~/.codex/skills/devbooks-*`
|
|
86
87
|
- Qoder: `~/.qoder/` (manual setup required)
|
|
88
|
+
- OpenCode: `~/.config/opencode/skill/devbooks-*`
|
|
87
89
|
|
|
88
90
|
### Quick integration
|
|
89
91
|
|