agentxchain 2.74.0 → 2.75.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/dashboard/app.js CHANGED
@@ -19,7 +19,7 @@ import { render as renderTimeouts } from './components/timeouts.js';
19
19
  import { render as renderCoordinatorTimeouts } from './components/coordinator-timeouts.js';
20
20
 
21
21
  const VIEWS = {
22
- timeline: { fetch: ['state', 'continuity', 'history', 'audit', 'annotations', 'connectors'], render: renderTimeline },
22
+ timeline: { fetch: ['state', 'continuity', 'history', 'audit', 'annotations', 'connectors', 'coordinatorAudit', 'coordinatorAnnotations'], render: renderTimeline },
23
23
  ledger: { fetch: ['state', 'ledger', 'coordinatorState', 'coordinatorLedger'], render: renderLedger },
24
24
  hooks: { fetch: ['audit', 'annotations', 'coordinatorAudit', 'coordinatorAnnotations'], render: renderHooks },
25
25
  blocked: { fetch: ['state', 'audit', 'coordinatorState', 'coordinatorAudit'], render: renderBlocked },
@@ -114,52 +114,74 @@ function roleBadge(role) {
114
114
  return `<span class="badge" style="color:${color};border-color:${color}">${esc(role)}</span>`;
115
115
  }
116
116
 
117
- function renderTurnDetailPanel(turnId, annotations, audit) {
117
+ function renderAuditSection(title, auditEntries) {
118
+ if (auditEntries.length === 0) return '';
119
+ let html = `<div class="turn-detail"><span class="detail-label">${esc(title)} (${auditEntries.length}):</span>
120
+ <table class="data-table">
121
+ <thead><tr><th>Phase</th><th>Hook</th><th>Verdict</th></tr></thead>
122
+ <tbody>`;
123
+ for (const entry of auditEntries) {
124
+ const phase = entry.hook_phase || entry.phase || '';
125
+ const hook = entry.hook_name || entry.hook || entry.name || '';
126
+ html += `<tr>
127
+ <td class="mono">${esc(phase)}</td>
128
+ <td>${esc(hook)}</td>
129
+ <td>${esc(entry.verdict || '')}</td>
130
+ </tr>`;
131
+ }
132
+ html += `</tbody></table></div>`;
133
+ return html;
134
+ }
135
+
136
+ function renderAnnotationSection(title, annotationEntries) {
137
+ if (annotationEntries.length === 0) return '';
138
+ let html = `<div class="turn-detail"><span class="detail-label">${esc(title)} (${annotationEntries.length}):</span><ul>`;
139
+ for (const ann of annotationEntries) {
140
+ const hookName = ann.hook_name || ann.hook || ann.name || '';
141
+ if (Array.isArray(ann.annotations)) {
142
+ for (const a of ann.annotations) {
143
+ html += `<li>${esc(hookName)}: ${esc(a.key || '')} = ${esc(a.value || '')}</li>`;
144
+ }
145
+ } else {
146
+ const text = ann.annotation || ann.message || '';
147
+ html += `<li>${esc(hookName)}: ${esc(text)}</li>`;
148
+ }
149
+ }
150
+ html += `</ul></div>`;
151
+ return html;
152
+ }
153
+
154
+ function renderTurnDetailPanel(turnId, annotations, audit, coordinatorAnnotations, coordinatorAudit) {
118
155
  const turnAnnotations = Array.isArray(annotations)
119
156
  ? annotations.filter((a) => a.turn_id === turnId)
120
157
  : [];
121
158
  const turnAudit = Array.isArray(audit)
122
159
  ? audit.filter((a) => a.turn_id === turnId)
123
160
  : [];
161
+ const turnCoordAnnotations = Array.isArray(coordinatorAnnotations)
162
+ ? coordinatorAnnotations.filter((a) => a.turn_id === turnId)
163
+ : [];
164
+ const turnCoordAudit = Array.isArray(coordinatorAudit)
165
+ ? coordinatorAudit.filter((a) => a.turn_id === turnId)
166
+ : [];
167
+
168
+ const hasRepo = turnAnnotations.length > 0 || turnAudit.length > 0;
169
+ const hasCoord = turnCoordAnnotations.length > 0 || turnCoordAudit.length > 0;
124
170
 
125
- if (turnAnnotations.length === 0 && turnAudit.length === 0) {
171
+ if (!hasRepo && !hasCoord) {
126
172
  return `<div class="turn-detail-panel"><p class="turn-detail">No hook evidence for this turn.</p></div>`;
127
173
  }
128
174
 
175
+ const dual = hasRepo && hasCoord;
129
176
  let html = `<div class="turn-detail-panel">`;
130
177
 
131
- if (turnAudit.length > 0) {
132
- html += `<div class="turn-detail"><span class="detail-label">Hook Audit (${turnAudit.length}):</span>
133
- <table class="data-table">
134
- <thead><tr><th>Phase</th><th>Hook</th><th>Verdict</th></tr></thead>
135
- <tbody>`;
136
- for (const entry of turnAudit) {
137
- const phase = entry.hook_phase || entry.phase || '';
138
- const hook = entry.hook_name || entry.hook || entry.name || '';
139
- html += `<tr>
140
- <td class="mono">${esc(phase)}</td>
141
- <td>${esc(hook)}</td>
142
- <td>${esc(entry.verdict || '')}</td>
143
- </tr>`;
144
- }
145
- html += `</tbody></table></div>`;
146
- }
178
+ // Repo-local hook evidence
179
+ html += renderAuditSection(dual ? 'Repo Hook Audit Log' : 'Hook Audit Log', turnAudit);
180
+ html += renderAnnotationSection(dual ? 'Repo Hook Annotations' : 'Hook Annotations', turnAnnotations);
147
181
 
148
- if (turnAnnotations.length > 0) {
149
- html += `<div class="turn-detail"><span class="detail-label">Annotations (${turnAnnotations.length}):</span><ul>`;
150
- for (const ann of turnAnnotations) {
151
- const hookName = ann.hook_name || ann.hook || ann.name || '';
152
- if (Array.isArray(ann.annotations)) {
153
- for (const a of ann.annotations) {
154
- html += `<li>${esc(hookName)}: ${esc(a.key || '')} = ${esc(a.value || '')}</li>`;
155
- }
156
- } else {
157
- const text = ann.annotation || ann.message || '';
158
- html += `<li>${esc(hookName)}: ${esc(text)}</li>`;
159
- }
160
- }
161
- html += `</ul></div>`;
162
- }
182
+ // Coordinator hook evidence
183
+ html += renderAuditSection(dual ? 'Coordinator Hook Audit Log' : 'Hook Audit Log', turnCoordAudit);
184
+ html += renderAnnotationSection(dual ? 'Coordinator Hook Annotations' : 'Hook Annotations', turnCoordAnnotations);
163
185
 
164
186
  html += `</div>`;
165
187
  return html;
@@ -265,7 +287,7 @@ function renderConnectorHealthPanel(connectorsPayload) {
265
287
 
266
288
  export { formatDuration, computeElapsed, formatTimestamp };
267
289
 
268
- export function render({ state, continuity, history, annotations, audit, connectors }) {
290
+ export function render({ state, continuity, history, annotations, audit, connectors, coordinatorAudit = null, coordinatorAnnotations = null }) {
269
291
  if (!state) {
270
292
  return `<div class="placeholder"><h2>No Run</h2><p>No governed run found. Start one with <code class="mono">agentxchain init --governed</code></p></div>`;
271
293
  }
@@ -353,7 +375,7 @@ export function render({ state, continuity, history, annotations, audit, connect
353
375
  html += `<div class="turn-detail"><span class="detail-label">Verification:</span> ${esc(verificationSummary)}</div>`;
354
376
  }
355
377
 
356
- html += renderTurnDetailPanel(entry.turn_id, annotations, audit);
378
+ html += renderTurnDetailPanel(entry.turn_id, annotations, audit, coordinatorAnnotations, coordinatorAudit);
357
379
 
358
380
  html += `</div>`;
359
381
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentxchain",
3
- "version": "2.74.0",
3
+ "version": "2.75.0",
4
4
  "description": "CLI for AgentXchain — governed multi-agent software delivery",
5
5
  "type": "module",
6
6
  "bin": {