speccrew 0.6.10 → 0.6.12
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/.speccrew/agents/speccrew-product-manager.md +36 -30
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/generate-inventory.js +7 -7
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/apply-module-mapping.js +1 -1
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/reindex-modules.js +38 -38
- package/.speccrew/skills/speccrew-pm-module-initializer/SKILL.md +83 -39
- package/lib/commands/doctor.js +7 -7
- package/lib/commands/init.js +35 -35
- package/lib/commands/list.js +8 -8
- package/lib/commands/uninstall.js +20 -20
- package/lib/commands/update.js +41 -41
- package/lib/ide-adapters.js +47 -47
- package/lib/utils.js +12 -12
- package/package.json +1 -1
- package/workspace-template/scripts/update-progress.js +148 -147
package/lib/commands/init.js
CHANGED
|
@@ -15,7 +15,7 @@ const {
|
|
|
15
15
|
} = require('../utils');
|
|
16
16
|
const { resolveIDE, transformAgentForIDE, transformSkillForIDE } = require('../ide-adapters');
|
|
17
17
|
|
|
18
|
-
//
|
|
18
|
+
// Parse command line arguments
|
|
19
19
|
function parseArgs() {
|
|
20
20
|
const args = process.argv.slice(2);
|
|
21
21
|
let ide = null;
|
|
@@ -30,7 +30,7 @@ function parseArgs() {
|
|
|
30
30
|
return { ide };
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
//
|
|
33
|
+
// Check Node.js version >= 16
|
|
34
34
|
function checkNodeVersion() {
|
|
35
35
|
const version = process.version;
|
|
36
36
|
const major = parseInt(version.slice(1).split('.')[0], 10);
|
|
@@ -39,7 +39,7 @@ function checkNodeVersion() {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
//
|
|
42
|
+
// Progress display helper functions
|
|
43
43
|
function printProgress(step, total, message) {
|
|
44
44
|
process.stdout.write(`[${step}/${total}] ${message}... `);
|
|
45
45
|
}
|
|
@@ -48,12 +48,12 @@ function printDone() {
|
|
|
48
48
|
console.log('done');
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
//
|
|
51
|
+
// Get npm package root directory
|
|
52
52
|
function getPackageRoot() {
|
|
53
53
|
return path.resolve(__dirname, '..', '..');
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
//
|
|
56
|
+
// Copy agents (speccrew-* prefixed files, always overwrite)
|
|
57
57
|
function copyAgents(sourceDir, destDir, ideConfig) {
|
|
58
58
|
if (!fs.existsSync(sourceDir)) return { copied: 0, skipped: 0 };
|
|
59
59
|
|
|
@@ -70,7 +70,7 @@ function copyAgents(sourceDir, destDir, ideConfig) {
|
|
|
70
70
|
const srcPath = path.join(sourceDir, entry.name);
|
|
71
71
|
const destPath = path.join(destDir, entry.name);
|
|
72
72
|
|
|
73
|
-
//
|
|
73
|
+
// If IDE needs frontmatter transformation and is .md file
|
|
74
74
|
if (ideConfig && ideConfig.transformFrontmatter && entry.name.endsWith('.md')) {
|
|
75
75
|
const originalContent = fs.readFileSync(srcPath, 'utf8');
|
|
76
76
|
const transformedContent = transformAgentForIDE(originalContent, ideConfig);
|
|
@@ -84,7 +84,7 @@ function copyAgents(sourceDir, destDir, ideConfig) {
|
|
|
84
84
|
return { copied, skipped };
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
//
|
|
87
|
+
// Copy skills (speccrew-* prefixed directories, recursive copy, always overwrite)
|
|
88
88
|
function copySkills(sourceDir, destDir, ideConfig) {
|
|
89
89
|
if (!fs.existsSync(sourceDir)) return { copied: 0, skipped: 0 };
|
|
90
90
|
|
|
@@ -101,14 +101,14 @@ function copySkills(sourceDir, destDir, ideConfig) {
|
|
|
101
101
|
const destPath = path.join(destDir, entry.name);
|
|
102
102
|
|
|
103
103
|
if (entry.isDirectory()) {
|
|
104
|
-
//
|
|
104
|
+
// Build contentTransform callback: only transform SKILL.md files
|
|
105
105
|
let contentTransform = null;
|
|
106
106
|
if (ideConfig && ideConfig.transformFrontmatter) {
|
|
107
107
|
contentTransform = (content, fileName, filePath) => {
|
|
108
108
|
if (fileName === 'SKILL.md') {
|
|
109
109
|
return transformSkillForIDE(content, ideConfig);
|
|
110
110
|
}
|
|
111
|
-
//
|
|
111
|
+
// Other files return null, indicating copy as-is
|
|
112
112
|
return null;
|
|
113
113
|
};
|
|
114
114
|
}
|
|
@@ -124,7 +124,7 @@ function copySkills(sourceDir, destDir, ideConfig) {
|
|
|
124
124
|
return { copied, skipped };
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
//
|
|
127
|
+
// Create workspace directory structure
|
|
128
128
|
function createWorkspaceStructure(workspaceDir) {
|
|
129
129
|
const dirs = [
|
|
130
130
|
'iterations',
|
|
@@ -143,7 +143,7 @@ function createWorkspaceStructure(workspaceDir) {
|
|
|
143
143
|
ensureDirectories(workspaceDir, dirs);
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
//
|
|
146
|
+
// Copy workspace template (only copy non-existent files)
|
|
147
147
|
function copyWorkspaceTemplate(templateDir, workspaceDir) {
|
|
148
148
|
if (!fs.existsSync(templateDir)) return { copied: 0, skipped: 0 };
|
|
149
149
|
|
|
@@ -169,7 +169,7 @@ function copyWorkspaceTemplate(templateDir, workspaceDir) {
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
//
|
|
172
|
+
// Iterate over all first-level subdirectories in workspace-template and copy
|
|
173
173
|
const entries = fs.readdirSync(templateDir, { withFileTypes: true });
|
|
174
174
|
for (const entry of entries) {
|
|
175
175
|
if (entry.isDirectory()) {
|
|
@@ -183,11 +183,11 @@ function copyWorkspaceTemplate(templateDir, workspaceDir) {
|
|
|
183
183
|
return { copied, skipped };
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
//
|
|
186
|
+
// Copy documentation files (only copy non-existent files)
|
|
187
187
|
function copyDocs(packageRoot, workspaceDir) {
|
|
188
188
|
let copied = 0;
|
|
189
189
|
|
|
190
|
-
//
|
|
190
|
+
// Copy GETTING-STARTED*.md to workspace/docs/
|
|
191
191
|
const docsSourceDir = path.join(packageRoot, 'docs');
|
|
192
192
|
const docsDestDir = path.join(workspaceDir, 'docs');
|
|
193
193
|
|
|
@@ -206,7 +206,7 @@ function copyDocs(packageRoot, workspaceDir) {
|
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
//
|
|
209
|
+
// Copy README*.md to workspace/
|
|
210
210
|
const entries = fs.readdirSync(packageRoot, { withFileTypes: true });
|
|
211
211
|
for (const entry of entries) {
|
|
212
212
|
if (entry.name.startsWith('README') && entry.name.endsWith('.md')) {
|
|
@@ -223,7 +223,7 @@ function copyDocs(packageRoot, workspaceDir) {
|
|
|
223
223
|
return { copied };
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
//
|
|
226
|
+
// Migrate old .speccrewrc to workspace directory
|
|
227
227
|
function migrateOldSpeccrewRC(projectRoot, workspaceDir) {
|
|
228
228
|
const oldRcPath = path.join(projectRoot, '.speccrewrc');
|
|
229
229
|
const newRcPath = path.join(workspaceDir, '.speccrewrc');
|
|
@@ -235,7 +235,7 @@ function migrateOldSpeccrewRC(projectRoot, workspaceDir) {
|
|
|
235
235
|
return false;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
//
|
|
238
|
+
// Count agents and skills
|
|
239
239
|
function countAgentsAndSkills(sourceRoot) {
|
|
240
240
|
let agentCount = 0;
|
|
241
241
|
let skillCount = 0;
|
|
@@ -256,7 +256,7 @@ function countAgentsAndSkills(sourceRoot) {
|
|
|
256
256
|
return { agentCount, skillCount };
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
//
|
|
259
|
+
// Ask user for confirmation
|
|
260
260
|
function askConfirm(message) {
|
|
261
261
|
return new Promise((resolve) => {
|
|
262
262
|
const rl = readline.createInterface({
|
|
@@ -272,7 +272,7 @@ function askConfirm(message) {
|
|
|
272
272
|
});
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
//
|
|
275
|
+
// Core installation logic
|
|
276
276
|
async function runInit(options = {}) {
|
|
277
277
|
const {
|
|
278
278
|
projectRoot = process.cwd(),
|
|
@@ -284,22 +284,22 @@ async function runInit(options = {}) {
|
|
|
284
284
|
const log = silent ? () => {} : console.log;
|
|
285
285
|
|
|
286
286
|
try {
|
|
287
|
-
// 1.
|
|
287
|
+
// 1. Check Node.js version
|
|
288
288
|
checkNodeVersion();
|
|
289
289
|
|
|
290
|
-
// 2.
|
|
290
|
+
// 2. Determine source file paths
|
|
291
291
|
const sourceRoot = getSourceRoot();
|
|
292
292
|
const packageRoot = getPackageRoot();
|
|
293
293
|
|
|
294
|
-
// 3.
|
|
294
|
+
// 3. Resolve IDE
|
|
295
295
|
if (!silent) printProgress(1, 5, 'Detecting IDE environment');
|
|
296
296
|
const ideConfigs = resolveIDE(projectRoot, ideArg);
|
|
297
297
|
if (!silent) printDone();
|
|
298
298
|
|
|
299
|
-
// 4.
|
|
299
|
+
// 4. Count agents and skills
|
|
300
300
|
const { agentCount, skillCount } = countAgentsAndSkills(sourceRoot);
|
|
301
301
|
|
|
302
|
-
// 5.
|
|
302
|
+
// 5. Show installation summary and confirm
|
|
303
303
|
const version = getPackageVersion();
|
|
304
304
|
const workspaceDir = path.join(projectRoot, 'speccrew-workspace');
|
|
305
305
|
|
|
@@ -323,10 +323,10 @@ async function runInit(options = {}) {
|
|
|
323
323
|
log('');
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
// 6.
|
|
326
|
+
// 6. Migrate old .speccrewrc (if exists)
|
|
327
327
|
migrateOldSpeccrewRC(projectRoot, workspaceDir);
|
|
328
328
|
|
|
329
|
-
//
|
|
329
|
+
// Statistics
|
|
330
330
|
const stats = {
|
|
331
331
|
ides: [],
|
|
332
332
|
totalAgents: 0,
|
|
@@ -335,7 +335,7 @@ async function runInit(options = {}) {
|
|
|
335
335
|
docsInstalled: 0,
|
|
336
336
|
};
|
|
337
337
|
|
|
338
|
-
// 7.
|
|
338
|
+
// 7. Copy agents and skills
|
|
339
339
|
if (!silent) printProgress(2, 5, `Installing agents (${agentCount})`);
|
|
340
340
|
for (const ideConfig of ideConfigs) {
|
|
341
341
|
const agentsSourceDir = path.join(sourceRoot, 'agents');
|
|
@@ -363,28 +363,28 @@ async function runInit(options = {}) {
|
|
|
363
363
|
}
|
|
364
364
|
if (!silent) printDone();
|
|
365
365
|
|
|
366
|
-
// 8.
|
|
366
|
+
// 8. Copy skills (show progress)
|
|
367
367
|
if (!silent) printProgress(3, 5, `Installing skills (${skillCount})`);
|
|
368
|
-
//
|
|
368
|
+
// Skills already copied above, just showing progress here
|
|
369
369
|
if (!silent) printDone();
|
|
370
370
|
|
|
371
|
-
// 9.
|
|
371
|
+
// 9. Create speccrew-workspace directory structure
|
|
372
372
|
if (!silent) printProgress(4, 5, 'Creating workspace structure');
|
|
373
373
|
createWorkspaceStructure(workspaceDir);
|
|
374
374
|
stats.workspaceCreated = true;
|
|
375
375
|
if (!silent) printDone();
|
|
376
376
|
|
|
377
|
-
// 10.
|
|
377
|
+
// 10. Copy workspace template
|
|
378
378
|
const templateDir = getWorkspaceTemplatePath();
|
|
379
379
|
copyWorkspaceTemplate(templateDir, workspaceDir);
|
|
380
380
|
|
|
381
|
-
// 11.
|
|
381
|
+
// 11. Copy documentation
|
|
382
382
|
if (!silent) printProgress(5, 5, 'Installing documentation');
|
|
383
383
|
const docsResult = copyDocs(packageRoot, workspaceDir);
|
|
384
384
|
stats.docsInstalled = docsResult.copied;
|
|
385
385
|
if (!silent) printDone();
|
|
386
386
|
|
|
387
|
-
// 12.
|
|
387
|
+
// 12. Write .speccrewrc to workspace directory
|
|
388
388
|
const rcConfig = {
|
|
389
389
|
ide: ideConfigs.length === 1 ? ideConfigs[0].id : ideConfigs.map(c => c.id),
|
|
390
390
|
version: version,
|
|
@@ -392,7 +392,7 @@ async function runInit(options = {}) {
|
|
|
392
392
|
};
|
|
393
393
|
writeSpeccrewRC(workspaceDir, rcConfig);
|
|
394
394
|
|
|
395
|
-
// 13.
|
|
395
|
+
// 13. Output installation summary
|
|
396
396
|
if (!silent) {
|
|
397
397
|
log(`\nSpecCrew v${version} installed successfully!\n`);
|
|
398
398
|
|
|
@@ -442,7 +442,7 @@ async function runInit(options = {}) {
|
|
|
442
442
|
}
|
|
443
443
|
}
|
|
444
444
|
|
|
445
|
-
// CLI
|
|
445
|
+
// CLI entry point
|
|
446
446
|
function run() {
|
|
447
447
|
const { ide: cliIdeArg } = parseArgs();
|
|
448
448
|
|
package/lib/commands/list.js
CHANGED
|
@@ -3,7 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const { readSpeccrewRC, getPackageVersion, isSpeccrewFile } = require('../utils');
|
|
4
4
|
|
|
5
5
|
function run(projectRoot, args) {
|
|
6
|
-
//
|
|
6
|
+
// Check if initialized
|
|
7
7
|
const rc = readSpeccrewRC(projectRoot);
|
|
8
8
|
if (!rc) {
|
|
9
9
|
console.log('SpecCrew is not initialized in this project.');
|
|
@@ -25,7 +25,7 @@ function run(projectRoot, args) {
|
|
|
25
25
|
|
|
26
26
|
console.log(`SpecCrew v${version} | IDE: ${ideDisplay} (${ideDirs.join(', ')})\n`);
|
|
27
27
|
|
|
28
|
-
//
|
|
28
|
+
// Collect all agents and skills
|
|
29
29
|
const speccrewAgents = new Set();
|
|
30
30
|
const speccrewSkills = new Set();
|
|
31
31
|
const userAgents = new Set();
|
|
@@ -35,7 +35,7 @@ function run(projectRoot, args) {
|
|
|
35
35
|
const ideConfig = getIDEConfig(ideId);
|
|
36
36
|
if (!ideConfig) continue;
|
|
37
37
|
|
|
38
|
-
//
|
|
38
|
+
// Scan agents
|
|
39
39
|
const agentsDir = path.join(projectRoot, ideConfig.agentsDir);
|
|
40
40
|
if (fs.existsSync(agentsDir)) {
|
|
41
41
|
const entries = fs.readdirSync(agentsDir, { withFileTypes: true });
|
|
@@ -49,7 +49,7 @@ function run(projectRoot, args) {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
//
|
|
52
|
+
// Scan skills
|
|
53
53
|
const skillsDir = path.join(projectRoot, ideConfig.skillsDir);
|
|
54
54
|
if (fs.existsSync(skillsDir)) {
|
|
55
55
|
const entries = fs.readdirSync(skillsDir, { withFileTypes: true });
|
|
@@ -64,7 +64,7 @@ function run(projectRoot, args) {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
//
|
|
67
|
+
// Output Agents
|
|
68
68
|
const sortedAgents = Array.from(speccrewAgents).sort();
|
|
69
69
|
console.log(`Agents (${sortedAgents.length}):`);
|
|
70
70
|
for (const agent of sortedAgents) {
|
|
@@ -72,7 +72,7 @@ function run(projectRoot, args) {
|
|
|
72
72
|
}
|
|
73
73
|
console.log('');
|
|
74
74
|
|
|
75
|
-
//
|
|
75
|
+
// Output Skills
|
|
76
76
|
const sortedSkills = Array.from(speccrewSkills).sort();
|
|
77
77
|
console.log(`Skills (${sortedSkills.length}):`);
|
|
78
78
|
for (const skill of sortedSkills) {
|
|
@@ -80,7 +80,7 @@ function run(projectRoot, args) {
|
|
|
80
80
|
}
|
|
81
81
|
console.log('');
|
|
82
82
|
|
|
83
|
-
//
|
|
83
|
+
// Output user-defined content
|
|
84
84
|
const allUserDefined = [...Array.from(userAgents), ...Array.from(userSkills)].sort();
|
|
85
85
|
if (allUserDefined.length > 0) {
|
|
86
86
|
console.log('User-defined:');
|
|
@@ -92,7 +92,7 @@ function run(projectRoot, args) {
|
|
|
92
92
|
return true;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
//
|
|
95
|
+
// Get IDE config (simplified version, avoid circular dependency)
|
|
96
96
|
function getIDEConfig(ideId) {
|
|
97
97
|
const configs = {
|
|
98
98
|
qoder: {
|
|
@@ -4,16 +4,16 @@ const readline = require('readline');
|
|
|
4
4
|
const { readSpeccrewRC, isSpeccrewFile, removeDirRecursive } = require('../utils');
|
|
5
5
|
|
|
6
6
|
function run(projectRoot, args) {
|
|
7
|
-
//
|
|
7
|
+
// Check if initialized (compatible with both old and new paths)
|
|
8
8
|
let rc = readSpeccrewRC(projectRoot);
|
|
9
9
|
const newRcPath = path.join(projectRoot, 'speccrew-workspace', '.speccrewrc');
|
|
10
10
|
|
|
11
|
-
//
|
|
11
|
+
// If config not found at old path, check new path
|
|
12
12
|
if (!rc && fs.existsSync(newRcPath)) {
|
|
13
13
|
try {
|
|
14
14
|
rc = JSON.parse(fs.readFileSync(newRcPath, 'utf8'));
|
|
15
15
|
} catch (e) {
|
|
16
|
-
//
|
|
16
|
+
// Ignore parse errors
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -25,10 +25,10 @@ function run(projectRoot, args) {
|
|
|
25
25
|
|
|
26
26
|
const isAll = args.includes('--all');
|
|
27
27
|
|
|
28
|
-
//
|
|
28
|
+
// Get IDE configuration
|
|
29
29
|
const ides = rc.ide ? (Array.isArray(rc.ide) ? rc.ide : [rc.ide]) : [];
|
|
30
30
|
|
|
31
|
-
//
|
|
31
|
+
// Scan content to be deleted (don't actually delete yet)
|
|
32
32
|
let totalAgents = 0;
|
|
33
33
|
let totalSkills = 0;
|
|
34
34
|
const idePaths = [];
|
|
@@ -40,7 +40,7 @@ function run(projectRoot, args) {
|
|
|
40
40
|
let agentCount = 0;
|
|
41
41
|
let skillCount = 0;
|
|
42
42
|
|
|
43
|
-
//
|
|
43
|
+
// Count agents
|
|
44
44
|
const agentsDir = path.join(projectRoot, ideConfig.agentsDir);
|
|
45
45
|
if (fs.existsSync(agentsDir)) {
|
|
46
46
|
const entries = fs.readdirSync(agentsDir, { withFileTypes: true });
|
|
@@ -51,7 +51,7 @@ function run(projectRoot, args) {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
//
|
|
54
|
+
// Count skills
|
|
55
55
|
const skillsDir = path.join(projectRoot, ideConfig.skillsDir);
|
|
56
56
|
if (fs.existsSync(skillsDir)) {
|
|
57
57
|
const entries = fs.readdirSync(skillsDir, { withFileTypes: true });
|
|
@@ -67,17 +67,17 @@ function run(projectRoot, args) {
|
|
|
67
67
|
idePaths.push({ ideConfig, agentCount, skillCount });
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
//
|
|
70
|
+
// Check if config file exists (new and old paths)
|
|
71
71
|
const oldRcPath = path.join(projectRoot, '.speccrewrc');
|
|
72
72
|
const hasNewRc = fs.existsSync(newRcPath);
|
|
73
73
|
const hasOldRc = fs.existsSync(oldRcPath);
|
|
74
74
|
const hasRcFile = hasNewRc || hasOldRc;
|
|
75
75
|
|
|
76
|
-
//
|
|
76
|
+
// Check if workspace exists
|
|
77
77
|
const workspaceDir = path.join(projectRoot, 'speccrew-workspace');
|
|
78
78
|
const hasWorkspace = fs.existsSync(workspaceDir);
|
|
79
79
|
|
|
80
|
-
//
|
|
80
|
+
// Display content to be deleted
|
|
81
81
|
console.log('SpecCrew Uninstall\n');
|
|
82
82
|
console.log('The following will be removed:');
|
|
83
83
|
|
|
@@ -99,7 +99,7 @@ function run(projectRoot, args) {
|
|
|
99
99
|
console.log('\nWARNING: This will permanently delete your workspace data!');
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
//
|
|
102
|
+
// Ask user for confirmation
|
|
103
103
|
const rl = readline.createInterface({
|
|
104
104
|
input: process.stdin,
|
|
105
105
|
output: process.stdout
|
|
@@ -117,7 +117,7 @@ function run(projectRoot, args) {
|
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
//
|
|
120
|
+
// Execute uninstall
|
|
121
121
|
const result = performUninstall(projectRoot, idePaths, isAll, hasOldRc);
|
|
122
122
|
resolve(result);
|
|
123
123
|
});
|
|
@@ -128,11 +128,11 @@ function performUninstall(projectRoot, idePaths, isAll, hasOldRc) {
|
|
|
128
128
|
let removedAgents = 0;
|
|
129
129
|
let removedSkills = 0;
|
|
130
130
|
|
|
131
|
-
//
|
|
131
|
+
// Calculate total steps
|
|
132
132
|
const totalSteps = isAll ? 4 : 3;
|
|
133
133
|
let currentStep = 0;
|
|
134
134
|
|
|
135
|
-
//
|
|
135
|
+
// Delete agents
|
|
136
136
|
currentStep++;
|
|
137
137
|
process.stdout.write(`[${currentStep}/${totalSteps}] Removing agents... `);
|
|
138
138
|
for (const { ideConfig } of idePaths) {
|
|
@@ -154,7 +154,7 @@ function performUninstall(projectRoot, idePaths, isAll, hasOldRc) {
|
|
|
154
154
|
}
|
|
155
155
|
console.log(`done (${removedAgents} removed)`);
|
|
156
156
|
|
|
157
|
-
//
|
|
157
|
+
// Delete skills
|
|
158
158
|
currentStep++;
|
|
159
159
|
process.stdout.write(`[${currentStep}/${totalSteps}] Removing skills... `);
|
|
160
160
|
for (const { ideConfig } of idePaths) {
|
|
@@ -176,17 +176,17 @@ function performUninstall(projectRoot, idePaths, isAll, hasOldRc) {
|
|
|
176
176
|
}
|
|
177
177
|
console.log(`done (${removedSkills} removed)`);
|
|
178
178
|
|
|
179
|
-
//
|
|
179
|
+
// Delete config files
|
|
180
180
|
currentStep++;
|
|
181
181
|
process.stdout.write(`[${currentStep}/${totalSteps}] Removing configuration... `);
|
|
182
182
|
|
|
183
|
-
//
|
|
183
|
+
// Delete config file at new path
|
|
184
184
|
const newRcPath = path.join(projectRoot, 'speccrew-workspace', '.speccrewrc');
|
|
185
185
|
if (fs.existsSync(newRcPath)) {
|
|
186
186
|
fs.unlinkSync(newRcPath);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
//
|
|
189
|
+
// Compatibility: Delete config file at old path
|
|
190
190
|
const oldRcPath = path.join(projectRoot, '.speccrewrc');
|
|
191
191
|
if (fs.existsSync(oldRcPath)) {
|
|
192
192
|
fs.unlinkSync(oldRcPath);
|
|
@@ -194,7 +194,7 @@ function performUninstall(projectRoot, idePaths, isAll, hasOldRc) {
|
|
|
194
194
|
|
|
195
195
|
console.log('done');
|
|
196
196
|
|
|
197
|
-
//
|
|
197
|
+
// If --all, delete workspace
|
|
198
198
|
if (isAll) {
|
|
199
199
|
currentStep++;
|
|
200
200
|
process.stdout.write(`[${currentStep}/${totalSteps}] Removing workspace... `);
|
|
@@ -213,7 +213,7 @@ function performUninstall(projectRoot, idePaths, isAll, hasOldRc) {
|
|
|
213
213
|
return true;
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
//
|
|
216
|
+
// Get IDE config (simplified version, avoid circular dependency)
|
|
217
217
|
function getIDEConfig(ideId) {
|
|
218
218
|
const configs = {
|
|
219
219
|
qoder: {
|