vericify 1.0.1 → 1.1.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/package.json +1 -1
- package/src/adapters/index.js +63 -1
- package/src/adapters/local-state.js +56 -22
- package/src/adapters/peer-capture.js +285 -0
- package/src/adapters/provenance.js +70 -0
- package/src/projection/live-signal.js +627 -0
- package/src/projection/runs.js +185 -30
- package/src/tui/app.js +13 -2
- package/src/tui/commands.js +4 -1
- package/src/tui/panels.js +162 -62
- package/src/tui/runtime-activity.js +2 -0
package/src/projection/runs.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
checkpointTriggerFromStatusEvent,
|
|
8
8
|
checkpointTriggerFromWorkspaceSummary,
|
|
9
9
|
} from "../checkpoints/policy.js";
|
|
10
|
+
import { collapseAndScoreActivityItems, compareRunsByAttention, deriveRunLiveSignal } from "./live-signal.js";
|
|
10
11
|
|
|
11
12
|
function sortByUpdatedDescending(items) {
|
|
12
13
|
return [...items].sort((left, right) => String(right.updated_at).localeCompare(String(left.updated_at)));
|
|
@@ -61,6 +62,85 @@ function statusFromProcessPostKind(kind) {
|
|
|
61
62
|
return "running";
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
const OBSERVER_STATUS_EVENT_TYPES = new Set([
|
|
66
|
+
"HUB_RUN_FOCUSED",
|
|
67
|
+
"HUB_VIEW_CHANGED",
|
|
68
|
+
"HUB_REFRESHED",
|
|
69
|
+
"HUB_COMMAND_WRITTEN",
|
|
70
|
+
"HUB_SESSION_STARTED",
|
|
71
|
+
"HUB_SESSION_STOPPED",
|
|
72
|
+
"HUB_SESSION_RESUMED",
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
const OBSERVER_LEDGER_CATEGORIES = new Set([
|
|
76
|
+
"operator_focus",
|
|
77
|
+
"operator_view",
|
|
78
|
+
"operator_refresh",
|
|
79
|
+
"operator_write",
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
const PRIMARY_PROCESS_POST_KINDS = new Set([
|
|
83
|
+
"blocker",
|
|
84
|
+
"completion",
|
|
85
|
+
"handoff_note",
|
|
86
|
+
"operator_note",
|
|
87
|
+
"intervention",
|
|
88
|
+
"stale_ack",
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
function isObserverStatusEvent(event) {
|
|
92
|
+
return event?.payload?.observer_telemetry === true ||
|
|
93
|
+
(event?.source_module === "vericify-hub" && OBSERVER_STATUS_EVENT_TYPES.has(event?.event_type));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function isObserverLedgerEntry(entry) {
|
|
97
|
+
return entry?.metadata?.observer_telemetry === true ||
|
|
98
|
+
(entry?.tool === "vericify-hub" && OBSERVER_LEDGER_CATEGORIES.has(entry?.category));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function recordSourceMetadata(record) {
|
|
102
|
+
return {
|
|
103
|
+
record_source: record.record_source,
|
|
104
|
+
record_source_kind: record.record_source_kind,
|
|
105
|
+
record_source_path: record.record_source_path,
|
|
106
|
+
record_sources: Array.isArray(record.record_sources) ? record.record_sources : [],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function signalPolicyForProcessPost(post) {
|
|
111
|
+
return {
|
|
112
|
+
signal_class: PRIMARY_PROCESS_POST_KINDS.has(post.kind) ? "primary" : "secondary",
|
|
113
|
+
visible_by_default: true,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function signalPolicyForStatusEvent(event) {
|
|
118
|
+
if (isObserverStatusEvent(event)) {
|
|
119
|
+
return {
|
|
120
|
+
signal_class: "background",
|
|
121
|
+
visible_by_default: false,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const normalizedStatus = statusFromEventStatus(event.status);
|
|
125
|
+
return {
|
|
126
|
+
signal_class: normalizedStatus === "blocked" || normalizedStatus === "completed" ? "primary" : "secondary",
|
|
127
|
+
visible_by_default: true,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function signalPolicyForLedgerEntry(entry) {
|
|
132
|
+
if (isObserverLedgerEntry(entry)) {
|
|
133
|
+
return {
|
|
134
|
+
signal_class: "background",
|
|
135
|
+
visible_by_default: false,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
signal_class: entry.category === "regression" ? "primary" : "secondary",
|
|
140
|
+
visible_by_default: true,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
64
144
|
function humanizeToken(value) {
|
|
65
145
|
return String(value ?? "")
|
|
66
146
|
.replace(/[-_]+/g, " ")
|
|
@@ -80,6 +160,8 @@ function activityItemFromProcessPost(post) {
|
|
|
80
160
|
status: statusFromProcessPostKind(post.kind),
|
|
81
161
|
summary: post.summary,
|
|
82
162
|
refs: unique([...asArray(post.evidence_refs), ...asArray(post.tool_refs)]),
|
|
163
|
+
...recordSourceMetadata(post),
|
|
164
|
+
...signalPolicyForProcessPost(post),
|
|
83
165
|
};
|
|
84
166
|
}
|
|
85
167
|
|
|
@@ -96,6 +178,8 @@ function activityItemFromStatusEvent(runId, event) {
|
|
|
96
178
|
status: statusFromEventStatus(event.status),
|
|
97
179
|
summary: event.payload?.summary ?? event.event_type,
|
|
98
180
|
refs: asArray(event.payload?.evidence_ref),
|
|
181
|
+
...recordSourceMetadata(event),
|
|
182
|
+
...signalPolicyForStatusEvent(event),
|
|
99
183
|
};
|
|
100
184
|
}
|
|
101
185
|
|
|
@@ -112,6 +196,8 @@ function activityItemFromLedgerEntry(runId, entry) {
|
|
|
112
196
|
status: statusFromLedgerCategory(entry.category),
|
|
113
197
|
summary: entry.message,
|
|
114
198
|
refs: asArray(entry.artifacts),
|
|
199
|
+
...recordSourceMetadata(entry),
|
|
200
|
+
...signalPolicyForLedgerEntry(entry),
|
|
115
201
|
};
|
|
116
202
|
}
|
|
117
203
|
|
|
@@ -140,6 +226,12 @@ function activityItemFromLaneHeartbeat(runDetail, lane, latestActivity) {
|
|
|
140
226
|
status: lane.status,
|
|
141
227
|
summary: summarizeLaneHeartbeat(lane, latestActivity),
|
|
142
228
|
refs: latestActivity?.refs ?? [],
|
|
229
|
+
record_source: "derived",
|
|
230
|
+
record_source_kind: "lane_heartbeat",
|
|
231
|
+
record_source_path: undefined,
|
|
232
|
+
record_sources: [],
|
|
233
|
+
signal_class: "continuity",
|
|
234
|
+
visible_by_default: false,
|
|
143
235
|
};
|
|
144
236
|
}
|
|
145
237
|
|
|
@@ -227,7 +319,7 @@ function deltaBetween(left, right, id) {
|
|
|
227
319
|
};
|
|
228
320
|
}
|
|
229
321
|
|
|
230
|
-
function summarizeRun(run, branches, lanes, nodes, handoffs, checkpoints, neighbors) {
|
|
322
|
+
function summarizeRun(run, branches, lanes, nodes, handoffs, checkpoints, neighbors, liveSignal) {
|
|
231
323
|
const latestCheckpoint = checkpoints[checkpoints.length - 1];
|
|
232
324
|
return {
|
|
233
325
|
run_id: run.run_id,
|
|
@@ -241,6 +333,19 @@ function summarizeRun(run, branches, lanes, nodes, handoffs, checkpoints, neighb
|
|
|
241
333
|
updated_at: run.updated_at,
|
|
242
334
|
similar_runs: neighbors,
|
|
243
335
|
latest_checkpoint: latestCheckpoint,
|
|
336
|
+
attention_class: liveSignal?.attention_class,
|
|
337
|
+
attention_reason: liveSignal?.attention_reason,
|
|
338
|
+
attention_score: liveSignal?.attention_score,
|
|
339
|
+
attention_rank: liveSignal?.attention_rank,
|
|
340
|
+
freshness_class: liveSignal?.freshness_class,
|
|
341
|
+
expected_next_event: liveSignal?.expected_next_event,
|
|
342
|
+
overdue_at: liveSignal?.overdue_at,
|
|
343
|
+
current_actor_id: liveSignal?.current_actor_id,
|
|
344
|
+
waiting_on_actor_id: liveSignal?.waiting_on_actor_id,
|
|
345
|
+
needs_narrative: liveSignal?.needs_narrative,
|
|
346
|
+
recommended_post_kind: liveSignal?.recommended_post_kind,
|
|
347
|
+
signal_confidence: liveSignal?.signal_confidence,
|
|
348
|
+
partner_dependency_class: liveSignal?.partner_dependency_class,
|
|
244
349
|
};
|
|
245
350
|
}
|
|
246
351
|
|
|
@@ -326,16 +431,18 @@ function buildHandoffRun(handoff, workspace) {
|
|
|
326
431
|
}
|
|
327
432
|
|
|
328
433
|
function buildWorkspaceRun(workspaceState, workspace) {
|
|
434
|
+
const meaningfulEvents = workspaceState.statusEvents.filter((event) => !isObserverStatusEvent(event));
|
|
435
|
+
const meaningfulLedger = workspaceState.ledgerEntries.filter((entry) => !isObserverLedgerEntry(entry));
|
|
329
436
|
if (
|
|
330
437
|
workspaceState.todoNodes.length === 0 &&
|
|
331
|
-
|
|
332
|
-
|
|
438
|
+
meaningfulEvents.length === 0 &&
|
|
439
|
+
meaningfulLedger.length === 0 &&
|
|
333
440
|
workspaceState.processPosts.length === 0
|
|
334
441
|
) return null;
|
|
335
442
|
const runId = "workspace:current";
|
|
336
443
|
const branchId = `${runId}:main`;
|
|
337
|
-
const activeEvents =
|
|
338
|
-
const activeLedger =
|
|
444
|
+
const activeEvents = meaningfulEvents.slice(-25);
|
|
445
|
+
const activeLedger = meaningfulLedger.slice(-12);
|
|
339
446
|
const activePosts = workspaceState.processPosts.slice(-12);
|
|
340
447
|
const laneMap = new Map();
|
|
341
448
|
for (const event of activeEvents) {
|
|
@@ -402,11 +509,16 @@ function buildWorkspaceRun(workspaceState, workspace) {
|
|
|
402
509
|
title: "Workspace Current",
|
|
403
510
|
objective: "Current workspace execution state",
|
|
404
511
|
status: branch.status,
|
|
405
|
-
created_at:
|
|
512
|
+
created_at: firstDefined(
|
|
513
|
+
meaningfulEvents[0]?.timestamp,
|
|
514
|
+
activePosts[0]?.timestamp,
|
|
515
|
+
meaningfulLedger[0]?.timestamp_utc,
|
|
516
|
+
isoNow()
|
|
517
|
+
),
|
|
406
518
|
updated_at: firstDefined(
|
|
407
519
|
workspaceState.processPosts[workspaceState.processPosts.length - 1]?.timestamp,
|
|
408
|
-
|
|
409
|
-
|
|
520
|
+
meaningfulEvents[meaningfulEvents.length - 1]?.timestamp,
|
|
521
|
+
meaningfulLedger[meaningfulLedger.length - 1]?.timestamp_utc,
|
|
410
522
|
isoNow()
|
|
411
523
|
),
|
|
412
524
|
branch_ids: [branchId],
|
|
@@ -441,18 +553,22 @@ function buildObjectiveRuns(workspaceState, workspace) {
|
|
|
441
553
|
grouped.get(key).push(event);
|
|
442
554
|
}
|
|
443
555
|
return [...grouped.entries()].map(([runId, events]) => {
|
|
556
|
+
if (runId === "workspace:current") return null;
|
|
444
557
|
const sortedEvents = sortByTimestamp(events, (event) => event.timestamp ?? "");
|
|
445
|
-
const
|
|
446
|
-
|
|
558
|
+
const meaningfulEvents = sortedEvents.filter((event) => !isObserverStatusEvent(event));
|
|
559
|
+
if (!meaningfulEvents.length) return null;
|
|
560
|
+
const latestMeaningfulEvent = meaningfulEvents[meaningfulEvents.length - 1];
|
|
561
|
+
const branchIds = unique(meaningfulEvents.map((event) => explicitBranchId(runId, event)));
|
|
562
|
+
const laneIds = unique(meaningfulEvents.map((event) => explicitLaneId(runId, event)));
|
|
447
563
|
const branches = branchIds.map((branchId) => ({
|
|
448
564
|
branch_id: branchId,
|
|
449
565
|
run_id: runId,
|
|
450
566
|
name: branchId === `${runId}:main` ? "main" : branchId.split(":").at(-1) ?? "branch",
|
|
451
|
-
status: statusFromEventStatus(
|
|
567
|
+
status: statusFromEventStatus(latestMeaningfulEvent?.status),
|
|
452
568
|
lane_ids: laneIds.filter((laneId) => laneId.startsWith(branchId) || branchId === `${runId}:main`),
|
|
453
569
|
}));
|
|
454
570
|
const lanes = laneIds.map((laneId) => {
|
|
455
|
-
const related =
|
|
571
|
+
const related = meaningfulEvents.filter((event) => explicitLaneId(runId, event) === laneId);
|
|
456
572
|
const latest = related[related.length - 1];
|
|
457
573
|
return {
|
|
458
574
|
lane_id: laneId,
|
|
@@ -463,7 +579,7 @@ function buildObjectiveRuns(workspaceState, workspace) {
|
|
|
463
579
|
updated_at: latest.timestamp ?? isoNow(),
|
|
464
580
|
};
|
|
465
581
|
});
|
|
466
|
-
const checkpoints =
|
|
582
|
+
const checkpoints = meaningfulEvents.map((event, index) => checkpointFromSummary({
|
|
467
583
|
checkpointId: `${runId}:cp:${index + 1}`,
|
|
468
584
|
runId,
|
|
469
585
|
branchId: explicitBranchId(runId, event),
|
|
@@ -473,7 +589,7 @@ function buildObjectiveRuns(workspaceState, workspace) {
|
|
|
473
589
|
taskDelta: event.payload?.summary ?? event.event_type,
|
|
474
590
|
evidenceRefs: event.payload?.evidence_ref ? [event.payload.evidence_ref] : [],
|
|
475
591
|
gitCommitSha: firstDefined(event.git_commit_sha, event.payload?.git_commit_sha, event.metadata?.git_commit_sha),
|
|
476
|
-
checkpointMeta: checkpointTriggerFromStatusEvent(event,
|
|
592
|
+
checkpointMeta: checkpointTriggerFromStatusEvent(event, meaningfulEvents[index - 1]),
|
|
477
593
|
}));
|
|
478
594
|
const deltas = checkpoints.length > 1
|
|
479
595
|
? checkpoints.slice(1).map((checkpoint, index) => deltaBetween(checkpoints[index], checkpoint, `${runId}:delta:${index + 1}`))
|
|
@@ -481,11 +597,11 @@ function buildObjectiveRuns(workspaceState, workspace) {
|
|
|
481
597
|
const run = {
|
|
482
598
|
run_id: runId,
|
|
483
599
|
workspace,
|
|
484
|
-
title:
|
|
485
|
-
objective:
|
|
486
|
-
status: statusFromEventStatus(
|
|
487
|
-
created_at:
|
|
488
|
-
updated_at:
|
|
600
|
+
title: latestMeaningfulEvent?.payload?.summary ?? runId,
|
|
601
|
+
objective: meaningfulEvents[0]?.objective_id ?? meaningfulEvents[0]?.trace_id ?? runId,
|
|
602
|
+
status: statusFromEventStatus(latestMeaningfulEvent?.status),
|
|
603
|
+
created_at: meaningfulEvents[0]?.timestamp ?? isoNow(),
|
|
604
|
+
updated_at: latestMeaningfulEvent?.timestamp ?? isoNow(),
|
|
489
605
|
branch_ids: branches.map((branch) => branch.branch_id),
|
|
490
606
|
lane_ids: lanes.map((lane) => lane.lane_id),
|
|
491
607
|
checkpoint_ids: checkpoints.map((checkpoint) => checkpoint.checkpoint_id),
|
|
@@ -502,7 +618,7 @@ function buildObjectiveRuns(workspaceState, workspace) {
|
|
|
502
618
|
activity_items: [],
|
|
503
619
|
similarity: { target_run_id: runId, neighbors: [] },
|
|
504
620
|
};
|
|
505
|
-
});
|
|
621
|
+
}).filter(Boolean);
|
|
506
622
|
}
|
|
507
623
|
|
|
508
624
|
function ensureBranch(runDetail, branchId) {
|
|
@@ -678,7 +794,9 @@ function attachActivityItems(runs, workspaceState) {
|
|
|
678
794
|
|
|
679
795
|
function attachLaneHeartbeats(runs) {
|
|
680
796
|
for (const runDetail of runs) {
|
|
681
|
-
const sourceItems = (runDetail.activity_items ?? []).filter((item) =>
|
|
797
|
+
const sourceItems = (runDetail.activity_items ?? []).filter((item) =>
|
|
798
|
+
item.source_kind !== "lane_heartbeat" && item.visible_by_default !== false
|
|
799
|
+
);
|
|
682
800
|
for (const lane of runDetail.lanes ?? []) {
|
|
683
801
|
const latestActivity = sortByTimestamp(
|
|
684
802
|
sourceItems.filter((item) => item.lane_id === lane.lane_id || (!item.lane_id && item.actor_id === lane.agent_id)),
|
|
@@ -689,9 +807,16 @@ function attachLaneHeartbeats(runs) {
|
|
|
689
807
|
}
|
|
690
808
|
}
|
|
691
809
|
|
|
810
|
+
function collapseActivityItems(runs, now) {
|
|
811
|
+
for (const runDetail of runs) {
|
|
812
|
+
runDetail.activity_items = collapseAndScoreActivityItems(runDetail.activity_items ?? [], { now });
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
692
816
|
function attachLedgerEntries(runs, workspaceState) {
|
|
693
817
|
const byId = new Map(runs.map((run) => [run.run.run_id, run]));
|
|
694
818
|
for (const entry of sortByTimestamp(workspaceState.ledgerEntries, (item) => item.timestamp_utc ?? "")) {
|
|
819
|
+
if (isObserverLedgerEntry(entry)) continue;
|
|
695
820
|
const runId = runIdFromLedgerEntry(entry);
|
|
696
821
|
if (!runId) continue;
|
|
697
822
|
const runDetail = byId.get(runId);
|
|
@@ -769,6 +894,16 @@ function attachSimilarity(runs) {
|
|
|
769
894
|
target_run_id: run.run.run_id,
|
|
770
895
|
neighbors,
|
|
771
896
|
};
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
function attachLiveSignals(runs, now) {
|
|
901
|
+
for (const run of runs) {
|
|
902
|
+
run.live_signal = deriveRunLiveSignal(run, { now });
|
|
903
|
+
}
|
|
904
|
+
const ranked = [...runs].sort(compareRunsByAttention);
|
|
905
|
+
ranked.forEach((run, index) => {
|
|
906
|
+
run.live_signal.attention_rank = index + 1;
|
|
772
907
|
run.run_summary = summarizeRun(
|
|
773
908
|
run.run,
|
|
774
909
|
run.branches,
|
|
@@ -776,12 +911,15 @@ function attachSimilarity(runs) {
|
|
|
776
911
|
run.nodes,
|
|
777
912
|
run.handoff_timeline.items,
|
|
778
913
|
run.recent_checkpoints,
|
|
779
|
-
neighbors
|
|
914
|
+
run.similarity?.neighbors ?? [],
|
|
915
|
+
run.live_signal
|
|
780
916
|
);
|
|
781
|
-
}
|
|
917
|
+
});
|
|
918
|
+
return ranked;
|
|
782
919
|
}
|
|
783
920
|
|
|
784
|
-
export function projectWorkspaceState(workspaceState) {
|
|
921
|
+
export function projectWorkspaceState(workspaceState, options = {}) {
|
|
922
|
+
const now = options.now ?? isoNow();
|
|
785
923
|
const workspace = workspaceRef(workspaceState.workspaceRoot);
|
|
786
924
|
const runs = [
|
|
787
925
|
...workspaceState.handoffs.map((handoff) => buildHandoffRun(handoff, workspace)),
|
|
@@ -791,19 +929,36 @@ export function projectWorkspaceState(workspaceState) {
|
|
|
791
929
|
if (workspaceRun) runs.push(workspaceRun);
|
|
792
930
|
attachProcessPosts(runs, workspaceState, workspace);
|
|
793
931
|
attachActivityItems(runs, workspaceState);
|
|
794
|
-
attachLaneHeartbeats(runs);
|
|
795
932
|
attachLedgerEntries(runs, workspaceState);
|
|
933
|
+
collapseActivityItems(runs, now);
|
|
934
|
+
attachLaneHeartbeats(runs);
|
|
796
935
|
finalizeRunDetails(runs);
|
|
797
936
|
attachSimilarity(runs);
|
|
798
|
-
const sorted =
|
|
799
|
-
...run,
|
|
800
|
-
updated_at: run.run.updated_at,
|
|
801
|
-
}))).map(({ updated_at, ...rest }) => rest);
|
|
937
|
+
const sorted = attachLiveSignals(runs, now);
|
|
802
938
|
return {
|
|
803
|
-
generated_at:
|
|
939
|
+
generated_at: now,
|
|
804
940
|
workspace,
|
|
805
941
|
adapter_profiles: workspaceState.adapterProfiles ?? [],
|
|
806
942
|
run_summaries: sorted.map((run) => run.run_summary),
|
|
807
943
|
runs: sorted,
|
|
944
|
+
attention_items: sorted.map((run) => ({
|
|
945
|
+
run_id: run.run.run_id,
|
|
946
|
+
title: run.run.title,
|
|
947
|
+
status: run.run.status,
|
|
948
|
+
attention_rank: run.live_signal?.attention_rank,
|
|
949
|
+
attention_class: run.live_signal?.attention_class,
|
|
950
|
+
attention_reason: run.live_signal?.attention_reason,
|
|
951
|
+
attention_score: run.live_signal?.attention_score,
|
|
952
|
+
why_now: run.live_signal?.why_now,
|
|
953
|
+
expected_next_event: run.live_signal?.expected_next_event,
|
|
954
|
+
overdue_at: run.live_signal?.overdue_at,
|
|
955
|
+
recommended_owner_action: run.live_signal?.recommended_owner_action,
|
|
956
|
+
recommended_post_kind: run.live_signal?.recommended_post_kind,
|
|
957
|
+
needs_narrative: run.live_signal?.needs_narrative,
|
|
958
|
+
freshness_class: run.live_signal?.freshness_class,
|
|
959
|
+
signal_confidence: run.live_signal?.signal_confidence,
|
|
960
|
+
current_actor_id: run.live_signal?.current_actor_id,
|
|
961
|
+
waiting_on_actor_id: run.live_signal?.waiting_on_actor_id,
|
|
962
|
+
})),
|
|
808
963
|
};
|
|
809
964
|
}
|
package/src/tui/app.js
CHANGED
|
@@ -11,6 +11,7 @@ import { upsertTodoNode } from "../store/todo-state.js";
|
|
|
11
11
|
import { formatTimestamp } from "../core/util.js";
|
|
12
12
|
import { completeCommand, executeCommand } from "./commands.js";
|
|
13
13
|
import {
|
|
14
|
+
buildAdaptersSections,
|
|
14
15
|
buildCompareSections,
|
|
15
16
|
buildHistorySections,
|
|
16
17
|
buildHubMetrics,
|
|
@@ -165,7 +166,9 @@ export async function runHub({ workspaceRoot, feedFile, loadState, watchedPaths
|
|
|
165
166
|
? buildInspectSections(selected, { tier })
|
|
166
167
|
: state.view === "history"
|
|
167
168
|
? buildHistorySections(state.projected, selected, { tier })
|
|
168
|
-
:
|
|
169
|
+
: state.view === "adapters"
|
|
170
|
+
? buildAdaptersSections(state.projected, { tier })
|
|
171
|
+
: buildHubSections(state.projected, selected, { tier })),
|
|
169
172
|
];
|
|
170
173
|
|
|
171
174
|
line(boxTitle(` Vericify Hub | ${state.mode} | ${workspaceRoot} `, width));
|
|
@@ -175,7 +178,7 @@ export async function runHub({ workspaceRoot, feedFile, loadState, watchedPaths
|
|
|
175
178
|
renderPanelGrid(sections, width, tier);
|
|
176
179
|
const prompt = state.mode === "command"
|
|
177
180
|
? `/${state.commandBuffer}`
|
|
178
|
-
: "[q quit] [j/k move] [Enter inspect] [c compare] [y history] [r refresh] [/ command] [h hub]";
|
|
181
|
+
: "[q quit] [j/k move] [Enter inspect] [c compare] [y history] [a adapters] [r refresh] [/ command] [h hub]";
|
|
179
182
|
line(truncate(prompt, width));
|
|
180
183
|
line(boxFooter(width));
|
|
181
184
|
};
|
|
@@ -277,6 +280,7 @@ export async function runHub({ workspaceRoot, feedFile, loadState, watchedPaths
|
|
|
277
280
|
summary,
|
|
278
281
|
run_id: runId,
|
|
279
282
|
workspace_root: workspaceRoot,
|
|
283
|
+
observer_telemetry: true,
|
|
280
284
|
},
|
|
281
285
|
});
|
|
282
286
|
};
|
|
@@ -512,6 +516,13 @@ export async function runHub({ workspaceRoot, feedFile, loadState, watchedPaths
|
|
|
512
516
|
recordInteractiveTransition(before, { source: "keyboard" });
|
|
513
517
|
return;
|
|
514
518
|
}
|
|
519
|
+
if (key.name === "a") {
|
|
520
|
+
const before = captureRuntimeState();
|
|
521
|
+
state.view = "adapters";
|
|
522
|
+
rerender();
|
|
523
|
+
recordInteractiveTransition(before, { source: "keyboard" });
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
515
526
|
if (key.name === "r") {
|
|
516
527
|
const before = captureRuntimeState();
|
|
517
528
|
refresh();
|
package/src/tui/commands.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export function completeCommand(input, runIds) {
|
|
2
|
-
const commands = ["help", "quit", "refresh", "hub", "run", "inspect", "compare", "history", "select", "next", "prev", "focus", "post", "handoff", "todo", "ledger", "event"];
|
|
2
|
+
const commands = ["help", "quit", "refresh", "hub", "run", "inspect", "compare", "history", "adapters", "select", "next", "prev", "focus", "post", "handoff", "todo", "ledger", "event"];
|
|
3
3
|
const parts = input.split(/\s+/);
|
|
4
4
|
const token = parts.at(-1) ?? "";
|
|
5
5
|
const options = parts.length > 1 ? [...runIds, ...commands] : [...commands, ...runIds];
|
|
@@ -107,6 +107,9 @@ export function executeCommand(command, state) {
|
|
|
107
107
|
const compareTarget = positionals[0];
|
|
108
108
|
return { patch: { view: "compare", compareTarget }, message: "Switched to compare view." };
|
|
109
109
|
}
|
|
110
|
+
if (name === "adapters") {
|
|
111
|
+
return { patch: { view: "adapters" }, message: "Switched to adapters view." };
|
|
112
|
+
}
|
|
110
113
|
if (name === "history") {
|
|
111
114
|
return { patch: { view: "history" }, message: "Switched to history view." };
|
|
112
115
|
}
|