claude-cli-advanced-starter-pack 1.1.0 → 1.8.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.
Files changed (56) hide show
  1. package/OVERVIEW.md +5 -1
  2. package/README.md +241 -132
  3. package/bin/gtask.js +53 -0
  4. package/package.json +1 -1
  5. package/src/cli/menu.js +27 -0
  6. package/src/commands/explore-mcp/mcp-registry.js +99 -0
  7. package/src/commands/init.js +339 -351
  8. package/src/commands/install-panel-hook.js +108 -0
  9. package/src/commands/install-scripts.js +232 -0
  10. package/src/commands/install-skill.js +220 -0
  11. package/src/commands/panel.js +297 -0
  12. package/src/commands/setup-wizard.js +4 -3
  13. package/src/commands/test-setup.js +4 -5
  14. package/src/data/releases.json +164 -0
  15. package/src/panel/queue.js +188 -0
  16. package/templates/commands/ask-claude.template.md +118 -0
  17. package/templates/commands/ccasp-panel.template.md +72 -0
  18. package/templates/commands/ccasp-setup.template.md +470 -79
  19. package/templates/commands/create-smoke-test.template.md +186 -0
  20. package/templates/commands/project-impl.template.md +9 -113
  21. package/templates/commands/refactor-check.template.md +112 -0
  22. package/templates/commands/refactor-cleanup.template.md +144 -0
  23. package/templates/commands/refactor-prep.template.md +192 -0
  24. package/templates/docs/AI_ARCHITECTURE_CONSTITUTION.template.md +198 -0
  25. package/templates/docs/DETAILED_GOTCHAS.template.md +347 -0
  26. package/templates/docs/PHASE-DEV-CHECKLIST.template.md +241 -0
  27. package/templates/docs/PROGRESS_JSON_TEMPLATE.json +117 -0
  28. package/templates/docs/background-agent.template.md +264 -0
  29. package/templates/hooks/autonomous-decision-logger.template.js +207 -0
  30. package/templates/hooks/branch-merge-checker.template.js +272 -0
  31. package/templates/hooks/git-commit-tracker.template.js +267 -0
  32. package/templates/hooks/issue-completion-detector.template.js +205 -0
  33. package/templates/hooks/panel-queue-reader.template.js +83 -0
  34. package/templates/hooks/phase-validation-gates.template.js +307 -0
  35. package/templates/hooks/session-id-generator.template.js +236 -0
  36. package/templates/hooks/token-usage-monitor.template.js +193 -0
  37. package/templates/patterns/README.md +129 -0
  38. package/templates/patterns/l1-l2-orchestration.md +189 -0
  39. package/templates/patterns/multi-phase-orchestration.md +258 -0
  40. package/templates/patterns/two-tier-query-pipeline.md +192 -0
  41. package/templates/scripts/README.md +109 -0
  42. package/templates/scripts/analyze-delegation-log.js +299 -0
  43. package/templates/scripts/autonomous-decision-logger.js +277 -0
  44. package/templates/scripts/git-history-analyzer.py +269 -0
  45. package/templates/scripts/phase-validation-gates.js +307 -0
  46. package/templates/scripts/poll-deployment-status.js +260 -0
  47. package/templates/scripts/roadmap-scanner.js +263 -0
  48. package/templates/scripts/validate-deployment.js +293 -0
  49. package/templates/skills/agent-creator/skill.json +18 -0
  50. package/templates/skills/agent-creator/skill.md +335 -0
  51. package/templates/skills/hook-creator/skill.json +18 -0
  52. package/templates/skills/hook-creator/skill.md +318 -0
  53. package/templates/skills/panel/skill.json +18 -0
  54. package/templates/skills/panel/skill.md +90 -0
  55. package/templates/skills/rag-agent-creator/skill.json +18 -0
  56. package/templates/skills/rag-agent-creator/skill.md +307 -0
@@ -93,6 +93,51 @@ const OPTIONAL_FEATURES = [
93
93
  default: false,
94
94
  requiresPostConfig: true,
95
95
  },
96
+ {
97
+ name: 'advancedHooks',
98
+ label: 'Advanced Hook Suite',
99
+ description: 'Extended hook system with session management, git commit tracking, branch validation, issue detection, token monitoring, autonomous logging, and phase validation gates.',
100
+ commands: [],
101
+ hooks: [
102
+ 'session-id-generator',
103
+ 'git-commit-tracker',
104
+ 'branch-merge-checker',
105
+ 'issue-completion-detector',
106
+ 'token-usage-monitor',
107
+ 'autonomous-decision-logger',
108
+ 'phase-validation-gates',
109
+ ],
110
+ default: false,
111
+ requiresPostConfig: false,
112
+ },
113
+ {
114
+ name: 'skillTemplates',
115
+ label: 'Skill Creator Templates',
116
+ description: 'Pre-built skills for agent creation, hook creation, and RAG-enhanced agent building. Provides best-practice templates for extending Claude Code.',
117
+ commands: [],
118
+ hooks: [],
119
+ skills: ['agent-creator', 'hook-creator', 'rag-agent-creator', 'panel'],
120
+ default: true,
121
+ requiresPostConfig: false,
122
+ },
123
+ {
124
+ name: 'refactoring',
125
+ label: 'Refactoring Tools',
126
+ description: 'Code quality commands for linting, cleanup, and safe refactoring. Includes pre-commit checks, auto-fix, and safety checklists.',
127
+ commands: ['refactor-check', 'refactor-cleanup', 'refactor-prep'],
128
+ hooks: [],
129
+ default: false,
130
+ requiresPostConfig: false,
131
+ },
132
+ {
133
+ name: 'testing',
134
+ label: 'Advanced Testing',
135
+ description: 'Extended testing capabilities including smoke test generation and test coverage analysis.',
136
+ commands: ['create-smoke-test'],
137
+ hooks: [],
138
+ default: false,
139
+ requiresPostConfig: false,
140
+ },
96
141
  ];
97
142
 
98
143
  /**
@@ -106,6 +151,12 @@ const AVAILABLE_COMMANDS = [
106
151
  selected: true,
107
152
  required: true,
108
153
  },
154
+ {
155
+ name: 'ccasp-panel',
156
+ description: 'Launch control panel in new terminal (agents, skills, hooks, MCP)',
157
+ category: 'Navigation',
158
+ selected: true,
159
+ },
109
160
  {
110
161
  name: 'e2e-test',
111
162
  description: 'Run E2E tests with Playwright (ralph loop, headed, watch modes)',
@@ -266,319 +317,125 @@ const AVAILABLE_COMMANDS = [
266
317
  category: 'Maintenance',
267
318
  selected: true,
268
319
  },
320
+ // Refactoring commands (Phase 4)
321
+ {
322
+ name: 'refactor-check',
323
+ description: 'Fast pre-commit quality gate - lint, type-check, test affected files',
324
+ category: 'Refactoring',
325
+ selected: false,
326
+ feature: 'refactoring',
327
+ },
328
+ {
329
+ name: 'refactor-cleanup',
330
+ description: 'Daily maintenance automation - fix lint, remove unused imports, format',
331
+ category: 'Refactoring',
332
+ selected: false,
333
+ feature: 'refactoring',
334
+ },
335
+ {
336
+ name: 'refactor-prep',
337
+ description: 'Pre-refactoring safety checklist - ensure safe conditions',
338
+ category: 'Refactoring',
339
+ selected: false,
340
+ feature: 'refactoring',
341
+ },
342
+ {
343
+ name: 'ask-claude',
344
+ description: 'Natural language command discovery - find the right command for any task',
345
+ category: 'Discovery',
346
+ selected: true,
347
+ },
348
+ {
349
+ name: 'create-smoke-test',
350
+ description: 'Auto-generate Playwright smoke tests for critical user flows',
351
+ category: 'Testing',
352
+ selected: false,
353
+ feature: 'testing',
354
+ },
269
355
  ];
270
356
 
271
357
  /**
272
- * Generate the sophisticated /menu command
358
+ * Generate the /menu command - launches CCASP Panel in new terminal
273
359
  */
274
360
  function generateMenuCommand(projectName, installedCommands, installedAgents, installedSkills, installedHooks) {
275
361
  const date = new Date().toISOString().split('T')[0];
276
362
 
277
- // Group commands by category
278
- const commandsByCategory = {};
363
+ // Build command list for reference
364
+ let commandList = '';
279
365
  for (const cmdName of installedCommands) {
280
366
  const cmd = AVAILABLE_COMMANDS.find((c) => c.name === cmdName);
281
367
  if (cmd && cmd.name !== 'menu') {
282
- if (!commandsByCategory[cmd.category]) {
283
- commandsByCategory[cmd.category] = [];
284
- }
285
- commandsByCategory[cmd.category].push(cmd);
368
+ commandList += `| /${cmd.name} | ${cmd.description} |\n`;
286
369
  }
287
370
  }
288
371
 
289
- // Build category sections for the menu
290
- let categoryMenuItems = '';
291
- let categoryInstructions = '';
292
- let keyIndex = 1;
293
- const keyMap = {};
294
-
295
- for (const [category, cmds] of Object.entries(commandsByCategory)) {
296
- categoryMenuItems += `\n### ${category}\n`;
297
- for (const cmd of cmds) {
298
- const key = keyIndex <= 9 ? keyIndex.toString() : String.fromCharCode(65 + keyIndex - 10); // 1-9, then A-Z
299
- keyMap[key] = cmd.name;
300
- categoryMenuItems += `- **[${key}]** \`/${cmd.name}\` - ${cmd.description}\n`;
301
- keyIndex++;
302
- }
303
- }
304
-
305
- // Build agents section
306
- let agentsSection = '';
307
- if (installedAgents.length > 0) {
308
- agentsSection = `\n### Agents\n`;
309
- for (const agent of installedAgents) {
310
- agentsSection += `- **${agent}** - Custom agent\n`;
311
- }
312
- }
313
-
314
- // Build skills section
315
- let skillsSection = '';
316
- if (installedSkills.length > 0) {
317
- skillsSection = `\n### Skills\n`;
318
- for (const skill of installedSkills) {
319
- skillsSection += `- **${skill}** - Custom skill\n`;
320
- }
321
- }
322
-
323
- // Build hooks section
324
- let hooksSection = '';
325
- if (installedHooks.length > 0) {
326
- hooksSection = `\n### Active Hooks\n`;
327
- for (const hook of installedHooks) {
328
- hooksSection += `- **${hook}**\n`;
329
- }
330
- }
331
-
332
- const ccaspVersion = getVersion();
333
-
334
372
  return `---
335
- description: Interactive project menu - Quick access to all commands, agents, skills, and tools
373
+ description: Launch CCASP Control Panel - Interactive menu in separate terminal
336
374
  ---
337
375
 
338
- # ${projectName} - Project Menu
339
-
340
- ## IMPORTANT: Check Update State First
341
-
342
- Before displaying the menu, read \`.claude/config/ccasp-state.json\` to check for updates:
343
-
344
- \`\`\`javascript
345
- {
346
- "currentVersion": "1.0.5",
347
- "latestVersion": "1.0.6",
348
- "updateAvailable": true,
349
- "updateHighlights": [...],
350
- "updateFirstDisplayed": false
351
- }
352
- \`\`\`
353
-
354
- ## Dynamic Menu Header
355
-
356
- Build the header based on update state. Replace \`{{VERSION}}\` and \`{{UPDATE_STATUS}}\` dynamically:
357
-
358
- \`\`\`
359
- ╔═══════════════════════════════════════════════════════════════════════════════╗
360
- ║ ║
361
- ║ ╔═╗╦ ╔═╗╦ ╦╔╦╗╔═╗ ╔═╗╔╦╗╦ ╦╔═╗╔╗╔╔═╗╔═╗╔╦╗ ╔═╗╔╦╗╔═╗╦═╗╔╦╗╔═╗╦═╗ ║
362
- ║ ║ ║ ╠═╣║ ║ ║║║╣ ╠═╣ ║║╚╗╔╝╠═╣║║║║ ║╣ ║║ ╚═╗ ║ ╠═╣╠╦╝ ║ ║╣ ╠╦╝ ║
363
- ║ ╚═╝╩═╝╩ ╩╚═╝═╩╝╚═╝ ╩ ╩═╩╝ ╚╝ ╩ ╩╝╚╝╚═╝╚═╝═╩╝ ╚═╝ ╩ ╩ ╩╩╚═ ╩ ╚═╝╩╚═ ║
364
- ║ ║
365
- ║ ${projectName.padEnd(35)} v{{VERSION}} {{UPDATE_STATUS}} ║
366
- ║ ║
367
- ╠═══════════════════════════════════════════════════════════════════════════════╣
368
- \`\`\`
369
-
370
- **If update is available**, replace:
371
- - \`{{VERSION}}\` with current version (e.g., "1.0.5")
372
- - \`{{UPDATE_STATUS}}\` with \`[NEW UPDATE]\` in bold/highlighted
373
-
374
- **If up to date**, replace:
375
- - \`{{VERSION}}\` with current version
376
- - \`{{UPDATE_STATUS}}\` with empty string
377
-
378
- ## Update Banner (Show When Update Available)
379
-
380
- If \`updateAvailable: true\`, display this banner BEFORE the main menu:
381
-
382
- \`\`\`
383
- ┌─────────────────────────────────────────────────────────────────────────────┐
384
- │ 📦 NEW UPDATE AVAILABLE: v{{currentVersion}} → v{{latestVersion}} │
385
- ├─────────────────────────────────────────────────────────────────────────────┤
386
- │ What's New: │
387
- │ {{#each updateHighlights}} │
388
- │ • {{summary}} │
389
- │ {{/each}} │
390
- ├─────────────────────────────────────────────────────────────────────────────┤
391
- │ Press [N] to update now │ Press [U] for details │ Press any to dismiss │
392
- └─────────────────────────────────────────────────────────────────────────────┘
393
- \`\`\`
394
-
395
- **IMPORTANT**: After displaying the update banner for the first time, update the state file:
396
- \`updateFirstDisplayed: true\` - This prevents showing the full highlights again.
397
-
398
- On subsequent displays (when \`updateFirstDisplayed: true\`), show a compact banner:
399
-
400
- \`\`\`
401
- ┌──────────────────────────────────────────────────────────────┐
402
- │ 📦 Update available: v{{currentVersion}} → v{{latestVersion}} │ [N] Update │
403
- └──────────────────────────────────────────────────────────────┘
404
- \`\`\`
405
-
406
- ## Main Menu Body
407
-
408
- \`\`\`
409
- ║ ║
410
- ║ Quick Actions: ║
411
- ║ ───────────── ║
412
- ║ [T] Run Tests [G] GitHub Task [P] Phase Dev Plan ║
413
- ║ [A] Create Agent [H] Create Hook [S] Create Skill ║
414
- ║ [M] Explore MCP [C] Claude Audit [E] Explore Codebase ║
415
- ║ ║
416
- ║ Project Resources: ║
417
- ║ ────────────────── ║
418
- ║ [1] View Agents [2] View Skills [3] View Hooks ║
419
- ║ [4] View Commands [5] Settings [6] Documentation ║
420
- ║ ║
421
- ║ Project Implementation: ║
422
- ║ ─────────────────────── ║
423
- ║ [I] /project-impl Agent-powered setup & configuration ║
424
- ║ ║
425
- ║ Navigation: ║
426
- ║ ─────────── ║
427
- ║ [U] Check for Updates [R] Refresh Menu [?] Help [Q] Exit ║
428
- {{#if updateAvailable}}
429
- ║ [N] UPDATE NOW Run: npm update -g claude-cli-advanced-starter-pack ║
430
- {{/if}}
431
- ║ ║
432
- ╚═══════════════════════════════════════════════════════════════════════════════╝
433
- \`\`\`
434
-
435
- ## How to Use This Menu
436
-
437
- When the user invokes \`/menu\`:
438
-
439
- 1. **Read update state**: Check \`.claude/config/ccasp-state.json\` for cached update info
440
- 2. **Build dynamic header**: Include version number and update status
441
- 3. **Show update banner**: If updates available, show banner with highlights (first time) or compact (subsequent)
442
- 4. **Display the menu**: Show the ASCII art menu with dynamic content
443
- 5. **Wait for input**: Accept single character or command name
444
-
445
- ### Key Bindings
446
-
447
- | Key | Action | Command |
448
- |-----|--------|---------|
449
- | **T** | Run E2E Tests | \`/e2e-test\` |
450
- | **G** | Create GitHub Task | \`/github-task\` |
451
- | **P** | Create Phase Dev Plan | \`/phase-dev-plan\` |
452
- | **A** | Create Agent | \`/create-agent\` |
453
- | **H** | Create Hook | \`/create-hook\` |
454
- | **S** | Create Skill | \`/create-skill\` |
455
- | **M** | Explore MCP Servers | \`/explore-mcp\` |
456
- | **C** | Claude Audit | \`/claude-audit\` |
457
- | **E** | Explore Codebase | \`/codebase-explorer\` |
458
- | **1** | List project agents | Read \`.claude/agents/\` |
459
- | **2** | List project skills | Read \`.claude/skills/\` |
460
- | **3** | List active hooks | Read \`.claude/hooks/\` |
461
- | **4** | List all commands | Read \`.claude/commands/INDEX.md\` |
462
- | **5** | View/edit settings | Read \`.claude/settings.json\` |
463
- | **6** | Open documentation | Read \`.claude/docs/\` |
464
- | **I** | Project Implementation | \`/project-impl\` |
465
- | **U** | Check for Updates | \`/update-check\` |
466
- | **N** | Update Now | Run npm update (only shown when update available) |
467
- | **R** | Refresh and redisplay menu | Re-invoke \`/menu\` |
468
- | **?** | Show help | Display command descriptions |
469
- | **Q** | Exit menu | End menu interaction |
470
-
471
- ## Installed Commands
472
- ${categoryMenuItems}
473
- ${agentsSection}
474
- ${skillsSection}
475
- ${hooksSection}
376
+ # ${projectName} - Menu
476
377
 
477
378
  ## Instructions for Claude
478
379
 
479
- When this command is invoked:
380
+ **EXECUTE IMMEDIATELY**: Launch the CCASP Control Panel in a new terminal window.
480
381
 
481
- ### Step 1: Read Update State
382
+ ### Step 1: Launch Panel
482
383
 
483
- Read \`.claude/config/ccasp-state.json\`:
384
+ Use the Bash tool to run this command:
484
385
 
386
+ **Windows:**
485
387
  \`\`\`bash
486
- cat .claude/config/ccasp-state.json 2>/dev/null || echo "{}"
388
+ start powershell -NoExit -Command "ccasp panel"
487
389
  \`\`\`
488
390
 
489
- Parse the JSON to extract:
490
- - \`currentVersion\`: Installed CCASP version
491
- - \`latestVersion\`: Latest version on npm
492
- - \`updateAvailable\`: Boolean indicating if update exists
493
- - \`updateHighlights\`: Array of release summaries
494
- - \`updateFirstDisplayed\`: Whether full highlights have been shown
495
- - \`projectImplCompleted\`: Whether user has run /project-impl (default: false)
496
-
497
- ### Step 2: Build Dynamic Menu
498
-
499
- Replace template variables in the menu:
500
- - \`{{VERSION}}\` → currentVersion (e.g., "1.0.6")
501
- - \`{{UPDATE_STATUS}}\` → "[NEW UPDATE]" if updateAvailable, else ""
502
-
503
- ### Step 3: Display Update Banner (If Applicable)
504
-
505
- **First time showing update** (\`updateAvailable && !updateFirstDisplayed\`):
506
- Show full banner with highlights, then update state:
507
-
391
+ **macOS:**
508
392
  \`\`\`bash
509
- # After displaying, update the state file to mark as displayed
393
+ osascript -e 'tell application "Terminal" to do script "ccasp panel"'
510
394
  \`\`\`
511
395
 
512
- Set \`updateFirstDisplayed: true\` in ccasp-state.json using Edit tool.
513
-
514
- **Subsequent displays** (\`updateAvailable && updateFirstDisplayed\`):
515
- Show compact banner only.
516
-
517
- ### Step 3b: Show Setup Recommendation (If Applicable)
518
-
519
- If \`projectImplCompleted\` is \`false\` or missing, display this banner at the BOTTOM of the menu (after the closing box but before the input prompt):
520
-
521
- \`\`\`
522
- 💡 Tip: Run /project-impl to configure your project (audit CLAUDE.md, detect tech stack, set up deployment)
396
+ **Linux:**
397
+ \`\`\`bash
398
+ gnome-terminal -- ccasp panel &
523
399
  \`\`\`
524
400
 
525
- This banner should be subtle - just a single line tip. Once the user runs any option in /project-impl, update the state file to set \`projectImplCompleted: true\` and this banner will no longer appear.
526
-
527
- ### Step 4: Display Menu and Wait for Input
528
-
529
- Ask: "What would you like to do? Enter a key:"
530
-
531
- ### Step 5: Handle User Selection
401
+ ### Step 2: Confirm Launch
532
402
 
533
- | Key | Action |
534
- |-----|--------|
535
- | **N** | **Update Now**: Run \`npm update -g claude-cli-advanced-starter-pack\` via Bash, then show: "Update complete! Restart Claude Code CLI to use new features." |
536
- | **U** | Invoke \`/update-check\` for detailed update info and feature management |
537
- | **I** | Invoke \`/project-impl\` for project implementation |
538
- | **R** | Re-invoke \`/menu\` (refresh) |
539
- | **Q** | End menu session |
540
- | **1-6** | Read and display the corresponding resource |
541
- | **Other** | Invoke the corresponding slash command |
542
-
543
- ### Example: Update Now Flow
403
+ After running the command, display this confirmation:
544
404
 
545
405
  \`\`\`
546
- User: N
547
-
548
- Claude: Updating CCASP...
549
-
550
- [Runs: npm update -g claude-cli-advanced-starter-pack]
551
-
552
- Claude:
553
- ┌─────────────────────────────────────────────────────────────┐
554
- Update Complete!
555
-
556
- Updated: v1.0.5 → v1.0.6
557
-
558
- ⚠️ RESTART REQUIRED
559
- Exit and restart Claude Code CLI to use new features.
560
-
561
- Then run: ccasp wizard select "Prior Releases" to add
562
- any new commands to this project.
563
- └─────────────────────────────────────────────────────────────┘
406
+ CCASP Control Panel launched in a new terminal window!
407
+
408
+ ┌─────────────────────────────────────────────────────────────────┐
409
+ │ CCASP Control Panel (NEW WINDOW) │
410
+ ├─────────────────────────────────────────────────────────────────┤
411
+ │ │
412
+ │ Agents & Skills:
413
+ │ [A] Create Agent [H] Create Hook [S] Create Skill │
414
+ [M] Explore MCP [C] Claude Audit [E] Explore Code
415
+
416
+ Quick Actions:
417
+ [P] Phase Dev Plan [G] GitHub Task [T] Run E2E Tests
418
+ [U] Update Check
419
+
420
+ Controls:
421
+ [Q] Quit [R] Refresh [X] Clear Queue [?] Help
422
+
423
+ └─────────────────────────────────────────────────────────────────┘
424
+
425
+ How to use:
426
+ 1. Switch to the new PowerShell window with the panel
427
+ 2. Press a single key to select a command (e.g., 'A' for Create Agent)
428
+ 3. Return to this Claude Code session
429
+ 4. Press Enter on an empty prompt - the command will execute automatically
564
430
  \`\`\`
565
431
 
566
- ### Update Check Behavior
567
-
568
- - The startup hook (\`ccasp-update-check.js\`) runs automatically on first prompt
569
- - Checks npm registry with 1-hour cache
570
- - Stores result in \`.claude/config/ccasp-state.json\`
571
- - Menu reads this cached state (no network call needed)
432
+ ## Direct Commands (Alternative)
572
433
 
573
- ### Dynamic Content
434
+ If the panel doesn't work, you can invoke these commands directly:
574
435
 
575
- When displaying resource views (1-6), read the actual contents from:
576
- - Agents: \`.claude/agents/*.md\` files
577
- - Skills: \`.claude/skills/*/skill.md\` files
578
- - Hooks: \`.claude/hooks/*.js\` files
579
- - Commands: \`.claude/commands/INDEX.md\`
580
- - Settings: \`.claude/settings.json\` and \`.claude/settings.local.json\`
581
- - Docs: \`.claude/docs/\` directory listing
436
+ | Command | Description |
437
+ |---------|-------------|
438
+ ${commandList}
582
439
 
583
440
  ---
584
441
 
@@ -1599,20 +1456,23 @@ export async function runInit(options = {}) {
1599
1456
  console.log(chalk.dim(' Use --force flag to overwrite specific commands if needed.'));
1600
1457
  console.log('');
1601
1458
 
1602
- const { confirmProceed } = await inquirer.prompt([
1603
- {
1604
- type: 'confirm',
1605
- name: 'confirmProceed',
1606
- message: 'Continue with installation? (existing files are safe)',
1607
- default: true,
1608
- },
1609
- ]);
1459
+ // Skip prompt if called non-interactively (e.g., from wizard)
1460
+ if (!options.skipPrompts) {
1461
+ const { confirmProceed } = await inquirer.prompt([
1462
+ {
1463
+ type: 'confirm',
1464
+ name: 'confirmProceed',
1465
+ message: 'Continue with installation? (existing files are safe)',
1466
+ default: true,
1467
+ },
1468
+ ]);
1610
1469
 
1611
- if (!confirmProceed) {
1612
- console.log(chalk.dim('\nCancelled. No changes made.'));
1613
- return;
1470
+ if (!confirmProceed) {
1471
+ console.log(chalk.dim('\nCancelled. No changes made.'));
1472
+ return;
1473
+ }
1474
+ console.log('');
1614
1475
  }
1615
- console.log('');
1616
1476
  }
1617
1477
 
1618
1478
  // Step 1: Check and create folder structure
@@ -1786,46 +1646,63 @@ export async function runInit(options = {}) {
1786
1646
  console.log('');
1787
1647
 
1788
1648
  // Step 4: Select optional features
1789
- console.log(chalk.bold('Step 4: Select optional features\n'));
1790
- console.log(chalk.dim(' Each feature adds commands and hooks to your project.'));
1791
- console.log(chalk.dim(' Features marked with (*) require additional configuration via /menu after installation.\n'));
1792
-
1793
- // Display feature descriptions in a nice format
1794
- for (const feature of OPTIONAL_FEATURES) {
1795
- const marker = feature.default ? chalk.green('●') : chalk.dim('○');
1796
- const postConfig = feature.requiresPostConfig ? chalk.yellow(' (*)') : '';
1797
- console.log(` ${marker} ${chalk.bold(feature.label)}${postConfig}`);
1798
- console.log(chalk.dim(` ${feature.description}`));
1799
- if (feature.commands.length > 0) {
1800
- console.log(chalk.dim(` Adds: ${feature.commands.map(c => '/' + c).join(', ')}`));
1649
+ let selectedFeatures;
1650
+
1651
+ if (options.skipPrompts && options.features) {
1652
+ // Use features passed from wizard
1653
+ selectedFeatures = options.features;
1654
+ console.log(chalk.bold('Step 4: Using pre-selected features\n'));
1655
+ if (selectedFeatures.length > 0) {
1656
+ console.log(chalk.dim(` Features: ${selectedFeatures.join(', ')}`));
1657
+ } else {
1658
+ console.log(chalk.dim(' Minimal mode - essential commands only'));
1801
1659
  }
1802
1660
  console.log('');
1803
- }
1661
+ } else {
1662
+ console.log(chalk.bold('Step 4: Select optional features\n'));
1663
+ console.log(chalk.dim(' Each feature adds commands and hooks to your project.'));
1664
+ console.log(chalk.dim(' Features marked with (*) require additional configuration via /menu after installation.\n'));
1665
+
1666
+ // Display feature descriptions in a nice format
1667
+ for (const feature of OPTIONAL_FEATURES) {
1668
+ const marker = feature.default ? chalk.green('●') : chalk.dim('○');
1669
+ const postConfig = feature.requiresPostConfig ? chalk.yellow(' (*)') : '';
1670
+ console.log(` ${marker} ${chalk.bold(feature.label)}${postConfig}`);
1671
+ console.log(chalk.dim(` ${feature.description}`));
1672
+ if (feature.commands.length > 0) {
1673
+ console.log(chalk.dim(` Adds: ${feature.commands.map(c => '/' + c).join(', ')}`));
1674
+ }
1675
+ console.log('');
1676
+ }
1804
1677
 
1805
- const { selectedFeatures } = await inquirer.prompt([
1806
- {
1807
- type: 'checkbox',
1808
- name: 'selectedFeatures',
1809
- message: 'Select features to enable:',
1810
- choices: OPTIONAL_FEATURES.map((feature) => ({
1811
- name: `${feature.label}${feature.requiresPostConfig ? ' (*)' : ''} - ${feature.commands.length} commands, ${feature.hooks.length} hooks`,
1812
- value: feature.name,
1813
- checked: feature.default,
1814
- })),
1815
- pageSize: 10,
1816
- },
1817
- ]);
1678
+ const result = await inquirer.prompt([
1679
+ {
1680
+ type: 'checkbox',
1681
+ name: 'selectedFeatures',
1682
+ message: 'Select features to enable:',
1683
+ choices: OPTIONAL_FEATURES.map((feature) => ({
1684
+ name: `${feature.label}${feature.requiresPostConfig ? ' (*)' : ''} - ${feature.commands.length} commands, ${feature.hooks.length} hooks`,
1685
+ value: feature.name,
1686
+ checked: feature.default,
1687
+ })),
1688
+ pageSize: 10,
1689
+ },
1690
+ ]);
1691
+ selectedFeatures = result.selectedFeatures;
1692
+ }
1818
1693
 
1819
1694
  // Store selected features for later use
1820
1695
  const enabledFeatures = OPTIONAL_FEATURES.filter((f) => selectedFeatures.includes(f.name));
1821
1696
  const featuresRequiringConfig = enabledFeatures.filter((f) => f.requiresPostConfig);
1822
1697
 
1823
- // Collect feature-specific commands and hooks to deploy
1698
+ // Collect feature-specific commands, hooks, and skills to deploy
1824
1699
  const featureCommands = [];
1825
1700
  const featureHooks = [];
1701
+ const featureSkills = [];
1826
1702
  for (const feature of enabledFeatures) {
1827
1703
  featureCommands.push(...feature.commands);
1828
- featureHooks.push(...feature.hooks);
1704
+ featureHooks.push(...(feature.hooks || []));
1705
+ featureSkills.push(...(feature.skills || []));
1829
1706
  }
1830
1707
 
1831
1708
  if (featureCommands.length > 0) {
@@ -1839,6 +1716,11 @@ export async function runInit(options = {}) {
1839
1716
  console.log(chalk.dim(` ${featureHooks.join(', ')}`));
1840
1717
  }
1841
1718
 
1719
+ if (featureSkills.length > 0) {
1720
+ console.log(chalk.green(` ✓ Selected features will add ${featureSkills.length} skill(s):`));
1721
+ console.log(chalk.dim(` ${featureSkills.join(', ')}`));
1722
+ }
1723
+
1842
1724
  if (featuresRequiringConfig.length > 0) {
1843
1725
  console.log('');
1844
1726
  console.log(chalk.yellow(' ℹ The following features require configuration after installation:'));
@@ -1850,7 +1732,7 @@ export async function runInit(options = {}) {
1850
1732
 
1851
1733
  // Check for optional npm package installs from selected features
1852
1734
  const featuresWithNpm = enabledFeatures.filter((f) => f.npmPackage);
1853
- if (featuresWithNpm.length > 0) {
1735
+ if (featuresWithNpm.length > 0 && !options.skipPrompts) {
1854
1736
  console.log('');
1855
1737
  console.log(chalk.bold(' Optional Package Installation\n'));
1856
1738
 
@@ -1882,6 +1764,10 @@ export async function runInit(options = {}) {
1882
1764
  console.log(chalk.dim(` Skipped. Install later with: npm install -g ${feature.npmPackage}`));
1883
1765
  }
1884
1766
  }
1767
+ } else if (featuresWithNpm.length > 0) {
1768
+ // In skipPrompts mode, just inform about optional packages
1769
+ console.log(chalk.dim(` ℹ Optional packages available: ${featuresWithNpm.map(f => f.npmPackage).join(', ')}`));
1770
+ console.log(chalk.dim(' Install manually if needed.'));
1885
1771
  }
1886
1772
 
1887
1773
  console.log('');
@@ -1895,45 +1781,54 @@ export async function runInit(options = {}) {
1895
1781
  : [];
1896
1782
  const existingCmdNames = existingCmdFiles.map(f => f.replace('.md', ''));
1897
1783
 
1898
- if (existingCmdNames.length > 0) {
1784
+ if (existingCmdNames.length > 0 && !options.skipPrompts) {
1899
1785
  console.log(chalk.blue(` ℹ Found ${existingCmdNames.length} existing command(s) in your project:`));
1900
1786
  console.log(chalk.dim(` ${existingCmdNames.map(c => '/' + c).join(', ')}`));
1901
1787
  console.log(chalk.dim(' These will be preserved unless you choose to overwrite.\n'));
1902
1788
  }
1903
1789
 
1904
- const categories = [...new Set(AVAILABLE_COMMANDS.map((c) => c.category))];
1790
+ let selectedCommands;
1905
1791
 
1906
- for (const category of categories) {
1907
- console.log(chalk.cyan(` ${category}:`));
1908
- const cmds = AVAILABLE_COMMANDS.filter((c) => c.category === category);
1909
- for (const cmd of cmds) {
1910
- const isExisting = existingCmdNames.includes(cmd.name);
1911
- const marker = cmd.selected ? chalk.green('●') : chalk.dim('○');
1912
- const required = cmd.required ? chalk.yellow(' (required)') : '';
1913
- const existing = isExisting ? chalk.blue(' [exists]') : '';
1914
- console.log(` ${marker} /${cmd.name}${required}${existing} - ${chalk.dim(cmd.description)}`);
1915
- }
1916
- console.log('');
1917
- }
1792
+ if (options.skipPrompts) {
1793
+ // Use default selections when called non-interactively
1794
+ selectedCommands = AVAILABLE_COMMANDS.filter(c => c.selected).map(c => c.name);
1795
+ console.log(chalk.dim(` Auto-selecting ${selectedCommands.length} default command(s)`));
1796
+ } else {
1797
+ const categories = [...new Set(AVAILABLE_COMMANDS.map((c) => c.category))];
1918
1798
 
1919
- // Ask which commands to install
1920
- const { selectedCommands } = await inquirer.prompt([
1921
- {
1922
- type: 'checkbox',
1923
- name: 'selectedCommands',
1924
- message: 'Select commands to install (existing commands marked with [exists]):',
1925
- choices: AVAILABLE_COMMANDS.map((cmd) => {
1799
+ for (const category of categories) {
1800
+ console.log(chalk.cyan(` ${category}:`));
1801
+ const cmds = AVAILABLE_COMMANDS.filter((c) => c.category === category);
1802
+ for (const cmd of cmds) {
1926
1803
  const isExisting = existingCmdNames.includes(cmd.name);
1927
- return {
1928
- name: `/${cmd.name}${isExisting ? ' [exists]' : ''} - ${cmd.description}`,
1929
- value: cmd.name,
1930
- checked: cmd.selected,
1931
- disabled: cmd.required ? 'Required' : false,
1932
- };
1933
- }),
1934
- pageSize: 15,
1935
- },
1936
- ]);
1804
+ const marker = cmd.selected ? chalk.green('●') : chalk.dim('○');
1805
+ const required = cmd.required ? chalk.yellow(' (required)') : '';
1806
+ const existing = isExisting ? chalk.blue(' [exists]') : '';
1807
+ console.log(` ${marker} /${cmd.name}${required}${existing} - ${chalk.dim(cmd.description)}`);
1808
+ }
1809
+ console.log('');
1810
+ }
1811
+
1812
+ // Ask which commands to install
1813
+ const result = await inquirer.prompt([
1814
+ {
1815
+ type: 'checkbox',
1816
+ name: 'selectedCommands',
1817
+ message: 'Select commands to install (existing commands marked with [exists]):',
1818
+ choices: AVAILABLE_COMMANDS.map((cmd) => {
1819
+ const isExisting = existingCmdNames.includes(cmd.name);
1820
+ return {
1821
+ name: `/${cmd.name}${isExisting ? ' [exists]' : ''} - ${cmd.description}`,
1822
+ value: cmd.name,
1823
+ checked: cmd.selected,
1824
+ disabled: cmd.required ? 'Required' : false,
1825
+ };
1826
+ }),
1827
+ pageSize: 15,
1828
+ },
1829
+ ]);
1830
+ selectedCommands = result.selectedCommands;
1831
+ }
1937
1832
 
1938
1833
  // Always include required commands AND feature-specific commands
1939
1834
  const requiredCommands = AVAILABLE_COMMANDS.filter(c => c.required).map(c => c.name);
@@ -1960,6 +1855,17 @@ export async function runInit(options = {}) {
1960
1855
 
1961
1856
  let overwrite = options.force || false;
1962
1857
  if (commandsToOverwrite.length > 0 && !overwrite) {
1858
+ // In skipPrompts mode, preserve all existing commands (no overwrite)
1859
+ if (options.skipPrompts) {
1860
+ for (const cmd of commandsToOverwrite) {
1861
+ smartMergeDecisions[cmd] = 'skip';
1862
+ }
1863
+ // Filter out skipped commands
1864
+ const filtered = finalCommands.filter((c) => !commandsToOverwrite.includes(c) || requiredCommands.includes(c));
1865
+ finalCommands.length = 0;
1866
+ finalCommands.push(...filtered);
1867
+ console.log(chalk.dim(` Preserving ${commandsToOverwrite.length} existing command(s), installing ${finalCommands.length} new`));
1868
+ } else {
1963
1869
  // Check for customized assets that have been used
1964
1870
  const assetsNeedingMerge = getAssetsNeedingMerge(process.cwd());
1965
1871
  const customizedCommands = commandsToOverwrite.filter(cmd =>
@@ -2152,6 +2058,7 @@ export async function runInit(options = {}) {
2152
2058
  finalCommands.push(...filtered);
2153
2059
  }
2154
2060
  }
2061
+ } // end else (!options.skipPrompts)
2155
2062
  }
2156
2063
 
2157
2064
  // Track if we should create backups (set outside the if block for use later)
@@ -2254,9 +2161,10 @@ export async function runInit(options = {}) {
2254
2161
  for (const hookName of featureHooks) {
2255
2162
  try {
2256
2163
  const hookPath = join(hooksDir, `${hookName}.js`);
2164
+ const hookExists = existsSync(hookPath);
2257
2165
 
2258
- // Skip if already exists
2259
- if (existsSync(hookPath)) {
2166
+ // Respect overwrite setting for hooks (like commands)
2167
+ if (hookExists && !overwrite) {
2260
2168
  console.log(chalk.blue(` ○ hooks/${hookName}.js exists (preserved)`));
2261
2169
  continue;
2262
2170
  }
@@ -2264,10 +2172,18 @@ export async function runInit(options = {}) {
2264
2172
  // Try to load from templates/hooks/ folder
2265
2173
  const templatePath = join(__dirname, '..', '..', 'templates', 'hooks', `${hookName}.template.js`);
2266
2174
  if (existsSync(templatePath)) {
2175
+ // Create backup if overwriting existing hook
2176
+ if (hookExists && overwrite) {
2177
+ const backupPath = createBackup(hookPath);
2178
+ if (backupPath) {
2179
+ backedUpFiles.push({ original: hookPath, backup: backupPath });
2180
+ }
2181
+ }
2267
2182
  const hookContent = readFileSync(templatePath, 'utf8');
2268
2183
  writeFileSync(hookPath, hookContent, 'utf8');
2269
2184
  deployedHooks.push(hookName);
2270
- console.log(chalk.green(` ✓ Created hooks/${hookName}.js`));
2185
+ const action = hookExists ? 'Updated' : 'Created';
2186
+ console.log(chalk.green(` ✓ ${action} hooks/${hookName}.js`));
2271
2187
  } else {
2272
2188
  failedHooks.push({ name: hookName, error: 'No template found' });
2273
2189
  console.log(chalk.yellow(` ⚠ Skipped hooks/${hookName}.js (no template)`));
@@ -2283,6 +2199,56 @@ export async function runInit(options = {}) {
2283
2199
  }
2284
2200
  }
2285
2201
 
2202
+ // Step 6c: Deploy feature skills
2203
+ const deployedSkills = [];
2204
+ const failedSkills = [];
2205
+
2206
+ if (featureSkills.length > 0) {
2207
+ console.log(chalk.bold('\nStep 6c: Deploying feature skills\n'));
2208
+
2209
+ for (const skillName of featureSkills) {
2210
+ try {
2211
+ const skillPath = join(skillsDir, skillName);
2212
+ const skillExists = existsSync(skillPath);
2213
+
2214
+ // Respect overwrite setting for skills (like commands)
2215
+ if (skillExists && !overwrite) {
2216
+ console.log(chalk.blue(` ○ skills/${skillName}/ exists (preserved)`));
2217
+ continue;
2218
+ }
2219
+
2220
+ // Try to load from templates/skills/ folder
2221
+ const templatePath = join(__dirname, '..', '..', 'templates', 'skills', skillName);
2222
+ if (existsSync(templatePath)) {
2223
+ // Create backup if overwriting existing skill
2224
+ if (skillExists && overwrite) {
2225
+ const backupPath = createBackup(skillPath);
2226
+ if (backupPath) {
2227
+ backedUpFiles.push({ original: skillPath, backup: backupPath });
2228
+ }
2229
+ }
2230
+ // Create skill directory and copy recursively
2231
+ mkdirSync(skillPath, { recursive: true });
2232
+ const { cpSync } = await import('fs');
2233
+ cpSync(templatePath, skillPath, { recursive: true });
2234
+ deployedSkills.push(skillName);
2235
+ const action = skillExists ? 'Updated' : 'Created';
2236
+ console.log(chalk.green(` ✓ ${action} skills/${skillName}/`));
2237
+ } else {
2238
+ failedSkills.push({ name: skillName, error: 'No template found' });
2239
+ console.log(chalk.yellow(` ⚠ Skipped skills/${skillName}/ (no template)`));
2240
+ }
2241
+ } catch (error) {
2242
+ failedSkills.push({ name: skillName, error: error.message });
2243
+ console.log(chalk.red(` ✗ Failed: skills/${skillName}/ - ${error.message}`));
2244
+ }
2245
+ }
2246
+
2247
+ if (deployedSkills.length > 0) {
2248
+ console.log(chalk.green(`\n ✓ Deployed ${deployedSkills.length} feature skill(s)`));
2249
+ }
2250
+ }
2251
+
2286
2252
  // Step 7: Generate INDEX.md
2287
2253
  const indexPath = join(commandsDir, 'INDEX.md');
2288
2254
  const indexContent = generateIndexFile(installed, projectName);
@@ -2416,6 +2382,8 @@ export async function runInit(options = {}) {
2416
2382
  featureCommands: featureCommands.filter(c => installed.includes(c)),
2417
2383
  hooks: deployedHooks,
2418
2384
  featureHooks: featureHooks,
2385
+ skills: deployedSkills,
2386
+ featureSkills: featureSkills,
2419
2387
  enabledFeatures: selectedFeatures,
2420
2388
  timestamp: new Date().toISOString(),
2421
2389
  },
@@ -2428,6 +2396,26 @@ export async function runInit(options = {}) {
2428
2396
  console.log(chalk.blue(' ○ config/tech-stack.json exists (preserved)'));
2429
2397
  }
2430
2398
 
2399
+ // Update ccasp-state.json with current version (fixes version display in /menu)
2400
+ const ccaspStatePath = join(configDir, 'ccasp-state.json');
2401
+ const currentVersion = getVersion();
2402
+ let ccaspState = { currentVersion, lastCheckTimestamp: 0, updateAvailable: false };
2403
+
2404
+ if (existsSync(ccaspStatePath)) {
2405
+ try {
2406
+ ccaspState = JSON.parse(readFileSync(ccaspStatePath, 'utf8'));
2407
+ } catch {
2408
+ // Use default state if parse fails
2409
+ }
2410
+ }
2411
+
2412
+ // Always update the current version to match installed CCASP
2413
+ ccaspState.currentVersion = currentVersion;
2414
+ ccaspState.installedAt = new Date().toISOString();
2415
+
2416
+ writeFileSync(ccaspStatePath, JSON.stringify(ccaspState, null, 2), 'utf8');
2417
+ console.log(chalk.green(` ✓ Updated ccasp-state.json (v${currentVersion})`));
2418
+
2431
2419
  // Show next steps
2432
2420
  console.log(chalk.bold('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
2433
2421
  console.log(chalk.bold('Next Steps:\n'));