agileflow 2.62.0 → 2.64.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agileflow",
3
- "version": "2.62.0",
3
+ "version": "2.64.0",
4
4
  "description": "AI-driven agile development system for Claude Code, Cursor, Windsurf, and more",
5
5
  "keywords": [
6
6
  "agile",
@@ -19,6 +19,7 @@ module.exports = {
19
19
  description: 'Remove AgileFlow from a project',
20
20
  options: [
21
21
  ['-d, --directory <path>', 'Project directory (default: current directory)'],
22
+ ['--ide <name>', 'Remove only a specific IDE (e.g., windsurf, cursor)'],
22
23
  ['--force', 'Skip confirmation prompt'],
23
24
  ],
24
25
  action: async options => {
@@ -35,6 +36,68 @@ module.exports = {
35
36
  process.exit(0);
36
37
  }
37
38
 
39
+ // Check if removing just one IDE
40
+ if (options.ide) {
41
+ const ideName = options.ide.toLowerCase();
42
+ displaySection('Removing IDE Configuration', `IDE: ${formatIdeName(ideName)}`);
43
+
44
+ if (!status.ides || !status.ides.includes(ideName)) {
45
+ warning(`${formatIdeName(ideName)} is not configured in this installation`);
46
+ console.log(chalk.dim(`Configured IDEs: ${(status.ides || []).join(', ') || 'none'}\n`));
47
+ process.exit(0);
48
+ }
49
+
50
+ // Confirm removal
51
+ if (!options.force) {
52
+ const proceed = await confirm(
53
+ `Remove ${formatIdeName(ideName)} configuration?`,
54
+ false
55
+ );
56
+ if (!proceed) {
57
+ console.log(chalk.dim('\nCancelled\n'));
58
+ process.exit(0);
59
+ }
60
+ }
61
+
62
+ console.log();
63
+
64
+ // Remove the IDE configuration
65
+ const configPath = getIdeConfigPath(directory, ideName);
66
+ if (await fs.pathExists(configPath)) {
67
+ await fs.remove(configPath);
68
+ success(`Removed ${formatIdeName(ideName)} configuration`);
69
+ }
70
+
71
+ // Also remove spawnable agents for claude-code
72
+ if (ideName === 'claude-code') {
73
+ const agentsPath = path.join(directory, '.claude', 'agents', 'agileflow');
74
+ if (await fs.pathExists(agentsPath)) {
75
+ await fs.remove(agentsPath);
76
+ success('Removed spawnable agents');
77
+ }
78
+ }
79
+
80
+ // Update the manifest to remove this IDE
81
+ const manifestPath = path.join(status.path, '_cfg', 'manifest.yaml');
82
+ if (await fs.pathExists(manifestPath)) {
83
+ const yaml = require('js-yaml');
84
+ const manifestContent = await fs.readFile(manifestPath, 'utf8');
85
+ const manifest = yaml.load(manifestContent);
86
+ manifest.ides = (manifest.ides || []).filter(ide => ide !== ideName);
87
+ manifest.updated_at = new Date().toISOString();
88
+ await fs.writeFile(manifestPath, yaml.dump(manifest), 'utf8');
89
+ success('Updated manifest');
90
+ }
91
+
92
+ console.log(chalk.green(`\n${formatIdeName(ideName)} has been removed.\n`));
93
+ if (status.ides.length > 1) {
94
+ console.log(chalk.dim(`Remaining IDEs: ${status.ides.filter(i => i !== ideName).join(', ')}\n`));
95
+ }
96
+
97
+ process.exit(0);
98
+ }
99
+
100
+ // Full uninstall
38
101
  displaySection('Uninstalling AgileFlow', `Location: ${status.path}`);
39
102
 
40
103
  // Confirm uninstall
@@ -56,6 +119,13 @@ module.exports = {
56
119
  await fs.remove(configPath);
57
120
  success(`Removed ${formatIdeName(ide)} configuration`);
58
121
  }
122
+ // Also remove spawnable agents for claude-code
123
+ if (ide === 'claude-code') {
124
+ const agentsPath = path.join(directory, '.claude', 'agents', 'agileflow');
125
+ if (await fs.pathExists(agentsPath)) {
126
+ await fs.remove(agentsPath);
127
+ }
128
+ }
59
129
  }
60
130
  }
61
131
 
@@ -32,6 +32,7 @@ module.exports = {
32
32
  options: [
33
33
  ['-d, --directory <path>', 'Project directory (default: current directory)'],
34
34
  ['--force', 'Force reinstall (skip prompts; overwrites local changes)'],
35
+ ['--ides <list>', 'Comma-separated list of IDEs to update (overrides manifest)'],
35
36
  ['--no-self-update', 'Skip automatic CLI self-update check'],
36
37
  ['--self-updated', 'Internal flag: indicates CLI was already self-updated'],
37
38
  ],
@@ -56,6 +57,7 @@ module.exports = {
56
57
  const args = ['agileflow@latest', 'update', '--self-updated'];
57
58
  if (options.directory) args.push('-d', options.directory);
58
59
  if (options.force) args.push('--force');
60
+ if (options.ides) args.push('--ides', options.ides);
59
61
 
60
62
  const result = spawnSync('npx', args, {
61
63
  stdio: 'inherit',
@@ -88,10 +90,10 @@ module.exports = {
88
90
 
89
91
  const latestVersion = npmLatestVersion || localCliVersion;
90
92
 
91
- console.log(chalk.bold('Installed: '), status.version);
92
- console.log(chalk.bold('CLI version: '), localCliVersion);
93
+ console.log(chalk.bold('Currently installed:'), status.version);
94
+ console.log(chalk.bold('CLI version: '), localCliVersion);
93
95
  if (npmLatestVersion) {
94
- console.log(chalk.bold('Latest (npm):'), npmLatestVersion);
96
+ console.log(chalk.bold('Latest (npm): '), npmLatestVersion);
95
97
  }
96
98
 
97
99
  // If we self-updated, show confirmation
@@ -136,10 +138,25 @@ module.exports = {
136
138
  // Get docs folder name from metadata (or default to 'docs')
137
139
  const docsFolder = await getDocsFolderName(directory);
138
140
 
141
+ // Determine which IDEs to update
142
+ let idesToUpdate;
143
+ if (options.ides) {
144
+ // User explicitly specified IDEs via --ides flag
145
+ idesToUpdate = options.ides.split(',').map(ide => ide.trim().toLowerCase());
146
+ console.log(chalk.dim(`Updating specified IDEs: ${idesToUpdate.join(', ')}`));
147
+ } else {
148
+ // Use IDEs from manifest
149
+ idesToUpdate = status.ides || ['claude-code'];
150
+ if (idesToUpdate.length > 1) {
151
+ console.log(chalk.dim(`IDEs to update (from manifest): ${idesToUpdate.join(', ')}`));
152
+ console.log(chalk.dim(` Tip: Use --ides=claude-code to update only specific IDEs\n`));
153
+ }
154
+ }
155
+
139
156
  // Re-run installation with existing config from manifest
140
157
  const config = {
141
158
  directory,
142
- ides: status.ides || ['claude-code'],
159
+ ides: idesToUpdate,
143
160
  userName: status.userName || 'Developer',
144
161
  agileflowFolder: status.agileflowFolder || path.basename(status.path),
145
162
  docsFolder: status.docsFolder || docsFolder,