agentxchain 0.8.7 → 2.1.1
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 +123 -154
- package/bin/agentxchain.js +240 -8
- package/dashboard/app.js +305 -0
- package/dashboard/components/blocked.js +145 -0
- package/dashboard/components/cross-repo.js +126 -0
- package/dashboard/components/gate.js +311 -0
- package/dashboard/components/hooks.js +177 -0
- package/dashboard/components/initiative.js +147 -0
- package/dashboard/components/ledger.js +165 -0
- package/dashboard/components/timeline.js +222 -0
- package/dashboard/index.html +352 -0
- package/package.json +16 -7
- package/scripts/agentxchain-autonudge.applescript +32 -5
- package/scripts/live-api-proxy-preflight-smoke.sh +531 -0
- package/scripts/publish-from-tag.sh +88 -0
- package/scripts/release-postflight.sh +231 -0
- package/scripts/release-preflight.sh +167 -0
- package/scripts/run-autonudge.sh +1 -1
- package/src/adapters/claude-code.js +7 -14
- package/src/adapters/cursor-local.js +17 -16
- package/src/commands/accept-turn.js +160 -0
- package/src/commands/approve-completion.js +80 -0
- package/src/commands/approve-transition.js +85 -0
- package/src/commands/branch.js +2 -2
- package/src/commands/claim.js +84 -9
- package/src/commands/config.js +16 -0
- package/src/commands/dashboard.js +70 -0
- package/src/commands/doctor.js +9 -1
- package/src/commands/init.js +540 -5
- package/src/commands/migrate.js +348 -0
- package/src/commands/multi.js +549 -0
- package/src/commands/plugin.js +157 -0
- package/src/commands/reject-turn.js +204 -0
- package/src/commands/resume.js +389 -0
- package/src/commands/status.js +196 -3
- package/src/commands/step.js +947 -0
- package/src/commands/stop.js +65 -33
- package/src/commands/template-list.js +33 -0
- package/src/commands/template-set.js +279 -0
- package/src/commands/update.js +24 -3
- package/src/commands/validate.js +20 -11
- package/src/commands/verify.js +71 -0
- package/src/commands/watch.js +112 -25
- package/src/lib/adapters/api-proxy-adapter.js +1076 -0
- package/src/lib/adapters/local-cli-adapter.js +337 -0
- package/src/lib/adapters/manual-adapter.js +169 -0
- package/src/lib/blocked-state.js +94 -0
- package/src/lib/config.js +143 -12
- package/src/lib/context-compressor.js +121 -0
- package/src/lib/context-section-parser.js +220 -0
- package/src/lib/coordinator-acceptance.js +428 -0
- package/src/lib/coordinator-config.js +461 -0
- package/src/lib/coordinator-dispatch.js +276 -0
- package/src/lib/coordinator-gates.js +487 -0
- package/src/lib/coordinator-hooks.js +239 -0
- package/src/lib/coordinator-recovery.js +523 -0
- package/src/lib/coordinator-state.js +365 -0
- package/src/lib/cross-repo-context.js +247 -0
- package/src/lib/dashboard/bridge-server.js +284 -0
- package/src/lib/dashboard/file-watcher.js +93 -0
- package/src/lib/dashboard/state-reader.js +96 -0
- package/src/lib/dispatch-bundle.js +568 -0
- package/src/lib/dispatch-manifest.js +252 -0
- package/src/lib/filter-agents.js +12 -0
- package/src/lib/gate-evaluator.js +285 -0
- package/src/lib/generate-vscode.js +158 -68
- package/src/lib/governed-state.js +2139 -0
- package/src/lib/governed-templates.js +145 -0
- package/src/lib/hook-runner.js +788 -0
- package/src/lib/next-owner.js +61 -6
- package/src/lib/normalized-config.js +539 -0
- package/src/lib/notify.js +14 -12
- package/src/lib/plugin-config-schema.js +192 -0
- package/src/lib/plugins.js +692 -0
- package/src/lib/prompt-core.js +108 -0
- package/src/lib/protocol-conformance.js +291 -0
- package/src/lib/reference-conformance-adapter.js +717 -0
- package/src/lib/repo-observer.js +597 -0
- package/src/lib/repo.js +0 -31
- package/src/lib/safe-write.js +44 -0
- package/src/lib/schema.js +189 -0
- package/src/lib/schemas/turn-result.schema.json +205 -0
- package/src/lib/seed-prompt-polling.js +15 -73
- package/src/lib/seed-prompt.js +17 -63
- package/src/lib/token-budget.js +206 -0
- package/src/lib/token-counter.js +27 -0
- package/src/lib/turn-paths.js +67 -0
- package/src/lib/turn-result-validator.js +496 -0
- package/src/lib/validation.js +167 -19
- package/src/lib/verify-command.js +72 -0
- package/src/templates/governed/api-service.json +31 -0
- package/src/templates/governed/cli-tool.json +30 -0
- package/src/templates/governed/generic.json +10 -0
- package/src/templates/governed/web-app.json +30 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migrate a legacy v3 AgentXchain project to governed mode.
|
|
3
|
+
*
|
|
4
|
+
* Non-destructive: backs up the original config, archives legacy coordination
|
|
5
|
+
* artifacts, and creates governed state + directory structure.
|
|
6
|
+
*
|
|
7
|
+
* Frozen rules (§32 + §38):
|
|
8
|
+
* - Legacy projects are supported, not upgraded silently.
|
|
9
|
+
* - No automatic rewrite on read.
|
|
10
|
+
* - Legacy history is archived, not backfilled into governed history.
|
|
11
|
+
* - Post-migration state is `paused`, not `active`.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, renameSync, copyFileSync } from 'fs';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
import chalk from 'chalk';
|
|
17
|
+
import inquirer from 'inquirer';
|
|
18
|
+
import { findProjectRoot, CONFIG_FILE } from '../lib/config.js';
|
|
19
|
+
import { loadNormalizedConfig, detectConfigVersion } from '../lib/normalized-config.js';
|
|
20
|
+
|
|
21
|
+
const LEGACY_ARTIFACTS = ['lock.json', 'state.json', 'state.md', 'history.jsonl', 'log.md'];
|
|
22
|
+
|
|
23
|
+
function inferPhase(legacyState) {
|
|
24
|
+
if (!legacyState) return 'planning';
|
|
25
|
+
const phase = String(legacyState.phase || '').toLowerCase();
|
|
26
|
+
if (phase.includes('build') || phase.includes('implement')) return 'implementation';
|
|
27
|
+
if (phase.includes('qa') || phase.includes('test')) return 'qa';
|
|
28
|
+
return 'planning';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function migrateCommand(opts) {
|
|
32
|
+
const root = findProjectRoot();
|
|
33
|
+
if (!root) {
|
|
34
|
+
console.error(chalk.red(' No agentxchain.json found. Run this from inside a project.'));
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Read raw config
|
|
39
|
+
let rawConfig;
|
|
40
|
+
try {
|
|
41
|
+
rawConfig = JSON.parse(readFileSync(join(root, CONFIG_FILE), 'utf8'));
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.error(chalk.red(` Could not read agentxchain.json: ${err.message}`));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const version = detectConfigVersion(rawConfig);
|
|
48
|
+
if (version === 4) {
|
|
49
|
+
console.log(chalk.yellow(' This project is already governed. Nothing to migrate.'));
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (version !== 3) {
|
|
53
|
+
console.error(chalk.red(' Unrecognized config format. Only v3 projects can be migrated.'));
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Normalize to understand the current shape
|
|
58
|
+
const normalized = loadNormalizedConfig(rawConfig);
|
|
59
|
+
if (!normalized.ok) {
|
|
60
|
+
console.error(chalk.red(` Config validation failed: ${normalized.errors.join(', ')}`));
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Confirmation
|
|
65
|
+
if (!opts.yes) {
|
|
66
|
+
console.log('');
|
|
67
|
+
console.log(chalk.cyan(' Migration preview:'));
|
|
68
|
+
console.log(` Project: ${rawConfig.project}`);
|
|
69
|
+
console.log(` Agents: ${Object.keys(rawConfig.agents || {}).join(', ')}`);
|
|
70
|
+
console.log('');
|
|
71
|
+
console.log(chalk.dim(' This will:'));
|
|
72
|
+
console.log(chalk.dim(' 1. Back up agentxchain.json'));
|
|
73
|
+
console.log(chalk.dim(' 2. Rewrite config to governed mode'));
|
|
74
|
+
console.log(chalk.dim(' 3. Create .agentxchain/ directory structure'));
|
|
75
|
+
console.log(chalk.dim(' 4. Archive legacy coordination files'));
|
|
76
|
+
console.log(chalk.dim(' 5. Set status to paused (requires human review)'));
|
|
77
|
+
console.log('');
|
|
78
|
+
|
|
79
|
+
const { confirm } = await inquirer.prompt([{
|
|
80
|
+
type: 'confirm',
|
|
81
|
+
name: 'confirm',
|
|
82
|
+
message: 'Proceed with migration?',
|
|
83
|
+
default: true
|
|
84
|
+
}]);
|
|
85
|
+
if (!confirm) {
|
|
86
|
+
console.log(chalk.yellow(' Aborted.'));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Create directories
|
|
92
|
+
mkdirSync(join(root, '.agentxchain', 'backups'), { recursive: true });
|
|
93
|
+
mkdirSync(join(root, '.agentxchain', 'legacy'), { recursive: true });
|
|
94
|
+
mkdirSync(join(root, '.agentxchain', 'staging'), { recursive: true });
|
|
95
|
+
mkdirSync(join(root, '.agentxchain', 'prompts'), { recursive: true });
|
|
96
|
+
mkdirSync(join(root, '.agentxchain', 'reviews'), { recursive: true });
|
|
97
|
+
mkdirSync(join(root, '.agentxchain', 'dispatch'), { recursive: true });
|
|
98
|
+
|
|
99
|
+
// Step 1: Backup
|
|
100
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
101
|
+
const backupPath = join(root, '.agentxchain', 'backups', `agentxchain.v3.${timestamp}.json`);
|
|
102
|
+
copyFileSync(join(root, CONFIG_FILE), backupPath);
|
|
103
|
+
|
|
104
|
+
// Step 2: Build governed config from legacy
|
|
105
|
+
const norm = normalized.normalized;
|
|
106
|
+
const projectId = norm.project.id;
|
|
107
|
+
const projectName = norm.project.name;
|
|
108
|
+
|
|
109
|
+
const roles = {};
|
|
110
|
+
const runtimes = {};
|
|
111
|
+
const inferences = [];
|
|
112
|
+
|
|
113
|
+
for (const [id, role] of Object.entries(norm.roles)) {
|
|
114
|
+
const runtimeId = `manual-${id}`;
|
|
115
|
+
roles[id] = {
|
|
116
|
+
title: role.title,
|
|
117
|
+
mandate: role.mandate,
|
|
118
|
+
write_authority: role.write_authority,
|
|
119
|
+
runtime: runtimeId
|
|
120
|
+
};
|
|
121
|
+
runtimes[runtimeId] = { type: 'manual' };
|
|
122
|
+
inferences.push({
|
|
123
|
+
role: id,
|
|
124
|
+
field: 'write_authority',
|
|
125
|
+
inferred: role.write_authority,
|
|
126
|
+
note: 'Inferred from role name heuristic. Review and adjust if incorrect.'
|
|
127
|
+
});
|
|
128
|
+
inferences.push({
|
|
129
|
+
role: id,
|
|
130
|
+
field: 'runtime',
|
|
131
|
+
inferred: 'manual',
|
|
132
|
+
note: 'All legacy agents default to manual runtime. Change to local_cli or api_proxy as needed.'
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const roleIds = Object.keys(roles);
|
|
137
|
+
const routing = {
|
|
138
|
+
planning: {
|
|
139
|
+
entry_role: roleIds[0] || 'pm',
|
|
140
|
+
allowed_next_roles: [...roleIds, 'human'],
|
|
141
|
+
exit_gate: 'planning_signoff'
|
|
142
|
+
},
|
|
143
|
+
implementation: {
|
|
144
|
+
entry_role: roleIds.find(r => r.includes('dev')) || roleIds[0],
|
|
145
|
+
allowed_next_roles: [...roleIds, 'human'],
|
|
146
|
+
exit_gate: 'implementation_complete'
|
|
147
|
+
},
|
|
148
|
+
qa: {
|
|
149
|
+
entry_role: roleIds.find(r => r.includes('qa')) || roleIds[0],
|
|
150
|
+
allowed_next_roles: [...roleIds, 'human'],
|
|
151
|
+
exit_gate: 'qa_ship_verdict'
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const governedConfig = {
|
|
156
|
+
schema_version: '1.0',
|
|
157
|
+
template: 'generic',
|
|
158
|
+
project: {
|
|
159
|
+
id: projectId,
|
|
160
|
+
name: projectName,
|
|
161
|
+
default_branch: norm.project.default_branch
|
|
162
|
+
},
|
|
163
|
+
roles,
|
|
164
|
+
runtimes,
|
|
165
|
+
routing,
|
|
166
|
+
gates: {
|
|
167
|
+
planning_signoff: {
|
|
168
|
+
requires_files: ['.planning/PM_SIGNOFF.md', '.planning/ROADMAP.md'],
|
|
169
|
+
requires_human_approval: true
|
|
170
|
+
},
|
|
171
|
+
implementation_complete: {
|
|
172
|
+
requires_verification_pass: true
|
|
173
|
+
},
|
|
174
|
+
qa_ship_verdict: {
|
|
175
|
+
requires_files: ['.planning/acceptance-matrix.md', '.planning/ship-verdict.md'],
|
|
176
|
+
requires_human_approval: true
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
budget: {
|
|
180
|
+
per_turn_max_usd: 2.0,
|
|
181
|
+
per_run_max_usd: 50.0,
|
|
182
|
+
on_exceed: 'pause_and_escalate'
|
|
183
|
+
},
|
|
184
|
+
retention: {
|
|
185
|
+
talk_strategy: 'append_only',
|
|
186
|
+
history_strategy: 'jsonl_append_only'
|
|
187
|
+
},
|
|
188
|
+
prompts: Object.fromEntries(roleIds.map(id => [id, `.agentxchain/prompts/${id}.md`])),
|
|
189
|
+
rules: {
|
|
190
|
+
challenge_required: norm.rules.challenge_required,
|
|
191
|
+
max_turn_retries: 2,
|
|
192
|
+
max_deadlock_cycles: 2
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// Step 3: Read legacy state for phase inference
|
|
197
|
+
let legacyState = null;
|
|
198
|
+
const legacyStatePath = join(root, 'state.json');
|
|
199
|
+
if (existsSync(legacyStatePath)) {
|
|
200
|
+
try { legacyState = JSON.parse(readFileSync(legacyStatePath, 'utf8')); } catch {}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const inferredPhase = inferPhase(legacyState);
|
|
204
|
+
|
|
205
|
+
const governedState = {
|
|
206
|
+
schema_version: '1.1',
|
|
207
|
+
run_id: null,
|
|
208
|
+
project_id: projectId,
|
|
209
|
+
status: 'paused',
|
|
210
|
+
phase: inferredPhase,
|
|
211
|
+
accepted_integration_ref: null,
|
|
212
|
+
active_turns: {},
|
|
213
|
+
turn_sequence: 0,
|
|
214
|
+
last_completed_turn_id: null,
|
|
215
|
+
blocked_on: 'human:migration-review',
|
|
216
|
+
blocked_reason: null,
|
|
217
|
+
escalation: null,
|
|
218
|
+
queued_phase_transition: null,
|
|
219
|
+
queued_run_completion: null,
|
|
220
|
+
phase_gate_status: {
|
|
221
|
+
planning_signoff: inferredPhase === 'planning' ? 'pending' : 'passed',
|
|
222
|
+
implementation_complete: inferredPhase === 'qa' ? 'passed' : 'pending',
|
|
223
|
+
qa_ship_verdict: 'pending'
|
|
224
|
+
},
|
|
225
|
+
budget_reservations: {},
|
|
226
|
+
budget_status: {
|
|
227
|
+
spent_usd: 0,
|
|
228
|
+
remaining_usd: governedConfig.budget.per_run_max_usd
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// Step 4: Write governed config and state
|
|
233
|
+
writeFileSync(join(root, CONFIG_FILE), JSON.stringify(governedConfig, null, 2) + '\n');
|
|
234
|
+
writeFileSync(join(root, '.agentxchain', 'state.json'), JSON.stringify(governedState, null, 2) + '\n');
|
|
235
|
+
writeFileSync(join(root, '.agentxchain', 'history.jsonl'), '');
|
|
236
|
+
writeFileSync(join(root, '.agentxchain', 'decision-ledger.jsonl'), '');
|
|
237
|
+
|
|
238
|
+
// Step 5: Generate prompt templates
|
|
239
|
+
for (const [id, role] of Object.entries(roles)) {
|
|
240
|
+
const promptContent = `# ${role.title}\n\n## Identity\n\nYou are the **${role.title}** on this project.\n\n**Mandate:** ${role.mandate}\n\n**Write authority:** ${role.write_authority}\n**Runtime:** ${role.runtime}\n\n## Protocol Rules\n\n1. Challenge the previous turn explicitly.\n2. Do not claim verification you did not perform.\n3. Do not modify reserved state files under \`.agentxchain/\`.\n4. Emit structured turn result to \`.agentxchain/staging/<turn_id>/turn-result.json\`.\n5. Propose next role, but do not assume routing authority.\n`;
|
|
241
|
+
writeFileSync(join(root, '.agentxchain', 'prompts', `${id}.md`), promptContent);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Step 6: Archive legacy artifacts
|
|
245
|
+
const archived = [];
|
|
246
|
+
for (const file of LEGACY_ARTIFACTS) {
|
|
247
|
+
const src = join(root, file);
|
|
248
|
+
if (existsSync(src)) {
|
|
249
|
+
const dest = join(root, '.agentxchain', 'legacy', file);
|
|
250
|
+
copyFileSync(src, dest);
|
|
251
|
+
archived.push(file);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Step 7: Write migration report
|
|
256
|
+
const report = {
|
|
257
|
+
migrated_at: new Date().toISOString(),
|
|
258
|
+
original_version: 3,
|
|
259
|
+
target_version: '1.0',
|
|
260
|
+
project: projectName,
|
|
261
|
+
template: 'generic',
|
|
262
|
+
backup_path: `.agentxchain/backups/agentxchain.v3.${timestamp}.json`,
|
|
263
|
+
inferred_phase: inferredPhase,
|
|
264
|
+
archived_files: archived,
|
|
265
|
+
inferences,
|
|
266
|
+
post_migration_status: 'paused',
|
|
267
|
+
post_migration_blocked_on: 'human:migration-review',
|
|
268
|
+
requires_human_review: [
|
|
269
|
+
'Verify write_authority for each role',
|
|
270
|
+
'Update runtimes from manual to local_cli or api_proxy as needed',
|
|
271
|
+
'Review inferred phase and gate status',
|
|
272
|
+
'Review and customize prompt templates in .agentxchain/prompts/',
|
|
273
|
+
'Review the migration state, then start the first governed turn with agentxchain resume'
|
|
274
|
+
]
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const reportMd = `# Migration Report
|
|
278
|
+
|
|
279
|
+
**Migrated at:** ${report.migrated_at}
|
|
280
|
+
**Original version:** v3 → governed mode (schema_version: "1.0")
|
|
281
|
+
**Project:** ${projectName}
|
|
282
|
+
**Template:** \`generic\` (explicit baseline; migrate does not infer project shape)
|
|
283
|
+
**Backup:** \`${report.backup_path}\`
|
|
284
|
+
|
|
285
|
+
## Inferred Phase
|
|
286
|
+
|
|
287
|
+
**${inferredPhase}** (derived from legacy state)
|
|
288
|
+
|
|
289
|
+
## Archived Legacy Files
|
|
290
|
+
|
|
291
|
+
${archived.map(f => `- \`${f}\` → \`.agentxchain/legacy/${f}\``).join('\n') || '(none)'}
|
|
292
|
+
|
|
293
|
+
## Inferred Fields Requiring Review
|
|
294
|
+
|
|
295
|
+
${inferences.map(i => `- **${i.role}.${i.field}** = \`${i.inferred}\` — ${i.note}`).join('\n')}
|
|
296
|
+
|
|
297
|
+
## Post-Migration Status
|
|
298
|
+
|
|
299
|
+
**Status:** paused
|
|
300
|
+
**Blocked on:** human:migration-review
|
|
301
|
+
|
|
302
|
+
## Required Human Actions
|
|
303
|
+
|
|
304
|
+
${report.requires_human_review.map((r, i) => `${i + 1}. ${r}`).join('\n')}
|
|
305
|
+
`;
|
|
306
|
+
|
|
307
|
+
writeFileSync(join(root, '.agentxchain', 'migration-report.md'), reportMd);
|
|
308
|
+
|
|
309
|
+
// Ensure planning artifacts exist
|
|
310
|
+
mkdirSync(join(root, '.planning'), { recursive: true });
|
|
311
|
+
const planningFiles = {
|
|
312
|
+
'PM_SIGNOFF.md': `# PM Signoff — ${projectName}\n\nApproved: NO\n`,
|
|
313
|
+
'ROADMAP.md': `# Roadmap — ${projectName}\n\n(Migrated from v3. Review and update.)\n`,
|
|
314
|
+
'acceptance-matrix.md': `# Acceptance Matrix — ${projectName}\n\n(QA fills this.)\n`,
|
|
315
|
+
'ship-verdict.md': `# Ship Verdict — ${projectName}\n\n## Verdict: PENDING\n`
|
|
316
|
+
};
|
|
317
|
+
for (const [file, content] of Object.entries(planningFiles)) {
|
|
318
|
+
const path = join(root, '.planning', file);
|
|
319
|
+
if (!existsSync(path)) {
|
|
320
|
+
writeFileSync(path, content);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Output
|
|
325
|
+
if (opts.json) {
|
|
326
|
+
console.log(JSON.stringify(report, null, 2));
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
console.log('');
|
|
331
|
+
console.log(chalk.green(` ✓ Migrated to governed mode`));
|
|
332
|
+
console.log('');
|
|
333
|
+
console.log(` ${chalk.dim('Backup:')} ${report.backup_path}`);
|
|
334
|
+
console.log(` ${chalk.dim('Archived:')} ${archived.join(', ') || '(none)'}`);
|
|
335
|
+
console.log(` ${chalk.dim('Phase:')} ${inferredPhase}`);
|
|
336
|
+
console.log(` ${chalk.dim('Status:')} paused (awaiting human review)`);
|
|
337
|
+
console.log('');
|
|
338
|
+
console.log(chalk.yellow(' ⚠ Review the migration report:'));
|
|
339
|
+
console.log(` ${chalk.bold('.agentxchain/migration-report.md')}`);
|
|
340
|
+
console.log('');
|
|
341
|
+
console.log(chalk.cyan(' Next:'));
|
|
342
|
+
console.log(` ${chalk.bold('agentxchain validate')} ${chalk.dim('# verify governed config')}`);
|
|
343
|
+
console.log(` ${chalk.bold('agentxchain status')} ${chalk.dim('# see governed state')}`);
|
|
344
|
+
console.log(` ${chalk.bold('agentxchain resume')} ${chalk.dim('# assign the first governed turn')}`);
|
|
345
|
+
console.log(` ${chalk.bold('agentxchain accept-turn')} ${chalk.dim('# accept a valid staged turn result')}`);
|
|
346
|
+
console.log(` ${chalk.bold('agentxchain reject-turn --reason "<reason>"')} ${chalk.dim('# retry or escalate a bad turn result')}`);
|
|
347
|
+
console.log('');
|
|
348
|
+
}
|