agentxchain 2.104.0 → 2.105.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.
Files changed (62) hide show
  1. package/README.md +12 -6
  2. package/bin/agentxchain.js +5 -5
  3. package/dashboard/app.js +111 -7
  4. package/dashboard/components/blocked.js +95 -11
  5. package/dashboard/components/blockers.js +85 -86
  6. package/dashboard/components/coordinator-timeouts.js +13 -0
  7. package/dashboard/components/cross-repo.js +17 -12
  8. package/dashboard/components/gate.js +31 -11
  9. package/dashboard/components/initiative.js +173 -78
  10. package/dashboard/components/ledger.js +28 -0
  11. package/dashboard/components/live-status.js +39 -0
  12. package/dashboard/components/run-history.js +76 -1
  13. package/dashboard/components/timeline.js +5 -1
  14. package/dashboard/index.html +21 -0
  15. package/dashboard/live-observer.js +91 -0
  16. package/package.json +1 -1
  17. package/scripts/release-bump.sh +26 -3
  18. package/src/commands/accept-turn.js +3 -3
  19. package/src/commands/decisions.js +98 -29
  20. package/src/commands/diff.js +27 -4
  21. package/src/commands/doctor.js +48 -16
  22. package/src/commands/history.js +21 -3
  23. package/src/commands/multi.js +223 -54
  24. package/src/commands/phase.js +11 -13
  25. package/src/commands/reject-turn.js +1 -1
  26. package/src/commands/restart.js +28 -11
  27. package/src/commands/resume.js +6 -6
  28. package/src/commands/role.js +51 -14
  29. package/src/commands/run.js +5 -11
  30. package/src/commands/status.js +145 -13
  31. package/src/commands/step.js +36 -29
  32. package/src/lib/admission-control.js +14 -12
  33. package/src/lib/blocked-state.js +150 -0
  34. package/src/lib/conflict-actions.js +17 -0
  35. package/src/lib/context-section-parser.js +2 -0
  36. package/src/lib/continuity-status.js +1 -1
  37. package/src/lib/coordinator-blocker-presentation.js +127 -0
  38. package/src/lib/coordinator-event-narrative.js +43 -0
  39. package/src/lib/coordinator-gate-approval.js +98 -0
  40. package/src/lib/coordinator-gate-evaluation-presentation.js +57 -0
  41. package/src/lib/coordinator-next-actions.js +128 -0
  42. package/src/lib/coordinator-pending-gate-presentation.js +79 -0
  43. package/src/lib/coordinator-presentation-detail.js +11 -0
  44. package/src/lib/coordinator-repo-snapshots.js +53 -0
  45. package/src/lib/coordinator-repo-status-presentation.js +134 -0
  46. package/src/lib/dashboard/actions.js +105 -29
  47. package/src/lib/dashboard/bridge-server.js +7 -0
  48. package/src/lib/dashboard/coordinator-blockers.js +17 -0
  49. package/src/lib/dashboard/coordinator-repo-status.js +50 -0
  50. package/src/lib/dashboard/coordinator-timeout-status.js +34 -11
  51. package/src/lib/dashboard/state-reader.js +36 -1
  52. package/src/lib/dispatch-bundle.js +23 -0
  53. package/src/lib/export-diff.js +70 -38
  54. package/src/lib/export-verifier.js +3 -0
  55. package/src/lib/history-diff-summary.js +249 -0
  56. package/src/lib/manual-qa-fallback.js +18 -0
  57. package/src/lib/normalized-config.js +27 -22
  58. package/src/lib/recent-event-summary.js +132 -0
  59. package/src/lib/repo-decisions.js +69 -28
  60. package/src/lib/report.js +353 -145
  61. package/src/lib/run-diff.js +4 -0
  62. package/src/lib/runtime-capabilities.js +222 -0
@@ -8,6 +8,7 @@ const SCALAR_FIELDS = [
8
8
  ['connector_used', 'Connector'],
9
9
  ['model_used', 'Model'],
10
10
  ['blocked_reason', 'Blocked reason'],
11
+ ['next_action', 'Next action'],
11
12
  ['headline', 'Headline'],
12
13
  ['inheritable', 'Inheritance snapshot'],
13
14
  ];
@@ -125,6 +126,9 @@ function normalizeRunEntry(entry) {
125
126
  connector_used: entry.connector_used || null,
126
127
  model_used: entry.model_used || null,
127
128
  blocked_reason: entry.blocked_reason || null,
129
+ next_action: entry.retrospective?.next_operator_action
130
+ || entry.retrospective?.follow_on_hint
131
+ || null,
128
132
  headline: entry.retrospective?.headline || null,
129
133
  inheritable: isInheritable(entry),
130
134
  total_turns: typeof entry.total_turns === 'number' ? entry.total_turns : null,
@@ -0,0 +1,222 @@
1
+ function normalizeMcpTransport(runtime) {
2
+ return typeof runtime?.transport === 'string' && runtime.transport.trim()
3
+ ? runtime.transport.trim()
4
+ : 'stdio';
5
+ }
6
+
7
+ export function getRuntimeCapabilityContract(runtime = {}) {
8
+ switch (runtime?.type) {
9
+ case 'manual':
10
+ return {
11
+ runtime_type: 'manual',
12
+ transport: 'manual',
13
+ can_write_files: 'direct',
14
+ review_only_behavior: 'Manual review roles may create planning and review artifacts without claiming automated repo writes.',
15
+ proposal_support: 'none',
16
+ requires_local_binary: false,
17
+ workflow_artifact_ownership: 'yes',
18
+ };
19
+
20
+ case 'local_cli':
21
+ return {
22
+ runtime_type: 'local_cli',
23
+ transport: 'local_cli',
24
+ can_write_files: 'direct',
25
+ review_only_behavior: 'Review-only bindings are invalid because local_cli exposes direct repo writes.',
26
+ proposal_support: 'optional',
27
+ requires_local_binary: true,
28
+ workflow_artifact_ownership: 'yes',
29
+ };
30
+
31
+ case 'api_proxy':
32
+ return {
33
+ runtime_type: 'api_proxy',
34
+ transport: 'provider_api',
35
+ can_write_files: 'proposal_only',
36
+ review_only_behavior: 'Review-only turns return structured review artifacts only; they do not write repo files directly.',
37
+ proposal_support: 'native',
38
+ requires_local_binary: false,
39
+ workflow_artifact_ownership: 'proposal_apply_required',
40
+ };
41
+
42
+ case 'remote_agent':
43
+ return {
44
+ runtime_type: 'remote_agent',
45
+ transport: 'remote_http',
46
+ can_write_files: 'proposal_only',
47
+ review_only_behavior: 'Review-only turns return JSON review results only; there is no proven local workspace write path.',
48
+ proposal_support: 'native',
49
+ requires_local_binary: false,
50
+ workflow_artifact_ownership: 'proposal_apply_required',
51
+ };
52
+
53
+ case 'mcp': {
54
+ const transport = normalizeMcpTransport(runtime) === 'streamable_http'
55
+ ? 'mcp_streamable_http'
56
+ : 'mcp_stdio';
57
+ return {
58
+ runtime_type: 'mcp',
59
+ transport,
60
+ can_write_files: 'tool_defined',
61
+ review_only_behavior: 'Review-only behavior depends on the configured MCP tool contract; AgentXchain only requires a valid governed turn result.',
62
+ proposal_support: 'tool_defined',
63
+ requires_local_binary: transport === 'mcp_stdio',
64
+ workflow_artifact_ownership: 'tool_defined',
65
+ };
66
+ }
67
+
68
+ default:
69
+ return {
70
+ runtime_type: runtime?.type || 'unknown',
71
+ transport: 'unknown',
72
+ can_write_files: 'unknown',
73
+ review_only_behavior: 'Unknown runtime type — capability contract is not defined.',
74
+ proposal_support: 'unknown',
75
+ requires_local_binary: false,
76
+ workflow_artifact_ownership: 'unknown',
77
+ };
78
+ }
79
+ }
80
+
81
+ function appendNote(notes, message) {
82
+ if (!message || notes.includes(message)) return;
83
+ notes.push(message);
84
+ }
85
+
86
+ export function getRoleRuntimeCapabilityContract(roleId, role = {}, runtime = {}) {
87
+ const base = getRuntimeCapabilityContract(runtime);
88
+ const authority = role?.write_authority || 'unknown';
89
+ const notes = [];
90
+ let effectiveWritePath = 'unknown';
91
+ let workflowArtifactOwnership = 'unknown';
92
+
93
+ if (authority === 'review_only') {
94
+ switch (runtime?.type) {
95
+ case 'manual':
96
+ effectiveWritePath = 'planning_only';
97
+ workflowArtifactOwnership = 'yes';
98
+ appendNote(notes, 'Manual review roles can satisfy workflow-kit ownership for planning artifacts.');
99
+ break;
100
+ case 'local_cli':
101
+ effectiveWritePath = 'invalid_review_only_binding';
102
+ workflowArtifactOwnership = 'invalid';
103
+ appendNote(notes, 'review_only + local_cli is invalid because local_cli exposes direct repo writes.');
104
+ break;
105
+ case 'api_proxy':
106
+ case 'remote_agent':
107
+ effectiveWritePath = 'review_artifact_only';
108
+ workflowArtifactOwnership = 'no';
109
+ appendNote(notes, 'Review-only remote turns can attest and produce review artifacts, not workflow-kit files.');
110
+ break;
111
+ case 'mcp':
112
+ effectiveWritePath = 'tool_defined';
113
+ workflowArtifactOwnership = 'tool_defined';
114
+ appendNote(notes, 'MCP review-only file production depends on the configured tool, not runtime type alone.');
115
+ break;
116
+ default:
117
+ effectiveWritePath = 'unknown';
118
+ workflowArtifactOwnership = 'unknown';
119
+ break;
120
+ }
121
+ } else if (authority === 'proposed') {
122
+ switch (runtime?.type) {
123
+ case 'manual':
124
+ case 'local_cli':
125
+ effectiveWritePath = 'patch_authoring';
126
+ workflowArtifactOwnership = 'yes';
127
+ appendNote(notes, 'This role can prepare patch-shaped work while still satisfying workflow-kit artifact ownership.');
128
+ break;
129
+ case 'api_proxy':
130
+ case 'remote_agent':
131
+ effectiveWritePath = 'proposal_apply_required';
132
+ workflowArtifactOwnership = 'proposal_apply_required';
133
+ appendNote(notes, 'Accepted proposals are staged under .agentxchain/proposed and require proposal apply before gate files exist in the repo.');
134
+ break;
135
+ case 'mcp':
136
+ effectiveWritePath = 'tool_defined';
137
+ workflowArtifactOwnership = 'tool_defined';
138
+ appendNote(notes, 'MCP proposed-authoring behavior depends on the governed tool implementation.');
139
+ break;
140
+ default:
141
+ effectiveWritePath = 'unknown';
142
+ workflowArtifactOwnership = 'unknown';
143
+ break;
144
+ }
145
+ } else if (authority === 'authoritative') {
146
+ switch (runtime?.type) {
147
+ case 'manual':
148
+ case 'local_cli':
149
+ effectiveWritePath = 'direct';
150
+ workflowArtifactOwnership = 'yes';
151
+ break;
152
+ case 'api_proxy':
153
+ case 'remote_agent':
154
+ effectiveWritePath = 'invalid_authoritative_binding';
155
+ workflowArtifactOwnership = 'invalid';
156
+ appendNote(notes, `${runtime.type} does not support authoritative roles in v1.`);
157
+ break;
158
+ case 'mcp':
159
+ effectiveWritePath = 'tool_defined';
160
+ workflowArtifactOwnership = 'tool_defined';
161
+ appendNote(notes, 'MCP authoritative repo writes are tool-defined, not guaranteed by runtime type.');
162
+ break;
163
+ default:
164
+ effectiveWritePath = 'unknown';
165
+ workflowArtifactOwnership = 'unknown';
166
+ break;
167
+ }
168
+ }
169
+
170
+ return {
171
+ role_id: roleId,
172
+ role_write_authority: authority,
173
+ effective_write_path: effectiveWritePath,
174
+ workflow_artifact_ownership: workflowArtifactOwnership,
175
+ notes,
176
+ runtime_contract: base,
177
+ };
178
+ }
179
+
180
+ export function canRoleParticipateInRequiredFileProduction(role = {}, runtime = {}) {
181
+ const contract = getRoleRuntimeCapabilityContract('__admission__', role, runtime);
182
+ switch (contract.effective_write_path) {
183
+ case 'direct':
184
+ case 'planning_only':
185
+ case 'patch_authoring':
186
+ case 'proposal_apply_required':
187
+ case 'tool_defined':
188
+ return true;
189
+ default:
190
+ return false;
191
+ }
192
+ }
193
+
194
+ export function canRoleSatisfyWorkflowArtifactOwnership(role = {}, runtime = {}) {
195
+ const contract = getRoleRuntimeCapabilityContract('__ownership__', role, runtime);
196
+ switch (contract.workflow_artifact_ownership) {
197
+ case 'yes':
198
+ case 'proposal_apply_required':
199
+ case 'tool_defined':
200
+ return true;
201
+ default:
202
+ return false;
203
+ }
204
+ }
205
+
206
+ export function summarizeRuntimeCapabilityContract(contract) {
207
+ return [
208
+ `transport=${contract.transport}`,
209
+ `writes=${contract.can_write_files}`,
210
+ `proposals=${contract.proposal_support}`,
211
+ `owned_by=${contract.workflow_artifact_ownership}`,
212
+ `binary=${contract.requires_local_binary ? 'yes' : 'no'}`,
213
+ ].join('; ');
214
+ }
215
+
216
+ export function summarizeRoleRuntimeCapability(contract) {
217
+ return [
218
+ `${contract.role_id}(${contract.role_write_authority})`,
219
+ `path=${contract.effective_write_path}`,
220
+ `owned_by=${contract.workflow_artifact_ownership}`,
221
+ ].join('; ');
222
+ }