agentxchain 2.54.0 → 2.55.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.
@@ -68,6 +68,14 @@ function truncateId(id, len = 12) {
68
68
  return id.length > len ? id.slice(0, len) + '…' : id;
69
69
  }
70
70
 
71
+ function isInheritable(entry) {
72
+ const snap = entry?.inheritance_snapshot;
73
+ if (!snap) return false;
74
+ const hasDecisions = Array.isArray(snap.recent_decisions) && snap.recent_decisions.length > 0;
75
+ const hasTurns = Array.isArray(snap.recent_accepted_turns) && snap.recent_accepted_turns.length > 0;
76
+ return hasDecisions || hasTurns;
77
+ }
78
+
71
79
  function renderRow(entry, index) {
72
80
  const rowClass = entry.status === 'blocked'
73
81
  ? ' style="border-left:3px solid var(--yellow)"'
@@ -83,10 +91,15 @@ function renderRow(entry, index) {
83
91
  ? `<div class="blocked-hint" style="font-size:0.85em;color:var(--yellow);margin-top:2px">${esc(typeof entry.blocked_reason === 'string' ? entry.blocked_reason : entry.blocked_reason?.detail || entry.blocked_reason?.category || '')}</div>`
84
92
  : '';
85
93
 
94
+ const ctxIndicator = isInheritable(entry)
95
+ ? `<span title="Has inheritance snapshot — usable by child runs" style="color:var(--green)">✓</span>`
96
+ : `<span style="color:var(--text-dim)">—</span>`;
97
+
86
98
  return `<tr${rowClass}>
87
99
  <td style="color:var(--text-dim)">${index + 1}</td>
88
100
  <td class="mono" title="${esc(entry.run_id)}">${esc(truncateId(entry.run_id))}</td>
89
101
  <td>${statusBadge(entry.status)}${blockedInfo}</td>
102
+ <td>${ctxIndicator}</td>
90
103
  <td>${phases}</td>
91
104
  <td>${entry.total_turns ?? '—'}</td>
92
105
  <td>${formatCost(entry.total_cost_usd)}</td>
@@ -125,6 +138,7 @@ export function render({ runHistory }) {
125
138
  <th>#</th>
126
139
  <th>Run ID</th>
127
140
  <th>Status</th>
141
+ <th>Ctx</th>
128
142
  <th>Phases</th>
129
143
  <th>Turns</th>
130
144
  <th>Cost</th>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentxchain",
3
- "version": "2.54.0",
3
+ "version": "2.55.0",
4
4
  "description": "CLI for AgentXchain — governed multi-agent software delivery",
5
5
  "type": "module",
6
6
  "bin": {
@@ -7,7 +7,7 @@
7
7
  import { resolve } from 'path';
8
8
  import { existsSync, readFileSync } from 'fs';
9
9
  import chalk from 'chalk';
10
- import { queryRunHistory, queryRunLineage } from '../lib/run-history.js';
10
+ import { queryRunHistory, queryRunLineage, isInheritable } from '../lib/run-history.js';
11
11
  import { getRunTriggerLabel, summarizeRunProvenance } from '../lib/run-provenance.js';
12
12
 
13
13
  /**
@@ -46,11 +46,12 @@ export async function historyCommand(opts) {
46
46
  const turns = `${entry.total_turns || 0} turns`;
47
47
  const cost = entry.total_cost_usd != null ? `$${entry.total_cost_usd.toFixed(2)}` : '';
48
48
  const trigger = getRunTriggerLabel(entry.provenance);
49
+ const ctxMarker = isInheritable(entry) ? ' [ctx]' : '';
49
50
  const parentNote = entry.provenance?.parent_run_id
50
51
  ? ` from ${entry.provenance.parent_run_id.slice(0, 12)}`
51
52
  : '';
52
53
  const prefix = i === 0 ? ' ' : ' └─ ';
53
- console.log(`${prefix}${runId} ${status} ${pad(phases, 20)} ${pad(turns, 10)} ${pad(cost, 8)} (${trigger}${parentNote})`);
54
+ console.log(`${prefix}${runId} ${status} ${pad(phases, 20)} ${pad(turns, 10)} ${pad(cost, 8)} (${trigger}${parentNote})${ctxMarker}`);
54
55
  });
55
56
  return;
56
57
  }
@@ -63,7 +64,8 @@ export async function historyCommand(opts) {
63
64
  });
64
65
 
65
66
  if (opts.json) {
66
- console.log(JSON.stringify(entries, null, 2));
67
+ const enriched = entries.map(e => ({ ...e, inheritable: isInheritable(e) }));
68
+ console.log(JSON.stringify(enriched, null, 2));
67
69
  return;
68
70
  }
69
71
 
@@ -81,6 +83,7 @@ export async function historyCommand(opts) {
81
83
  pad('Run ID', 14),
82
84
  pad('Status', 11),
83
85
  pad('Trigger', 14),
86
+ pad('Ctx', 4),
84
87
  pad('Phases', 8),
85
88
  pad('Turns', 6),
86
89
  pad('Cost', 10),
@@ -96,6 +99,7 @@ export async function historyCommand(opts) {
96
99
  const runId = (entry.run_id || '—').slice(0, 12);
97
100
  const status = formatStatus(entry.status);
98
101
  const trigger = getRunTriggerLabel(entry.provenance);
102
+ const ctx = isInheritable(entry) ? '✓' : '—';
99
103
  const phases = String(entry.phases_completed?.length || 0);
100
104
  const turns = String(entry.total_turns || 0);
101
105
  const cost = entry.total_cost_usd != null
@@ -113,6 +117,7 @@ export async function historyCommand(opts) {
113
117
  pad(runId, 14),
114
118
  pad(status, 11),
115
119
  pad(trigger, 14),
120
+ pad(ctx, 4),
116
121
  pad(phases, 8),
117
122
  pad(turns, 6),
118
123
  pad(cost, 10),
@@ -249,6 +249,21 @@ export function validateParentRun(root, runId) {
249
249
  return { ok: true, entry };
250
250
  }
251
251
 
252
+ /**
253
+ * Check whether a run-history entry has a usable inheritance snapshot
254
+ * (at least one decision or one accepted turn available for child runs).
255
+ *
256
+ * @param {object} entry - a run-history record
257
+ * @returns {boolean}
258
+ */
259
+ export function isInheritable(entry) {
260
+ const snap = entry?.inheritance_snapshot;
261
+ if (!snap) return false;
262
+ const hasDecisions = Array.isArray(snap.recent_decisions) && snap.recent_decisions.length > 0;
263
+ const hasTurns = Array.isArray(snap.recent_accepted_turns) && snap.recent_accepted_turns.length > 0;
264
+ return hasDecisions || hasTurns;
265
+ }
266
+
252
267
  /**
253
268
  * Get the path to the run-history file.
254
269
  */