agentfootprint-lens 0.60.0 → 0.61.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/README.md +1 -1
- package/dist/chunk-2VGWAAXY.js +594 -0
- package/dist/chunk-2VGWAAXY.js.map +1 -0
- package/dist/{chunk-4AKGKXD6.js → chunk-3LXZ7D65.js} +2 -2
- package/dist/{chunk-RJ4OWNKV.js → chunk-GCDO7N6B.js} +97 -4
- package/dist/chunk-GCDO7N6B.js.map +1 -0
- package/dist/{chunk-RMY2NAL3.js → chunk-IPCNNYQU.js} +2 -2
- package/dist/{chunk-JH5SK5E3.js → chunk-P63SOXBD.js} +2 -2
- package/dist/{chunk-FU62BGLS.js → chunk-UEIY7ZJ5.js} +4 -4
- package/dist/{chunk-37NHCNSS.js → chunk-XEAZRBOH.js} +6 -3
- package/dist/chunk-XEAZRBOH.js.map +1 -0
- package/dist/context.cjs +738 -390
- package/dist/context.cjs.map +1 -1
- package/dist/context.d.cts +6 -1
- package/dist/context.d.ts +6 -1
- package/dist/context.js +4 -4
- package/dist/core.cjs +5 -2
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +8 -1
- package/dist/core.d.ts +8 -1
- package/dist/core.js +4 -4
- package/dist/index.cjs +679 -329
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +7 -7
- package/dist/why.cjs +100 -4
- package/dist/why.cjs.map +1 -1
- package/dist/why.js +4 -4
- package/package.json +2 -2
- package/dist/chunk-2VBBOUD2.js +0 -340
- package/dist/chunk-2VBBOUD2.js.map +0 -1
- package/dist/chunk-37NHCNSS.js.map +0 -1
- package/dist/chunk-RJ4OWNKV.js.map +0 -1
- /package/dist/{chunk-4AKGKXD6.js.map → chunk-3LXZ7D65.js.map} +0 -0
- /package/dist/{chunk-RMY2NAL3.js.map → chunk-IPCNNYQU.js.map} +0 -0
- /package/dist/{chunk-JH5SK5E3.js.map → chunk-P63SOXBD.js.map} +0 -0
- /package/dist/{chunk-FU62BGLS.js.map → chunk-UEIY7ZJ5.js.map} +0 -0
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ changes.
|
|
|
78
78
|
|---|---|
|
|
79
79
|
| `agentfootprint-lens/why` | Replay a recording as the agent's own milestones. `<WhyLens recording={...} />` takes the recording straight (`recordRun()`'s `{ snapshot, events, structure }`, or the `persistRecording` envelope), validates it at mount, and mounts the shipped `<Lens>` shell on the milestone axis — plus the axis helpers (`scrubAxisFor`, `stepForCommitIdx`, `stepForRuntimeStageId`, `resolveNavigation`) for hosts holding one cursor across views. |
|
|
80
80
|
| `agentfootprint-lens/skillgraph` | Debug how a run routed through its skills. `<SkillGraphDebugger recorder={...} />` plus its headless selectors (`selectSkillRoute`, `selectSkillBeats`, `selectSkillTopology`, `selectSkillFrameContext`, `stepForRuntimeStageId`, `resolveNavigation`). |
|
|
81
|
-
| `agentfootprint-lens/context` | What the model HAD at a stop — the served document of that epoch on top (the Served tab itself: pieces, messages, tools, verdicts, delta since the previous call) — and what it was BUILT from beneath: the record key by key, who wrote each, what moved; a long value opens in place (0.54.0). `<ContextView runner={...} />` walks the milestone axis on its own; hand it `cursor` and it follows the ONE cursor (0.53.1). |
|
|
81
|
+
| `agentfootprint-lens/context` | What the model HAD at a stop — the served document of that epoch on top (the Served tab itself: pieces, messages, tools, verdicts, delta since the previous call) — and what it was BUILT from beneath: the record key by key, who wrote each, what moved; a long value opens in place (0.54.0). `<ContextView runner={...} />` walks the milestone axis on its own; hand it `cursor` and it follows the ONE cursor (0.53.1). Under the record, the **Findings** band (0.61.0): on an armed run (`.findings()`, agentfootprint 9.101) the model's own ledger at the stop, folded for reading — facts, conflicts as first seen (each witness with its current standing, no verdict), open, ruled out, noise, undeclared — every string off the record, absent on an unarmed run. |
|
|
82
82
|
|
|
83
83
|
The axis model in three sentences: one run leaves one causal trace, and each
|
|
84
84
|
lens replays one AXIS of it — the Why reading scrubs the milestones, the Flow
|
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
import {
|
|
2
|
+
contextAt
|
|
3
|
+
} from "./chunk-3LXZ7D65.js";
|
|
4
|
+
import {
|
|
5
|
+
ServedTab
|
|
6
|
+
} from "./chunk-GCDO7N6B.js";
|
|
7
|
+
import {
|
|
8
|
+
snapshotLogKey,
|
|
9
|
+
snapshotOfRunner,
|
|
10
|
+
tagAxisPositions
|
|
11
|
+
} from "./chunk-XEAZRBOH.js";
|
|
12
|
+
import {
|
|
13
|
+
TimeTravel
|
|
14
|
+
} from "./chunk-CO5R2ODI.js";
|
|
15
|
+
import {
|
|
16
|
+
lensCursorFrom,
|
|
17
|
+
scrubAxisFor
|
|
18
|
+
} from "./chunk-BFAI2IPA.js";
|
|
19
|
+
|
|
20
|
+
// src/react/components/ContextView.tsx
|
|
21
|
+
import { useMemo as useMemo2, useState } from "react";
|
|
22
|
+
|
|
23
|
+
// src/react/components/FindingsBand.tsx
|
|
24
|
+
import React, { useMemo } from "react";
|
|
25
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
26
|
+
var LABELS = Object.freeze({
|
|
27
|
+
band: "findings",
|
|
28
|
+
rows: "rows",
|
|
29
|
+
facts: "facts",
|
|
30
|
+
/** The conflict ROWS — the history of when each was first seen, not the current set (see the header). */
|
|
31
|
+
conflicts: "conflicts first seen",
|
|
32
|
+
open: "open",
|
|
33
|
+
ruledOut: "ruled out",
|
|
34
|
+
noise: "noise",
|
|
35
|
+
undeclared: "undeclared",
|
|
36
|
+
settles: "settles",
|
|
37
|
+
line: "line"
|
|
38
|
+
});
|
|
39
|
+
var isRecord = (v) => typeof v === "object" && v !== null;
|
|
40
|
+
function subjectOf(v) {
|
|
41
|
+
if (!isRecord(v) || typeof v.kind !== "string" || typeof v.id !== "string") return void 0;
|
|
42
|
+
return { kind: v.kind, id: v.id };
|
|
43
|
+
}
|
|
44
|
+
function assertionOf(v) {
|
|
45
|
+
if (!isRecord(v) || typeof v.predicate !== "string") return void 0;
|
|
46
|
+
const subject = subjectOf(v.subject);
|
|
47
|
+
if (subject === void 0) return void 0;
|
|
48
|
+
return {
|
|
49
|
+
subject,
|
|
50
|
+
predicate: v.predicate,
|
|
51
|
+
value: v.value,
|
|
52
|
+
...typeof v.provenance === "string" ? { provenance: v.provenance } : {}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function standingOf(row) {
|
|
56
|
+
if (!isRecord(row) || row.kind !== "standing") return void 0;
|
|
57
|
+
if (typeof row.toolCallId !== "string" || typeof row.standing !== "string") return void 0;
|
|
58
|
+
const assertions = Array.isArray(row.assertions) ? row.assertions.flatMap((a) => {
|
|
59
|
+
const shaped = assertionOf(a);
|
|
60
|
+
return shaped !== void 0 ? [shaped] : [];
|
|
61
|
+
}) : [];
|
|
62
|
+
return {
|
|
63
|
+
toolCallId: row.toolCallId,
|
|
64
|
+
standing: row.standing,
|
|
65
|
+
assertions,
|
|
66
|
+
...typeof row.toolName === "string" ? { toolName: row.toolName } : {},
|
|
67
|
+
...typeof row.settles === "string" ? { settles: row.settles } : {},
|
|
68
|
+
...typeof row.line === "string" ? { line: row.line } : {}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function witnessOf(v) {
|
|
72
|
+
if (!isRecord(v) || typeof v.toolCallId !== "string" || typeof v.predicate !== "string") return void 0;
|
|
73
|
+
const subject = subjectOf(v.subject);
|
|
74
|
+
if (subject === void 0) return void 0;
|
|
75
|
+
return { toolCallId: v.toolCallId, subject, predicate: v.predicate };
|
|
76
|
+
}
|
|
77
|
+
function conflictOf(row) {
|
|
78
|
+
if (!isRecord(row) || row.kind !== "conflict" || typeof row.key !== "string") return void 0;
|
|
79
|
+
if (!Array.isArray(row.witnesses)) return void 0;
|
|
80
|
+
const witnesses = row.witnesses.flatMap((w) => {
|
|
81
|
+
const shaped = witnessOf(w);
|
|
82
|
+
return shaped !== void 0 ? [shaped] : [];
|
|
83
|
+
});
|
|
84
|
+
return { key: row.key, witnesses };
|
|
85
|
+
}
|
|
86
|
+
function resultIdOf(entry) {
|
|
87
|
+
return isRecord(entry) && typeof entry.toolCallId === "string" ? entry.toolCallId : void 0;
|
|
88
|
+
}
|
|
89
|
+
function foldFindings(rows, toolResults) {
|
|
90
|
+
const standing = /* @__PURE__ */ new Map();
|
|
91
|
+
const conflictRows = [];
|
|
92
|
+
for (const row of rows) {
|
|
93
|
+
const s = standingOf(row);
|
|
94
|
+
if (s !== void 0) {
|
|
95
|
+
standing.set(s.toolCallId, s);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const c = conflictOf(row);
|
|
99
|
+
if (c !== void 0) conflictRows.push(c);
|
|
100
|
+
}
|
|
101
|
+
const conflicts = conflictRows.map(
|
|
102
|
+
(c) => Object.freeze({
|
|
103
|
+
key: c.key,
|
|
104
|
+
witnesses: Object.freeze(
|
|
105
|
+
c.witnesses.map((w) => {
|
|
106
|
+
const now = standing.get(w.toolCallId)?.standing;
|
|
107
|
+
return Object.freeze({ ...w, ...now !== void 0 ? { standing: now } : {} });
|
|
108
|
+
})
|
|
109
|
+
)
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
const facts = [];
|
|
113
|
+
const open = [];
|
|
114
|
+
const ruledOut = [];
|
|
115
|
+
const noise = [];
|
|
116
|
+
for (const s of standing.values()) {
|
|
117
|
+
if (s.standing === "fact") for (const assertion of s.assertions) facts.push({ toolCallId: s.toolCallId, assertion });
|
|
118
|
+
else if (s.standing === "open") open.push(s);
|
|
119
|
+
else if (s.standing === "ruled-out") ruledOut.push(s);
|
|
120
|
+
else if (s.standing === "noise") noise.push(s.toolCallId);
|
|
121
|
+
}
|
|
122
|
+
const undeclared = [];
|
|
123
|
+
for (const entry of toolResults ?? []) {
|
|
124
|
+
const id = resultIdOf(entry);
|
|
125
|
+
if (id !== void 0 && !standing.has(id)) undeclared.push(id);
|
|
126
|
+
}
|
|
127
|
+
return Object.freeze({
|
|
128
|
+
rows: rows.length,
|
|
129
|
+
facts: Object.freeze(facts),
|
|
130
|
+
conflicts: Object.freeze(conflicts),
|
|
131
|
+
open: Object.freeze(open),
|
|
132
|
+
ruledOut: Object.freeze(ruledOut),
|
|
133
|
+
noise: Object.freeze(noise),
|
|
134
|
+
undeclared: Object.freeze(undeclared)
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function valueText(value) {
|
|
138
|
+
if (typeof value === "string") return value;
|
|
139
|
+
return JSON.stringify(value) ?? String(value);
|
|
140
|
+
}
|
|
141
|
+
function FindingsBand(props) {
|
|
142
|
+
const { rows, toolResults, since } = props;
|
|
143
|
+
const fold = useMemo(() => foldFindings(rows, toolResults), [rows, toolResults]);
|
|
144
|
+
return /* @__PURE__ */ jsxs("div", { style: band, "data-testid": "context-findings", "data-rows": fold.rows, "data-since": since ?? "", children: [
|
|
145
|
+
/* @__PURE__ */ jsxs("span", { style: dim, children: [
|
|
146
|
+
LABELS.band,
|
|
147
|
+
" \xB7 ",
|
|
148
|
+
fold.rows,
|
|
149
|
+
" ",
|
|
150
|
+
LABELS.rows
|
|
151
|
+
] }),
|
|
152
|
+
fold.facts.length > 0 && /* @__PURE__ */ jsx(Group, { id: "facts", label: LABELS.facts, count: fold.facts.length, children: fold.facts.map((f, i) => /* @__PURE__ */ jsxs("li", { style: mono, "data-testid": "context-findings-fact", "data-tool-call-id": f.toolCallId, children: [
|
|
153
|
+
/* @__PURE__ */ jsx(AssertionLine, { assertion: f.assertion }),
|
|
154
|
+
" \u2190 ",
|
|
155
|
+
/* @__PURE__ */ jsx("code", { children: f.assertion.provenance ?? f.toolCallId })
|
|
156
|
+
] }, i)) }),
|
|
157
|
+
fold.conflicts.length > 0 && /* @__PURE__ */ jsx(Group, { id: "conflicts", label: LABELS.conflicts, count: fold.conflicts.length, children: fold.conflicts.map((c, i) => /* @__PURE__ */ jsx("li", { style: mono, "data-testid": "context-findings-conflict", "data-key": c.key, children: c.witnesses.map((w, j) => /* @__PURE__ */ jsxs(
|
|
158
|
+
"div",
|
|
159
|
+
{
|
|
160
|
+
"data-testid": "context-findings-witness",
|
|
161
|
+
"data-tool-call-id": w.toolCallId,
|
|
162
|
+
"data-standing": w.standing ?? "",
|
|
163
|
+
children: [
|
|
164
|
+
/* @__PURE__ */ jsxs("code", { children: [
|
|
165
|
+
w.subject.kind,
|
|
166
|
+
"/",
|
|
167
|
+
w.subject.id
|
|
168
|
+
] }),
|
|
169
|
+
" \xB7 ",
|
|
170
|
+
/* @__PURE__ */ jsx("code", { children: w.predicate }),
|
|
171
|
+
" \u2190 ",
|
|
172
|
+
/* @__PURE__ */ jsx("code", { children: w.toolCallId }),
|
|
173
|
+
w.standing !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
174
|
+
" \xB7 ",
|
|
175
|
+
/* @__PURE__ */ jsx("code", { children: w.standing })
|
|
176
|
+
] })
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
j
|
|
180
|
+
)) }, i)) }),
|
|
181
|
+
fold.open.length > 0 && /* @__PURE__ */ jsx(Group, { id: "open", label: LABELS.open, count: fold.open.length, children: fold.open.map((s) => /* @__PURE__ */ jsxs("li", { style: mono, "data-testid": "context-findings-open-row", "data-tool-call-id": s.toolCallId, children: [
|
|
182
|
+
/* @__PURE__ */ jsx(StandingHead, { standing: s }),
|
|
183
|
+
s.assertions.map((a, i) => /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(AssertionLine, { assertion: a }) }, i)),
|
|
184
|
+
s.settles !== void 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
185
|
+
/* @__PURE__ */ jsx("span", { style: dim, children: LABELS.settles }),
|
|
186
|
+
" \xB7 ",
|
|
187
|
+
s.settles
|
|
188
|
+
] })
|
|
189
|
+
] }, s.toolCallId)) }),
|
|
190
|
+
fold.ruledOut.length > 0 && /* @__PURE__ */ jsx(Group, { id: "ruled-out", label: LABELS.ruledOut, count: fold.ruledOut.length, children: fold.ruledOut.map((s) => /* @__PURE__ */ jsxs("li", { style: mono, "data-testid": "context-findings-ruled-out-row", "data-tool-call-id": s.toolCallId, children: [
|
|
191
|
+
/* @__PURE__ */ jsx(StandingHead, { standing: s }),
|
|
192
|
+
s.line !== void 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
193
|
+
/* @__PURE__ */ jsx("span", { style: dim, children: LABELS.line }),
|
|
194
|
+
" \xB7 ",
|
|
195
|
+
s.line
|
|
196
|
+
] })
|
|
197
|
+
] }, s.toolCallId)) }),
|
|
198
|
+
fold.noise.length > 0 && /* @__PURE__ */ jsx(Group, { id: "noise", label: LABELS.noise, count: fold.noise.length, children: /* @__PURE__ */ jsx("li", { style: mono, children: /* @__PURE__ */ jsx(IdList, { ids: fold.noise, testId: "context-findings-noise-id" }) }) }),
|
|
199
|
+
fold.undeclared.length > 0 && /* @__PURE__ */ jsx(Group, { id: "undeclared", label: LABELS.undeclared, count: fold.undeclared.length, children: /* @__PURE__ */ jsx("li", { style: mono, children: /* @__PURE__ */ jsx(IdList, { ids: fold.undeclared, testId: "context-findings-undeclared-id" }) }) })
|
|
200
|
+
] });
|
|
201
|
+
}
|
|
202
|
+
function Group({
|
|
203
|
+
id,
|
|
204
|
+
label,
|
|
205
|
+
count,
|
|
206
|
+
children
|
|
207
|
+
}) {
|
|
208
|
+
return /* @__PURE__ */ jsxs("div", { "data-testid": `context-findings-${id}`, "data-count": count, children: [
|
|
209
|
+
/* @__PURE__ */ jsxs("span", { style: dim, children: [
|
|
210
|
+
label,
|
|
211
|
+
" \xB7 ",
|
|
212
|
+
count
|
|
213
|
+
] }),
|
|
214
|
+
/* @__PURE__ */ jsx("ul", { style: list, children })
|
|
215
|
+
] });
|
|
216
|
+
}
|
|
217
|
+
function AssertionLine({ assertion }) {
|
|
218
|
+
return /* @__PURE__ */ jsxs("span", { "data-testid": "context-findings-assertion", children: [
|
|
219
|
+
/* @__PURE__ */ jsxs("code", { children: [
|
|
220
|
+
assertion.subject.kind,
|
|
221
|
+
"/",
|
|
222
|
+
assertion.subject.id
|
|
223
|
+
] }),
|
|
224
|
+
" \xB7 ",
|
|
225
|
+
/* @__PURE__ */ jsx("code", { children: assertion.predicate }),
|
|
226
|
+
" = ",
|
|
227
|
+
/* @__PURE__ */ jsx("code", { children: valueText(assertion.value) })
|
|
228
|
+
] });
|
|
229
|
+
}
|
|
230
|
+
function StandingHead({ standing }) {
|
|
231
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
232
|
+
/* @__PURE__ */ jsx("code", { children: standing.toolCallId }),
|
|
233
|
+
standing.toolName !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
234
|
+
" \xB7 ",
|
|
235
|
+
/* @__PURE__ */ jsx("code", { children: standing.toolName })
|
|
236
|
+
] })
|
|
237
|
+
] });
|
|
238
|
+
}
|
|
239
|
+
function IdList({ ids, testId }) {
|
|
240
|
+
return /* @__PURE__ */ jsx(Fragment, { children: ids.map((id, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
241
|
+
i > 0 && " \xB7 ",
|
|
242
|
+
/* @__PURE__ */ jsx("code", { "data-testid": testId, children: id })
|
|
243
|
+
] }, id)) });
|
|
244
|
+
}
|
|
245
|
+
var band = {
|
|
246
|
+
display: "flex",
|
|
247
|
+
flexDirection: "column",
|
|
248
|
+
gap: 4,
|
|
249
|
+
paddingTop: 6,
|
|
250
|
+
borderTop: "1px solid",
|
|
251
|
+
borderTopColor: "currentColor"
|
|
252
|
+
};
|
|
253
|
+
var dim = { opacity: 0.7 };
|
|
254
|
+
var mono = {
|
|
255
|
+
fontFamily: "monospace",
|
|
256
|
+
fontSize: 12,
|
|
257
|
+
wordBreak: "break-word"
|
|
258
|
+
};
|
|
259
|
+
var list = { margin: "2px 0 0", paddingLeft: 18 };
|
|
260
|
+
|
|
261
|
+
// src/react/components/ContextView.tsx
|
|
262
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
263
|
+
var LABELS2 = Object.freeze({
|
|
264
|
+
view: "Context",
|
|
265
|
+
keys: "keys",
|
|
266
|
+
wroteBy: "wrote by",
|
|
267
|
+
at: "at",
|
|
268
|
+
entered: "entered",
|
|
269
|
+
changed: "changed",
|
|
270
|
+
unchanged: "unchanged",
|
|
271
|
+
left: "left",
|
|
272
|
+
unattributed: "unattributed",
|
|
273
|
+
rows: "rows",
|
|
274
|
+
served: "served",
|
|
275
|
+
why: "why",
|
|
276
|
+
epoch: "epoch",
|
|
277
|
+
system: "system",
|
|
278
|
+
tools: "tools",
|
|
279
|
+
redacted: "redacted",
|
|
280
|
+
skipped: "skipped",
|
|
281
|
+
foldError: "fold error",
|
|
282
|
+
servedError: "served error",
|
|
283
|
+
json: "JSON",
|
|
284
|
+
empty: "{ }",
|
|
285
|
+
more: "more",
|
|
286
|
+
less: "less",
|
|
287
|
+
builtFrom: "built from"
|
|
288
|
+
});
|
|
289
|
+
var MILESTONE_AXIS = Object.freeze([
|
|
290
|
+
"milestone:iteration",
|
|
291
|
+
"milestone:slot",
|
|
292
|
+
"milestone:llm-turn",
|
|
293
|
+
"milestone:tool-call",
|
|
294
|
+
"milestone:decision"
|
|
295
|
+
]);
|
|
296
|
+
function positionsOf(snapshot) {
|
|
297
|
+
return tagAxisPositions(snapshot, MILESTONE_AXIS, []) ?? [];
|
|
298
|
+
}
|
|
299
|
+
function servedCursorOf(cursor) {
|
|
300
|
+
return {
|
|
301
|
+
runtimeStageId: cursor.at.runtimeStageId,
|
|
302
|
+
commitIdx: cursor.at.commitIdx
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function previousOf(cursor, positions) {
|
|
306
|
+
if (cursor.at.step <= 0) return void 0;
|
|
307
|
+
const p = positions?.[cursor.at.step - 1];
|
|
308
|
+
return p !== void 0 ? { runtimeStageId: p.runtimeStageId, commitIdx: p.commitIdx } : void 0;
|
|
309
|
+
}
|
|
310
|
+
function ContextView(props) {
|
|
311
|
+
const { runner, events, shared, recorder } = props;
|
|
312
|
+
const fresh = snapshotOfRunner(runner);
|
|
313
|
+
const logKey = snapshotLogKey(fresh);
|
|
314
|
+
const snapshot = useMemo2(() => fresh, [runner, logKey]);
|
|
315
|
+
const ownPositions = useMemo2(
|
|
316
|
+
() => props.cursor !== void 0 ? void 0 : recorder !== void 0 ? scrubAxisFor(recorder, "group") : positionsOf(snapshot),
|
|
317
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- the recorder's axis moves with the log key
|
|
318
|
+
[snapshot, props.cursor, recorder, logKey]
|
|
319
|
+
);
|
|
320
|
+
const [ownStep, setOwnStep] = useState(0);
|
|
321
|
+
const cursor = props.cursor ?? (shared !== void 0 ? shared.over(ownPositions ?? []) : lensCursorFrom(
|
|
322
|
+
ownPositions ?? [],
|
|
323
|
+
Math.min(ownStep, Math.max(0, (ownPositions?.length ?? 1) - 1)),
|
|
324
|
+
setOwnStep
|
|
325
|
+
));
|
|
326
|
+
const mover = props.cursor === void 0 && cursor.total > 0 && cursor.at.step >= 0;
|
|
327
|
+
const [mode, setMode] = useState(props.initialMode ?? "keys");
|
|
328
|
+
const context = useMemo2(
|
|
329
|
+
() => contextAt(snapshot, servedCursorOf(cursor), {
|
|
330
|
+
previous: props.previous ?? previousOf(cursor, ownPositions),
|
|
331
|
+
events
|
|
332
|
+
}),
|
|
333
|
+
[snapshot, cursor.at.runtimeStageId, cursor.at.commitIdx, cursor.at.step, ownPositions, events]
|
|
334
|
+
);
|
|
335
|
+
return /* @__PURE__ */ jsxs2(
|
|
336
|
+
"div",
|
|
337
|
+
{
|
|
338
|
+
style: panel,
|
|
339
|
+
"data-testid": "context-view",
|
|
340
|
+
"data-step": cursor.at.step,
|
|
341
|
+
"data-commit": cursor.at.commitIdx,
|
|
342
|
+
children: [
|
|
343
|
+
/* @__PURE__ */ jsxs2("div", { style: header, children: [
|
|
344
|
+
/* @__PURE__ */ jsx2("span", { style: title, children: LABELS2.view }),
|
|
345
|
+
/* @__PURE__ */ jsxs2("span", { style: dim2, children: [
|
|
346
|
+
cursor.at.label,
|
|
347
|
+
" \xB7 ",
|
|
348
|
+
cursor.at.step + 1,
|
|
349
|
+
"/",
|
|
350
|
+
cursor.total
|
|
351
|
+
] }),
|
|
352
|
+
/* @__PURE__ */ jsxs2("span", { style: { marginLeft: "auto", display: "flex", gap: 6 }, children: [
|
|
353
|
+
/* @__PURE__ */ jsx2(
|
|
354
|
+
"button",
|
|
355
|
+
{
|
|
356
|
+
type: "button",
|
|
357
|
+
style: btn,
|
|
358
|
+
"aria-pressed": mode === "keys",
|
|
359
|
+
onClick: () => setMode("keys"),
|
|
360
|
+
"data-testid": "context-mode-keys",
|
|
361
|
+
children: LABELS2.keys
|
|
362
|
+
}
|
|
363
|
+
),
|
|
364
|
+
/* @__PURE__ */ jsx2(
|
|
365
|
+
"button",
|
|
366
|
+
{
|
|
367
|
+
type: "button",
|
|
368
|
+
style: btn,
|
|
369
|
+
"aria-pressed": mode === "json",
|
|
370
|
+
onClick: () => setMode("json"),
|
|
371
|
+
"data-testid": "context-mode-json",
|
|
372
|
+
children: LABELS2.json
|
|
373
|
+
}
|
|
374
|
+
)
|
|
375
|
+
] })
|
|
376
|
+
] }),
|
|
377
|
+
mover && /* @__PURE__ */ jsx2("div", { "data-testid": "context-transport", children: /* @__PURE__ */ jsx2(
|
|
378
|
+
TimeTravel,
|
|
379
|
+
{
|
|
380
|
+
total: cursor.total,
|
|
381
|
+
focusSeq: Math.max(0, cursor.at.step),
|
|
382
|
+
onFocusChange: (n) => cursor.moveTo(n),
|
|
383
|
+
isLive: false,
|
|
384
|
+
compact: true
|
|
385
|
+
}
|
|
386
|
+
) }),
|
|
387
|
+
/* @__PURE__ */ jsx2(Facts, { context }),
|
|
388
|
+
/* @__PURE__ */ jsx2(ServedLayer, { context, runner, cursor }),
|
|
389
|
+
/* @__PURE__ */ jsxs2("div", { style: dim2, "data-testid": "context-built-from", children: [
|
|
390
|
+
LABELS2.builtFrom,
|
|
391
|
+
" \xB7 ",
|
|
392
|
+
context.keys.length,
|
|
393
|
+
" ",
|
|
394
|
+
LABELS2.keys
|
|
395
|
+
] }),
|
|
396
|
+
mode === "json" ? /* @__PURE__ */ jsx2(JsonPane, { context }) : /* @__PURE__ */ jsx2(KeyTable, { context }),
|
|
397
|
+
/* @__PURE__ */ jsx2(FindingsLayer, { context }),
|
|
398
|
+
/* @__PURE__ */ jsx2(WhyBand, { context })
|
|
399
|
+
]
|
|
400
|
+
}
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
function FindingsLayer({ context }) {
|
|
404
|
+
const ledger = context.keys.find((k) => k.path === "findingsLedger");
|
|
405
|
+
if (ledger === void 0 || !Array.isArray(ledger.value)) return null;
|
|
406
|
+
const results = context.keys.find((k) => k.path === "toolResults")?.value;
|
|
407
|
+
return /* @__PURE__ */ jsx2(
|
|
408
|
+
FindingsBand,
|
|
409
|
+
{
|
|
410
|
+
rows: ledger.value,
|
|
411
|
+
...Array.isArray(results) ? { toolResults: results } : {},
|
|
412
|
+
...ledger.since !== void 0 ? { since: ledger.since } : {}
|
|
413
|
+
}
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
function Facts({ context }) {
|
|
417
|
+
const facts = [];
|
|
418
|
+
if (context.redacted) facts.push(LABELS2.redacted);
|
|
419
|
+
if (context.skipped !== void 0) facts.push(`${LABELS2.skipped} ${context.skipped.join(",")}`);
|
|
420
|
+
if (context.foldError !== void 0) facts.push(`${LABELS2.foldError}: ${context.foldError}`);
|
|
421
|
+
if (context.servedError !== void 0) facts.push(`${LABELS2.servedError}: ${context.servedError}`);
|
|
422
|
+
if (facts.length === 0) return null;
|
|
423
|
+
return /* @__PURE__ */ jsx2("div", { style: dim2, "data-testid": "context-facts", children: facts.join(" \xB7 ") });
|
|
424
|
+
}
|
|
425
|
+
function KeyTable({ context }) {
|
|
426
|
+
if (context.keys.length === 0 && context.left.length === 0) {
|
|
427
|
+
return /* @__PURE__ */ jsx2("div", { style: mono2, "data-testid": "context-empty", children: LABELS2.empty });
|
|
428
|
+
}
|
|
429
|
+
return /* @__PURE__ */ jsxs2("table", { style: table, "data-testid": "context-keys", children: [
|
|
430
|
+
/* @__PURE__ */ jsxs2("colgroup", { children: [
|
|
431
|
+
/* @__PURE__ */ jsx2("col", { style: { width: "28%" } }),
|
|
432
|
+
/* @__PURE__ */ jsx2("col", { style: { width: "34%" } }),
|
|
433
|
+
/* @__PURE__ */ jsx2("col", {})
|
|
434
|
+
] }),
|
|
435
|
+
/* @__PURE__ */ jsxs2("tbody", { children: [
|
|
436
|
+
context.keys.map((k) => /* @__PURE__ */ jsx2(KeyRow, { k }, k.path)),
|
|
437
|
+
context.left.map((path) => /* @__PURE__ */ jsxs2("tr", { "data-testid": "context-key", "data-since": "left", style: { opacity: 0.6 }, children: [
|
|
438
|
+
/* @__PURE__ */ jsx2("td", { style: cell, children: /* @__PURE__ */ jsx2("code", { children: path }) }),
|
|
439
|
+
/* @__PURE__ */ jsx2("td", { style: cell, children: LABELS2.left }),
|
|
440
|
+
/* @__PURE__ */ jsx2("td", { style: cell })
|
|
441
|
+
] }, `left:${path}`))
|
|
442
|
+
] })
|
|
443
|
+
] });
|
|
444
|
+
}
|
|
445
|
+
function KeyRow({ k }) {
|
|
446
|
+
const since = k.since === void 0 ? void 0 : LABELS2[k.since];
|
|
447
|
+
return /* @__PURE__ */ jsxs2(
|
|
448
|
+
"tr",
|
|
449
|
+
{
|
|
450
|
+
"data-testid": "context-key",
|
|
451
|
+
"data-path": k.path,
|
|
452
|
+
"data-since": k.since ?? "",
|
|
453
|
+
style: k.since === "unchanged" ? { opacity: 0.6 } : void 0,
|
|
454
|
+
children: [
|
|
455
|
+
/* @__PURE__ */ jsxs2("td", { style: cell, children: [
|
|
456
|
+
/* @__PURE__ */ jsx2("code", { children: k.path }),
|
|
457
|
+
since !== void 0 && /* @__PURE__ */ jsx2("span", { style: pill, children: since })
|
|
458
|
+
] }),
|
|
459
|
+
/* @__PURE__ */ jsx2("td", { style: cell, "data-testid": "context-wrote-by", children: k.wroteBy !== void 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
460
|
+
/* @__PURE__ */ jsxs2("span", { style: dim2, children: [
|
|
461
|
+
LABELS2.wroteBy,
|
|
462
|
+
" "
|
|
463
|
+
] }),
|
|
464
|
+
/* @__PURE__ */ jsx2("code", { children: k.wroteBy }),
|
|
465
|
+
/* @__PURE__ */ jsxs2("span", { style: dim2, children: [
|
|
466
|
+
" ",
|
|
467
|
+
LABELS2.at,
|
|
468
|
+
" #",
|
|
469
|
+
k.wroteAt,
|
|
470
|
+
" \xB7 ",
|
|
471
|
+
k.verb
|
|
472
|
+
] })
|
|
473
|
+
] }) : /* @__PURE__ */ jsx2("span", { style: dim2, children: LABELS2.unattributed }) }),
|
|
474
|
+
/* @__PURE__ */ jsx2("td", { style: { ...cell, ...mono2 }, children: /* @__PURE__ */ jsx2(ValueCell, { value: k.value }) })
|
|
475
|
+
]
|
|
476
|
+
}
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
function ValueCell({ value }) {
|
|
480
|
+
const [open, setOpen] = useState(false);
|
|
481
|
+
const text = JSON.stringify(value) ?? "";
|
|
482
|
+
const long = text.length > 160;
|
|
483
|
+
if (!long) return /* @__PURE__ */ jsx2("span", { children: text });
|
|
484
|
+
return /* @__PURE__ */ jsxs2("span", { "data-testid": "context-value", "data-open": open, children: [
|
|
485
|
+
open ? /* @__PURE__ */ jsx2("pre", { style: { ...mono2, ...pre }, "data-testid": "context-value-full", children: text }) : /* @__PURE__ */ jsx2("span", { children: `${text.slice(0, 157)}\u2026` }),
|
|
486
|
+
" ",
|
|
487
|
+
/* @__PURE__ */ jsx2("button", { type: "button", style: btn, onClick: () => setOpen(!open), "data-testid": "context-value-toggle", children: open ? LABELS2.less : LABELS2.more })
|
|
488
|
+
] });
|
|
489
|
+
}
|
|
490
|
+
function JsonPane({ context }) {
|
|
491
|
+
const object = {};
|
|
492
|
+
for (const k of context.keys) object[k.path] = k.value;
|
|
493
|
+
return /* @__PURE__ */ jsx2("pre", { style: { ...mono2, ...pre }, "data-testid": "context-json", children: JSON.stringify(object, null, 2) });
|
|
494
|
+
}
|
|
495
|
+
function ServedLayer({
|
|
496
|
+
context,
|
|
497
|
+
runner,
|
|
498
|
+
cursor
|
|
499
|
+
}) {
|
|
500
|
+
const served = context.served;
|
|
501
|
+
if (served === void 0) return null;
|
|
502
|
+
return /* @__PURE__ */ jsxs2("div", { style: band2, "data-testid": "context-served", "data-epoch": served.row.view.epoch, children: [
|
|
503
|
+
/* @__PURE__ */ jsxs2("span", { style: dim2, children: [
|
|
504
|
+
LABELS2.served,
|
|
505
|
+
" \xB7 ",
|
|
506
|
+
LABELS2.epoch,
|
|
507
|
+
" ",
|
|
508
|
+
served.row.view.epoch
|
|
509
|
+
] }),
|
|
510
|
+
/* @__PURE__ */ jsx2(
|
|
511
|
+
ServedTab,
|
|
512
|
+
{
|
|
513
|
+
runner,
|
|
514
|
+
cursor,
|
|
515
|
+
onJumpTo: (runtimeStageId) => {
|
|
516
|
+
const to = cursor.resolve(runtimeStageId);
|
|
517
|
+
if (to.ok && to.step !== void 0) cursor.moveTo(to.step);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
)
|
|
521
|
+
] });
|
|
522
|
+
}
|
|
523
|
+
function WhyBand({ context }) {
|
|
524
|
+
if (context.why.length === 0) return null;
|
|
525
|
+
return /* @__PURE__ */ jsxs2("div", { style: band2, "data-testid": "context-why", children: [
|
|
526
|
+
/* @__PURE__ */ jsx2("span", { style: dim2, children: LABELS2.why }),
|
|
527
|
+
/* @__PURE__ */ jsx2("ul", { style: list2, children: context.why.map((w) => /* @__PURE__ */ jsxs2("li", { style: mono2, children: [
|
|
528
|
+
/* @__PURE__ */ jsx2("code", { children: w.name }),
|
|
529
|
+
" ",
|
|
530
|
+
/* @__PURE__ */ jsxs2("span", { style: dim2, children: [
|
|
531
|
+
"#",
|
|
532
|
+
w.seq
|
|
533
|
+
] })
|
|
534
|
+
] }, w.seq)) })
|
|
535
|
+
] });
|
|
536
|
+
}
|
|
537
|
+
var panel = {
|
|
538
|
+
display: "flex",
|
|
539
|
+
flexDirection: "column",
|
|
540
|
+
gap: 8,
|
|
541
|
+
padding: 10,
|
|
542
|
+
fontSize: 13
|
|
543
|
+
};
|
|
544
|
+
var header = {
|
|
545
|
+
display: "flex",
|
|
546
|
+
alignItems: "center",
|
|
547
|
+
gap: 10
|
|
548
|
+
};
|
|
549
|
+
var title = { fontWeight: 600 };
|
|
550
|
+
var dim2 = { opacity: 0.7 };
|
|
551
|
+
var mono2 = {
|
|
552
|
+
fontFamily: "monospace",
|
|
553
|
+
fontSize: 12
|
|
554
|
+
};
|
|
555
|
+
var pre = {
|
|
556
|
+
margin: 0,
|
|
557
|
+
whiteSpace: "pre-wrap",
|
|
558
|
+
wordBreak: "break-word"
|
|
559
|
+
};
|
|
560
|
+
var table = {
|
|
561
|
+
borderCollapse: "collapse",
|
|
562
|
+
width: "100%",
|
|
563
|
+
tableLayout: "fixed"
|
|
564
|
+
};
|
|
565
|
+
var cell = {
|
|
566
|
+
wordBreak: "break-all",
|
|
567
|
+
overflowWrap: "anywhere",
|
|
568
|
+
padding: "4px 6px",
|
|
569
|
+
verticalAlign: "top",
|
|
570
|
+
borderTop: "1px solid",
|
|
571
|
+
borderTopColor: "currentColor"
|
|
572
|
+
};
|
|
573
|
+
var pill = {
|
|
574
|
+
marginLeft: 6,
|
|
575
|
+
padding: "0 6px",
|
|
576
|
+
borderRadius: 8,
|
|
577
|
+
fontSize: 11,
|
|
578
|
+
border: "1px solid",
|
|
579
|
+
borderColor: "currentColor"
|
|
580
|
+
};
|
|
581
|
+
var band2 = {
|
|
582
|
+
paddingTop: 6,
|
|
583
|
+
borderTop: "1px solid",
|
|
584
|
+
borderTopColor: "currentColor"
|
|
585
|
+
};
|
|
586
|
+
var list2 = { margin: "4px 0 0", paddingLeft: 18 };
|
|
587
|
+
var btn = { fontSize: 12, padding: "2px 8px" };
|
|
588
|
+
|
|
589
|
+
export {
|
|
590
|
+
LABELS2 as LABELS,
|
|
591
|
+
MILESTONE_AXIS,
|
|
592
|
+
ContextView
|
|
593
|
+
};
|
|
594
|
+
//# sourceMappingURL=chunk-2VGWAAXY.js.map
|