claude-cli-advanced-starter-pack 1.8.2 → 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 +6 -2
- package/bin/gtask.js +35 -0
- package/package.json +1 -1
- package/src/commands/global-reinstall.js +243 -0
- package/src/commands/global-uninstall.js +229 -0
- package/src/commands/init.js +224 -0
- package/src/commands/uninstall.js +414 -0
- package/src/data/releases.json +15 -0
- package/src/utils/global-registry.js +230 -0
- package/src/utils/paths.js +146 -0
- package/templates/commands/create-task-list-for-issue.template.md +216 -0
- package/templates/commands/create-task-list.template.md +280 -82
- package/templates/commands/menu-issues-list.template.md +288 -0
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
║ ║ ║ ╠═╣║ ║ ║║║╣ ╠═╣ ║║╚╗╔╝╠═╣║║║║ ║╣ ║║ ╚═╗ ║ ╠═╣╠╦╝ ║ ║╣ ╠╦╝ ║
|
|
10
10
|
║ ╚═╝╩═╝╩ ╩╚═╝═╩╝╚═╝ ╩ ╩═╩╝ ╚╝ ╩ ╩╝╚╝╚═╝╚═╝═╩╝ ╚═╝ ╩ ╩ ╩╩╚═ ╩ ╚═╝╩╚═ ║
|
|
11
11
|
║ ║
|
|
12
|
-
║ v1.8.
|
|
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.
|
|
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
|
@@ -35,6 +35,9 @@ import { installSkillCommand, listSkills } from '../src/commands/install-skill.j
|
|
|
35
35
|
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
|
+
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';
|
|
38
41
|
import { getVersion, checkPrerequisites } from '../src/utils.js';
|
|
39
42
|
|
|
40
43
|
program
|
|
@@ -47,10 +50,42 @@ program
|
|
|
47
50
|
.command('init')
|
|
48
51
|
.description('Deploy Claude CLI Advanced Starter Pack to current project')
|
|
49
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')
|
|
50
55
|
.action(async (options) => {
|
|
51
56
|
await runInit(options);
|
|
52
57
|
});
|
|
53
58
|
|
|
59
|
+
// Uninstall command - remove CCASP from project
|
|
60
|
+
program
|
|
61
|
+
.command('uninstall')
|
|
62
|
+
.description('Remove CCASP from current project and restore backups')
|
|
63
|
+
.option('--force', 'Skip confirmation prompts')
|
|
64
|
+
.option('--all', 'Remove entire .claude/ directory')
|
|
65
|
+
.action(async (options) => {
|
|
66
|
+
await runUninstall(options);
|
|
67
|
+
});
|
|
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
|
+
|
|
54
89
|
// Interactive menu (default when no command)
|
|
55
90
|
program
|
|
56
91
|
.command('menu', { isDefault: true })
|
package/package.json
CHANGED
|
@@ -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
|
+
}
|