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 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.AGENTS,
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.BASIC,
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, Continue'));
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
- const choices = AI_TOOLS.filter(t => t.available).map(tool => ({
283
- name: `${tool.name} ${chalk.gray(`(${tool.description})`)} ${getSkillsSupportLabel(tool.skillsSupport)}`,
284
- value: tool.id,
285
- checked: tool.id === 'claude' // 默认选中 Claude Code
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(仅 Claude Code Qoder)
361
+ // 安装 SkillsClaude 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
- if (toolId === 'claude' && tool.skillsDir) {
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: 'Claude Code', type: 'skills', count: installedCount, total: skillDirs.length });
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-playbooks-cn",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "AI-driven spec-based development workflow",
5
5
  "keywords": [
6
6
  "devbooks",
@@ -77,11 +77,18 @@ AI coding assistants are powerful, but often **unpredictable**:
77
77
 
78
78
  ### Supported AI tools
79
79
 
80
- | Tool | Slash commands | Natural language |
81
- |------|-----------|----------|
82
- | **Claude Code** | `/devbooks:*` | Yes |
83
- | **Codex CLI** | `/devbooks:*` | Yes |
84
- | Other assistants | - | “Run DevBooks proposal skill…” |
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: `$CODEX_HOME/skills/devbooks-*` (default `~/.codex/skills/devbooks-*`)
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