agentxchain 0.1.0 → 0.1.2
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 +27 -0
- package/bin/agentxchain.js +19 -4
- package/package.json +12 -2
- package/src/commands/config.js +148 -0
- package/src/commands/init.js +66 -50
- package/src/commands/update.js +42 -0
package/README.md
CHANGED
|
@@ -58,6 +58,33 @@ For Cursor Cloud Agents, set `CURSOR_API_KEY` in your environment. Without it, t
|
|
|
58
58
|
|
|
59
59
|
Stop all running agent sessions. Reads `.agentxchain-session.json` to find active agents.
|
|
60
60
|
|
|
61
|
+
### `agentxchain config`
|
|
62
|
+
|
|
63
|
+
View or edit project configuration.
|
|
64
|
+
|
|
65
|
+
- `--add-agent` — interactively add a new agent
|
|
66
|
+
- `--remove-agent <id>` — remove an agent by ID
|
|
67
|
+
- `--set "<key> <value>"` — update a setting (e.g. `--set "rules.max_consecutive_claims 3"`)
|
|
68
|
+
- `-j, --json` — output config as JSON
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
agentxchain config # show current config
|
|
74
|
+
agentxchain config --add-agent # add a new agent
|
|
75
|
+
agentxchain config --remove-agent ux # remove the ux agent
|
|
76
|
+
agentxchain config --set "project My New Name" # change project name
|
|
77
|
+
agentxchain config --set "rules.compress_after_words 8000"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `agentxchain update`
|
|
81
|
+
|
|
82
|
+
Update the CLI to the latest version from npm.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
agentxchain update
|
|
86
|
+
```
|
|
87
|
+
|
|
61
88
|
## How it works
|
|
62
89
|
|
|
63
90
|
AgentXchain uses a **claim-based protocol**:
|
package/bin/agentxchain.js
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
|
-
import chalk from 'chalk';
|
|
5
4
|
import { initCommand } from '../src/commands/init.js';
|
|
6
5
|
import { statusCommand } from '../src/commands/status.js';
|
|
7
6
|
import { startCommand } from '../src/commands/start.js';
|
|
8
7
|
import { stopCommand } from '../src/commands/stop.js';
|
|
8
|
+
import { configCommand } from '../src/commands/config.js';
|
|
9
|
+
import { updateCommand } from '../src/commands/update.js';
|
|
9
10
|
|
|
10
11
|
const program = new Command();
|
|
11
12
|
|
|
12
13
|
program
|
|
13
14
|
.name('agentxchain')
|
|
14
15
|
.description('Multi-agent coordination in your IDE')
|
|
15
|
-
.version('0.1.
|
|
16
|
+
.version('0.1.1');
|
|
16
17
|
|
|
17
18
|
program
|
|
18
19
|
.command('init')
|
|
19
|
-
.description('
|
|
20
|
+
.description('Create a new AgentXchain project folder')
|
|
20
21
|
.option('-y, --yes', 'Skip prompts, use defaults')
|
|
21
22
|
.action(initCommand);
|
|
22
23
|
|
|
23
24
|
program
|
|
24
25
|
.command('status')
|
|
25
|
-
.description('Show
|
|
26
|
+
.description('Show lock status, phase, and agents')
|
|
26
27
|
.option('-j, --json', 'Output as JSON')
|
|
27
28
|
.action(statusCommand);
|
|
28
29
|
|
|
@@ -39,4 +40,18 @@ program
|
|
|
39
40
|
.description('Stop all running agent sessions')
|
|
40
41
|
.action(stopCommand);
|
|
41
42
|
|
|
43
|
+
program
|
|
44
|
+
.command('config')
|
|
45
|
+
.description('View or edit project configuration')
|
|
46
|
+
.option('--add-agent', 'Add a new agent interactively')
|
|
47
|
+
.option('--remove-agent <id>', 'Remove an agent by ID')
|
|
48
|
+
.option('--set <key_value>', 'Set a config value (e.g. --set "rules.max_consecutive_claims 3")')
|
|
49
|
+
.option('-j, --json', 'Output config as JSON')
|
|
50
|
+
.action(configCommand);
|
|
51
|
+
|
|
52
|
+
program
|
|
53
|
+
.command('update')
|
|
54
|
+
.description('Update agentxchain CLI to the latest version')
|
|
55
|
+
.action(updateCommand);
|
|
56
|
+
|
|
42
57
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentxchain",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "CLI for AgentXchain — multi-agent coordination in your IDE",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,7 +16,17 @@
|
|
|
16
16
|
"build:macos": "bun build bin/agentxchain.js --compile --target=bun-darwin-arm64 --outfile=dist/agentxchain-macos-arm64",
|
|
17
17
|
"build:linux": "bun build bin/agentxchain.js --compile --target=bun-linux-x64 --outfile=dist/agentxchain-linux-x64"
|
|
18
18
|
},
|
|
19
|
-
"keywords": [
|
|
19
|
+
"keywords": [
|
|
20
|
+
"ai",
|
|
21
|
+
"agents",
|
|
22
|
+
"multi-agent",
|
|
23
|
+
"coordination",
|
|
24
|
+
"sdlc",
|
|
25
|
+
"cursor",
|
|
26
|
+
"vscode",
|
|
27
|
+
"claude-code",
|
|
28
|
+
"agentxchain"
|
|
29
|
+
],
|
|
20
30
|
"author": "shivamtiwari93",
|
|
21
31
|
"license": "MIT",
|
|
22
32
|
"repository": {
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import { loadConfig, CONFIG_FILE } from '../lib/config.js';
|
|
6
|
+
|
|
7
|
+
export async function configCommand(opts) {
|
|
8
|
+
const result = loadConfig();
|
|
9
|
+
if (!result) {
|
|
10
|
+
console.log(chalk.red(' No agentxchain.json found. Run `agentxchain init` first.'));
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { root, config } = result;
|
|
15
|
+
const configPath = join(root, CONFIG_FILE);
|
|
16
|
+
|
|
17
|
+
if (opts.addAgent) {
|
|
18
|
+
await addAgent(config, configPath);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (opts.removeAgent) {
|
|
23
|
+
removeAgent(config, configPath, opts.removeAgent);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (opts.set) {
|
|
28
|
+
setSetting(config, configPath, opts.set);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (opts.json) {
|
|
33
|
+
console.log(JSON.stringify(config, null, 2));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
printConfig(config);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function printConfig(config) {
|
|
41
|
+
console.log('');
|
|
42
|
+
console.log(chalk.bold(' AgentXchain Config'));
|
|
43
|
+
console.log(chalk.dim(' ' + '─'.repeat(40)));
|
|
44
|
+
console.log('');
|
|
45
|
+
console.log(` ${chalk.dim('Project:')} ${config.project}`);
|
|
46
|
+
console.log(` ${chalk.dim('Version:')} ${config.version}`);
|
|
47
|
+
console.log(` ${chalk.dim('Log:')} ${config.log}`);
|
|
48
|
+
console.log('');
|
|
49
|
+
|
|
50
|
+
console.log(` ${chalk.dim('Rules:')}`);
|
|
51
|
+
for (const [key, val] of Object.entries(config.rules || {})) {
|
|
52
|
+
console.log(` ${chalk.dim(key + ':')} ${val}`);
|
|
53
|
+
}
|
|
54
|
+
console.log('');
|
|
55
|
+
|
|
56
|
+
console.log(` ${chalk.dim('Agents:')} ${Object.keys(config.agents).length}`);
|
|
57
|
+
for (const [id, agent] of Object.entries(config.agents)) {
|
|
58
|
+
console.log(` ${chalk.cyan(id)} — ${agent.name}`);
|
|
59
|
+
console.log(` ${chalk.dim(agent.mandate.slice(0, 80))}${agent.mandate.length > 80 ? '...' : ''}`);
|
|
60
|
+
console.log('');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log(chalk.dim(' Commands:'));
|
|
64
|
+
console.log(` ${chalk.bold('agentxchain config --add-agent')} Add a new agent`);
|
|
65
|
+
console.log(` ${chalk.bold('agentxchain config --remove-agent <id>')} Remove an agent`);
|
|
66
|
+
console.log(` ${chalk.bold('agentxchain config --set <key> <val>')} Update a setting`);
|
|
67
|
+
console.log(` ${chalk.bold('agentxchain config --json')} Output as JSON`);
|
|
68
|
+
console.log('');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function addAgent(config, configPath) {
|
|
72
|
+
const answers = await inquirer.prompt([
|
|
73
|
+
{
|
|
74
|
+
type: 'input',
|
|
75
|
+
name: 'id',
|
|
76
|
+
message: 'Agent ID (lowercase, no spaces):',
|
|
77
|
+
validate: (val) => {
|
|
78
|
+
if (!val.match(/^[a-z0-9-]+$/)) return 'Use lowercase letters, numbers, and hyphens only.';
|
|
79
|
+
if (config.agents[val]) return `Agent "${val}" already exists.`;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{ type: 'input', name: 'name', message: 'Display name:' },
|
|
84
|
+
{ type: 'input', name: 'mandate', message: 'Mandate (what this agent does):' }
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
config.agents[answers.id] = { name: answers.name, mandate: answers.mandate };
|
|
88
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
89
|
+
|
|
90
|
+
console.log('');
|
|
91
|
+
console.log(chalk.green(` ✓ Added agent ${chalk.bold(answers.id)} (${answers.name})`));
|
|
92
|
+
console.log(` ${chalk.dim('Agents now:')} ${Object.keys(config.agents).join(', ')}`);
|
|
93
|
+
console.log('');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function removeAgent(config, configPath, id) {
|
|
97
|
+
if (!config.agents[id]) {
|
|
98
|
+
console.log(chalk.red(` Agent "${id}" not found.`));
|
|
99
|
+
console.log(` ${chalk.dim('Available:')} ${Object.keys(config.agents).join(', ')}`);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const name = config.agents[id].name;
|
|
104
|
+
delete config.agents[id];
|
|
105
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
106
|
+
|
|
107
|
+
console.log('');
|
|
108
|
+
console.log(chalk.green(` ✓ Removed agent ${chalk.bold(id)} (${name})`));
|
|
109
|
+
console.log(` ${chalk.dim('Agents now:')} ${Object.keys(config.agents).join(', ')}`);
|
|
110
|
+
console.log('');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function setSetting(config, configPath, keyValPair) {
|
|
114
|
+
const parts = keyValPair.split(/\s+/);
|
|
115
|
+
if (parts.length < 2) {
|
|
116
|
+
console.log(chalk.red(' Usage: agentxchain config --set <key> <value>'));
|
|
117
|
+
console.log(chalk.dim(' Example: agentxchain config --set rules.max_consecutive_claims 3'));
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const key = parts[0];
|
|
122
|
+
const rawVal = parts.slice(1).join(' ');
|
|
123
|
+
const segments = key.split('.');
|
|
124
|
+
|
|
125
|
+
let target = config;
|
|
126
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
127
|
+
if (target[segments[i]] === undefined) {
|
|
128
|
+
target[segments[i]] = {};
|
|
129
|
+
}
|
|
130
|
+
target = target[segments[i]];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const lastKey = segments[segments.length - 1];
|
|
134
|
+
const oldVal = target[lastKey];
|
|
135
|
+
|
|
136
|
+
let val = rawVal;
|
|
137
|
+
if (rawVal === 'true') val = true;
|
|
138
|
+
else if (rawVal === 'false') val = false;
|
|
139
|
+
else if (!isNaN(rawVal) && rawVal !== '') val = Number(rawVal);
|
|
140
|
+
|
|
141
|
+
target[lastKey] = val;
|
|
142
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
143
|
+
|
|
144
|
+
console.log('');
|
|
145
|
+
console.log(chalk.green(` ✓ Set ${chalk.bold(key)} = ${val}`));
|
|
146
|
+
if (oldVal !== undefined) console.log(chalk.dim(` (was: ${oldVal})`));
|
|
147
|
+
console.log('');
|
|
148
|
+
}
|
package/src/commands/init.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
2
|
-
import { join } from 'path';
|
|
2
|
+
import { join, resolve } from 'path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import inquirer from 'inquirer';
|
|
5
5
|
import { CONFIG_FILE, LOCK_FILE, STATE_FILE } from '../lib/config.js';
|
|
@@ -23,46 +23,48 @@ const DEFAULT_AGENTS = {
|
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
name: 'overwrite',
|
|
33
|
-
message: `${CONFIG_FILE} already exists. Overwrite?`,
|
|
34
|
-
default: false
|
|
35
|
-
}]);
|
|
36
|
-
if (!overwrite) {
|
|
37
|
-
console.log(chalk.yellow('Aborted.'));
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
26
|
+
function slugify(name) {
|
|
27
|
+
return name
|
|
28
|
+
.toLowerCase()
|
|
29
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
30
|
+
.replace(/^-|-$/g, '');
|
|
31
|
+
}
|
|
41
32
|
|
|
42
|
-
|
|
33
|
+
export async function initCommand(opts) {
|
|
34
|
+
let project, agents, folderName;
|
|
43
35
|
|
|
44
36
|
if (opts.yes) {
|
|
45
37
|
project = 'My AgentXchain project';
|
|
46
38
|
agents = DEFAULT_AGENTS;
|
|
39
|
+
folderName = slugify(project);
|
|
47
40
|
} else {
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
41
|
+
const nameAnswer = await inquirer.prompt([{
|
|
42
|
+
type: 'input',
|
|
43
|
+
name: 'project',
|
|
44
|
+
message: 'Project name:',
|
|
45
|
+
default: 'My AgentXchain project'
|
|
46
|
+
}]);
|
|
47
|
+
|
|
48
|
+
project = nameAnswer.project;
|
|
49
|
+
folderName = slugify(project);
|
|
50
|
+
|
|
51
|
+
const folderAnswer = await inquirer.prompt([{
|
|
52
|
+
type: 'input',
|
|
53
|
+
name: 'folder',
|
|
54
|
+
message: 'Folder name:',
|
|
55
|
+
default: folderName
|
|
56
|
+
}]);
|
|
62
57
|
|
|
63
|
-
|
|
58
|
+
folderName = folderAnswer.folder;
|
|
64
59
|
|
|
65
|
-
|
|
60
|
+
const agentAnswer = await inquirer.prompt([{
|
|
61
|
+
type: 'confirm',
|
|
62
|
+
name: 'useDefaults',
|
|
63
|
+
message: 'Use default agents (pm, dev, qa, ux)?',
|
|
64
|
+
default: true
|
|
65
|
+
}]);
|
|
66
|
+
|
|
67
|
+
if (agentAnswer.useDefaults) {
|
|
66
68
|
agents = DEFAULT_AGENTS;
|
|
67
69
|
} else {
|
|
68
70
|
agents = {};
|
|
@@ -80,6 +82,27 @@ export async function initCommand(opts) {
|
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
const dir = resolve(process.cwd(), folderName);
|
|
86
|
+
|
|
87
|
+
if (existsSync(dir)) {
|
|
88
|
+
if (existsSync(join(dir, CONFIG_FILE))) {
|
|
89
|
+
if (!opts.yes) {
|
|
90
|
+
const { overwrite } = await inquirer.prompt([{
|
|
91
|
+
type: 'confirm',
|
|
92
|
+
name: 'overwrite',
|
|
93
|
+
message: `${folderName}/ already has an agentxchain.json. Overwrite?`,
|
|
94
|
+
default: false
|
|
95
|
+
}]);
|
|
96
|
+
if (!overwrite) {
|
|
97
|
+
console.log(chalk.yellow(' Aborted.'));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
mkdirSync(dir, { recursive: true });
|
|
104
|
+
}
|
|
105
|
+
|
|
83
106
|
const config = {
|
|
84
107
|
version: 3,
|
|
85
108
|
project,
|
|
@@ -109,27 +132,20 @@ export async function initCommand(opts) {
|
|
|
109
132
|
writeFileSync(join(dir, CONFIG_FILE), JSON.stringify(config, null, 2) + '\n');
|
|
110
133
|
writeFileSync(join(dir, LOCK_FILE), JSON.stringify(lock, null, 2) + '\n');
|
|
111
134
|
writeFileSync(join(dir, STATE_FILE), JSON.stringify(state, null, 2) + '\n');
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (!existsSync(join(dir, logFile))) {
|
|
115
|
-
writeFileSync(join(dir, logFile), `# ${project} — Agent Log\n\n## COMPRESSED CONTEXT\n\n(No compressed context yet.)\n\n## MESSAGE LOG\n\n(Agents append messages below this line.)\n`);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (!existsSync(join(dir, 'HUMAN_TASKS.md'))) {
|
|
119
|
-
writeFileSync(join(dir, 'HUMAN_TASKS.md'), '# Human Tasks\n\n(Agents append tasks here when they need human action.)\n');
|
|
120
|
-
}
|
|
135
|
+
writeFileSync(join(dir, config.log), `# ${project} — Agent Log\n\n## COMPRESSED CONTEXT\n\n(No compressed context yet.)\n\n## MESSAGE LOG\n\n(Agents append messages below this line.)\n`);
|
|
136
|
+
writeFileSync(join(dir, 'HUMAN_TASKS.md'), '# Human Tasks\n\n(Agents append tasks here when they need human action.)\n');
|
|
121
137
|
|
|
122
138
|
console.log('');
|
|
123
|
-
console.log(chalk.green(
|
|
139
|
+
console.log(chalk.green(` ✓ Created ${chalk.bold(folderName)}/`));
|
|
124
140
|
console.log('');
|
|
125
|
-
console.log(`
|
|
126
|
-
console.log(`
|
|
127
|
-
console.log(`
|
|
128
|
-
console.log(`
|
|
129
|
-
console.log(`
|
|
141
|
+
console.log(` ${chalk.dim('├──')} ${CONFIG_FILE}`);
|
|
142
|
+
console.log(` ${chalk.dim('├──')} ${LOCK_FILE}`);
|
|
143
|
+
console.log(` ${chalk.dim('├──')} ${STATE_FILE}`);
|
|
144
|
+
console.log(` ${chalk.dim('├──')} ${config.log}`);
|
|
145
|
+
console.log(` ${chalk.dim('└──')} HUMAN_TASKS.md`);
|
|
130
146
|
console.log('');
|
|
131
|
-
console.log(` ${chalk.dim('Agents:')}
|
|
147
|
+
console.log(` ${chalk.dim('Agents:')} ${Object.keys(agents).join(', ')}`);
|
|
132
148
|
console.log('');
|
|
133
|
-
console.log(` ${chalk.cyan('Next:')}
|
|
149
|
+
console.log(` ${chalk.cyan('Next:')} ${chalk.bold(`cd ${folderName}`)} && ${chalk.bold('agentxchain start')}`);
|
|
134
150
|
console.log('');
|
|
135
151
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { readFileSync } from 'fs';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
|
|
7
|
+
export async function updateCommand() {
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf8'));
|
|
10
|
+
const currentVersion = pkg.version;
|
|
11
|
+
|
|
12
|
+
console.log('');
|
|
13
|
+
console.log(` ${chalk.dim('Current version:')} ${currentVersion}`);
|
|
14
|
+
console.log(` ${chalk.dim('Checking npm for latest...')}`);
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const latest = execSync('npm view agentxchain version', { encoding: 'utf8' }).trim();
|
|
18
|
+
|
|
19
|
+
if (latest === currentVersion) {
|
|
20
|
+
console.log(chalk.green(` ✓ Already on the latest version (${currentVersion}).`));
|
|
21
|
+
console.log('');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.log(` ${chalk.dim('Latest version:')} ${chalk.cyan(latest)}`);
|
|
26
|
+
console.log('');
|
|
27
|
+
console.log(` Updating...`);
|
|
28
|
+
|
|
29
|
+
execSync('npm install -g agentxchain@latest', { stdio: 'inherit' });
|
|
30
|
+
|
|
31
|
+
console.log('');
|
|
32
|
+
console.log(chalk.green(` ✓ Updated to ${latest}`));
|
|
33
|
+
console.log('');
|
|
34
|
+
} catch (err) {
|
|
35
|
+
console.log('');
|
|
36
|
+
console.log(chalk.yellow(' Could not auto-update. Run manually:'));
|
|
37
|
+
console.log(` ${chalk.bold('npm install -g agentxchain@latest')}`);
|
|
38
|
+
console.log('');
|
|
39
|
+
console.log(chalk.dim(` Error: ${err.message}`));
|
|
40
|
+
console.log('');
|
|
41
|
+
}
|
|
42
|
+
}
|