agentxchain 2.58.0 → 2.60.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/README.md CHANGED
@@ -63,15 +63,19 @@ Duplicate execution remains intentional for the current 36-file slice until a la
63
63
  ### Governed workflow
64
64
 
65
65
  ```bash
66
- agentxchain init --governed --dir my-agentxchain-project -y
66
+ agentxchain init --governed --goal "Build an API change planner for release teams" --dir my-agentxchain-project -y
67
67
  cd my-agentxchain-project
68
68
  git init
69
+ agentxchain template validate
70
+ agentxchain doctor
69
71
  git add -A
70
72
  git commit -m "initial governed scaffold"
71
73
  agentxchain status
72
74
  agentxchain step --role pm
73
75
  ```
74
76
 
77
+ If you skipped `--goal` during scaffold, run `agentxchain config --set project.goal "Build an API change planner for release teams"` before the first governed turn instead of re-running init in place.
78
+
75
79
  The default governed dev runtime is `claude --print --dangerously-skip-permissions` with stdin prompt delivery. The non-interactive governed path needs write access, so do not pretend bare `claude --print` is sufficient for unattended implementation turns. If your local coding agent uses a different launch contract, set it during scaffold creation:
76
80
 
77
81
  ```bash
@@ -192,7 +192,7 @@ program
192
192
  .description('View or edit project configuration')
193
193
  .option('--add-agent', 'Add a new agent interactively')
194
194
  .option('--remove-agent <id>', 'Remove an agent by ID')
195
- .option('--set <key_value>', 'Set a config value (e.g. --set "rules.max_consecutive_claims 3")')
195
+ .option('--set <path_and_value...>', 'Set a config value (e.g. --set project.goal "Build a governed CLI")')
196
196
  .option('-j, --json', 'Output config as JSON')
197
197
  .action(configCommand);
198
198
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentxchain",
3
- "version": "2.58.0",
3
+ "version": "2.60.0",
4
4
  "description": "CLI for AgentXchain — governed multi-agent software delivery",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,31 +2,43 @@ import { readFileSync, writeFileSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import chalk from 'chalk';
4
4
  import inquirer from 'inquirer';
5
- import { loadConfig, CONFIG_FILE } from '../lib/config.js';
5
+ import { loadProjectContext, CONFIG_FILE } from '../lib/config.js';
6
6
  import { validateConfigSchema } from '../lib/schema.js';
7
+ import { validateV4Config } from '../lib/normalized-config.js';
7
8
 
8
9
  export async function configCommand(opts) {
9
- const result = loadConfig();
10
- if (!result) {
10
+ const context = loadProjectContext();
11
+ if (!context) {
11
12
  console.log(chalk.red(' No agentxchain.json found. Run `agentxchain init` first.'));
12
13
  process.exit(1);
13
14
  }
14
15
 
15
- const { root, config } = result;
16
+ const { root, rawConfig, version } = context;
17
+ const config = rawConfig;
16
18
  const configPath = join(root, CONFIG_FILE);
17
19
 
20
+ if (version === 4 && opts.addAgent) {
21
+ printLegacyOnlyMutationError('--add-agent');
22
+ return;
23
+ }
24
+
18
25
  if (opts.addAgent) {
19
26
  await addAgent(config, configPath);
20
27
  return;
21
28
  }
22
29
 
30
+ if (version === 4 && opts.removeAgent) {
31
+ printLegacyOnlyMutationError('--remove-agent');
32
+ return;
33
+ }
34
+
23
35
  if (opts.removeAgent) {
24
36
  removeAgent(config, configPath, opts.removeAgent);
25
37
  return;
26
38
  }
27
39
 
28
40
  if (opts.set) {
29
- setSetting(config, configPath, opts.set);
41
+ setSetting(config, configPath, opts.set, { version, root });
30
42
  return;
31
43
  }
32
44
 
@@ -35,10 +47,15 @@ export async function configCommand(opts) {
35
47
  return;
36
48
  }
37
49
 
38
- printConfig(config);
50
+ if (version === 4) {
51
+ printGovernedConfig(config);
52
+ return;
53
+ }
54
+
55
+ printLegacyConfig(config);
39
56
  }
40
57
 
41
- function printConfig(config) {
58
+ function printLegacyConfig(config) {
42
59
  console.log('');
43
60
  console.log(chalk.bold(' AgentXchain Config'));
44
61
  console.log(chalk.dim(' ' + '─'.repeat(40)));
@@ -69,6 +86,32 @@ function printConfig(config) {
69
86
  console.log('');
70
87
  }
71
88
 
89
+ function printGovernedConfig(config) {
90
+ console.log('');
91
+ console.log(chalk.bold(' AgentXchain Governed Config'));
92
+ console.log(chalk.dim(' ' + '─'.repeat(40)));
93
+ console.log('');
94
+ console.log(` ${chalk.dim('Project:')} ${config.project?.name || '(unknown)'}`);
95
+ console.log(` ${chalk.dim('Project ID:')} ${config.project?.id || '(unknown)'}`);
96
+ console.log(` ${chalk.dim('Goal:')} ${config.project?.goal || '(not set)'}`);
97
+ console.log(` ${chalk.dim('Template:')} ${config.template || 'generic'}`);
98
+ console.log(` ${chalk.dim('Roles:')} ${Object.keys(config.roles || {}).length}`);
99
+ console.log(` ${chalk.dim('Runtimes:')} ${Object.keys(config.runtimes || {}).length}`);
100
+ console.log('');
101
+ console.log(chalk.dim(' Commands:'));
102
+ console.log(` ${chalk.bold('agentxchain config --set project.goal "Build a ..."')} Set mission context without hand-editing JSON`);
103
+ console.log(` ${chalk.bold('agentxchain config --set roles.qa.runtime manual-qa')} Switch a governed role runtime`);
104
+ console.log(` ${chalk.bold('agentxchain config --json')} Output raw config`);
105
+ console.log('');
106
+ }
107
+
108
+ function printLegacyOnlyMutationError(flag) {
109
+ console.log(chalk.red(` ${flag} is legacy-only.`));
110
+ console.log(chalk.dim(' Governed repos use roles and runtimes instead of legacy v3 agents.'));
111
+ console.log(chalk.dim(' Use `agentxchain config --set <path> <value>` for governed config changes.'));
112
+ process.exit(1);
113
+ }
114
+
72
115
  async function addAgent(config, configPath) {
73
116
  const answers = await inquirer.prompt([
74
117
  {
@@ -117,16 +160,15 @@ function removeAgent(config, configPath, id) {
117
160
  console.log('');
118
161
  }
119
162
 
120
- function setSetting(config, configPath, keyValPair) {
121
- const parts = keyValPair.split(/\s+/);
122
- if (parts.length < 2) {
163
+ function setSetting(config, configPath, keyValPair, context) {
164
+ const parsed = parseSetInput(keyValPair);
165
+ if (!parsed) {
123
166
  console.log(chalk.red(' Usage: agentxchain config --set <key> <value>'));
124
- console.log(chalk.dim(' Example: agentxchain config --set rules.max_consecutive_claims 3'));
167
+ console.log(chalk.dim(' Example: agentxchain config --set project.goal "Build a governed CLI"'));
125
168
  process.exit(1);
126
169
  }
127
170
 
128
- const key = parts[0];
129
- const rawVal = parts.slice(1).join(' ');
171
+ const { key, rawVal } = parsed;
130
172
  const segments = key.split('.');
131
173
  const forbiddenKeys = new Set(['__proto__', 'prototype', 'constructor']);
132
174
 
@@ -152,7 +194,7 @@ function setSetting(config, configPath, keyValPair) {
152
194
  else if (!isNaN(rawVal) && rawVal !== '') val = Number(rawVal);
153
195
 
154
196
  target[lastKey] = val;
155
- const validation = validateConfigSchema(config);
197
+ const validation = validateEditedConfig(config, context);
156
198
  if (!validation.ok) {
157
199
  target[lastKey] = oldVal;
158
200
  if (oldVal === undefined) {
@@ -168,3 +210,34 @@ function setSetting(config, configPath, keyValPair) {
168
210
  if (oldVal !== undefined) console.log(chalk.dim(` (was: ${oldVal})`));
169
211
  console.log('');
170
212
  }
213
+
214
+ function parseSetInput(input) {
215
+ if (Array.isArray(input)) {
216
+ if (input.length >= 2) {
217
+ return { key: input[0], rawVal: input.slice(1).join(' ') };
218
+ }
219
+ if (input.length === 1 && typeof input[0] === 'string') {
220
+ const parts = input[0].trim().split(/\s+/);
221
+ if (parts.length >= 2) {
222
+ return { key: parts[0], rawVal: parts.slice(1).join(' ') };
223
+ }
224
+ }
225
+ return null;
226
+ }
227
+
228
+ if (typeof input === 'string') {
229
+ const parts = input.trim().split(/\s+/);
230
+ if (parts.length >= 2) {
231
+ return { key: parts[0], rawVal: parts.slice(1).join(' ') };
232
+ }
233
+ }
234
+
235
+ return null;
236
+ }
237
+
238
+ function validateEditedConfig(config, context) {
239
+ if (context.version === 4) {
240
+ return validateV4Config(config, context.root);
241
+ }
242
+ return validateConfigSchema(config);
243
+ }
@@ -604,9 +604,13 @@ All acceptance criteria met. OBJ-002 (clock skew) noted for follow-up. OBJ-003 (
604
604
  console.log('');
605
605
  console.log(chalk.dim(' ─'.repeat(26)));
606
606
  console.log('');
607
- console.log(` ${chalk.bold('Try it for real:')} agentxchain init --governed`);
608
- console.log(` ${chalk.bold('Step by step:')} https://agentxchain.dev/docs/getting-started`);
609
- console.log(` ${chalk.bold('Read more:')} https://agentxchain.dev/docs/quickstart`);
607
+ console.log(` ${chalk.bold('Next steps:')}`);
608
+ console.log('');
609
+ console.log(` ${chalk.dim('1.')} ${chalk.bold('Scaffold')} agentxchain init --governed --goal "Your project mission"`);
610
+ console.log(` ${chalk.dim('2.')} ${chalk.bold('Verify')} agentxchain doctor`);
611
+ console.log(` ${chalk.dim('3.')} ${chalk.bold('First turn')} agentxchain run`);
612
+ console.log('');
613
+ console.log(` ${chalk.bold('Docs:')} https://agentxchain.dev/docs/quickstart`);
610
614
  console.log('');
611
615
  }
612
616
 
@@ -978,7 +978,8 @@ async function initGoverned(opts) {
978
978
  console.log('');
979
979
  if (!config?.project?.goal) {
980
980
  console.log(` ${chalk.dim('Tip:')} Add a project goal to guide agent context:`);
981
- console.log(` ${chalk.bold('agentxchain init --governed --goal "Build a ..."')} ${chalk.dim('# or set project.goal in agentxchain.json')}`);
981
+ console.log(` ${chalk.bold('agentxchain init --governed --goal "Build a ..."')} ${chalk.dim('# preferred during scaffold')}`);
982
+ console.log(` ${chalk.bold('agentxchain config --set project.goal "Build a ..."')} ${chalk.dim('# add it later without hand-editing JSON')}`);
982
983
  console.log('');
983
984
  }
984
985
  console.log(` ${chalk.dim('Guide:')} https://agentxchain.dev/docs/getting-started`);