dev-playbooks-cn 1.0.0 → 1.0.1
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/bin/devbooks.js +43 -27
- package/package.json +1 -1
- package/templates/dev-playbooks/README.md +14 -6
- package/skills/devbooks-delivery-workflow/scripts/migrate-from-openspec.sh +0 -385
- package/skills/devbooks-delivery-workflow/scripts/verify-all.sh +0 -78
- package/skills/devbooks-delivery-workflow/scripts/verify-npm-package.sh +0 -123
- package/skills/devbooks-delivery-workflow/scripts/verify-openspec-free.sh +0 -81
- package/skills/devbooks-delivery-workflow/scripts/verify-slash-commands.sh +0 -146
package/bin/devbooks.js
CHANGED
|
@@ -131,23 +131,27 @@ const AI_TOOLS = [
|
|
|
131
131
|
instructionFile: '.github/copilot-instructions.md',
|
|
132
132
|
available: true
|
|
133
133
|
},
|
|
134
|
+
|
|
135
|
+
// === Continue(Rules/Prompts 系统)===
|
|
134
136
|
{
|
|
135
137
|
id: 'continue',
|
|
136
138
|
name: 'Continue',
|
|
137
139
|
description: 'Continue (VS Code / JetBrains)',
|
|
138
|
-
skillsSupport: SKILLS_SUPPORT.
|
|
140
|
+
skillsSupport: SKILLS_SUPPORT.RULES,
|
|
139
141
|
slashDir: '.continue/prompts/devbooks',
|
|
142
|
+
rulesDir: '.continue/rules',
|
|
140
143
|
instructionFile: null,
|
|
141
144
|
available: true
|
|
142
145
|
},
|
|
143
146
|
|
|
144
|
-
// ===
|
|
147
|
+
// === Codex CLI(完整 Skills 支持)===
|
|
145
148
|
{
|
|
146
149
|
id: 'codex',
|
|
147
150
|
name: 'Codex CLI',
|
|
148
151
|
description: 'OpenAI Codex CLI',
|
|
149
|
-
skillsSupport: SKILLS_SUPPORT.
|
|
152
|
+
skillsSupport: SKILLS_SUPPORT.FULL,
|
|
150
153
|
slashDir: null,
|
|
154
|
+
skillsDir: path.join(os.homedir(), '.codex', 'skills'),
|
|
151
155
|
globalSlashDir: path.join(os.homedir(), '.codex', 'prompts'),
|
|
152
156
|
instructionFile: 'AGENTS.md',
|
|
153
157
|
available: true
|
|
@@ -253,21 +257,17 @@ function printSkillsSupportInfo() {
|
|
|
253
257
|
console.log(chalk.gray('─'.repeat(50)));
|
|
254
258
|
console.log();
|
|
255
259
|
|
|
256
|
-
console.log(chalk.green('★ 完整 Skills') + chalk.gray(' - Claude Code, Qoder'));
|
|
260
|
+
console.log(chalk.green('★ 完整 Skills') + chalk.gray(' - Claude Code, Codex CLI, Qoder'));
|
|
257
261
|
console.log(chalk.gray(' └ 独立的 Skills/Agents 系统,可按需调用,有独立上下文'));
|
|
258
262
|
console.log();
|
|
259
263
|
|
|
260
|
-
console.log(chalk.blue('◆ Rules 系统') + chalk.gray(' - Cursor, Windsurf, Gemini, Antigravity, OpenCode'));
|
|
264
|
+
console.log(chalk.blue('◆ Rules 系统') + chalk.gray(' - Cursor, Windsurf, Gemini, Antigravity, OpenCode, Continue'));
|
|
261
265
|
console.log(chalk.gray(' └ 规则自动应用于匹配的文件/场景,功能接近 Skills'));
|
|
262
266
|
console.log();
|
|
263
267
|
|
|
264
|
-
console.log(chalk.yellow('● 自定义指令') + chalk.gray(' - GitHub Copilot
|
|
268
|
+
console.log(chalk.yellow('● 自定义指令') + chalk.gray(' - GitHub Copilot'));
|
|
265
269
|
console.log(chalk.gray(' └ 项目级指令文件,AI 会参考但无法主动调用'));
|
|
266
270
|
console.log();
|
|
267
|
-
|
|
268
|
-
console.log(chalk.gray('○ 基础支持') + chalk.gray(' - Codex'));
|
|
269
|
-
console.log(chalk.gray(' └ 仅支持全局提示词,通过 AGENTS.md 模拟'));
|
|
270
|
-
console.log();
|
|
271
271
|
console.log(chalk.gray('─'.repeat(50)));
|
|
272
272
|
console.log();
|
|
273
273
|
}
|
|
@@ -276,14 +276,30 @@ function printSkillsSupportInfo() {
|
|
|
276
276
|
// 交互式选择(inquirer)
|
|
277
277
|
// ============================================================================
|
|
278
278
|
|
|
279
|
-
async function promptToolSelection() {
|
|
279
|
+
async function promptToolSelection(projectDir) {
|
|
280
280
|
printSkillsSupportInfo();
|
|
281
281
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
282
|
+
// 读取已保存的配置
|
|
283
|
+
const config = loadConfig(projectDir);
|
|
284
|
+
const savedTools = config.aiTools || [];
|
|
285
|
+
const hasSavedConfig = savedTools.length > 0;
|
|
286
|
+
|
|
287
|
+
const choices = AI_TOOLS.filter(t => t.available).map(tool => {
|
|
288
|
+
const isSelected = hasSavedConfig
|
|
289
|
+
? savedTools.includes(tool.id)
|
|
290
|
+
: tool.id === 'claude'; // 首次运行默认选中 Claude Code
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
name: `${tool.name} ${chalk.gray(`(${tool.description})`)} ${getSkillsSupportLabel(tool.skillsSupport)}`,
|
|
294
|
+
value: tool.id,
|
|
295
|
+
checked: isSelected
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
if (hasSavedConfig) {
|
|
300
|
+
console.log(chalk.blue('ℹ') + ` 检测到已保存的配置: ${savedTools.join(', ')}`);
|
|
301
|
+
console.log();
|
|
302
|
+
}
|
|
287
303
|
|
|
288
304
|
const selectedTools = await checkbox({
|
|
289
305
|
message: '选择要配置的 AI 工具(空格选择,回车确认)',
|
|
@@ -342,7 +358,7 @@ function installSlashCommands(toolIds, projectDir) {
|
|
|
342
358
|
}
|
|
343
359
|
|
|
344
360
|
// ============================================================================
|
|
345
|
-
// 安装 Skills
|
|
361
|
+
// 安装 Skills(Claude Code, Codex CLI, Qoder)
|
|
346
362
|
// ============================================================================
|
|
347
363
|
|
|
348
364
|
function installSkills(toolIds, update = false) {
|
|
@@ -352,7 +368,8 @@ function installSkills(toolIds, update = false) {
|
|
|
352
368
|
const tool = AI_TOOLS.find(t => t.id === toolId);
|
|
353
369
|
if (!tool || tool.skillsSupport !== SKILLS_SUPPORT.FULL) continue;
|
|
354
370
|
|
|
355
|
-
|
|
371
|
+
// Claude Code 和 Codex CLI 都支持相同格式的 Skills
|
|
372
|
+
if ((toolId === 'claude' || toolId === 'codex') && tool.skillsDir) {
|
|
356
373
|
const skillsSrcDir = path.join(__dirname, '..', 'skills');
|
|
357
374
|
const skillsDestDir = tool.skillsDir;
|
|
358
375
|
|
|
@@ -380,7 +397,7 @@ function installSkills(toolIds, update = false) {
|
|
|
380
397
|
installedCount++;
|
|
381
398
|
}
|
|
382
399
|
|
|
383
|
-
results.push({ tool:
|
|
400
|
+
results.push({ tool: tool.name, type: 'skills', count: installedCount, total: skillDirs.length });
|
|
384
401
|
}
|
|
385
402
|
|
|
386
403
|
// Qoder: 创建 agents 目录结构(但不复制 Skills,因为格式不同)
|
|
@@ -393,7 +410,7 @@ function installSkills(toolIds, update = false) {
|
|
|
393
410
|
}
|
|
394
411
|
|
|
395
412
|
// ============================================================================
|
|
396
|
-
// 安装 Rules(Cursor, Windsurf, Gemini, Antigravity, OpenCode)
|
|
413
|
+
// 安装 Rules(Cursor, Windsurf, Gemini, Antigravity, OpenCode, Continue)
|
|
397
414
|
// ============================================================================
|
|
398
415
|
|
|
399
416
|
function installRules(toolIds, projectDir) {
|
|
@@ -436,7 +453,11 @@ description: DevBooks 工作流规则 - 在处理功能开发、架构变更时
|
|
|
436
453
|
antigravity: `---
|
|
437
454
|
description: DevBooks 工作流规则
|
|
438
455
|
---`,
|
|
439
|
-
opencode: ''
|
|
456
|
+
opencode: '',
|
|
457
|
+
continue: `---
|
|
458
|
+
name: DevBooks 工作流规则
|
|
459
|
+
description: DevBooks spec-driven development workflow
|
|
460
|
+
---`
|
|
440
461
|
};
|
|
441
462
|
|
|
442
463
|
return `${frontmatter[toolId] || ''}
|
|
@@ -706,7 +727,7 @@ async function initCommand(projectDir, options) {
|
|
|
706
727
|
}
|
|
707
728
|
console.log(chalk.blue('ℹ') + ` 非交互式模式:${selectedTools.length > 0 ? selectedTools.join(', ') : '无'}`);
|
|
708
729
|
} else {
|
|
709
|
-
selectedTools = await promptToolSelection();
|
|
730
|
+
selectedTools = await promptToolSelection(projectDir);
|
|
710
731
|
}
|
|
711
732
|
|
|
712
733
|
// 创建项目结构
|
|
@@ -916,11 +937,6 @@ function showHelp() {
|
|
|
916
937
|
}
|
|
917
938
|
|
|
918
939
|
console.log();
|
|
919
|
-
console.log(chalk.gray(' ○ 基础支持:'));
|
|
920
|
-
for (const tool of groupedTools[SKILLS_SUPPORT.BASIC]) {
|
|
921
|
-
console.log(` ${tool.id.padEnd(15)} ${tool.name}`);
|
|
922
|
-
}
|
|
923
|
-
|
|
924
940
|
console.log();
|
|
925
941
|
console.log(chalk.cyan('示例:'));
|
|
926
942
|
console.log(` ${CLI_COMMAND} init # 交互式初始化`);
|
package/package.json
CHANGED
|
@@ -77,11 +77,18 @@ AI coding assistants are powerful, but often **unpredictable**:
|
|
|
77
77
|
|
|
78
78
|
### Supported AI tools
|
|
79
79
|
|
|
80
|
-
| Tool | Slash
|
|
81
|
-
|
|
82
|
-
| **Claude Code** | `/devbooks:*` |
|
|
83
|
-
| **Codex CLI** | `/devbooks:*` |
|
|
84
|
-
|
|
|
80
|
+
| Tool | Support Level | Slash Commands | Config File |
|
|
81
|
+
|------|---------------|----------------|-------------|
|
|
82
|
+
| **Claude Code** | Full Skills | `/devbooks:*` | `CLAUDE.md` |
|
|
83
|
+
| **Codex CLI** | Full Skills | `/devbooks:*` | `AGENTS.md` |
|
|
84
|
+
| **Qoder** | Full Skills | `/devbooks:*` | `AGENTS.md` |
|
|
85
|
+
| **Cursor** | Rules | - | `.cursor/rules/` |
|
|
86
|
+
| **Windsurf** | Rules | - | `.windsurf/rules/` |
|
|
87
|
+
| **Gemini CLI** | Rules | - | `GEMINI.md` |
|
|
88
|
+
| **Continue** | Rules | - | `.continue/rules/` |
|
|
89
|
+
| **GitHub Copilot** | Instructions | - | `.github/copilot-instructions.md` |
|
|
90
|
+
|
|
91
|
+
> **Tip**: For tools without Slash command support, use natural language, e.g., "Run DevBooks proposal skill..."
|
|
85
92
|
|
|
86
93
|
### Install & init
|
|
87
94
|
|
|
@@ -111,7 +118,8 @@ npx dev-playbooks-cn@latest init
|
|
|
111
118
|
|
|
112
119
|
After initialization:
|
|
113
120
|
- Claude Code: `~/.claude/skills/devbooks-*`
|
|
114
|
-
- Codex CLI:
|
|
121
|
+
- Codex CLI: `~/.codex/skills/devbooks-*`
|
|
122
|
+
- Qoder: `~/.qoder/` (manual setup required)
|
|
115
123
|
|
|
116
124
|
### Quick integration
|
|
117
125
|
|
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# skills/devbooks-delivery-workflow/scripts/migrate-to-devbooks-2.sh
|
|
3
|
-
# OpenSpec -> DevBooks 2.0 Migration Script
|
|
4
|
-
#
|
|
5
|
-
# Migrate dev-playbooks/ directory structure to dev-playbooks/.
|
|
6
|
-
# Supports idempotent execution, state checkpoints, and reference updates.
|
|
7
|
-
#
|
|
8
|
-
# Usage:
|
|
9
|
-
# ./migrate-to-devbooks-2.sh [options]
|
|
10
|
-
# ./migrate-to-devbooks-2.sh --help
|
|
11
|
-
#
|
|
12
|
-
# Exit codes:
|
|
13
|
-
# 0 - Migration successful
|
|
14
|
-
# 1 - Migration failed
|
|
15
|
-
# 2 - Usage error
|
|
16
|
-
|
|
17
|
-
set -euo pipefail
|
|
18
|
-
|
|
19
|
-
VERSION="1.0.0"
|
|
20
|
-
|
|
21
|
-
# Default configuration
|
|
22
|
-
project_root="."
|
|
23
|
-
dry_run=false
|
|
24
|
-
keep_old=false
|
|
25
|
-
force=false
|
|
26
|
-
checkpoint_file=""
|
|
27
|
-
|
|
28
|
-
# Color definitions
|
|
29
|
-
RED='\033[0;31m'
|
|
30
|
-
GREEN='\033[0;32m'
|
|
31
|
-
YELLOW='\033[0;33m'
|
|
32
|
-
BLUE='\033[0;34m'
|
|
33
|
-
NC='\033[0m'
|
|
34
|
-
|
|
35
|
-
show_help() {
|
|
36
|
-
cat << 'EOF'
|
|
37
|
-
OpenSpec -> DevBooks 2.0 Migration Script (migrate-to-devbooks-2.sh)
|
|
38
|
-
|
|
39
|
-
Usage:
|
|
40
|
-
./migrate-to-devbooks-2.sh [options]
|
|
41
|
-
|
|
42
|
-
Options:
|
|
43
|
-
--project-root DIR Project root directory (default: current directory)
|
|
44
|
-
--dry-run Simulate run, do not actually modify files
|
|
45
|
-
--keep-old Keep dev-playbooks/ directory after migration
|
|
46
|
-
--force Force re-execute all steps (ignore checkpoints)
|
|
47
|
-
--help, -h Show help
|
|
48
|
-
|
|
49
|
-
Migration Steps:
|
|
50
|
-
1. [STRUCTURE] Create dev-playbooks/ directory structure
|
|
51
|
-
2. [CONTENT] Migrate specs/ and changes/ content
|
|
52
|
-
3. [CONFIG] Create/update .devbooks/config.yaml
|
|
53
|
-
4. [REFS] Update path references in all documents
|
|
54
|
-
5. [CLEANUP] Cleanup (optionally keep old directory)
|
|
55
|
-
|
|
56
|
-
Features:
|
|
57
|
-
- Idempotent execution: safe to run repeatedly
|
|
58
|
-
- State checkpoints: supports resume from breakpoint
|
|
59
|
-
- Reference updates: automatic batch path replacement
|
|
60
|
-
- Rollback support: use with migrate-from-openspec.sh
|
|
61
|
-
|
|
62
|
-
EOF
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
log_info() { echo -e "${BLUE}[INFO]${NC} $*"; }
|
|
66
|
-
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*" >&2; }
|
|
67
|
-
log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
|
|
68
|
-
log_pass() { echo -e "${GREEN}[PASS]${NC} $*"; }
|
|
69
|
-
log_step() { echo -e "${BLUE}[STEP]${NC} $*"; }
|
|
70
|
-
|
|
71
|
-
# Checkpoint management
|
|
72
|
-
init_checkpoint() {
|
|
73
|
-
checkpoint_file="${project_root}/.devbooks/.migrate-checkpoint"
|
|
74
|
-
if [[ "$force" == true ]]; then
|
|
75
|
-
rm -f "$checkpoint_file" 2>/dev/null || true
|
|
76
|
-
fi
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
save_checkpoint() {
|
|
80
|
-
local step="$1"
|
|
81
|
-
if [[ "$dry_run" == false ]]; then
|
|
82
|
-
mkdir -p "$(dirname "$checkpoint_file")"
|
|
83
|
-
echo "$step" >> "$checkpoint_file"
|
|
84
|
-
fi
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
is_step_done() {
|
|
88
|
-
local step="$1"
|
|
89
|
-
if [[ -f "$checkpoint_file" ]]; then
|
|
90
|
-
grep -qx "$step" "$checkpoint_file" 2>/dev/null
|
|
91
|
-
return $?
|
|
92
|
-
fi
|
|
93
|
-
return 1
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
# Step 1: Create directory structure
|
|
97
|
-
step_structure() {
|
|
98
|
-
log_step "1. Creating directory structure"
|
|
99
|
-
|
|
100
|
-
if is_step_done "STRUCTURE" && [[ "$force" == false ]]; then
|
|
101
|
-
log_info "Directory structure already created (skipping)"
|
|
102
|
-
return 0
|
|
103
|
-
fi
|
|
104
|
-
|
|
105
|
-
local dirs=(
|
|
106
|
-
"dev-playbooks"
|
|
107
|
-
"dev-playbooks/specs"
|
|
108
|
-
"dev-playbooks/specs/_meta"
|
|
109
|
-
"dev-playbooks/specs/_meta/anti-patterns"
|
|
110
|
-
"dev-playbooks/specs/_staged"
|
|
111
|
-
"dev-playbooks/specs/architecture"
|
|
112
|
-
"dev-playbooks/changes"
|
|
113
|
-
"dev-playbooks/changes/archive"
|
|
114
|
-
"dev-playbooks/scripts"
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
for dir in "${dirs[@]}"; do
|
|
118
|
-
local full_path="${project_root}/${dir}"
|
|
119
|
-
if [[ ! -d "$full_path" ]]; then
|
|
120
|
-
if [[ "$dry_run" == true ]]; then
|
|
121
|
-
log_info "[DRY-RUN] mkdir -p $full_path"
|
|
122
|
-
else
|
|
123
|
-
mkdir -p "$full_path"
|
|
124
|
-
fi
|
|
125
|
-
fi
|
|
126
|
-
done
|
|
127
|
-
|
|
128
|
-
save_checkpoint "STRUCTURE"
|
|
129
|
-
log_pass "Directory structure creation complete"
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
# Step 2: Migrate content
|
|
133
|
-
step_content() {
|
|
134
|
-
log_step "2. Migrating content"
|
|
135
|
-
|
|
136
|
-
if is_step_done "CONTENT" && [[ "$force" == false ]]; then
|
|
137
|
-
log_info "Content already migrated (skipping)"
|
|
138
|
-
return 0
|
|
139
|
-
fi
|
|
140
|
-
|
|
141
|
-
local openspec_dir="${project_root}/openspec"
|
|
142
|
-
|
|
143
|
-
if [[ ! -d "$openspec_dir" ]]; then
|
|
144
|
-
log_warn "dev-playbooks/ directory does not exist, skipping content migration"
|
|
145
|
-
save_checkpoint "CONTENT"
|
|
146
|
-
return 0
|
|
147
|
-
fi
|
|
148
|
-
|
|
149
|
-
# Migrate specs/
|
|
150
|
-
if [[ -d "${openspec_dir}/specs" ]]; then
|
|
151
|
-
log_info "Migrating specs/ ..."
|
|
152
|
-
if [[ "$dry_run" == true ]]; then
|
|
153
|
-
log_info "[DRY-RUN] cp -r ${openspec_dir}/specs/* ${project_root}/dev-playbooks/specs/"
|
|
154
|
-
else
|
|
155
|
-
cp -r "${openspec_dir}/specs/"* "${project_root}/dev-playbooks/specs/" 2>/dev/null || true
|
|
156
|
-
fi
|
|
157
|
-
fi
|
|
158
|
-
|
|
159
|
-
# Migrate changes/
|
|
160
|
-
if [[ -d "${openspec_dir}/changes" ]]; then
|
|
161
|
-
log_info "Migrating changes/ ..."
|
|
162
|
-
if [[ "$dry_run" == true ]]; then
|
|
163
|
-
log_info "[DRY-RUN] cp -r ${openspec_dir}/changes/* ${project_root}/dev-playbooks/changes/"
|
|
164
|
-
else
|
|
165
|
-
cp -r "${openspec_dir}/changes/"* "${project_root}/dev-playbooks/changes/" 2>/dev/null || true
|
|
166
|
-
fi
|
|
167
|
-
fi
|
|
168
|
-
|
|
169
|
-
# Migrate project.md
|
|
170
|
-
if [[ -f "${openspec_dir}/project.md" ]]; then
|
|
171
|
-
log_info "Migrating project.md ..."
|
|
172
|
-
if [[ "$dry_run" == true ]]; then
|
|
173
|
-
log_info "[DRY-RUN] cp ${openspec_dir}/project.md ${project_root}/dev-playbooks/project.md"
|
|
174
|
-
else
|
|
175
|
-
cp "${openspec_dir}/project.md" "${project_root}/dev-playbooks/project.md" 2>/dev/null || true
|
|
176
|
-
fi
|
|
177
|
-
fi
|
|
178
|
-
|
|
179
|
-
save_checkpoint "CONTENT"
|
|
180
|
-
log_pass "Content migration complete"
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
# Step 3: Create/update configuration
|
|
184
|
-
step_config() {
|
|
185
|
-
log_step "3. Creating/updating configuration"
|
|
186
|
-
|
|
187
|
-
if is_step_done "CONFIG" && [[ "$force" == false ]]; then
|
|
188
|
-
log_info "Configuration already updated (skipping)"
|
|
189
|
-
return 0
|
|
190
|
-
fi
|
|
191
|
-
|
|
192
|
-
local config_dir="${project_root}/.devbooks"
|
|
193
|
-
local config_file="${config_dir}/config.yaml"
|
|
194
|
-
|
|
195
|
-
if [[ "$dry_run" == true ]]; then
|
|
196
|
-
log_info "[DRY-RUN] Creating/updating ${config_file}"
|
|
197
|
-
else
|
|
198
|
-
mkdir -p "$config_dir"
|
|
199
|
-
|
|
200
|
-
# If configuration file does not exist or needs updating
|
|
201
|
-
if [[ ! -f "$config_file" ]] || grep -q "root: dev-playbooks/" "$config_file" 2>/dev/null; then
|
|
202
|
-
cat > "$config_file" << 'YAML'
|
|
203
|
-
# DevBooks 2.0 Configuration
|
|
204
|
-
# Generated by migrate-to-devbooks-2.sh
|
|
205
|
-
|
|
206
|
-
root: dev-playbooks/
|
|
207
|
-
constitution: constitution.md
|
|
208
|
-
project: project.md
|
|
209
|
-
|
|
210
|
-
paths:
|
|
211
|
-
specs: specs/
|
|
212
|
-
changes: changes/
|
|
213
|
-
staged: specs/_staged/
|
|
214
|
-
archive: changes/archive/
|
|
215
|
-
|
|
216
|
-
constraints:
|
|
217
|
-
require_constitution: true
|
|
218
|
-
allow_legacy_protocol: false
|
|
219
|
-
|
|
220
|
-
fitness:
|
|
221
|
-
mode: warn
|
|
222
|
-
rules_file: specs/architecture/fitness-rules.md
|
|
223
|
-
|
|
224
|
-
tracing:
|
|
225
|
-
coverage_threshold: 80
|
|
226
|
-
evidence_dir: evidence/
|
|
227
|
-
YAML
|
|
228
|
-
fi
|
|
229
|
-
fi
|
|
230
|
-
|
|
231
|
-
save_checkpoint "CONFIG"
|
|
232
|
-
log_pass "Configuration update complete"
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
# Step 4: Update references
|
|
236
|
-
step_refs() {
|
|
237
|
-
log_step "4. Updating path references"
|
|
238
|
-
|
|
239
|
-
if is_step_done "REFS" && [[ "$force" == false ]]; then
|
|
240
|
-
log_info "References already updated (skipping)"
|
|
241
|
-
return 0
|
|
242
|
-
fi
|
|
243
|
-
|
|
244
|
-
local files_updated=0
|
|
245
|
-
|
|
246
|
-
# Find files that need updating
|
|
247
|
-
while IFS= read -r file; do
|
|
248
|
-
[[ -z "$file" ]] && continue
|
|
249
|
-
[[ ! -f "$file" ]] && continue
|
|
250
|
-
|
|
251
|
-
# Skip binary files and .git directory
|
|
252
|
-
[[ "$file" == *".git"* ]] && continue
|
|
253
|
-
[[ "$file" == *".png" ]] && continue
|
|
254
|
-
[[ "$file" == *".jpg" ]] && continue
|
|
255
|
-
[[ "$file" == *".ico" ]] && continue
|
|
256
|
-
|
|
257
|
-
# Check if contains dev-playbooks/ references
|
|
258
|
-
if grep -q "dev-playbooks/" "$file" 2>/dev/null; then
|
|
259
|
-
if [[ "$dry_run" == true ]]; then
|
|
260
|
-
log_info "[DRY-RUN] Updating references: $file"
|
|
261
|
-
else
|
|
262
|
-
# macOS compatible sed
|
|
263
|
-
if [[ "$(uname)" == "Darwin" ]]; then
|
|
264
|
-
sed -i '' 's|dev-playbooks/|dev-playbooks/|g' "$file"
|
|
265
|
-
else
|
|
266
|
-
sed -i 's|dev-playbooks/|dev-playbooks/|g' "$file"
|
|
267
|
-
fi
|
|
268
|
-
fi
|
|
269
|
-
files_updated=$((files_updated + 1))
|
|
270
|
-
fi
|
|
271
|
-
done < <(find "${project_root}" -type f \( -name "*.md" -o -name "*.yaml" -o -name "*.yml" -o -name "*.sh" -o -name "*.ts" -o -name "*.js" -o -name "*.json" \) 2>/dev/null)
|
|
272
|
-
|
|
273
|
-
save_checkpoint "REFS"
|
|
274
|
-
log_pass "Updated references in ${files_updated} files"
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
# Step 5: Cleanup
|
|
278
|
-
step_cleanup() {
|
|
279
|
-
log_step "5. Cleanup"
|
|
280
|
-
|
|
281
|
-
if is_step_done "CLEANUP" && [[ "$force" == false ]]; then
|
|
282
|
-
log_info "Cleanup already complete (skipping)"
|
|
283
|
-
return 0
|
|
284
|
-
fi
|
|
285
|
-
|
|
286
|
-
local openspec_dir="${project_root}/openspec"
|
|
287
|
-
|
|
288
|
-
if [[ "$keep_old" == true ]]; then
|
|
289
|
-
log_info "Keeping dev-playbooks/ directory (--keep-old)"
|
|
290
|
-
elif [[ -d "$openspec_dir" ]]; then
|
|
291
|
-
if [[ "$dry_run" == true ]]; then
|
|
292
|
-
log_info "[DRY-RUN] rm -rf $openspec_dir"
|
|
293
|
-
else
|
|
294
|
-
# Create backup
|
|
295
|
-
local backup_dir="${project_root}/.devbooks/backup/openspec-$(date +%Y%m%d%H%M%S)"
|
|
296
|
-
mkdir -p "$(dirname "$backup_dir")"
|
|
297
|
-
mv "$openspec_dir" "$backup_dir"
|
|
298
|
-
log_info "Backed up dev-playbooks/ to ${backup_dir}"
|
|
299
|
-
fi
|
|
300
|
-
fi
|
|
301
|
-
|
|
302
|
-
save_checkpoint "CLEANUP"
|
|
303
|
-
log_pass "Cleanup complete"
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
# Verify migration result
|
|
307
|
-
verify_migration() {
|
|
308
|
-
log_step "Verifying migration result"
|
|
309
|
-
|
|
310
|
-
local errors=0
|
|
311
|
-
|
|
312
|
-
# Check directory structure
|
|
313
|
-
local required_dirs=(
|
|
314
|
-
"dev-playbooks"
|
|
315
|
-
"dev-playbooks/specs"
|
|
316
|
-
"dev-playbooks/changes"
|
|
317
|
-
)
|
|
318
|
-
|
|
319
|
-
for dir in "${required_dirs[@]}"; do
|
|
320
|
-
if [[ ! -d "${project_root}/${dir}" ]]; then
|
|
321
|
-
log_error "Missing directory: $dir"
|
|
322
|
-
errors=$((errors + 1))
|
|
323
|
-
fi
|
|
324
|
-
done
|
|
325
|
-
|
|
326
|
-
# Check configuration file
|
|
327
|
-
if [[ ! -f "${project_root}/.devbooks/config.yaml" ]]; then
|
|
328
|
-
log_error "Missing configuration file: .devbooks/config.yaml"
|
|
329
|
-
errors=$((errors + 1))
|
|
330
|
-
fi
|
|
331
|
-
|
|
332
|
-
# Check remaining references (warning only)
|
|
333
|
-
local remaining_refs
|
|
334
|
-
remaining_refs=$(grep -r "dev-playbooks/" "${project_root}" --include="*.md" --include="*.yaml" --include="*.sh" 2>/dev/null | grep -v ".devbooks/backup" | wc -l || echo "0")
|
|
335
|
-
if [[ "$remaining_refs" -gt 0 ]]; then
|
|
336
|
-
log_warn "Still ${remaining_refs} dev-playbooks/ references remaining"
|
|
337
|
-
fi
|
|
338
|
-
|
|
339
|
-
if [[ "$errors" -eq 0 ]]; then
|
|
340
|
-
log_pass "Migration verification passed"
|
|
341
|
-
return 0
|
|
342
|
-
else
|
|
343
|
-
log_error "Migration verification failed, ${errors} errors"
|
|
344
|
-
return 1
|
|
345
|
-
fi
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
main() {
|
|
349
|
-
while [[ $# -gt 0 ]]; do
|
|
350
|
-
case "$1" in
|
|
351
|
-
--help|-h) show_help; exit 0 ;;
|
|
352
|
-
--version|-v) echo "migrate-to-devbooks-2.sh v${VERSION}"; exit 0 ;;
|
|
353
|
-
--project-root) project_root="${2:-.}"; shift 2 ;;
|
|
354
|
-
--dry-run) dry_run=true; shift ;;
|
|
355
|
-
--keep-old) keep_old=true; shift ;;
|
|
356
|
-
--force) force=true; shift ;;
|
|
357
|
-
-*) log_error "Unknown option: $1"; exit 2 ;;
|
|
358
|
-
*) log_error "Unknown argument: $1"; exit 2 ;;
|
|
359
|
-
esac
|
|
360
|
-
done
|
|
361
|
-
|
|
362
|
-
log_info "OpenSpec -> DevBooks 2.0 Migration"
|
|
363
|
-
log_info "Project root: ${project_root}"
|
|
364
|
-
[[ "$dry_run" == true ]] && log_info "Mode: DRY-RUN"
|
|
365
|
-
[[ "$force" == true ]] && log_info "Mode: FORCE"
|
|
366
|
-
|
|
367
|
-
init_checkpoint
|
|
368
|
-
|
|
369
|
-
# Execute migration steps
|
|
370
|
-
step_structure
|
|
371
|
-
step_content
|
|
372
|
-
step_config
|
|
373
|
-
step_refs
|
|
374
|
-
step_cleanup
|
|
375
|
-
|
|
376
|
-
# Verify
|
|
377
|
-
if [[ "$dry_run" == false ]]; then
|
|
378
|
-
verify_migration
|
|
379
|
-
fi
|
|
380
|
-
|
|
381
|
-
log_pass "Migration complete!"
|
|
382
|
-
exit 0
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
main "$@"
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# verify-all.sh - Run all verification scripts
|
|
3
|
-
#
|
|
4
|
-
# Aggregate AC-001 ~ AC-022 verification results
|
|
5
|
-
|
|
6
|
-
set -uo pipefail
|
|
7
|
-
|
|
8
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
-
|
|
10
|
-
GREEN='\033[0;32m'
|
|
11
|
-
RED='\033[0;31m'
|
|
12
|
-
YELLOW='\033[1;33m'
|
|
13
|
-
CYAN='\033[0;36m'
|
|
14
|
-
NC='\033[0m'
|
|
15
|
-
|
|
16
|
-
echo -e "${CYAN}╔════════════════════════════════════════════════╗${NC}"
|
|
17
|
-
echo -e "${CYAN}║ DevBooks Independence Verification Suite ║${NC}"
|
|
18
|
-
echo -e "${CYAN}╚════════════════════════════════════════════════╝${NC}"
|
|
19
|
-
echo ""
|
|
20
|
-
|
|
21
|
-
# Run each verification script
|
|
22
|
-
echo -e "${YELLOW}>>> OpenSpec Cleanup Verification (AC-001 ~ AC-004)${NC}"
|
|
23
|
-
echo ""
|
|
24
|
-
openspec_result=0
|
|
25
|
-
if "$SCRIPT_DIR/verify-openspec-free.sh"; then
|
|
26
|
-
openspec_result=1
|
|
27
|
-
fi
|
|
28
|
-
echo ""
|
|
29
|
-
|
|
30
|
-
echo -e "${YELLOW}>>> Slash Command Verification (AC-005 ~ AC-010)${NC}"
|
|
31
|
-
echo ""
|
|
32
|
-
slash_result=0
|
|
33
|
-
if "$SCRIPT_DIR/verify-slash-commands.sh"; then
|
|
34
|
-
slash_result=1
|
|
35
|
-
fi
|
|
36
|
-
echo ""
|
|
37
|
-
|
|
38
|
-
echo -e "${YELLOW}>>> npm Package Verification (AC-011 ~ AC-016)${NC}"
|
|
39
|
-
echo ""
|
|
40
|
-
npm_result=0
|
|
41
|
-
if "$SCRIPT_DIR/verify-npm-package.sh"; then
|
|
42
|
-
npm_result=1
|
|
43
|
-
fi
|
|
44
|
-
echo ""
|
|
45
|
-
|
|
46
|
-
echo -e "${CYAN}╔════════════════════════════════════════════════╗${NC}"
|
|
47
|
-
echo -e "${CYAN}║ Summary Results ║${NC}"
|
|
48
|
-
echo -e "${CYAN}╚════════════════════════════════════════════════╝${NC}"
|
|
49
|
-
echo ""
|
|
50
|
-
|
|
51
|
-
if [[ $openspec_result -eq 1 ]]; then
|
|
52
|
-
echo -e "${GREEN}✅ OpenSpec Cleanup Verification${NC}"
|
|
53
|
-
else
|
|
54
|
-
echo -e "${RED}❌ OpenSpec Cleanup Verification${NC}"
|
|
55
|
-
fi
|
|
56
|
-
|
|
57
|
-
if [[ $slash_result -eq 1 ]]; then
|
|
58
|
-
echo -e "${GREEN}✅ Slash Command Verification${NC}"
|
|
59
|
-
else
|
|
60
|
-
echo -e "${RED}❌ Slash Command Verification${NC}"
|
|
61
|
-
fi
|
|
62
|
-
|
|
63
|
-
if [[ $npm_result -eq 1 ]]; then
|
|
64
|
-
echo -e "${GREEN}✅ npm Package Verification${NC}"
|
|
65
|
-
else
|
|
66
|
-
echo -e "${RED}❌ npm Package Verification${NC}"
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
echo ""
|
|
70
|
-
|
|
71
|
-
total=$((openspec_result + slash_result + npm_result))
|
|
72
|
-
if [[ $total -eq 3 ]]; then
|
|
73
|
-
echo -e "${GREEN}All verifications passed! DevBooks independence verification successful.${NC}"
|
|
74
|
-
exit 0
|
|
75
|
-
else
|
|
76
|
-
echo -e "${RED}Some verifications failed, please check the output above.${NC}"
|
|
77
|
-
exit 1
|
|
78
|
-
fi
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# verify-npm-package.sh - Verify npm package structure
|
|
3
|
-
#
|
|
4
|
-
# Verify AC-011 ~ AC-016
|
|
5
|
-
|
|
6
|
-
set -uo pipefail # Remove -e, handle errors manually
|
|
7
|
-
|
|
8
|
-
GREEN='\033[0;32m'
|
|
9
|
-
RED='\033[0;31m'
|
|
10
|
-
NC='\033[0m'
|
|
11
|
-
|
|
12
|
-
PASSED=0
|
|
13
|
-
FAILED=0
|
|
14
|
-
|
|
15
|
-
check() {
|
|
16
|
-
local name="$1"
|
|
17
|
-
local result="$2"
|
|
18
|
-
if [[ "$result" == "0" ]]; then
|
|
19
|
-
echo -e "${GREEN}✅ $name${NC}"
|
|
20
|
-
PASSED=$((PASSED + 1))
|
|
21
|
-
else
|
|
22
|
-
echo -e "${RED}❌ $name${NC}"
|
|
23
|
-
FAILED=$((FAILED + 1))
|
|
24
|
-
fi
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
echo "=== npm Package Verification ==="
|
|
28
|
-
echo ""
|
|
29
|
-
|
|
30
|
-
# Use an isolated npm cache to avoid permission issues in CI/dev environments.
|
|
31
|
-
NPM_CACHE_DIR="$(mktemp -d 2>/dev/null || mktemp -d -t 'devbooks-npm-cache')"
|
|
32
|
-
cleanup() {
|
|
33
|
-
rm -rf "$NPM_CACHE_DIR"
|
|
34
|
-
}
|
|
35
|
-
trap cleanup EXIT
|
|
36
|
-
|
|
37
|
-
# AC-011: CLI entry exists and is executable
|
|
38
|
-
# Note: Design changed to `devbooks init` instead of `create-devbooks`
|
|
39
|
-
echo "AC-011: Checking CLI entry..."
|
|
40
|
-
if [[ -f "bin/devbooks.js" ]] && [[ -x "bin/devbooks.js" ]]; then
|
|
41
|
-
check "AC-011: CLI entry exists and is executable" "0"
|
|
42
|
-
else
|
|
43
|
-
check "AC-011: CLI entry exists and is executable" "1"
|
|
44
|
-
fi
|
|
45
|
-
|
|
46
|
-
# AC-012: package.json exists and is valid
|
|
47
|
-
echo "AC-012: Checking package.json..."
|
|
48
|
-
if [[ -f "package.json" ]] && node -e '
|
|
49
|
-
const fs = require("fs");
|
|
50
|
-
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
51
|
-
const hasName = typeof pkg.name === "string" && pkg.name.trim().length > 0;
|
|
52
|
-
const bin = pkg.bin;
|
|
53
|
-
const normalize = (p) => (typeof p === "string" && p.startsWith("./")) ? p.slice(2) : p;
|
|
54
|
-
const hasBin = (() => {
|
|
55
|
-
if (typeof bin === "string") return normalize(bin) === "bin/devbooks.js";
|
|
56
|
-
if (!bin || typeof bin !== "object") return false;
|
|
57
|
-
return Object.values(bin).some(v => typeof v === "string" && normalize(v) === "bin/devbooks.js");
|
|
58
|
-
})();
|
|
59
|
-
process.exit(hasName && hasBin ? 0 : 1);
|
|
60
|
-
' >/dev/null 2>&1; then
|
|
61
|
-
check "AC-012: package.json exists and is valid" "0"
|
|
62
|
-
else
|
|
63
|
-
check "AC-012: package.json exists and is valid" "1"
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
|
-
# AC-013: templates/ directory exists
|
|
67
|
-
echo "AC-013: Checking templates/ directory..."
|
|
68
|
-
if [[ -d "templates" ]]; then
|
|
69
|
-
check "AC-013: templates/ directory exists" "0"
|
|
70
|
-
else
|
|
71
|
-
check "AC-013: templates/ directory exists" "1"
|
|
72
|
-
fi
|
|
73
|
-
|
|
74
|
-
# AC-014: Skills count is correct (21 devbooks-* Skills)
|
|
75
|
-
echo "AC-014: Checking Skills count..."
|
|
76
|
-
skill_count=$(ls -d skills/devbooks-* 2>/dev/null | wc -l | tr -d ' ')
|
|
77
|
-
if [[ "$skill_count" -ge 20 ]]; then
|
|
78
|
-
check "AC-014: Skills count is correct ($skill_count)" "0"
|
|
79
|
-
else
|
|
80
|
-
check "AC-014: Skills count is correct ($skill_count, expected >= 20)" "1"
|
|
81
|
-
fi
|
|
82
|
-
|
|
83
|
-
# AC-015: Packaging is controlled (files whitelist or .npmignore)
|
|
84
|
-
echo "AC-015: Checking packaging control..."
|
|
85
|
-
has_files_whitelist="1"
|
|
86
|
-
if [[ -f "package.json" ]] && node -e '
|
|
87
|
-
const fs = require("fs");
|
|
88
|
-
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
89
|
-
const files = pkg.files;
|
|
90
|
-
const ok = Array.isArray(files) && files.length > 0;
|
|
91
|
-
process.exit(ok ? 0 : 1);
|
|
92
|
-
' >/dev/null 2>&1; then
|
|
93
|
-
has_files_whitelist="0"
|
|
94
|
-
fi
|
|
95
|
-
if [[ "$has_files_whitelist" == "0" || -f ".npmignore" ]]; then
|
|
96
|
-
check "AC-015: packaging is controlled" "0"
|
|
97
|
-
else
|
|
98
|
-
check "AC-015: packaging is controlled" "1"
|
|
99
|
-
fi
|
|
100
|
-
|
|
101
|
-
# AC-016: npm pack does not include project change packages (exclude template directory)
|
|
102
|
-
# Note: templates/dev-playbooks/changes/ is user project template, should be included
|
|
103
|
-
# dev-playbooks/changes/ is project development change package, should be excluded
|
|
104
|
-
echo "AC-016: Checking npm pack output..."
|
|
105
|
-
pack_output="$(npm --cache "$NPM_CACHE_DIR" pack --dry-run --ignore-scripts 2>&1 || true)"
|
|
106
|
-
if echo "$pack_output" | grep "changes/" | grep -v "templates/" | grep -q "changes/"; then
|
|
107
|
-
check "AC-016: npm pack does not include changes/" "1"
|
|
108
|
-
else
|
|
109
|
-
check "AC-016: npm pack does not include changes/" "0"
|
|
110
|
-
fi
|
|
111
|
-
|
|
112
|
-
echo ""
|
|
113
|
-
echo "=== Results ==="
|
|
114
|
-
echo "Passed: $PASSED"
|
|
115
|
-
echo "Failed: $FAILED"
|
|
116
|
-
|
|
117
|
-
if [[ $FAILED -eq 0 ]]; then
|
|
118
|
-
echo -e "${GREEN}All passed!${NC}"
|
|
119
|
-
exit 0
|
|
120
|
-
else
|
|
121
|
-
echo -e "${RED}Some checks failed${NC}"
|
|
122
|
-
exit 1
|
|
123
|
-
fi
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# verify-openspec-free.sh - Verify OpenSpec references are cleared
|
|
3
|
-
#
|
|
4
|
-
# Verify AC-001 ~ AC-004
|
|
5
|
-
|
|
6
|
-
set -uo pipefail # Remove -e, handle errors manually
|
|
7
|
-
|
|
8
|
-
GREEN='\033[0;32m'
|
|
9
|
-
RED='\033[0;31m'
|
|
10
|
-
NC='\033[0m'
|
|
11
|
-
|
|
12
|
-
PASSED=0
|
|
13
|
-
FAILED=0
|
|
14
|
-
|
|
15
|
-
check() {
|
|
16
|
-
local name="$1"
|
|
17
|
-
local result="$2"
|
|
18
|
-
if [[ "$result" == "0" ]]; then
|
|
19
|
-
echo -e "${GREEN}✅ $name${NC}"
|
|
20
|
-
PASSED=$((PASSED + 1))
|
|
21
|
-
else
|
|
22
|
-
echo -e "${RED}❌ $name${NC}"
|
|
23
|
-
FAILED=$((FAILED + 1))
|
|
24
|
-
fi
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
echo "=== OpenSpec Cleanup Verification ==="
|
|
28
|
-
echo ""
|
|
29
|
-
|
|
30
|
-
# AC-001: No OpenSpec references (exclude legitimate references)
|
|
31
|
-
echo "AC-001: Checking OpenSpec references..."
|
|
32
|
-
# Exclude legitimate references:
|
|
33
|
-
# - backup, changes, .git: history/work directories
|
|
34
|
-
# - migrate-from-openspec.sh: migration script
|
|
35
|
-
# - verify-*.sh: verification scripts
|
|
36
|
-
# - c4.md: architecture documentation (records historical changes)
|
|
37
|
-
# - specs/config-protocol/spec.md: rule definition document
|
|
38
|
-
# - specs/slash-commands/spec.md: historical record document
|
|
39
|
-
ref_count=$(grep -rn "openspec\|OpenSpec" . --include="*.md" --include="*.sh" --include="*.yaml" --include="*.yml" --include="*.js" 2>/dev/null | grep -v backup | grep -v changes | grep -v "\.git" | grep -v "DEVBOOKS-EVOLUTION-PROPOSAL.md" | grep -v "migrate-from-openspec.sh" | grep -v "tests/" | grep -v "verify-openspec-free.sh" | grep -v "verify-all.sh" | grep -v "c4.md" | grep -v "specs/config-protocol/spec.md" | grep -v "specs/slash-commands/spec.md" | wc -l | tr -d ' ') || ref_count=0
|
|
40
|
-
if [[ "$ref_count" == "0" ]]; then
|
|
41
|
-
check "AC-001: OpenSpec references cleared" "0"
|
|
42
|
-
else
|
|
43
|
-
check "AC-001: OpenSpec references cleared ($ref_count remaining)" "1"
|
|
44
|
-
fi
|
|
45
|
-
|
|
46
|
-
# AC-002: setup/openspec deleted
|
|
47
|
-
echo "AC-002: Checking setup/openspec directory..."
|
|
48
|
-
if [[ ! -d "setup/openspec" ]]; then
|
|
49
|
-
check "AC-002: setup/openspec deleted" "0"
|
|
50
|
-
else
|
|
51
|
-
check "AC-002: setup/openspec deleted" "1"
|
|
52
|
-
fi
|
|
53
|
-
|
|
54
|
-
# AC-003: .claude/commands/openspec deleted
|
|
55
|
-
echo "AC-003: Checking .claude/commands/openspec directory..."
|
|
56
|
-
if [[ ! -d ".claude/commands/openspec" ]]; then
|
|
57
|
-
check "AC-003: .claude/commands/openspec deleted" "0"
|
|
58
|
-
else
|
|
59
|
-
check "AC-003: .claude/commands/openspec deleted" "1"
|
|
60
|
-
fi
|
|
61
|
-
|
|
62
|
-
# AC-004: dev-playbooks/specs/openspec-integration deleted
|
|
63
|
-
echo "AC-004: Checking dev-playbooks/specs/openspec-integration directory..."
|
|
64
|
-
if [[ ! -d "dev-playbooks/specs/openspec-integration" ]]; then
|
|
65
|
-
check "AC-004: dev-playbooks/specs/openspec-integration deleted" "0"
|
|
66
|
-
else
|
|
67
|
-
check "AC-004: dev-playbooks/specs/openspec-integration deleted" "1"
|
|
68
|
-
fi
|
|
69
|
-
|
|
70
|
-
echo ""
|
|
71
|
-
echo "=== Results ==="
|
|
72
|
-
echo "Passed: $PASSED"
|
|
73
|
-
echo "Failed: $FAILED"
|
|
74
|
-
|
|
75
|
-
if [[ $FAILED -eq 0 ]]; then
|
|
76
|
-
echo -e "${GREEN}All passed!${NC}"
|
|
77
|
-
exit 0
|
|
78
|
-
else
|
|
79
|
-
echo -e "${RED}Some checks failed${NC}"
|
|
80
|
-
exit 1
|
|
81
|
-
fi
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# verify-slash-commands.sh - Verify Slash command definitions
|
|
3
|
-
#
|
|
4
|
-
# Verify AC-001 (24 commands) and AC-002 (command to Skill 1:1 mapping)
|
|
5
|
-
|
|
6
|
-
set -uo pipefail
|
|
7
|
-
|
|
8
|
-
GREEN='\033[0;32m'
|
|
9
|
-
RED='\033[0;31m'
|
|
10
|
-
YELLOW='\033[1;33m'
|
|
11
|
-
NC='\033[0m'
|
|
12
|
-
|
|
13
|
-
PASSED=0
|
|
14
|
-
FAILED=0
|
|
15
|
-
|
|
16
|
-
check() {
|
|
17
|
-
local name="$1"
|
|
18
|
-
local result="$2"
|
|
19
|
-
if [[ "$result" == "0" ]]; then
|
|
20
|
-
echo -e "${GREEN}✅ $name${NC}"
|
|
21
|
-
PASSED=$((PASSED + 1))
|
|
22
|
-
else
|
|
23
|
-
echo -e "${RED}❌ $name${NC}"
|
|
24
|
-
FAILED=$((FAILED + 1))
|
|
25
|
-
fi
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
check_skill_mapping() {
|
|
29
|
-
local cmd="$1"
|
|
30
|
-
local expected_skill="$2"
|
|
31
|
-
local file="$COMMANDS_DIR/$cmd.md"
|
|
32
|
-
if [[ -f "$file" ]]; then
|
|
33
|
-
if grep -q "skill: $expected_skill" "$file"; then
|
|
34
|
-
check "AC-002: $cmd.md → $expected_skill" "0"
|
|
35
|
-
else
|
|
36
|
-
check "AC-002: $cmd.md → $expected_skill (skill metadata mismatch)" "1"
|
|
37
|
-
fi
|
|
38
|
-
fi
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
echo "=== Slash Command Verification (21 core + 3 backward compatible = 24 commands) ==="
|
|
42
|
-
echo ""
|
|
43
|
-
|
|
44
|
-
COMMANDS_DIR="templates/claude-commands/devbooks"
|
|
45
|
-
|
|
46
|
-
# AC-001: Check command count (24 = 21 core + 3 backward compatible)
|
|
47
|
-
echo "AC-001: Checking command count..."
|
|
48
|
-
cmd_count=$(ls "$COMMANDS_DIR"/*.md 2>/dev/null | wc -l | tr -d ' ')
|
|
49
|
-
if [[ "$cmd_count" -eq 24 ]]; then
|
|
50
|
-
check "AC-001: Command count is 24 (21 core + 3 backward compatible)" "0"
|
|
51
|
-
else
|
|
52
|
-
check "AC-001: Command count is 24 (actual: $cmd_count)" "1"
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
echo ""
|
|
56
|
-
echo "=== Checking 21 command file existence ==="
|
|
57
|
-
|
|
58
|
-
# 21 command files list
|
|
59
|
-
COMMANDS=(
|
|
60
|
-
"router"
|
|
61
|
-
"proposal"
|
|
62
|
-
"challenger"
|
|
63
|
-
"judge"
|
|
64
|
-
"debate"
|
|
65
|
-
"design"
|
|
66
|
-
"backport"
|
|
67
|
-
"plan"
|
|
68
|
-
"spec"
|
|
69
|
-
"gardener"
|
|
70
|
-
"test"
|
|
71
|
-
"test-review"
|
|
72
|
-
"code"
|
|
73
|
-
"review"
|
|
74
|
-
"delivery"
|
|
75
|
-
"c4"
|
|
76
|
-
"impact"
|
|
77
|
-
"entropy"
|
|
78
|
-
"federation"
|
|
79
|
-
"bootstrap"
|
|
80
|
-
"index"
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
for cmd in "${COMMANDS[@]}"; do
|
|
84
|
-
if [[ -f "$COMMANDS_DIR/$cmd.md" ]]; then
|
|
85
|
-
check "AC-011~AC-031: $cmd.md exists" "0"
|
|
86
|
-
else
|
|
87
|
-
check "AC-011~AC-031: $cmd.md exists" "1"
|
|
88
|
-
fi
|
|
89
|
-
done
|
|
90
|
-
|
|
91
|
-
echo ""
|
|
92
|
-
echo "=== AC-002: Checking command to Skill mapping ==="
|
|
93
|
-
|
|
94
|
-
# Command -> Skill mapping check
|
|
95
|
-
check_skill_mapping "router" "devbooks-router"
|
|
96
|
-
check_skill_mapping "proposal" "devbooks-proposal-author"
|
|
97
|
-
check_skill_mapping "challenger" "devbooks-proposal-challenger"
|
|
98
|
-
check_skill_mapping "judge" "devbooks-proposal-judge"
|
|
99
|
-
check_skill_mapping "debate" "devbooks-proposal-debate-workflow"
|
|
100
|
-
check_skill_mapping "design" "devbooks-design-doc"
|
|
101
|
-
check_skill_mapping "backport" "devbooks-design-backport"
|
|
102
|
-
check_skill_mapping "plan" "devbooks-implementation-plan"
|
|
103
|
-
check_skill_mapping "spec" "devbooks-spec-contract"
|
|
104
|
-
check_skill_mapping "gardener" "devbooks-spec-gardener"
|
|
105
|
-
check_skill_mapping "test" "devbooks-test-owner"
|
|
106
|
-
check_skill_mapping "test-review" "devbooks-test-reviewer"
|
|
107
|
-
check_skill_mapping "code" "devbooks-coder"
|
|
108
|
-
check_skill_mapping "review" "devbooks-code-review"
|
|
109
|
-
check_skill_mapping "delivery" "devbooks-delivery-workflow"
|
|
110
|
-
check_skill_mapping "c4" "devbooks-c4-map"
|
|
111
|
-
check_skill_mapping "impact" "devbooks-impact-analysis"
|
|
112
|
-
check_skill_mapping "entropy" "devbooks-entropy-monitor"
|
|
113
|
-
check_skill_mapping "federation" "devbooks-federation"
|
|
114
|
-
check_skill_mapping "bootstrap" "devbooks-brownfield-bootstrap"
|
|
115
|
-
check_skill_mapping "index" "devbooks-index-bootstrap"
|
|
116
|
-
|
|
117
|
-
echo ""
|
|
118
|
-
echo "=== AC-008: Checking backward compatible commands ==="
|
|
119
|
-
|
|
120
|
-
# Backward compatible commands list
|
|
121
|
-
COMPAT_COMMANDS=("apply" "archive" "quick")
|
|
122
|
-
|
|
123
|
-
for cmd in "${COMPAT_COMMANDS[@]}"; do
|
|
124
|
-
if [[ -f "$COMMANDS_DIR/$cmd.md" ]]; then
|
|
125
|
-
if grep -q "backward-compat: true" "$COMMANDS_DIR/$cmd.md"; then
|
|
126
|
-
check "AC-008: $cmd.md exists and marked as backward compatible" "0"
|
|
127
|
-
else
|
|
128
|
-
check "AC-008: $cmd.md exists but missing backward-compat marker" "1"
|
|
129
|
-
fi
|
|
130
|
-
else
|
|
131
|
-
check "AC-008: $cmd.md exists" "1"
|
|
132
|
-
fi
|
|
133
|
-
done
|
|
134
|
-
|
|
135
|
-
echo ""
|
|
136
|
-
echo "=== Results ==="
|
|
137
|
-
echo "Passed: $PASSED"
|
|
138
|
-
echo "Failed: $FAILED"
|
|
139
|
-
|
|
140
|
-
if [[ $FAILED -eq 0 ]]; then
|
|
141
|
-
echo -e "${GREEN}All passed!${NC}"
|
|
142
|
-
exit 0
|
|
143
|
-
else
|
|
144
|
-
echo -e "${RED}Some checks failed${NC}"
|
|
145
|
-
exit 1
|
|
146
|
-
fi
|