agentxchain 2.12.0 → 2.13.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
|
@@ -91,6 +91,19 @@ agentxchain approve-completion
|
|
|
91
91
|
|
|
92
92
|
Default governed scaffolding configures QA as `api_proxy` with `ANTHROPIC_API_KEY`. For a provider-free walkthrough, switch the QA runtime to `manual` before the QA step. If you override the dev runtime, either include `{prompt}` for argv delivery or set `--dev-prompt-transport` explicitly.
|
|
93
93
|
|
|
94
|
+
### Multi-repo coordination
|
|
95
|
+
|
|
96
|
+
For initiatives spanning multiple governed repos, use the coordinator to add cross-repo sequencing and shared gates:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npx agentxchain init --governed --template api-service --dir repos/backend -y
|
|
100
|
+
npx agentxchain init --governed --template web-app --dir repos/frontend -y
|
|
101
|
+
agentxchain multi init
|
|
102
|
+
agentxchain multi step --repo backend --role pm
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
See the [multi-repo quickstart](https://agentxchain.dev/docs/quickstart#multi-repo-cold-start) for the full cold-start walkthrough.
|
|
106
|
+
|
|
94
107
|
### Migrate a legacy project
|
|
95
108
|
|
|
96
109
|
```bash
|
package/package.json
CHANGED
|
@@ -66,6 +66,16 @@ function readRepoLocalHistory(repoPath) {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
function isAcceptedRepoHistoryEntry(entry) {
|
|
70
|
+
if (!entry || typeof entry !== 'object') {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Real governed history records the turn outcome in `status` and acceptance
|
|
75
|
+
// via `accepted_at`. Older coordinator fixtures used `status: "accepted"`.
|
|
76
|
+
return Boolean(entry.accepted_at) || entry.status === 'accepted';
|
|
77
|
+
}
|
|
78
|
+
|
|
69
79
|
// ── Divergence Detection ────────────────────────────────────────────────────
|
|
70
80
|
|
|
71
81
|
/**
|
|
@@ -166,7 +176,7 @@ export function detectDivergence(workspacePath, state, config) {
|
|
|
166
176
|
// Read repo-local history to determine what happened
|
|
167
177
|
const repoHistory = readRepoLocalHistory(repo.resolved_path);
|
|
168
178
|
const turnAccepted = repoHistory.some(
|
|
169
|
-
e => e?.turn_id === dispatch.repo_turn_id && e
|
|
179
|
+
e => e?.turn_id === dispatch.repo_turn_id && isAcceptedRepoHistoryEntry(e)
|
|
170
180
|
);
|
|
171
181
|
const turnRejected = repoHistory.some(
|
|
172
182
|
e => e?.turn_id === dispatch.repo_turn_id && e?.status === 'rejected'
|
|
@@ -279,7 +289,7 @@ export function resyncFromRepoAuthority(workspacePath, state, config) {
|
|
|
279
289
|
|
|
280
290
|
const repoHistory = readRepoLocalHistory(repo.resolved_path);
|
|
281
291
|
const acceptedEntry = repoHistory.find(
|
|
282
|
-
e => e?.turn_id === dispatch.repo_turn_id && e
|
|
292
|
+
e => e?.turn_id === dispatch.repo_turn_id && isAcceptedRepoHistoryEntry(e)
|
|
283
293
|
);
|
|
284
294
|
|
|
285
295
|
if (acceptedEntry) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
|
-
import { evaluatePhaseExit } from './gate-evaluator.js';
|
|
4
|
+
import { evaluatePhaseExit, evaluateRunCompletion } from './gate-evaluator.js';
|
|
5
5
|
import {
|
|
6
6
|
approvePhaseTransition,
|
|
7
7
|
approveRunCompletion,
|
|
@@ -708,6 +708,51 @@ function executeFixtureOperation(workspace, fixture) {
|
|
|
708
708
|
};
|
|
709
709
|
}
|
|
710
710
|
|
|
711
|
+
case 'evaluate_run_completion': {
|
|
712
|
+
const state = readJson(join(root, '.agentxchain', 'state.json'));
|
|
713
|
+
const acceptedTurn = {
|
|
714
|
+
run_completion_request: fixture.setup.turn_result?.run_completion_request ?? true,
|
|
715
|
+
verification: fixture.setup.turn_result?.verification || { status: 'pass' },
|
|
716
|
+
};
|
|
717
|
+
const result = evaluateRunCompletion({
|
|
718
|
+
state,
|
|
719
|
+
config: fixtureConfig,
|
|
720
|
+
acceptedTurn,
|
|
721
|
+
root,
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
if (result.action === 'awaiting_human_approval') {
|
|
725
|
+
return {
|
|
726
|
+
result: 'success',
|
|
727
|
+
action: result.action,
|
|
728
|
+
new_status: 'paused',
|
|
729
|
+
pending_run_completion: {
|
|
730
|
+
phase: state.phase,
|
|
731
|
+
gate: result.gate_id,
|
|
732
|
+
},
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
if (result.action === 'complete') {
|
|
737
|
+
return {
|
|
738
|
+
result: 'success',
|
|
739
|
+
action: result.action,
|
|
740
|
+
new_status: 'completed',
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
return {
|
|
745
|
+
result: 'success',
|
|
746
|
+
action: result.action,
|
|
747
|
+
state_unchanged: true,
|
|
748
|
+
reason: result.missing_files.length > 0
|
|
749
|
+
? 'requires_files predicate failed'
|
|
750
|
+
: result.missing_verification
|
|
751
|
+
? 'requires_verification_pass predicate failed'
|
|
752
|
+
: (result.reasons[0] || null),
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
|
|
711
756
|
case 'append_decision': {
|
|
712
757
|
const ledgerPath = join(root, '.agentxchain', 'decision-ledger.jsonl');
|
|
713
758
|
const existingLedger = readJsonl(ledgerPath);
|