dev-playbooks 1.5.4 → 1.5.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
@@ -196,7 +196,6 @@ Run devbooks-archiver skill for change add-oauth2
196
196
  | Skill | Description |
197
197
  |-------|-------------|
198
198
  | devbooks-archiver | Maintain/dedupe specs |
199
- | devbooks-delivery-workflow | End-to-end delivery workflow |
200
199
 
201
200
  ### Standalone Skills
202
201
 
@@ -206,6 +205,14 @@ Run devbooks-archiver skill for change add-oauth2
206
205
  | devbooks-brownfield-bootstrap | Brownfield project bootstrap |
207
206
  | devbooks-convergence-audit | Convergence audit (anti-deception design) |
208
207
 
208
+ ### Orchestration Layer (For tools with sub-agent support)
209
+
210
+ | Skill | Description |
211
+ |-------|-------------|
212
+ | devbooks-delivery-workflow | Complete closed-loop orchestrator, auto-orchestrates Proposal→Design→Spec→Plan→Test→Code→Review→Archive workflow |
213
+
214
+ > **Note**: `devbooks-delivery-workflow` is an orchestration layer Skill, designed for AI programming tools with sub-agent support (e.g., Claude Code with Task tool). It calls sub-agents to execute each stage's Skill, completing the full change closed-loop.
215
+
209
216
  ---
210
217
 
211
218
  ## DevBooks Comparisons
package/bin/devbooks.js CHANGED
@@ -5,17 +5,17 @@
5
5
  *
6
6
  * AI-agnostic spec-driven development workflow
7
7
  *
8
- * 用法:
9
- * dev-playbooks-cn init [path] [options]
10
- * dev-playbooks-cn update [path]
11
- * dev-playbooks-cn migrate --from <framework> [options]
8
+ * Usage:
9
+ * dev-playbooks init [path] [options]
10
+ * dev-playbooks update [path] # Update CLI and configured tools
11
+ * dev-playbooks migrate --from <framework> [options]
12
12
  *
13
- * 选项:
14
- * --tools <tools> 非交互式指定 AI 工具:all, none, 或逗号分隔的列表
15
- * --from <framework> 迁移来源框架:openspec, speckit
16
- * --dry-run 模拟运行,不实际修改文件
17
- * --keep-old 迁移后保留原目录
18
- * --help 显示帮助信息
13
+ * Options:
14
+ * --tools <tools> Non-interactive tool selection: all, none, or comma-separated list
15
+ * --from <framework> Migration source: openspec, speckit
16
+ * --dry-run Dry run, don't modify files
17
+ * --keep-old Keep old directory after migration
18
+ * --help Show help
19
19
  * --version Show version
20
20
  */
21
21
 
@@ -316,6 +316,70 @@ function getCliVersion() {
316
316
  }
317
317
  }
318
318
 
319
+ /**
320
+ * Check if a new version is available on npm
321
+ * @returns {Promise<{hasUpdate: boolean, latestVersion: string|null, currentVersion: string}>}
322
+ */
323
+ async function checkNpmUpdate() {
324
+ const currentVersion = getCliVersion();
325
+ try {
326
+ const { execSync } = await import('child_process');
327
+ const latestVersion = execSync(`npm view ${CLI_COMMAND} version`, {
328
+ encoding: 'utf-8',
329
+ timeout: 10000,
330
+ stdio: ['pipe', 'pipe', 'pipe']
331
+ }).trim();
332
+
333
+ if (latestVersion && latestVersion !== currentVersion) {
334
+ // Simple semver comparison
335
+ const current = currentVersion.split('.').map(Number);
336
+ const latest = latestVersion.split('.').map(Number);
337
+ const hasUpdate = latest[0] > current[0] ||
338
+ (latest[0] === current[0] && latest[1] > current[1]) ||
339
+ (latest[0] === current[0] && latest[1] === current[1] && latest[2] > current[2]);
340
+ return { hasUpdate, latestVersion, currentVersion };
341
+ }
342
+ return { hasUpdate: false, latestVersion, currentVersion };
343
+ } catch {
344
+ // Network error or timeout, silently ignore
345
+ return { hasUpdate: false, latestVersion: null, currentVersion };
346
+ }
347
+ }
348
+
349
+ /**
350
+ * Perform npm global update
351
+ * @returns {Promise<boolean>} Whether the update succeeded
352
+ */
353
+ async function performNpmUpdate() {
354
+ return new Promise((resolve) => {
355
+ const spinner = ora(`Updating ${CLI_COMMAND}...`).start();
356
+ const child = spawn('npm', ['install', '-g', CLI_COMMAND], {
357
+ stdio: ['pipe', 'pipe', 'pipe'],
358
+ shell: true
359
+ });
360
+
361
+ let stderr = '';
362
+ child.stderr.on('data', (data) => {
363
+ stderr += data.toString();
364
+ });
365
+
366
+ child.on('close', (code) => {
367
+ if (code === 0) {
368
+ spinner.succeed(`${CLI_COMMAND} updated to latest version`);
369
+ resolve(true);
370
+ } else {
371
+ spinner.fail(`Update failed: ${stderr || 'Unknown error'}`);
372
+ resolve(false);
373
+ }
374
+ });
375
+
376
+ child.on('error', (err) => {
377
+ spinner.fail(`Update failed: ${err.message}`);
378
+ resolve(false);
379
+ });
380
+ });
381
+ }
382
+
319
383
  // ============================================================================
320
384
  // Auto-update .gitignore and .npmignore
321
385
  // ============================================================================
@@ -1297,7 +1361,32 @@ async function updateCommand(projectDir) {
1297
1361
  console.log(chalk.bold('DevBooks Update'));
1298
1362
  console.log();
1299
1363
 
1300
- // Check if initialized
1364
+ // 1. Check if CLI has a new version
1365
+ const spinner = ora('Checking for CLI updates...').start();
1366
+ const { hasUpdate, latestVersion, currentVersion } = await checkNpmUpdate();
1367
+
1368
+ if (hasUpdate) {
1369
+ spinner.info(`New version available: ${currentVersion} → ${latestVersion}`);
1370
+ const shouldUpdate = await confirm({
1371
+ message: `Update ${CLI_COMMAND} to ${latestVersion}?`,
1372
+ default: true
1373
+ });
1374
+
1375
+ if (shouldUpdate) {
1376
+ const success = await performNpmUpdate();
1377
+ if (success) {
1378
+ console.log(chalk.blue('ℹ') + ` Please run \`${CLI_COMMAND} update\` again to update project files.`);
1379
+ return;
1380
+ }
1381
+ // Update failed, continue with local file updates
1382
+ }
1383
+ } else {
1384
+ spinner.succeed(`CLI is up to date (v${currentVersion})`);
1385
+ }
1386
+
1387
+ console.log();
1388
+
1389
+ // 2. Check if initialized (update project files)
1301
1390
  const configPath = path.join(projectDir, '.devbooks', 'config.yaml');
1302
1391
  if (!fs.existsSync(configPath)) {
1303
1392
  console.log(chalk.red('✗') + ` DevBooks config not found. Please run \`${CLI_COMMAND} init\` first.`);
@@ -1464,7 +1553,7 @@ function showHelp() {
1464
1553
  console.log();
1465
1554
  console.log(chalk.cyan('Usage:'));
1466
1555
  console.log(` ${CLI_COMMAND} init [path] [options] Initialize DevBooks`);
1467
- console.log(` ${CLI_COMMAND} update [path] Update configured tools`);
1556
+ console.log(` ${CLI_COMMAND} update [path] Update CLI and configured tools`);
1468
1557
  console.log(` ${CLI_COMMAND} migrate --from <framework> [opts] Migrate from other frameworks`);
1469
1558
  console.log();
1470
1559
  console.log(chalk.cyan('Options:'));
@@ -1518,7 +1607,7 @@ function showHelp() {
1518
1607
  console.log(` ${CLI_COMMAND} init my-project # Initialize in my-project directory`);
1519
1608
  console.log(` ${CLI_COMMAND} init --tools claude,cursor # Non-interactive (project-level by default)`);
1520
1609
  console.log(` ${CLI_COMMAND} init --tools claude --scope global # Non-interactive (global installation)`);
1521
- console.log(` ${CLI_COMMAND} update # Update configured tools`);
1610
+ console.log(` ${CLI_COMMAND} update # Update CLI and Skills`);
1522
1611
  console.log(` ${CLI_COMMAND} migrate --from openspec # Migrate from OpenSpec`);
1523
1612
  console.log(` ${CLI_COMMAND} migrate --from speckit # Migrate from spec-kit`);
1524
1613
  console.log(` ${CLI_COMMAND} migrate --from openspec --dry-run # Dry run migration`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-playbooks",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "description": "AI-powered spec-driven development workflow",
5
5
  "keywords": [
6
6
  "devbooks",