@agents-at-scale/ark 0.1.31

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.
Files changed (76) hide show
  1. package/README.md +95 -0
  2. package/dist/commands/cluster/get-ip.d.ts +2 -0
  3. package/dist/commands/cluster/get-ip.js +32 -0
  4. package/dist/commands/cluster/get-type.d.ts +2 -0
  5. package/dist/commands/cluster/get-type.js +26 -0
  6. package/dist/commands/cluster/index.d.ts +2 -0
  7. package/dist/commands/cluster/index.js +10 -0
  8. package/dist/commands/completion.d.ts +2 -0
  9. package/dist/commands/completion.js +108 -0
  10. package/dist/commands/config.d.ts +5 -0
  11. package/dist/commands/config.js +327 -0
  12. package/dist/commands/generate/config.d.ts +145 -0
  13. package/dist/commands/generate/config.js +253 -0
  14. package/dist/commands/generate/generators/agent.d.ts +2 -0
  15. package/dist/commands/generate/generators/agent.js +156 -0
  16. package/dist/commands/generate/generators/index.d.ts +6 -0
  17. package/dist/commands/generate/generators/index.js +6 -0
  18. package/dist/commands/generate/generators/marketplace.d.ts +2 -0
  19. package/dist/commands/generate/generators/marketplace.js +304 -0
  20. package/dist/commands/generate/generators/mcpserver.d.ts +25 -0
  21. package/dist/commands/generate/generators/mcpserver.js +350 -0
  22. package/dist/commands/generate/generators/project.d.ts +2 -0
  23. package/dist/commands/generate/generators/project.js +784 -0
  24. package/dist/commands/generate/generators/query.d.ts +2 -0
  25. package/dist/commands/generate/generators/query.js +213 -0
  26. package/dist/commands/generate/generators/team.d.ts +2 -0
  27. package/dist/commands/generate/generators/team.js +407 -0
  28. package/dist/commands/generate/index.d.ts +24 -0
  29. package/dist/commands/generate/index.js +357 -0
  30. package/dist/commands/generate/templateDiscovery.d.ts +30 -0
  31. package/dist/commands/generate/templateDiscovery.js +94 -0
  32. package/dist/commands/generate/templateEngine.d.ts +78 -0
  33. package/dist/commands/generate/templateEngine.js +368 -0
  34. package/dist/commands/generate/utils/nameUtils.d.ts +35 -0
  35. package/dist/commands/generate/utils/nameUtils.js +110 -0
  36. package/dist/commands/generate/utils/projectUtils.d.ts +28 -0
  37. package/dist/commands/generate/utils/projectUtils.js +133 -0
  38. package/dist/components/DashboardCLI.d.ts +3 -0
  39. package/dist/components/DashboardCLI.js +149 -0
  40. package/dist/components/GeneratorUI.d.ts +3 -0
  41. package/dist/components/GeneratorUI.js +167 -0
  42. package/dist/components/statusChecker.d.ts +48 -0
  43. package/dist/components/statusChecker.js +251 -0
  44. package/dist/config.d.ts +42 -0
  45. package/dist/config.js +243 -0
  46. package/dist/index.d.ts +2 -0
  47. package/dist/index.js +67 -0
  48. package/dist/lib/arkClient.d.ts +32 -0
  49. package/dist/lib/arkClient.js +43 -0
  50. package/dist/lib/cluster.d.ts +8 -0
  51. package/dist/lib/cluster.js +134 -0
  52. package/dist/lib/config.d.ts +82 -0
  53. package/dist/lib/config.js +223 -0
  54. package/dist/lib/consts.d.ts +10 -0
  55. package/dist/lib/consts.js +15 -0
  56. package/dist/lib/errors.d.ts +56 -0
  57. package/dist/lib/errors.js +208 -0
  58. package/dist/lib/exec.d.ts +5 -0
  59. package/dist/lib/exec.js +20 -0
  60. package/dist/lib/gatewayManager.d.ts +24 -0
  61. package/dist/lib/gatewayManager.js +85 -0
  62. package/dist/lib/kubernetes.d.ts +28 -0
  63. package/dist/lib/kubernetes.js +122 -0
  64. package/dist/lib/progress.d.ts +128 -0
  65. package/dist/lib/progress.js +273 -0
  66. package/dist/lib/security.d.ts +37 -0
  67. package/dist/lib/security.js +295 -0
  68. package/dist/lib/types.d.ts +37 -0
  69. package/dist/lib/types.js +1 -0
  70. package/dist/lib/wrappers/git.d.ts +2 -0
  71. package/dist/lib/wrappers/git.js +43 -0
  72. package/dist/ui/MainMenu.d.ts +3 -0
  73. package/dist/ui/MainMenu.js +116 -0
  74. package/dist/ui/statusFormatter.d.ts +9 -0
  75. package/dist/ui/statusFormatter.js +47 -0
  76. package/package.json +62 -0
package/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # ARK CLI
2
+
3
+ Interactive terminal interface for ARK agents.
4
+
5
+ ## Prerequisites
6
+
7
+ 1. **ARK system deployed** in your Kubernetes cluster
8
+ 2. **Gateway setup** for service discovery:
9
+ ```bash
10
+ # From agents-at-scale project root
11
+ make localhost-gateway-install
12
+ ```
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ cd tools/ark-cli
18
+ npm run build
19
+ npm install -g .
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ```bash
25
+ # Interactive mode (no arguments)
26
+ ark
27
+
28
+ # Show help
29
+ ark --help
30
+ ark cluster --help
31
+
32
+ # Check system status
33
+ ark check status
34
+
35
+ # Generate (project, agent, team, etc)
36
+ ark generate
37
+
38
+ # Cluster operations
39
+ ark cluster get-type
40
+ ark cluster get-ip
41
+ ark cluster get-ip --verbose
42
+ ark cluster get-ip --context minikube
43
+
44
+ # Show shell autocomplete options.
45
+ ark autocomplete
46
+ ```
47
+
48
+ ## Configuration
49
+
50
+ ARK CLI automatically detects services via:
51
+
52
+ 1. **localhost-gateway** (when running) - `*.127.0.0.1.nip.io:8080`
53
+ 2. **Kubernetes service discovery** - for internal services
54
+ 3. **Default localhost URLs** - fallback
55
+
56
+ Settings stored in `~/.config/ark-cli/config.json`
57
+
58
+ ## Development
59
+
60
+ **Note:** All make commands must be run from the repository root directory.
61
+
62
+ ```bash
63
+ # From repository root
64
+ make ark-cli-install # Build and install globally
65
+ make ark-cli-build # Build only
66
+ make clean # Clean build artifacts and stamp files
67
+ make ark-cli-uninstall # Remove global installation
68
+
69
+ # From tools/ark-cli directory
70
+ npm run lint # Run linting and formatting
71
+ npm run lint:check # Check linting without fixing
72
+ ```
73
+
74
+ ## Troubleshooting
75
+
76
+ Enable debug logging to see detailed configuration discovery and service resolution:
77
+
78
+ ```bash
79
+ # Debug configuration discovery and service resolution
80
+ DEBUG=ark:config ark check status
81
+
82
+ # Debug all ARK CLI components
83
+ DEBUG=ark:* ark check status
84
+
85
+ # Keep debug enabled for multiple commands
86
+ export DEBUG=ark:config
87
+ ark check status
88
+ ark dashboard
89
+ ```
90
+
91
+ **Common debug scenarios:**
92
+
93
+ - **Wrong URL detected**: See which discovery method is being used
94
+ - **Service timeouts**: Check localhost-gateway and kubernetes connectivity
95
+ - **Config issues**: Trace fallback logic through multiple discovery methods
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function createGetIpCommand(): Command;
@@ -0,0 +1,32 @@
1
+ import chalk from 'chalk';
2
+ import { Command } from 'commander';
3
+ import { getClusterIp } from '../../lib/cluster.js';
4
+ export function createGetIpCommand() {
5
+ const getIp = new Command('get-ip');
6
+ getIp
7
+ .description('Get the IP address of the current Kubernetes cluster')
8
+ .option('-c, --context <context>', 'Kubernetes context to use')
9
+ .action(async (options) => {
10
+ try {
11
+ const clusterInfo = await getClusterIp(options.context);
12
+ if (clusterInfo.error) {
13
+ console.error(chalk.red('Error getting cluster IP:'), clusterInfo.error);
14
+ process.exit(1);
15
+ }
16
+ if (!clusterInfo.ip) {
17
+ console.error(chalk.red('Could not determine cluster IP'));
18
+ process.exit(1);
19
+ }
20
+ console.log(clusterInfo.ip);
21
+ console.error(chalk.grey(`Cluster type: ${clusterInfo.type}`));
22
+ if (clusterInfo.context) {
23
+ console.error(chalk.grey(`Context: ${clusterInfo.context}`));
24
+ }
25
+ }
26
+ catch (error) {
27
+ console.error(chalk.red('Failed to get cluster IP:'), error.message);
28
+ process.exit(1);
29
+ }
30
+ });
31
+ return getIp;
32
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function createGetTypeCommand(): Command;
@@ -0,0 +1,26 @@
1
+ import chalk from 'chalk';
2
+ import { Command } from 'commander';
3
+ import { detectClusterType } from '../../lib/cluster.js';
4
+ export function createGetTypeCommand() {
5
+ const getType = new Command('get-type');
6
+ getType
7
+ .description('Detect and display the current Kubernetes cluster type')
8
+ .action(async () => {
9
+ try {
10
+ const clusterInfo = await detectClusterType();
11
+ if (clusterInfo.error) {
12
+ console.error(chalk.red('Error detecting cluster type:'), clusterInfo.error);
13
+ process.exit(1);
14
+ }
15
+ console.log(clusterInfo.type);
16
+ if (clusterInfo.context) {
17
+ console.error(chalk.grey(`Context: ${clusterInfo.context}`));
18
+ }
19
+ }
20
+ catch (error) {
21
+ console.error(chalk.red('Failed to detect cluster type:'), error.message);
22
+ process.exit(1);
23
+ }
24
+ });
25
+ return getType;
26
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function createClusterCommand(): Command;
@@ -0,0 +1,10 @@
1
+ import { Command } from 'commander';
2
+ import { createGetIpCommand } from './get-ip.js';
3
+ import { createGetTypeCommand } from './get-type.js';
4
+ export function createClusterCommand() {
5
+ const cluster = new Command('cluster');
6
+ cluster.description('Cluster management commands');
7
+ cluster.addCommand(createGetTypeCommand());
8
+ cluster.addCommand(createGetIpCommand());
9
+ return cluster;
10
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function createCompletionCommand(): Command;
@@ -0,0 +1,108 @@
1
+ import chalk from 'chalk';
2
+ import { Command } from 'commander';
3
+ export function createCompletionCommand() {
4
+ const completion = new Command('completion');
5
+ completion.description('Generate shell completion scripts').action(() => {
6
+ console.log(chalk.cyan('Shell completion for ARK CLI'));
7
+ console.log('');
8
+ console.log('Usage:');
9
+ console.log(' ark completion bash Generate bash completion script');
10
+ console.log(' ark completion zsh Generate zsh completion script');
11
+ console.log('');
12
+ console.log('To enable completion, add this to your shell profile:');
13
+ console.log(chalk.grey(' # For bash:'));
14
+ console.log(chalk.grey(' eval "$(ark completion bash)"'));
15
+ console.log(chalk.grey(' # For zsh:'));
16
+ console.log(chalk.grey(' eval "$(ark completion zsh)"'));
17
+ });
18
+ completion
19
+ .command('bash')
20
+ .description('Generate bash completion script')
21
+ .action(() => {
22
+ console.log(`
23
+ _ark_completion() {
24
+ local cur prev opts
25
+ COMPREPLY=()
26
+ cur="\${COMP_WORDS[COMP_CWORD]}"
27
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
28
+
29
+ case \${COMP_CWORD} in
30
+ 1)
31
+ opts="cluster completion check help"
32
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
33
+ return 0
34
+ ;;
35
+ 2)
36
+ case \${prev} in
37
+ cluster)
38
+ opts="get-ip get-type"
39
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
40
+ return 0
41
+ ;;
42
+ completion)
43
+ opts="bash zsh"
44
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
45
+ return 0
46
+ ;;
47
+ check)
48
+ opts="status"
49
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
50
+ return 0
51
+ ;;
52
+ esac
53
+ ;;
54
+ esac
55
+ }
56
+
57
+ complete -F _ark_completion ark
58
+ `.trim());
59
+ });
60
+ completion
61
+ .command('zsh')
62
+ .description('Generate zsh completion script')
63
+ .action(() => {
64
+ console.log(`
65
+ #compdef ark
66
+
67
+ _ark() {
68
+ local context state line
69
+
70
+ _arguments -C \\
71
+ '1:command:->command' \\
72
+ '2:subcommand:->subcommand' \\
73
+ '*::arg:->args'
74
+
75
+ case $state in
76
+ command)
77
+ _values 'ark commands' \\
78
+ 'cluster[Cluster management commands]' \\
79
+ 'completion[Generate shell completion scripts]' \\
80
+ 'check[Check system components]' \\
81
+ 'help[Show help information]'
82
+ ;;
83
+ subcommand)
84
+ case $words[2] in
85
+ cluster)
86
+ _values 'cluster commands' \\
87
+ 'get-ip[Get cluster IP address]' \\
88
+ 'get-type[Get cluster type]'
89
+ ;;
90
+ completion)
91
+ _values 'completion shells' \\
92
+ 'bash[Generate bash completion]' \\
93
+ 'zsh[Generate zsh completion]'
94
+ ;;
95
+ check)
96
+ _values 'check commands' \\
97
+ 'status[Check system status]'
98
+ ;;
99
+ esac
100
+ ;;
101
+ esac
102
+ }
103
+
104
+ _ark
105
+ `.trim());
106
+ });
107
+ return completion;
108
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Configuration management commands for ARK CLI
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function createConfigCommand(): Command;
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Configuration management commands for ARK CLI
3
+ */
4
+ import { Command } from 'commander';
5
+ import chalk from 'chalk';
6
+ import inquirer from 'inquirer';
7
+ import { ConfigManager } from '../lib/config.js';
8
+ import { ErrorHandler } from '../lib/errors.js';
9
+ import { OutputFormatter, EnhancedPrompts } from '../lib/progress.js';
10
+ export function createConfigCommand() {
11
+ const config = new Command('config');
12
+ config
13
+ .description('Manage ARK CLI configuration')
14
+ .addHelpText('before', `
15
+ ${chalk.blue('⚙️ ARK Configuration Management')}
16
+ Manage your ARK CLI preferences and defaults.
17
+ `)
18
+ .addHelpText('after', `
19
+ ${chalk.cyan('Examples:')}
20
+ ${chalk.yellow('ark config list')} # Show current configuration
21
+ ${chalk.yellow('ark config set defaultProjectType with-samples')}
22
+ ${chalk.yellow('ark config get defaultProjectType')} # Get specific value
23
+ ${chalk.yellow('ark config edit')} # Interactive configuration
24
+ ${chalk.yellow('ark config reset')} # Reset to defaults
25
+ `);
26
+ // List command - show current configuration
27
+ const listCommand = new Command('list');
28
+ listCommand
29
+ .alias('ls')
30
+ .description('Show current configuration')
31
+ .option('--json', 'Output in JSON format', false)
32
+ .action((options) => {
33
+ ErrorHandler.catchAndHandle(async () => {
34
+ const configManager = new ConfigManager();
35
+ const currentConfig = configManager.getMergedConfig();
36
+ if (options.json) {
37
+ console.log(JSON.stringify(currentConfig, null, 2));
38
+ return;
39
+ }
40
+ console.log(chalk.blue('\n⚙️ ARK CLI Configuration\n'));
41
+ // Generator settings
42
+ console.log(chalk.cyan('🎯 Generator Defaults:'));
43
+ OutputFormatter.formatKeyValueList([
44
+ {
45
+ key: 'Project Type',
46
+ value: currentConfig.defaultProjectType,
47
+ highlight: true,
48
+ },
49
+ {
50
+ key: 'Default Destination',
51
+ value: currentConfig.defaultDestination,
52
+ },
53
+ {
54
+ key: 'Skip Git by Default',
55
+ value: currentConfig.skipGitByDefault ? 'yes' : 'no',
56
+ },
57
+ {
58
+ key: 'Skip Models by Default',
59
+ value: currentConfig.skipModelsbyDefault ? 'yes' : 'no',
60
+ },
61
+ {
62
+ key: 'Default Model Provider',
63
+ value: currentConfig.defaultModelProvider,
64
+ },
65
+ ]);
66
+ // User preferences
67
+ console.log(chalk.cyan('\n👤 User Preferences:'));
68
+ OutputFormatter.formatKeyValueList([
69
+ { key: 'Preferred Editor', value: currentConfig.preferredEditor },
70
+ {
71
+ key: 'Color Output',
72
+ value: currentConfig.colorOutput ? 'enabled' : 'disabled',
73
+ },
74
+ {
75
+ key: 'Verbose Output',
76
+ value: currentConfig.verboseOutput ? 'enabled' : 'disabled',
77
+ },
78
+ ]);
79
+ // Advanced settings
80
+ console.log(chalk.cyan('\n🔧 Advanced Settings:'));
81
+ OutputFormatter.formatKeyValueList([
82
+ {
83
+ key: 'Parallel Operations',
84
+ value: currentConfig.parallelOperations ? 'enabled' : 'disabled',
85
+ },
86
+ {
87
+ key: 'Max Concurrent Files',
88
+ value: currentConfig.maxConcurrentFiles.toString(),
89
+ },
90
+ {
91
+ key: 'File Watching',
92
+ value: currentConfig.fileWatchingEnabled ? 'enabled' : 'disabled',
93
+ },
94
+ {
95
+ key: 'Telemetry',
96
+ value: currentConfig.telemetryEnabled ? 'enabled' : 'disabled',
97
+ },
98
+ ]);
99
+ console.log(chalk.gray(`\nConfig file: ${configManager.getConfigFilePath()}`));
100
+ console.log(chalk.gray('Use "ark config edit" for interactive configuration\n'));
101
+ }, 'Listing configuration').catch(ErrorHandler.handleAndExit);
102
+ });
103
+ // Get command - get a specific configuration value
104
+ const getCommand = new Command('get');
105
+ getCommand
106
+ .description('Get a specific configuration value')
107
+ .argument('<key>', 'Configuration key to retrieve')
108
+ .action((key) => {
109
+ ErrorHandler.catchAndHandle(async () => {
110
+ const configManager = new ConfigManager();
111
+ const currentConfig = configManager.getMergedConfig();
112
+ if (key in currentConfig) {
113
+ const value = currentConfig[key];
114
+ console.log(typeof value === 'object'
115
+ ? JSON.stringify(value, null, 2)
116
+ : String(value));
117
+ }
118
+ else {
119
+ console.error(chalk.red(`Unknown configuration key: ${key}`));
120
+ console.log(chalk.gray('Available keys:'));
121
+ Object.keys(currentConfig).forEach((k) => console.log(chalk.gray(` ${k}`)));
122
+ process.exit(1);
123
+ }
124
+ }, 'Getting configuration value').catch(ErrorHandler.handleAndExit);
125
+ });
126
+ // Set command - set a specific configuration value
127
+ const setCommand = new Command('set');
128
+ setCommand
129
+ .description('Set a specific configuration value')
130
+ .argument('<key>', 'Configuration key to set')
131
+ .argument('<value>', 'Value to set')
132
+ .action((key, value) => {
133
+ ErrorHandler.catchAndHandle(async () => {
134
+ const configManager = new ConfigManager();
135
+ const currentConfig = configManager.getConfig();
136
+ if (!(key in currentConfig)) {
137
+ console.error(chalk.red(`Unknown configuration key: ${key}`));
138
+ console.log(chalk.gray('Available keys:'));
139
+ Object.keys(currentConfig).forEach((k) => console.log(chalk.gray(` ${k}`)));
140
+ process.exit(1);
141
+ }
142
+ // Parse value based on the current type
143
+ const currentValue = currentConfig[key];
144
+ let parsedValue = value;
145
+ if (typeof currentValue === 'boolean') {
146
+ parsedValue = ['true', 'yes', '1', 'on'].includes(value.toLowerCase());
147
+ }
148
+ else if (typeof currentValue === 'number') {
149
+ parsedValue = parseInt(value, 10);
150
+ if (isNaN(parsedValue)) {
151
+ console.error(chalk.red(`Invalid number value: ${value}`));
152
+ process.exit(1);
153
+ }
154
+ }
155
+ // Update configuration
156
+ configManager.set(key, parsedValue);
157
+ // Validate the configuration
158
+ configManager.validateConfig();
159
+ console.log(chalk.green(`✅ Set ${key} = ${parsedValue}`));
160
+ }, 'Setting configuration value').catch(ErrorHandler.handleAndExit);
161
+ });
162
+ // Edit command - interactive configuration editor
163
+ const editCommand = new Command('edit');
164
+ editCommand.description('Edit configuration interactively').action(() => {
165
+ ErrorHandler.catchAndHandle(async () => {
166
+ const configManager = new ConfigManager();
167
+ const currentConfig = configManager.getConfig();
168
+ console.log(chalk.blue('\n⚙️ ARK CLI Configuration Editor\n'));
169
+ EnhancedPrompts.showInfo('Leave fields empty to keep current values');
170
+ const answers = await inquirer.prompt([
171
+ {
172
+ type: 'list',
173
+ name: 'defaultProjectType',
174
+ message: 'Default project type:',
175
+ choices: [
176
+ {
177
+ name: 'with-samples (recommended for beginners)',
178
+ value: 'with-samples',
179
+ },
180
+ { name: 'empty (for experienced users)', value: 'empty' },
181
+ ],
182
+ default: currentConfig.defaultProjectType,
183
+ },
184
+ {
185
+ type: 'input',
186
+ name: 'defaultDestination',
187
+ message: 'Default destination directory:',
188
+ default: currentConfig.defaultDestination,
189
+ },
190
+ {
191
+ type: 'list',
192
+ name: 'defaultModelProvider',
193
+ message: 'Default model provider:',
194
+ choices: [
195
+ { name: 'Azure OpenAI (recommended)', value: 'azure' },
196
+ { name: 'OpenAI', value: 'openai' },
197
+ { name: 'Claude (Anthropic)', value: 'claude' },
198
+ { name: 'Gemini (Google)', value: 'gemini' },
199
+ { name: 'Custom', value: 'custom' },
200
+ ],
201
+ default: currentConfig.defaultModelProvider,
202
+ },
203
+ {
204
+ type: 'input',
205
+ name: 'preferredEditor',
206
+ message: 'Preferred editor command:',
207
+ default: currentConfig.preferredEditor,
208
+ },
209
+ {
210
+ type: 'confirm',
211
+ name: 'skipGitByDefault',
212
+ message: 'Skip git setup by default?',
213
+ default: currentConfig.skipGitByDefault,
214
+ },
215
+ {
216
+ type: 'confirm',
217
+ name: 'skipModelsbyDefault',
218
+ message: 'Skip model configuration by default?',
219
+ default: currentConfig.skipModelsbyDefault,
220
+ },
221
+ {
222
+ type: 'confirm',
223
+ name: 'colorOutput',
224
+ message: 'Enable colored output?',
225
+ default: currentConfig.colorOutput,
226
+ },
227
+ {
228
+ type: 'confirm',
229
+ name: 'verboseOutput',
230
+ message: 'Enable verbose output?',
231
+ default: currentConfig.verboseOutput,
232
+ },
233
+ {
234
+ type: 'number',
235
+ name: 'maxConcurrentFiles',
236
+ message: 'Maximum concurrent file operations:',
237
+ default: currentConfig.maxConcurrentFiles,
238
+ validate: (input) => input !== undefined && input >= 1 && input <= 100
239
+ ? true
240
+ : 'Must be between 1 and 100',
241
+ },
242
+ ]);
243
+ // Update configuration
244
+ configManager.updateConfig(answers);
245
+ // Validate the configuration
246
+ configManager.validateConfig();
247
+ EnhancedPrompts.showSuccess('Configuration updated successfully');
248
+ console.log(chalk.gray(`Config saved to: ${configManager.getConfigFilePath()}\n`));
249
+ }, 'Editing configuration').catch(ErrorHandler.handleAndExit);
250
+ });
251
+ // Reset command - reset to default configuration
252
+ const resetCommand = new Command('reset');
253
+ resetCommand
254
+ .description('Reset configuration to defaults')
255
+ .option('--confirm', 'Skip confirmation prompt', false)
256
+ .action((options) => {
257
+ ErrorHandler.catchAndHandle(async () => {
258
+ if (!options.confirm) {
259
+ const { confirmReset } = await inquirer.prompt([
260
+ {
261
+ type: 'confirm',
262
+ name: 'confirmReset',
263
+ message: 'Are you sure you want to reset all configuration to defaults?',
264
+ default: false,
265
+ },
266
+ ]);
267
+ if (!confirmReset) {
268
+ console.log(chalk.yellow('Reset cancelled'));
269
+ return;
270
+ }
271
+ }
272
+ const configManager = new ConfigManager();
273
+ configManager.resetConfig();
274
+ EnhancedPrompts.showSuccess('Configuration reset to defaults');
275
+ console.log(chalk.gray(`Config file: ${configManager.getConfigFilePath()}\n`));
276
+ }, 'Resetting configuration').catch(ErrorHandler.handleAndExit);
277
+ });
278
+ // Export command - export configuration for backup
279
+ const exportCommand = new Command('export');
280
+ exportCommand
281
+ .description('Export configuration to JSON')
282
+ .option('-o, --output <file>', 'Output file (default: stdout)')
283
+ .action((options) => {
284
+ ErrorHandler.catchAndHandle(async () => {
285
+ const configManager = new ConfigManager();
286
+ const configJson = configManager.exportConfig();
287
+ if (options.output) {
288
+ const fs = await import('fs');
289
+ fs.writeFileSync(options.output, configJson);
290
+ EnhancedPrompts.showSuccess(`Configuration exported to ${options.output}`);
291
+ }
292
+ else {
293
+ console.log(configJson);
294
+ }
295
+ }, 'Exporting configuration').catch(ErrorHandler.handleAndExit);
296
+ });
297
+ // Import command - import configuration from backup
298
+ const importCommand = new Command('import');
299
+ importCommand
300
+ .description('Import configuration from JSON file')
301
+ .argument('<file>', 'JSON file to import')
302
+ .option('--merge', 'Merge with existing configuration', false)
303
+ .action((file, options) => {
304
+ ErrorHandler.catchAndHandle(async () => {
305
+ const fs = await import('fs');
306
+ const configJson = fs.readFileSync(file, 'utf-8');
307
+ const configManager = new ConfigManager();
308
+ if (options.merge) {
309
+ const importedConfig = JSON.parse(configJson);
310
+ configManager.updateConfig(importedConfig);
311
+ }
312
+ else {
313
+ configManager.importConfig(configJson);
314
+ }
315
+ EnhancedPrompts.showSuccess(`Configuration imported from ${file}`);
316
+ }, 'Importing configuration').catch(ErrorHandler.handleAndExit);
317
+ });
318
+ // Add subcommands
319
+ config.addCommand(listCommand);
320
+ config.addCommand(getCommand);
321
+ config.addCommand(setCommand);
322
+ config.addCommand(editCommand);
323
+ config.addCommand(resetCommand);
324
+ config.addCommand(exportCommand);
325
+ config.addCommand(importCommand);
326
+ return config;
327
+ }