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.
- package/OVERVIEW.md +5 -1
- package/README.md +241 -132
- package/bin/gtask.js +53 -0
- package/package.json +1 -1
- package/src/cli/menu.js +27 -0
- package/src/commands/explore-mcp/mcp-registry.js +99 -0
- package/src/commands/init.js +339 -351
- package/src/commands/install-panel-hook.js +108 -0
- package/src/commands/install-scripts.js +232 -0
- package/src/commands/install-skill.js +220 -0
- package/src/commands/panel.js +297 -0
- package/src/commands/setup-wizard.js +4 -3
- package/src/commands/test-setup.js +4 -5
- package/src/data/releases.json +164 -0
- package/src/panel/queue.js +188 -0
- package/templates/commands/ask-claude.template.md +118 -0
- package/templates/commands/ccasp-panel.template.md +72 -0
- package/templates/commands/ccasp-setup.template.md +470 -79
- package/templates/commands/create-smoke-test.template.md +186 -0
- package/templates/commands/project-impl.template.md +9 -113
- package/templates/commands/refactor-check.template.md +112 -0
- package/templates/commands/refactor-cleanup.template.md +144 -0
- package/templates/commands/refactor-prep.template.md +192 -0
- package/templates/docs/AI_ARCHITECTURE_CONSTITUTION.template.md +198 -0
- package/templates/docs/DETAILED_GOTCHAS.template.md +347 -0
- package/templates/docs/PHASE-DEV-CHECKLIST.template.md +241 -0
- package/templates/docs/PROGRESS_JSON_TEMPLATE.json +117 -0
- package/templates/docs/background-agent.template.md +264 -0
- package/templates/hooks/autonomous-decision-logger.template.js +207 -0
- package/templates/hooks/branch-merge-checker.template.js +272 -0
- package/templates/hooks/git-commit-tracker.template.js +267 -0
- package/templates/hooks/issue-completion-detector.template.js +205 -0
- package/templates/hooks/panel-queue-reader.template.js +83 -0
- package/templates/hooks/phase-validation-gates.template.js +307 -0
- package/templates/hooks/session-id-generator.template.js +236 -0
- package/templates/hooks/token-usage-monitor.template.js +193 -0
- package/templates/patterns/README.md +129 -0
- package/templates/patterns/l1-l2-orchestration.md +189 -0
- package/templates/patterns/multi-phase-orchestration.md +258 -0
- package/templates/patterns/two-tier-query-pipeline.md +192 -0
- package/templates/scripts/README.md +109 -0
- package/templates/scripts/analyze-delegation-log.js +299 -0
- package/templates/scripts/autonomous-decision-logger.js +277 -0
- package/templates/scripts/git-history-analyzer.py +269 -0
- package/templates/scripts/phase-validation-gates.js +307 -0
- package/templates/scripts/poll-deployment-status.js +260 -0
- package/templates/scripts/roadmap-scanner.js +263 -0
- package/templates/scripts/validate-deployment.js +293 -0
- package/templates/skills/agent-creator/skill.json +18 -0
- package/templates/skills/agent-creator/skill.md +335 -0
- package/templates/skills/hook-creator/skill.json +18 -0
- package/templates/skills/hook-creator/skill.md +318 -0
- package/templates/skills/panel/skill.json +18 -0
- package/templates/skills/panel/skill.md +90 -0
- package/templates/skills/rag-agent-creator/skill.json +18 -0
- package/templates/skills/rag-agent-creator/skill.md +307 -0
package/src/commands/init.js
CHANGED
|
@@ -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
|
|
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
|
-
//
|
|
278
|
-
|
|
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
|
-
|
|
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:
|
|
373
|
+
description: Launch CCASP Control Panel - Interactive menu in separate terminal
|
|
336
374
|
---
|
|
337
375
|
|
|
338
|
-
# ${projectName} -
|
|
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
|
-
|
|
380
|
+
**EXECUTE IMMEDIATELY**: Launch the CCASP Control Panel in a new terminal window.
|
|
480
381
|
|
|
481
|
-
### Step 1:
|
|
382
|
+
### Step 1: Launch Panel
|
|
482
383
|
|
|
483
|
-
|
|
384
|
+
Use the Bash tool to run this command:
|
|
484
385
|
|
|
386
|
+
**Windows:**
|
|
485
387
|
\`\`\`bash
|
|
486
|
-
|
|
388
|
+
start powershell -NoExit -Command "ccasp panel"
|
|
487
389
|
\`\`\`
|
|
488
390
|
|
|
489
|
-
|
|
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
|
-
|
|
393
|
+
osascript -e 'tell application "Terminal" to do script "ccasp panel"'
|
|
510
394
|
\`\`\`
|
|
511
395
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
│
|
|
555
|
-
│
|
|
556
|
-
│
|
|
557
|
-
│
|
|
558
|
-
│
|
|
559
|
-
│
|
|
560
|
-
│
|
|
561
|
-
│
|
|
562
|
-
│
|
|
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
|
-
|
|
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
|
-
|
|
434
|
+
If the panel doesn't work, you can invoke these commands directly:
|
|
574
435
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
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
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
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
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
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
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
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
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
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
|
|
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
|
-
|
|
1790
|
+
let selectedCommands;
|
|
1905
1791
|
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
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
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
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
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
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
|
-
//
|
|
2259
|
-
if (
|
|
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
|
-
|
|
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'));
|