agentxchain 2.134.0 → 2.134.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentxchain",
3
- "version": "2.134.0",
3
+ "version": "2.134.1",
4
4
  "description": "CLI for AgentXchain — governed multi-agent software delivery",
5
5
  "type": "module",
6
6
  "bin": {
@@ -88,7 +88,10 @@ function printEvent(evt) {
88
88
  const coordinatorRetryDetail = evt.event_type === 'coordinator_retry' && evt.payload
89
89
  ? ` — ws ${evt.payload.workstream_id || '?'} repo ${evt.payload.repo_id || '?'} (retry of ${evt.payload.failed_turn_id || '?'})`
90
90
  : '';
91
- console.log(`${chalk.dim(ts)} ${type} ${chalk.cyan(runId)} ${phase}${turnInfo}${intentInfo}${conflictDetail}${conflictResolvedDetail}${rejectionDetail}${acceptanceFailedDetail}${phaseTransitionDetail}${gateFailedDetail}${humanEscalationDetail}${coordinatorRetryDetail}`);
91
+ const projectionWarningDetail = evt.event_type === 'coordinator_retry_projection_warning' && evt.payload
92
+ ? ` — ws ${evt.payload.workstream_id || '?'} repo ${evt.payload.repo_id || '?'} (reconciliation required)`
93
+ : '';
94
+ console.log(`${chalk.dim(ts)} ${type} ${chalk.cyan(runId)} ${phase}${turnInfo}${intentInfo}${conflictDetail}${conflictResolvedDetail}${rejectionDetail}${acceptanceFailedDetail}${phaseTransitionDetail}${gateFailedDetail}${humanEscalationDetail}${coordinatorRetryDetail}${projectionWarningDetail}`);
92
95
  }
93
96
 
94
97
  function formatConflictDetail(evt) {
@@ -150,6 +153,7 @@ function colorEventType(type) {
150
153
  gate_failed: chalk.red,
151
154
  budget_exceeded_warn: chalk.yellowBright,
152
155
  coordinator_retry: chalk.cyan.bold,
156
+ coordinator_retry_projection_warning: chalk.yellow.bold,
153
157
  turn_checkpointed: chalk.green,
154
158
  dispatch_progress: chalk.blue.dim,
155
159
  };
@@ -38,6 +38,7 @@ import { executeGovernedRun } from './run.js';
38
38
  import { dispatchCoordinatorTurn, selectAssignmentForWorkstream } from '../lib/coordinator-dispatch.js';
39
39
  import { loadCoordinatorState } from '../lib/coordinator-state.js';
40
40
  import { projectRepoAcceptance } from '../lib/coordinator-acceptance.js';
41
+ import { emitRunEvent } from '../lib/run-events.js';
41
42
 
42
43
  export async function missionStartCommand(opts) {
43
44
  const root = findProjectRoot(opts.dir || process.cwd());
@@ -182,6 +183,13 @@ function projectAcceptedCoordinatorTurn(workspacePath, coordinatorConfig, repoId
182
183
  );
183
184
  }
184
185
 
186
+ function buildCoordinatorProjectionWarning(message) {
187
+ return {
188
+ code: 'coordinator_acceptance_projection_incomplete',
189
+ message,
190
+ };
191
+ }
192
+
185
193
  export async function missionListCommand(opts) {
186
194
  const root = findProjectRoot(opts.dir || process.cwd());
187
195
  if (!root) {
@@ -634,6 +642,7 @@ export async function missionPlanLaunchCommand(planTarget, opts) {
634
642
  };
635
643
 
636
644
  let execution;
645
+ const retryWarnings = [];
637
646
  try {
638
647
  execution = await executor(repoContext, runOpts);
639
648
  } catch (error) {
@@ -669,7 +678,21 @@ export async function missionPlanLaunchCommand(planTarget, opts) {
669
678
  loadCoordinatorState(mission.coordinator.workspace_path),
670
679
  );
671
680
  if (!projection.ok) {
672
- console.error(chalk.yellow(`Coordinator retry projection warning: ${projection.error}`));
681
+ const warning = buildCoordinatorProjectionWarning(projection.error);
682
+ retryWarnings.push(warning);
683
+ console.error(chalk.yellow(`Coordinator retry projection warning: ${warning.message}`));
684
+ emitRunEvent(mission.coordinator.workspace_path, 'coordinator_retry_projection_warning', {
685
+ run_id: mission.coordinator.super_run_id,
686
+ phase: coordinatorConfigResult.config?.workstreams?.[opts.workstream]?.phase || null,
687
+ status: 'active',
688
+ payload: {
689
+ workstream_id: opts.workstream,
690
+ repo_id: retry.retryResult.repo_id,
691
+ reissued_turn_id: retry.retryResult.reissued_turn_id,
692
+ warning_code: warning.code,
693
+ warning_message: warning.message,
694
+ },
695
+ });
673
696
  }
674
697
  }
675
698
 
@@ -697,6 +720,8 @@ export async function missionPlanLaunchCommand(planTarget, opts) {
697
720
  workstream_status: retriedWorkstream?.launch_status || 'launched',
698
721
  launch_record: retriedLaunchRecord,
699
722
  exit_code: execution?.exitCode ?? 0,
723
+ warnings: retryWarnings,
724
+ reconciliation_required: retryWarnings.length > 0,
700
725
  }, null, 2));
701
726
  if ((execution?.exitCode ?? 0) !== 0) {
702
727
  process.exit(execution.exitCode);
@@ -713,6 +738,9 @@ export async function missionPlanLaunchCommand(planTarget, opts) {
713
738
  console.log(chalk.dim(` Old Turn: ${retry.retryResult.failed_turn_id}`));
714
739
  console.log(chalk.dim(` New Turn: ${retry.retryResult.reissued_turn_id}`));
715
740
  console.log(chalk.dim(` Workstream: ${retriedWorkstream?.launch_status || 'launched'}`));
741
+ if (retryWarnings.length > 0) {
742
+ console.log(chalk.yellow(` Warning: ${retryWarnings[0].message}`));
743
+ }
716
744
  console.log('');
717
745
  renderPlan(retriedPlan);
718
746
  if ((execution?.exitCode ?? 0) !== 0) {
@@ -24,6 +24,7 @@ import { getDashboardPid, getDashboardSession } from './dashboard.js';
24
24
  import { readPreemptionMarker, findPendingApprovedIntents } from '../lib/intake.js';
25
25
  import { readContinuousSession } from '../lib/continuous-run.js';
26
26
  import { readAllDispatchProgress } from '../lib/dispatch-progress.js';
27
+ import { readCoordinatorWarnings } from '../lib/coordinator-warnings.js';
27
28
 
28
29
  export async function statusCommand(opts) {
29
30
  const context = loadStatusContext();
@@ -111,10 +112,22 @@ function loadStatusContext(dir = process.cwd()) {
111
112
  return null;
112
113
  }
113
114
 
115
+ const fallbackConfig = {
116
+ ...rawConfig,
117
+ files: {
118
+ talk: rawConfig.files?.talk || 'TALK.md',
119
+ history: rawConfig.files?.history || '.agentxchain/history.jsonl',
120
+ state: rawConfig.files?.state || '.agentxchain/state.json',
121
+ log: Object.prototype.hasOwnProperty.call(rawConfig.files || {}, 'log')
122
+ ? rawConfig.files.log
123
+ : null,
124
+ },
125
+ };
126
+
114
127
  return {
115
128
  root,
116
129
  rawConfig,
117
- config: rawConfig,
130
+ config: fallbackConfig,
118
131
  version: 4,
119
132
  };
120
133
  }
@@ -122,6 +135,7 @@ function loadStatusContext(dir = process.cwd()) {
122
135
  function renderGovernedStatus(context, opts) {
123
136
  const { root, config, version } = context;
124
137
  const state = loadProjectState(root, config);
138
+ const stateRunId = state?.run_id || readRawStateRunId(root, config);
125
139
  const continuity = getContinuityStatus(root, state);
126
140
  const connectorHealth = getConnectorHealth(root, config, state);
127
141
  const recovery = deriveRecoveryDescriptor(state, config);
@@ -147,6 +161,9 @@ function renderGovernedStatus(context, opts) {
147
161
  const activeTurns = getActiveTurns(state);
148
162
  const dispatchProgress = filterDispatchProgressForActiveTurns(readAllDispatchProgress(root), activeTurns);
149
163
 
164
+ // Coordinator warning surfacing — DEC-COORD-RETRY-PROJECTION-EVENT-001
165
+ const coordinatorWarnings = readCoordinatorWarnings(root, { runId: stateRunId || null });
166
+
150
167
  if (opts.json) {
151
168
  const dashPid = getDashboardPid(root);
152
169
  const dashSession = getDashboardSession(root);
@@ -183,6 +200,7 @@ function renderGovernedStatus(context, opts) {
183
200
  dashboard_session: dashboardSessionObj,
184
201
  binding_drift: detectActiveTurnBindingDrift(state, config),
185
202
  bundle_integrity: detectStateBundleDesync(root, state),
203
+ coordinator_warnings: coordinatorWarnings,
186
204
  }, null, 2));
187
205
  return;
188
206
  }
@@ -284,6 +302,7 @@ function renderGovernedStatus(context, opts) {
284
302
  renderContinuityStatus(continuity, state);
285
303
  renderConnectorHealthStatus(connectorHealth);
286
304
  renderRecentEventSummary(recentEventSummary);
305
+ renderCoordinatorWarnings(coordinatorWarnings);
287
306
 
288
307
  // BUG-18: State/bundle integrity check
289
308
  const desync = detectStateBundleDesync(root, state);
@@ -908,3 +927,37 @@ function formatUsd(value) {
908
927
  if (typeof value !== 'number' || Number.isNaN(value)) return '0.00';
909
928
  return value.toFixed(2);
910
929
  }
930
+
931
+ /**
932
+ * Read coordinator retry projection warnings from the event log.
933
+ * Returns a structured summary for both JSON and CLI output.
934
+ */
935
+ function renderCoordinatorWarnings(warnings) {
936
+ if (!warnings || warnings.count === 0) return;
937
+ console.log(chalk.yellow.bold(` ⚠ Coordinator reconciliation required (${warnings.count} projection warning${warnings.count !== 1 ? 's' : ''})`));
938
+ for (const w of warnings.warnings) {
939
+ const wsLabel = w.workstream_id ? `ws:${w.workstream_id}` : '';
940
+ const repoLabel = w.repo_id ? `repo:${w.repo_id}` : '';
941
+ const parts = [wsLabel, repoLabel].filter(Boolean).join(' ');
942
+ console.log(` ${chalk.yellow('●')} ${parts} — ${w.warning_code}`);
943
+ }
944
+ console.log(chalk.dim(' Run `agentxchain mission plan show latest --json` to force plan sync and verify.'));
945
+ console.log('');
946
+ }
947
+
948
+ function readRawStateRunId(root, config) {
949
+ const relPath = config?.files?.state || '.agentxchain/state.json';
950
+ const filePath = join(root, relPath);
951
+ if (!existsSync(filePath)) {
952
+ return null;
953
+ }
954
+
955
+ try {
956
+ const parsed = JSON.parse(readFileSync(filePath, 'utf8'));
957
+ return typeof parsed?.run_id === 'string' && parsed.run_id.trim().length > 0
958
+ ? parsed.run_id.trim()
959
+ : null;
960
+ } catch {
961
+ return null;
962
+ }
963
+ }
@@ -0,0 +1,31 @@
1
+ import { readRunEvents } from './run-events.js';
2
+
3
+ function normalizeCoordinatorWarning(event) {
4
+ return {
5
+ event_id: event.event_id,
6
+ timestamp: event.timestamp,
7
+ run_id: event.run_id || null,
8
+ workstream_id: event.payload?.workstream_id || null,
9
+ repo_id: event.payload?.repo_id || null,
10
+ reissued_turn_id: event.payload?.reissued_turn_id || null,
11
+ warning_code: event.payload?.warning_code || 'coordinator_acceptance_projection_incomplete',
12
+ warning_message: event.payload?.warning_message || null,
13
+ };
14
+ }
15
+
16
+ export function readCoordinatorWarnings(root, { runId = null } = {}) {
17
+ const events = readRunEvents(root, { type: 'coordinator_retry_projection_warning' });
18
+ const filtered = runId
19
+ ? events.filter((event) => event.run_id === runId)
20
+ : events;
21
+
22
+ if (filtered.length === 0) {
23
+ return { count: 0, reconciliation_required: false, warnings: [] };
24
+ }
25
+
26
+ return {
27
+ count: filtered.length,
28
+ reconciliation_required: true,
29
+ warnings: filtered.map(normalizeCoordinatorWarning),
30
+ };
31
+ }
@@ -7,6 +7,8 @@
7
7
 
8
8
  import { buildPlanProgressSummary, loadAllPlans } from '../mission-plans.js';
9
9
  import { loadAllMissionArtifacts } from '../missions.js';
10
+ import { loadCoordinatorState } from '../coordinator-state.js';
11
+ import { readCoordinatorWarnings } from '../coordinator-warnings.js';
10
12
 
11
13
  /**
12
14
  * Build a dashboard-ready plan snapshot across all missions.
@@ -49,12 +51,19 @@ export function readPlanSnapshot(workspacePath, { limit, missionId } = {}) {
49
51
  latestSummary = buildPlanSummary(latest);
50
52
  }
51
53
 
54
+ // Surface coordinator projection warnings for dashboard consumers
55
+ const coordinatorState = loadCoordinatorState(workspacePath);
56
+ const coordinatorWarnings = readCoordinatorWarnings(workspacePath, {
57
+ runId: coordinatorState?.super_run_id || null,
58
+ });
59
+
52
60
  return {
53
61
  ok: true,
54
62
  status: 200,
55
63
  body: {
56
64
  latest: latestSummary,
57
65
  plans: plans.map(buildPlanSummary),
66
+ coordinator_warnings: coordinatorWarnings,
58
67
  },
59
68
  };
60
69
  }
@@ -47,6 +47,11 @@ function describeEvent(eventType, entry) {
47
47
  const retryRepo = trimToNull(entry.payload?.repo_id);
48
48
  return `${prefix}${eventType}${wsId ? ` ${wsId}` : ''}${retryRepo ? ` (${retryRepo})` : ''}`;
49
49
  }
50
+ case 'coordinator_retry_projection_warning': {
51
+ const wsIdWarn = trimToNull(entry.payload?.workstream_id);
52
+ const warnRepo = trimToNull(entry.payload?.repo_id);
53
+ return `${prefix}${eventType}${wsIdWarn ? ` ${wsIdWarn}` : ''}${warnRepo ? ` (${warnRepo})` : ''} — reconciliation required`;
54
+ }
50
55
  case 'turn_checkpointed':
51
56
  return `${prefix}${eventType}${roleId ? ` [${roleId}]` : ''}`;
52
57
  case 'dispatch_progress':
@@ -23,6 +23,7 @@ export const VALID_RUN_EVENTS = [
23
23
  'turn_reissued',
24
24
  'turn_checkpointed',
25
25
  'coordinator_retry',
26
+ 'coordinator_retry_projection_warning',
26
27
  'run_blocked',
27
28
  'run_completed',
28
29
  'escalation_raised',