claude-cli-advanced-starter-pack 1.8.3 → 1.8.4

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
@@ -9,7 +9,7 @@
9
9
  ║ ║ ║ ╠═╣║ ║ ║║║╣ ╠═╣ ║║╚╗╔╝╠═╣║║║║ ║╣ ║║ ╚═╗ ║ ╠═╣╠╦╝ ║ ║╣ ╠╦╝ ║
10
10
  ║ ╚═╝╩═╝╩ ╩╚═╝═╩╝╚═╝ ╩ ╩═╩╝ ╚╝ ╩ ╩╝╚╝╚═╝╚═╝═╩╝ ╚═╝ ╩ ╩ ╩╩╚═ ╩ ╚═╝╩╚═ ║
11
11
  ║ ║
12
- ║ v1.8.0 • Production Ready ║
12
+ ║ v1.8.3 • Production Ready ║
13
13
  ║ ║
14
14
  ╚═══════════════════════════════════════════════════════════════════════════════╝
15
15
  ```
@@ -65,7 +65,11 @@ CCASP is a **two-phase toolkit** that extends Claude Code CLI capabilities:
65
65
 
66
66
  ---
67
67
 
68
- ## What's New in v1.8.0
68
+ ## What's New in v1.8.3
69
+
70
+ **Latest updates:**
71
+ - **`ccasp init --dev`**: Dev mode for rapid template testing - reuses existing tech-stack.json, processes all templates, preserves custom commands
72
+ - **`npm-deploy.js --auto`**: Auto mode for CI/CD - skips confirmation prompts for automation
69
73
 
70
74
  **60+ components** across 8 implementation phases:
71
75
 
package/bin/gtask.js CHANGED
@@ -36,6 +36,8 @@ import { runInstallScripts } from '../src/commands/install-scripts.js';
36
36
  import { runPanel, launchPanel } from '../src/commands/panel.js';
37
37
  import { runInstallPanelHook } from '../src/commands/install-panel-hook.js';
38
38
  import { runUninstall } from '../src/commands/uninstall.js';
39
+ import { runGlobalUninstall } from '../src/commands/global-uninstall.js';
40
+ import { runGlobalReinstall } from '../src/commands/global-reinstall.js';
39
41
  import { getVersion, checkPrerequisites } from '../src/utils.js';
40
42
 
41
43
  program
@@ -48,6 +50,8 @@ program
48
50
  .command('init')
49
51
  .description('Deploy Claude CLI Advanced Starter Pack to current project')
50
52
  .option('--force', 'Overwrite existing commands')
53
+ .option('--no-register', 'Do not register project in global registry')
54
+ .option('--dev', 'Development mode: reuse existing tech-stack.json, process templates, skip prompts')
51
55
  .action(async (options) => {
52
56
  await runInit(options);
53
57
  });
@@ -62,6 +66,26 @@ program
62
66
  await runUninstall(options);
63
67
  });
64
68
 
69
+ // Global uninstall command - remove CCASP from ALL projects
70
+ program
71
+ .command('global-uninstall')
72
+ .description('Remove CCASP from all registered projects and clear global config')
73
+ .option('--force', 'Skip confirmation prompts')
74
+ .option('--all', 'Remove entire .claude/ directory from each project')
75
+ .action(async (options) => {
76
+ await runGlobalUninstall(options);
77
+ });
78
+
79
+ // Global reinstall command - reinstall CCASP across all projects
80
+ program
81
+ .command('global-reinstall')
82
+ .description('Reinstall CCASP globally (use --projects to reinstall in all projects)')
83
+ .option('--force', 'Skip confirmation prompts')
84
+ .option('--projects', 'Reinstall CCASP in all registered projects')
85
+ .action(async (options) => {
86
+ await runGlobalReinstall(options);
87
+ });
88
+
65
89
  // Interactive menu (default when no command)
66
90
  program
67
91
  .command('menu', { isDefault: true })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-cli-advanced-starter-pack",
3
- "version": "1.8.3",
3
+ "version": "1.8.4",
4
4
  "description": "Advanced Claude Code CLI toolkit - agents, hooks, skills, MCP servers, phased development, and GitHub integration",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Global Reinstall Command
3
+ *
4
+ * Reinstalls CCASP globally:
5
+ * - Without --projects: Just refreshes the npm package (user must run manually)
6
+ * - With --projects: Uninstalls from all projects, then re-runs init on each
7
+ *
8
+ * Useful for:
9
+ * - Upgrading to a new version across all projects
10
+ * - Resetting CCASP configuration to defaults
11
+ * - Recovering from corrupted installations
12
+ */
13
+
14
+ import chalk from 'chalk';
15
+ import { existsSync } from 'fs';
16
+ import { createInterface } from 'readline';
17
+ import {
18
+ loadRegistry,
19
+ getRegistryStats,
20
+ saveRegistry
21
+ } from '../utils/global-registry.js';
22
+ import { runGlobalUninstall } from './global-uninstall.js';
23
+ import { runInit } from './init.js';
24
+ import { getVersion } from '../utils.js';
25
+
26
+ /**
27
+ * Prompt user for confirmation
28
+ */
29
+ function confirm(question) {
30
+ const rl = createInterface({
31
+ input: process.stdin,
32
+ output: process.stdout
33
+ });
34
+
35
+ return new Promise((resolve) => {
36
+ rl.question(question, (answer) => {
37
+ rl.close();
38
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
39
+ });
40
+ });
41
+ }
42
+
43
+ /**
44
+ * Run init in a specific project directory
45
+ */
46
+ async function initProject(projectPath, options = {}) {
47
+ const originalCwd = process.cwd();
48
+
49
+ try {
50
+ // Change to project directory
51
+ process.chdir(projectPath);
52
+
53
+ // Run init with skipPrompts to avoid interactive questions
54
+ await runInit({ skipPrompts: true, force: true, ...options });
55
+
56
+ return { success: true };
57
+ } catch (err) {
58
+ return { success: false, error: err.message };
59
+ } finally {
60
+ // Restore original cwd
61
+ process.chdir(originalCwd);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Main global reinstall function
67
+ */
68
+ export async function runGlobalReinstall(options = {}) {
69
+ console.log(chalk.cyan('\n ╔══════════════════════════════════════════════════════════════╗'));
70
+ console.log(chalk.cyan(' ║') + chalk.bold.white(' CCASP Global Reinstall ') + chalk.cyan('║'));
71
+ console.log(chalk.cyan(' ╚══════════════════════════════════════════════════════════════╝\n'));
72
+
73
+ const version = getVersion();
74
+ console.log(chalk.dim(` CCASP Version: ${version}\n`));
75
+
76
+ // Get current registry state
77
+ const stats = getRegistryStats();
78
+ const registry = loadRegistry();
79
+
80
+ // Store project list before uninstall (for --projects mode)
81
+ const projectsToReinstall = registry.projects.map(p => ({
82
+ path: p.path,
83
+ name: p.name,
84
+ features: p.features || []
85
+ }));
86
+
87
+ // Check if --projects flag is set
88
+ if (!options.projects) {
89
+ console.log(chalk.bold(' Reinstall Mode: Package Only\n'));
90
+ console.log(chalk.dim(' This mode refreshes the npm package but does NOT touch project installations.'));
91
+ console.log(chalk.dim(' Use --projects flag to reinstall CCASP in all registered projects.\n'));
92
+
93
+ if (stats.total > 0) {
94
+ console.log(chalk.yellow(` 📁 ${stats.total} project(s) currently registered:`));
95
+ for (const project of registry.projects) {
96
+ const exists = existsSync(project.path);
97
+ const statusIcon = exists ? chalk.green('✓') : chalk.red('✗');
98
+ console.log(` ${statusIcon} ${project.name}`);
99
+ }
100
+ console.log('');
101
+ }
102
+
103
+ console.log(chalk.bold(' To reinstall the npm package:\n'));
104
+ console.log(chalk.cyan(' npm uninstall -g claude-cli-advanced-starter-pack'));
105
+ console.log(chalk.cyan(' npm install -g claude-cli-advanced-starter-pack@latest\n'));
106
+
107
+ console.log(chalk.dim(' Or use --projects to reinstall in all projects:'));
108
+ console.log(chalk.cyan(' ccasp global-reinstall --projects\n'));
109
+
110
+ return;
111
+ }
112
+
113
+ // --projects mode: Full reinstall
114
+ console.log(chalk.bold(' Reinstall Mode: Full (Projects)\n'));
115
+
116
+ if (stats.total === 0) {
117
+ console.log(chalk.yellow(' No projects registered in global registry.\n'));
118
+ console.log(chalk.dim(' To register a project, run: cd /path/to/project && ccasp init\n'));
119
+ return;
120
+ }
121
+
122
+ console.log(chalk.yellow(` 📁 ${stats.total} project(s) will be reinstalled:`));
123
+ for (const project of projectsToReinstall) {
124
+ const exists = existsSync(project.path);
125
+ const statusIcon = exists ? chalk.green('✓') : chalk.red('✗');
126
+ const statusText = exists ? '' : chalk.dim(' (will be skipped)');
127
+ console.log(` ${statusIcon} ${project.name}${statusText}`);
128
+ }
129
+ console.log('');
130
+
131
+ // Count existing projects
132
+ const existingProjects = projectsToReinstall.filter(p => existsSync(p.path));
133
+
134
+ if (existingProjects.length === 0) {
135
+ console.log(chalk.red(' No project directories found. Nothing to reinstall.\n'));
136
+ return;
137
+ }
138
+
139
+ // Confirm unless --force
140
+ if (!options.force) {
141
+ console.log(chalk.yellow.bold(' ⚠️ This will:'));
142
+ console.log(chalk.yellow(` 1. Uninstall CCASP from ${existingProjects.length} project(s)`));
143
+ console.log(chalk.yellow(' 2. Restore any backed-up files'));
144
+ console.log(chalk.yellow(` 3. Reinstall CCASP v${version} in each project`));
145
+ console.log('');
146
+
147
+ const shouldContinue = await confirm(chalk.yellow(' Proceed with global reinstall? (y/N): '));
148
+ if (!shouldContinue) {
149
+ console.log(chalk.dim('\n Cancelled. No changes made.\n'));
150
+ return;
151
+ }
152
+ console.log('');
153
+ }
154
+
155
+ // Track results
156
+ const results = {
157
+ uninstalled: 0,
158
+ reinstalled: 0,
159
+ failed: [],
160
+ skipped: 0
161
+ };
162
+
163
+ // Phase 1: Uninstall from all projects
164
+ console.log(chalk.bold(' Phase 1: Uninstalling from all projects...\n'));
165
+
166
+ // Run global uninstall but preserve project list for reinstall
167
+ // We don't call runGlobalUninstall directly because it clears the registry
168
+ for (const project of projectsToReinstall) {
169
+ process.stdout.write(` ${chalk.dim('○')} Uninstalling from ${project.name}... `);
170
+
171
+ if (!existsSync(project.path)) {
172
+ console.log(chalk.yellow('skipped'));
173
+ results.skipped++;
174
+ continue;
175
+ }
176
+
177
+ const originalCwd = process.cwd();
178
+ try {
179
+ process.chdir(project.path);
180
+
181
+ // Import and run uninstall dynamically to avoid circular dependency issues
182
+ const { runUninstall } = await import('./uninstall.js');
183
+ await runUninstall({ force: true });
184
+
185
+ console.log(chalk.green('✓'));
186
+ results.uninstalled++;
187
+ } catch (err) {
188
+ console.log(chalk.red(`✗ ${err.message}`));
189
+ results.failed.push({ project: project.name, phase: 'uninstall', error: err.message });
190
+ } finally {
191
+ process.chdir(originalCwd);
192
+ }
193
+ }
194
+
195
+ console.log('');
196
+
197
+ // Phase 2: Reinstall in all projects
198
+ console.log(chalk.bold(' Phase 2: Reinstalling CCASP in all projects...\n'));
199
+
200
+ for (const project of projectsToReinstall) {
201
+ process.stdout.write(` ${chalk.dim('○')} Installing in ${project.name}... `);
202
+
203
+ if (!existsSync(project.path)) {
204
+ console.log(chalk.yellow('skipped'));
205
+ continue;
206
+ }
207
+
208
+ const result = await initProject(project.path, { skipPrompts: true });
209
+
210
+ if (result.success) {
211
+ console.log(chalk.green('✓'));
212
+ results.reinstalled++;
213
+ } else {
214
+ console.log(chalk.red(`✗ ${result.error}`));
215
+ results.failed.push({ project: project.name, phase: 'reinstall', error: result.error });
216
+ }
217
+ }
218
+
219
+ // Summary
220
+ console.log(chalk.bold('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
221
+
222
+ if (results.failed.length === 0) {
223
+ console.log(chalk.green.bold(' ✓ Global reinstall complete!\n'));
224
+ } else {
225
+ console.log(chalk.yellow.bold(' ⚠️ Global reinstall completed with errors\n'));
226
+ }
227
+
228
+ console.log(chalk.dim(` Projects reinstalled: ${results.reinstalled}`));
229
+ if (results.skipped > 0) {
230
+ console.log(chalk.dim(` Projects skipped (not found): ${results.skipped}`));
231
+ }
232
+
233
+ if (results.failed.length > 0) {
234
+ console.log(chalk.yellow(` Projects with errors: ${results.failed.length}`));
235
+ for (const failure of results.failed) {
236
+ console.log(chalk.red(` • ${failure.project} (${failure.phase}): ${failure.error}`));
237
+ }
238
+ }
239
+
240
+ console.log('');
241
+ console.log(chalk.dim(' Each project now has the latest CCASP commands.'));
242
+ console.log(chalk.dim(' Restart Claude Code CLI to use the updated commands.\n'));
243
+ }
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Global Uninstall Command
3
+ *
4
+ * Removes CCASP from ALL registered projects and cleans up global configuration.
5
+ * - Restores backups in each project
6
+ * - Removes CCASP files from each project
7
+ * - Clears the global registry
8
+ * - Removes global CCASP cache/config files
9
+ */
10
+
11
+ import chalk from 'chalk';
12
+ import { existsSync, rmSync, readdirSync, statSync } from 'fs';
13
+ import { join } from 'path';
14
+ import { createInterface } from 'readline';
15
+ import {
16
+ loadRegistry,
17
+ clearRegistry,
18
+ getRegistryStats,
19
+ getGlobalClaudeDir,
20
+ getRegistryPath
21
+ } from '../utils/global-registry.js';
22
+ import { runUninstall } from './uninstall.js';
23
+
24
+ /**
25
+ * Prompt user for confirmation
26
+ */
27
+ function confirm(question) {
28
+ const rl = createInterface({
29
+ input: process.stdin,
30
+ output: process.stdout
31
+ });
32
+
33
+ return new Promise((resolve) => {
34
+ rl.question(question, (answer) => {
35
+ rl.close();
36
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
37
+ });
38
+ });
39
+ }
40
+
41
+ /**
42
+ * Run uninstall in a specific project directory
43
+ */
44
+ async function uninstallProject(projectPath, options = {}) {
45
+ const originalCwd = process.cwd();
46
+
47
+ try {
48
+ // Change to project directory
49
+ process.chdir(projectPath);
50
+
51
+ // Run uninstall with force flag to skip prompts
52
+ await runUninstall({ force: true, ...options });
53
+
54
+ return { success: true };
55
+ } catch (err) {
56
+ return { success: false, error: err.message };
57
+ } finally {
58
+ // Restore original cwd
59
+ process.chdir(originalCwd);
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Get global CCASP files/directories to clean up
65
+ */
66
+ function getGlobalCcaspFiles() {
67
+ const globalClaudeDir = getGlobalClaudeDir();
68
+ const files = [];
69
+
70
+ if (!existsSync(globalClaudeDir)) {
71
+ return files;
72
+ }
73
+
74
+ // CCASP-specific files in ~/.claude/
75
+ const ccaspFiles = [
76
+ 'ccasp-registry.json',
77
+ 'ccasp-panel', // Panel queue directory
78
+ ];
79
+
80
+ for (const file of ccaspFiles) {
81
+ const filePath = join(globalClaudeDir, file);
82
+ if (existsSync(filePath)) {
83
+ files.push({
84
+ path: filePath,
85
+ name: file,
86
+ type: statSync(filePath).isDirectory() ? 'directory' : 'file'
87
+ });
88
+ }
89
+ }
90
+
91
+ return files;
92
+ }
93
+
94
+ /**
95
+ * Main global uninstall function
96
+ */
97
+ export async function runGlobalUninstall(options = {}) {
98
+ console.log(chalk.cyan('\n ╔══════════════════════════════════════════════════════════════╗'));
99
+ console.log(chalk.cyan(' ║') + chalk.bold.white(' CCASP Global Uninstall ') + chalk.cyan('║'));
100
+ console.log(chalk.cyan(' ╚══════════════════════════════════════════════════════════════╝\n'));
101
+
102
+ // Get registry stats
103
+ const stats = getRegistryStats();
104
+ const registry = loadRegistry();
105
+ const globalFiles = getGlobalCcaspFiles();
106
+
107
+ // Show what will be affected
108
+ console.log(chalk.bold(' What will be removed:\n'));
109
+
110
+ // Projects
111
+ if (stats.total > 0) {
112
+ console.log(chalk.yellow(` 📁 ${stats.total} registered project(s):`));
113
+ for (const project of registry.projects) {
114
+ const exists = existsSync(project.path);
115
+ const statusIcon = exists ? chalk.green('✓') : chalk.red('✗');
116
+ const statusText = exists ? '' : chalk.dim(' (not found)');
117
+ console.log(` ${statusIcon} ${project.name} - ${chalk.dim(project.path)}${statusText}`);
118
+ }
119
+ console.log('');
120
+ } else {
121
+ console.log(chalk.dim(' 📁 No projects registered\n'));
122
+ }
123
+
124
+ // Global files
125
+ if (globalFiles.length > 0) {
126
+ console.log(chalk.yellow(' 🗂️ Global CCASP files:'));
127
+ for (const file of globalFiles) {
128
+ console.log(` • ~/.claude/${file.name}`);
129
+ }
130
+ console.log('');
131
+ }
132
+
133
+ // npm package note
134
+ console.log(chalk.dim(' 📦 Note: The npm package itself is NOT uninstalled.'));
135
+ console.log(chalk.dim(' To fully remove: npm uninstall -g claude-cli-advanced-starter-pack\n'));
136
+
137
+ // Nothing to do?
138
+ if (stats.total === 0 && globalFiles.length === 0) {
139
+ console.log(chalk.green(' ✓ Nothing to uninstall - CCASP is not configured globally.\n'));
140
+ return;
141
+ }
142
+
143
+ // Confirm unless --force
144
+ if (!options.force) {
145
+ console.log(chalk.red.bold(' ⚠️ This will:'));
146
+ if (stats.existing > 0) {
147
+ console.log(chalk.red(` • Uninstall CCASP from ${stats.existing} project(s)`));
148
+ console.log(chalk.red(' • Restore any backed-up files'));
149
+ }
150
+ if (globalFiles.length > 0) {
151
+ console.log(chalk.red(' • Delete global CCASP configuration'));
152
+ }
153
+ console.log('');
154
+
155
+ const shouldContinue = await confirm(chalk.yellow(' Proceed with global uninstall? (y/N): '));
156
+ if (!shouldContinue) {
157
+ console.log(chalk.dim('\n Cancelled. No changes made.\n'));
158
+ return;
159
+ }
160
+ console.log('');
161
+ }
162
+
163
+ // Track results
164
+ const results = {
165
+ projectsUninstalled: 0,
166
+ projectsFailed: 0,
167
+ projectsSkipped: 0,
168
+ globalFilesRemoved: 0
169
+ };
170
+
171
+ // Uninstall from each project
172
+ if (stats.total > 0) {
173
+ console.log(chalk.bold(' Uninstalling from projects...\n'));
174
+
175
+ for (const project of registry.projects) {
176
+ process.stdout.write(` ${chalk.dim('○')} ${project.name}... `);
177
+
178
+ if (!existsSync(project.path)) {
179
+ console.log(chalk.yellow('skipped (not found)'));
180
+ results.projectsSkipped++;
181
+ continue;
182
+ }
183
+
184
+ const result = await uninstallProject(project.path, { all: options.all });
185
+
186
+ if (result.success) {
187
+ console.log(chalk.green('✓'));
188
+ results.projectsUninstalled++;
189
+ } else {
190
+ console.log(chalk.red(`✗ ${result.error}`));
191
+ results.projectsFailed++;
192
+ }
193
+ }
194
+ console.log('');
195
+ }
196
+
197
+ // Clear global registry
198
+ clearRegistry();
199
+ console.log(chalk.green(' ✓ Cleared global project registry'));
200
+
201
+ // Remove global CCASP files
202
+ for (const file of globalFiles) {
203
+ try {
204
+ rmSync(file.path, { recursive: true, force: true });
205
+ console.log(chalk.green(` ✓ Removed ~/.claude/${file.name}`));
206
+ results.globalFilesRemoved++;
207
+ } catch (err) {
208
+ console.log(chalk.red(` ✗ Failed to remove ~/.claude/${file.name}: ${err.message}`));
209
+ }
210
+ }
211
+
212
+ // Summary
213
+ console.log(chalk.bold('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
214
+ console.log(chalk.green.bold(' ✓ Global uninstall complete!\n'));
215
+
216
+ if (results.projectsUninstalled > 0) {
217
+ console.log(chalk.dim(` Projects uninstalled: ${results.projectsUninstalled}`));
218
+ }
219
+ if (results.projectsSkipped > 0) {
220
+ console.log(chalk.dim(` Projects skipped (not found): ${results.projectsSkipped}`));
221
+ }
222
+ if (results.projectsFailed > 0) {
223
+ console.log(chalk.yellow(` Projects failed: ${results.projectsFailed}`));
224
+ }
225
+
226
+ console.log('');
227
+ console.log(chalk.dim(' To reinstall globally: ccasp global-reinstall'));
228
+ console.log(chalk.dim(' To reinstall in a project: cd /path/to/project && ccasp init\n'));
229
+ }