@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.
- package/README.md +95 -0
- package/dist/commands/cluster/get-ip.d.ts +2 -0
- package/dist/commands/cluster/get-ip.js +32 -0
- package/dist/commands/cluster/get-type.d.ts +2 -0
- package/dist/commands/cluster/get-type.js +26 -0
- package/dist/commands/cluster/index.d.ts +2 -0
- package/dist/commands/cluster/index.js +10 -0
- package/dist/commands/completion.d.ts +2 -0
- package/dist/commands/completion.js +108 -0
- package/dist/commands/config.d.ts +5 -0
- package/dist/commands/config.js +327 -0
- package/dist/commands/generate/config.d.ts +145 -0
- package/dist/commands/generate/config.js +253 -0
- package/dist/commands/generate/generators/agent.d.ts +2 -0
- package/dist/commands/generate/generators/agent.js +156 -0
- package/dist/commands/generate/generators/index.d.ts +6 -0
- package/dist/commands/generate/generators/index.js +6 -0
- package/dist/commands/generate/generators/marketplace.d.ts +2 -0
- package/dist/commands/generate/generators/marketplace.js +304 -0
- package/dist/commands/generate/generators/mcpserver.d.ts +25 -0
- package/dist/commands/generate/generators/mcpserver.js +350 -0
- package/dist/commands/generate/generators/project.d.ts +2 -0
- package/dist/commands/generate/generators/project.js +784 -0
- package/dist/commands/generate/generators/query.d.ts +2 -0
- package/dist/commands/generate/generators/query.js +213 -0
- package/dist/commands/generate/generators/team.d.ts +2 -0
- package/dist/commands/generate/generators/team.js +407 -0
- package/dist/commands/generate/index.d.ts +24 -0
- package/dist/commands/generate/index.js +357 -0
- package/dist/commands/generate/templateDiscovery.d.ts +30 -0
- package/dist/commands/generate/templateDiscovery.js +94 -0
- package/dist/commands/generate/templateEngine.d.ts +78 -0
- package/dist/commands/generate/templateEngine.js +368 -0
- package/dist/commands/generate/utils/nameUtils.d.ts +35 -0
- package/dist/commands/generate/utils/nameUtils.js +110 -0
- package/dist/commands/generate/utils/projectUtils.d.ts +28 -0
- package/dist/commands/generate/utils/projectUtils.js +133 -0
- package/dist/components/DashboardCLI.d.ts +3 -0
- package/dist/components/DashboardCLI.js +149 -0
- package/dist/components/GeneratorUI.d.ts +3 -0
- package/dist/components/GeneratorUI.js +167 -0
- package/dist/components/statusChecker.d.ts +48 -0
- package/dist/components/statusChecker.js +251 -0
- package/dist/config.d.ts +42 -0
- package/dist/config.js +243 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +67 -0
- package/dist/lib/arkClient.d.ts +32 -0
- package/dist/lib/arkClient.js +43 -0
- package/dist/lib/cluster.d.ts +8 -0
- package/dist/lib/cluster.js +134 -0
- package/dist/lib/config.d.ts +82 -0
- package/dist/lib/config.js +223 -0
- package/dist/lib/consts.d.ts +10 -0
- package/dist/lib/consts.js +15 -0
- package/dist/lib/errors.d.ts +56 -0
- package/dist/lib/errors.js +208 -0
- package/dist/lib/exec.d.ts +5 -0
- package/dist/lib/exec.js +20 -0
- package/dist/lib/gatewayManager.d.ts +24 -0
- package/dist/lib/gatewayManager.js +85 -0
- package/dist/lib/kubernetes.d.ts +28 -0
- package/dist/lib/kubernetes.js +122 -0
- package/dist/lib/progress.d.ts +128 -0
- package/dist/lib/progress.js +273 -0
- package/dist/lib/security.d.ts +37 -0
- package/dist/lib/security.js +295 -0
- package/dist/lib/types.d.ts +37 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/wrappers/git.d.ts +2 -0
- package/dist/lib/wrappers/git.js +43 -0
- package/dist/ui/MainMenu.d.ts +3 -0
- package/dist/ui/MainMenu.js +116 -0
- package/dist/ui/statusFormatter.d.ts +9 -0
- package/dist/ui/statusFormatter.js +47 -0
- 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,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,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,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,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,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
|
+
}
|