sitelooper 0.3.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +625 -0
  3. package/bin/sitelooper.js +6 -0
  4. package/dist/agent/llm.js +460 -0
  5. package/dist/agent/llm.js.map +1 -0
  6. package/dist/agent/loop.js +870 -0
  7. package/dist/agent/loop.js.map +1 -0
  8. package/dist/agent/prompt.js +40 -0
  9. package/dist/agent/prompt.js.map +1 -0
  10. package/dist/agent/report.js +545 -0
  11. package/dist/agent/report.js.map +1 -0
  12. package/dist/agent/tools.js +1147 -0
  13. package/dist/agent/tools.js.map +1 -0
  14. package/dist/cli.js +1692 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/daemon/browser.js +218 -0
  17. package/dist/daemon/browser.js.map +1 -0
  18. package/dist/daemon/codegen.js +241 -0
  19. package/dist/daemon/codegen.js.map +1 -0
  20. package/dist/daemon/dialogs.js +57 -0
  21. package/dist/daemon/dialogs.js.map +1 -0
  22. package/dist/daemon/diff.js +198 -0
  23. package/dist/daemon/diff.js.map +1 -0
  24. package/dist/daemon/fingerprint.js +98 -0
  25. package/dist/daemon/fingerprint.js.map +1 -0
  26. package/dist/daemon/inputs.js +134 -0
  27. package/dist/daemon/inputs.js.map +1 -0
  28. package/dist/daemon/recorder.js +1232 -0
  29. package/dist/daemon/recorder.js.map +1 -0
  30. package/dist/daemon/refs.js +194 -0
  31. package/dist/daemon/refs.js.map +1 -0
  32. package/dist/daemon/server.js +1724 -0
  33. package/dist/daemon/server.js.map +1 -0
  34. package/dist/daemon/state.js +239 -0
  35. package/dist/daemon/state.js.map +1 -0
  36. package/dist/doctor.js +90 -0
  37. package/dist/doctor.js.map +1 -0
  38. package/dist/shared/paths.js +80 -0
  39. package/dist/shared/paths.js.map +1 -0
  40. package/dist/shared/protocol.js +28 -0
  41. package/dist/shared/protocol.js.map +1 -0
  42. package/dist/shared/secrets.js +92 -0
  43. package/dist/shared/secrets.js.map +1 -0
  44. package/dist/shared/text.js +39 -0
  45. package/dist/shared/text.js.map +1 -0
  46. package/dist/skills/compile.js +1420 -0
  47. package/dist/skills/compile.js.map +1 -0
  48. package/dist/skills/components.js +456 -0
  49. package/dist/skills/components.js.map +1 -0
  50. package/dist/skills/flow.js +1041 -0
  51. package/dist/skills/flow.js.map +1 -0
  52. package/dist/skills/learn.js +406 -0
  53. package/dist/skills/learn.js.map +1 -0
  54. package/dist/skills/ledger.js +304 -0
  55. package/dist/skills/ledger.js.map +1 -0
  56. package/dist/skills/relabel.js +206 -0
  57. package/dist/skills/relabel.js.map +1 -0
  58. package/dist/skills/repair.js +570 -0
  59. package/dist/skills/repair.js.map +1 -0
  60. package/dist/skills/replay.js +1281 -0
  61. package/dist/skills/replay.js.map +1 -0
  62. package/dist/skills/store.js +147 -0
  63. package/dist/skills/store.js.map +1 -0
  64. package/dist/spec/check.js +428 -0
  65. package/dist/spec/check.js.map +1 -0
  66. package/dist/spec/diagnostics.js +58 -0
  67. package/dist/spec/diagnostics.js.map +1 -0
  68. package/dist/spec/emit.js +2084 -0
  69. package/dist/spec/emit.js.map +1 -0
  70. package/dist/spec/index.js +62 -0
  71. package/dist/spec/index.js.map +1 -0
  72. package/dist/spec/ir.js +216 -0
  73. package/dist/spec/ir.js.map +1 -0
  74. package/dist/spec/lift.js +162 -0
  75. package/dist/spec/lift.js.map +1 -0
  76. package/dist/spec/locators.js +270 -0
  77. package/dist/spec/locators.js.map +1 -0
  78. package/dist/spec/lower.js +124 -0
  79. package/dist/spec/lower.js.map +1 -0
  80. package/dist/spec/repair.js +657 -0
  81. package/dist/spec/repair.js.map +1 -0
  82. package/dist/spec/rerecord.js +169 -0
  83. package/dist/spec/rerecord.js.map +1 -0
  84. package/dist/spec/rethread.js +120 -0
  85. package/dist/spec/rethread.js.map +1 -0
  86. package/package.json +50 -0
  87. package/skills/sitelooper/SKILL.md +228 -0
@@ -0,0 +1,545 @@
1
+ import { Ajv } from 'ajv';
2
+ export const REPORT_SCHEMA = {
3
+ type: 'object',
4
+ additionalProperties: false,
5
+ required: ['status', 'summary'],
6
+ properties: {
7
+ status: { type: 'string', enum: ['success', 'failure', 'blocked'] },
8
+ summary: { type: 'string', minLength: 1, maxLength: 2000 },
9
+ details: { type: 'string' },
10
+ evidence: {
11
+ type: 'object',
12
+ additionalProperties: false,
13
+ properties: {
14
+ url: { type: 'string' },
15
+ capturedDialogs: { type: 'array', items: { type: 'string' } },
16
+ values: {
17
+ type: 'object',
18
+ additionalProperties: { type: ['string', 'number', 'boolean', 'null'] },
19
+ },
20
+ },
21
+ },
22
+ },
23
+ };
24
+ let compiled = null;
25
+ function validator() {
26
+ if (!compiled) {
27
+ const ajv = new Ajv({ allErrors: true, allowUnionTypes: true });
28
+ compiled = ajv.compile(REPORT_SCHEMA);
29
+ }
30
+ return compiled;
31
+ }
32
+ /** Longest stringified value kept for a single evidence entry. */
33
+ const VALUE_CHARS = 300;
34
+ const SUMMARY_CHARS = 2000;
35
+ /**
36
+ * Validate the agent's `report` tool call, repairing near-misses first.
37
+ *
38
+ * Providers vary in how strictly they honour tool schemas, and the common
39
+ * failures are presentational rather than substantive: a list of ids where the
40
+ * schema wants one scalar, a stray extra key, a status that differs only in
41
+ * case. Rejecting those is expensive out of all proportion to the mistake —
42
+ * it costs a retry turn, then a blocked bail-out, and (with escalation on) a
43
+ * paid retry of the whole instruction on a pricier model, all because the
44
+ * agent formatted a value it had already correctly obtained.
45
+ *
46
+ * So: repair what is unambiguously repairable, and report what was repaired.
47
+ * Anything still invalid after coercion is a real disagreement about content
48
+ * and is fed back to the model as before.
49
+ */
50
+ /**
51
+ * The phrase in a `success` summary that says the work was NOT finished, or
52
+ * null. rpgr3-r2's 03-add reported success with "the visualization is still
53
+ * 'Time series' rather than 'Text' … ran out of turns" — accepted as-is, the
54
+ * flow marked the step done and the API verifier found no text panel. The
55
+ * status and the prose disagree; the loop holds such a report once and asks
56
+ * the model to make them agree.
57
+ */
58
+ export function admitsIncompletion(summary) {
59
+ const m = /\b(ran out of turns|out of turns|unable to|was not able to|not able to|could not|couldn't|did not (?:complete|finish|save|succeed|manage)|failed to|not (?:yet )?saved|unsaved changes|incomplete|still (?:shows?|set to|the default|remains?)|remains? (?:unset|unchanged|the default))\b/i.exec(summary);
60
+ if (!m)
61
+ return null;
62
+ // "still shows 3 panels after refresh, as expected" is a verified
63
+ // invariant, not an admission: an assertion word right after the phrase
64
+ // clears it.
65
+ const tail = summary.slice(m.index + m[0].length, m.index + m[0].length + 60);
66
+ if (/\b(as (?:expected|required|intended|designed)|which is (?:correct|right|expected)|correctly)\b/i.test(tail))
67
+ return null;
68
+ return m[1];
69
+ }
70
+ export function validateReport(input) {
71
+ const validate = validator();
72
+ if (validate(input))
73
+ return { ok: true, report: input };
74
+ const { value, notes } = coerce(input);
75
+ if (notes.length && validate(value)) {
76
+ return { ok: true, report: value, coerced: notes };
77
+ }
78
+ const error = (validate.errors ?? [])
79
+ .map((e) => `${e.instancePath || '(root)'} ${e.message}`)
80
+ .join('; ');
81
+ return { ok: false, error: error || 'report did not match the required schema' };
82
+ }
83
+ /** A scalar the schema accepts, or null when the input cannot be reduced to one. */
84
+ function toScalar(v) {
85
+ if (v === null || typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {
86
+ return typeof v === 'string' && v.length > VALUE_CHARS ? v.slice(0, VALUE_CHARS - 1) + '…' : v;
87
+ }
88
+ // The frequent real-world miss: an array of ids/names where one scalar was asked for.
89
+ const text = Array.isArray(v) ? v.map((x) => (x === null ? 'null' : String(x))).join(', ') : safeJson(v);
90
+ return text.length > VALUE_CHARS ? text.slice(0, VALUE_CHARS - 1) + '…' : text;
91
+ }
92
+ function safeJson(v) {
93
+ try {
94
+ return JSON.stringify(v) ?? String(v);
95
+ }
96
+ catch {
97
+ return String(v);
98
+ }
99
+ }
100
+ function coerce(input) {
101
+ const notes = [];
102
+ if (typeof input !== 'object' || input === null || Array.isArray(input)) {
103
+ return { value: {}, notes };
104
+ }
105
+ const src = input;
106
+ const out = {};
107
+ if (typeof src.status === 'string') {
108
+ const norm = src.status.trim().toLowerCase();
109
+ if (norm !== src.status)
110
+ notes.push(`status normalised to "${norm}"`);
111
+ out.status = norm;
112
+ }
113
+ else if (src.status !== undefined) {
114
+ out.status = src.status; // leave it: not something we can guess
115
+ }
116
+ if (typeof src.summary === 'string') {
117
+ out.summary =
118
+ src.summary.length > SUMMARY_CHARS ? src.summary.slice(0, SUMMARY_CHARS - 1) + '…' : src.summary;
119
+ if (out.summary !== src.summary)
120
+ notes.push('summary truncated');
121
+ }
122
+ else if (src.summary !== undefined) {
123
+ out.summary = String(src.summary);
124
+ notes.push('summary stringified');
125
+ }
126
+ if (src.details !== undefined) {
127
+ out.details = typeof src.details === 'string' ? src.details : safeJson(src.details);
128
+ if (out.details !== src.details)
129
+ notes.push('details stringified');
130
+ }
131
+ if (typeof src.evidence === 'object' && src.evidence !== null && !Array.isArray(src.evidence)) {
132
+ const ev = src.evidence;
133
+ const evOut = {};
134
+ if (ev.url !== undefined) {
135
+ evOut.url = typeof ev.url === 'string' ? ev.url : String(ev.url);
136
+ if (evOut.url !== ev.url)
137
+ notes.push('evidence.url stringified');
138
+ }
139
+ if (ev.capturedDialogs !== undefined) {
140
+ const list = Array.isArray(ev.capturedDialogs) ? ev.capturedDialogs : [ev.capturedDialogs];
141
+ if (!Array.isArray(ev.capturedDialogs))
142
+ notes.push('evidence.capturedDialogs wrapped in an array');
143
+ const strs = list.map((d) => (typeof d === 'string' ? d : safeJson(d)));
144
+ if (strs.some((s, i) => s !== list[i]))
145
+ notes.push('evidence.capturedDialogs entries stringified');
146
+ evOut.capturedDialogs = strs;
147
+ }
148
+ if (typeof ev.values === 'object' && ev.values !== null && !Array.isArray(ev.values)) {
149
+ const vals = {};
150
+ const fixed = [];
151
+ for (const [k, v] of Object.entries(ev.values)) {
152
+ if (v === undefined) {
153
+ fixed.push(k);
154
+ continue; // JSON has no undefined; drop rather than invent a value
155
+ }
156
+ const scalar = toScalar(v);
157
+ if (scalar !== v)
158
+ fixed.push(k);
159
+ vals[k] = scalar;
160
+ }
161
+ if (fixed.length)
162
+ notes.push(`evidence.values flattened to scalars: ${fixed.join(', ')}`);
163
+ evOut.values = vals;
164
+ }
165
+ else if (ev.values !== undefined) {
166
+ notes.push('evidence.values dropped (not an object)');
167
+ }
168
+ const extras = Object.keys(ev).filter((k) => !['url', 'capturedDialogs', 'values'].includes(k));
169
+ if (extras.length)
170
+ notes.push(`unknown evidence key(s) dropped: ${extras.join(', ')}`);
171
+ out.evidence = evOut;
172
+ }
173
+ else if (src.evidence !== undefined) {
174
+ notes.push('evidence dropped (not an object)');
175
+ }
176
+ const rootExtras = Object.keys(src).filter((k) => !['status', 'summary', 'details', 'evidence'].includes(k));
177
+ if (rootExtras.length)
178
+ notes.push(`unknown key(s) dropped: ${rootExtras.join(', ')}`);
179
+ return { value: out, notes };
180
+ }
181
+ /**
182
+ * Publish reads the model LABELLED at call time into `evidence.values`.
183
+ *
184
+ * The naming problem is an attention problem, not a comprehension one: asked at
185
+ * report time, the model must recall a value it read fifteen turns earlier, and
186
+ * the probe put wording changes at noise level while MOVING the ask 4x'd
187
+ * compliance. This moves it all the way — the label is given in the same tool
188
+ * call that reads the value, when the model's attention is on that exact value,
189
+ * and everything after is deterministic: the labelled value goes into evidence
190
+ * under the model's own name, the naming ask never needs to fire for it, and
191
+ * `readLabel` in compile ties the recorded read to that name for replay.
192
+ *
193
+ * Runs BEFORE backfillReadValues so the model's name wins over a selector slug
194
+ * — `order_reference`, not `h1`. Singular reads only: read_all's label would
195
+ * name a table. Mutates the report; returns the names added.
196
+ */
197
+ export function promoteLabelledReads(report, reads) {
198
+ if (report.status !== 'success')
199
+ return [];
200
+ const values = { ...(report.evidence?.values ?? {}) };
201
+ const present = new Set(Object.values(values).map((v) => String(v).trim()));
202
+ const added = [];
203
+ for (const read of reads) {
204
+ if (!read.label || read.values.length !== 1)
205
+ continue;
206
+ const v = read.values[0].trim();
207
+ if (!v || v.length > VALUE_CHARS || present.has(v))
208
+ continue;
209
+ // The model vouched for this value by labelling it, so an unusable label
210
+ // falls back rather than dropping the value (same stance as addEvidenceValue).
211
+ const name = uniqueName(slug(read.label) ?? 'value', values);
212
+ values[name] = v;
213
+ present.add(v);
214
+ added.push(name);
215
+ }
216
+ if (added.length)
217
+ (report.evidence ??= {}).values = values;
218
+ return added;
219
+ }
220
+ /** Most read values promoted into evidence per report — enough for any real page summary, a cap against read_all floods. */
221
+ const MAX_PROMOTED = 8;
222
+ const MIN_PROMOTED_LEN = 3;
223
+ /**
224
+ * Deterministically promote read results the report MENTIONED but did not
225
+ * structure. Compile keeps a recorded `read` only when its value appears in
226
+ * `evidence.values` (that is the proof the read mattered) — but models often
227
+ * put the value in the summary prose instead, so the read is dropped, no
228
+ * replayable step survives, and the instruction compiles to no skill. This
229
+ * closes that gap without gating: for each value a real read observed, if the
230
+ * prose cites it verbatim (token boundaries) and `evidence.values` does not
231
+ * already carry it, add it under a name derived from the read's target.
232
+ * Mutates the report; returns the names added.
233
+ */
234
+ export function backfillReadValues(report, reads, opts = {}) {
235
+ const values = { ...(report.evidence?.values ?? {}) };
236
+ const present = new Set(Object.values(values).map((v) => String(v).trim()));
237
+ const added = [];
238
+ for (const { read, value: v } of promotableReads(report, reads, opts)) {
239
+ if (added.length >= MAX_PROMOTED)
240
+ break;
241
+ // A value whose only available name would be "value" is not worth
242
+ // publishing. fwod18's 03-create promoted the column heading "Untaxed
243
+ // Amount" and the status badge "New" under `value` and `value_2`,
244
+ // because both reads targeted a snapshot ref and slug() can make no
245
+ // name from `@e757`. Those became report outputs no later step would
246
+ // ever reference, while the value seven steps DID need went unpinned.
247
+ // Publishing page furniture under a meaningless name is strictly worse
248
+ // than not publishing it: it is noise a replay must still reproduce.
249
+ const base = slug(read.target);
250
+ if (!base)
251
+ continue;
252
+ const name = uniqueName(base, values);
253
+ values[name] = v;
254
+ present.add(v);
255
+ added.push(name);
256
+ }
257
+ if (added.length)
258
+ (report.evidence ??= {}).values = values;
259
+ return added;
260
+ }
261
+ /**
262
+ * Read values the report CITED in prose but did not put in `evidence.values`,
263
+ * paired with the read that observed them. The one filter both the deterministic
264
+ * backfill and the naming retry work from, so they can never disagree about
265
+ * which values are unnamed.
266
+ */
267
+ function promotableReads(report, reads, opts = {}) {
268
+ const { requireCitation = true } = opts;
269
+ const prose = `${report.summary} ${report.details ?? ''}`;
270
+ const present = new Set(Object.values(report.evidence?.values ?? {}).map((v) => String(v).trim()));
271
+ const out = [];
272
+ const seen = new Set();
273
+ for (const read of reads) {
274
+ for (const raw of read.values) {
275
+ const v = raw.trim();
276
+ if (v.length < MIN_PROMOTED_LEN || v.length > VALUE_CHARS || present.has(v) || seen.has(v))
277
+ continue;
278
+ // Citation is the proof the read MATTERED, and dropping it is only safe
279
+ // for singular reads: a read that deliberately targeted one element is
280
+ // itself the claim the value matters, while read_all's forty cells are a
281
+ // table, not forty claims. So `requireCitation: false` still requires it
282
+ // of bulk values.
283
+ if (!cites(prose, v) && (requireCitation || read.values.length > 1))
284
+ continue;
285
+ seen.add(v);
286
+ out.push({ read, value: v });
287
+ }
288
+ }
289
+ return out;
290
+ }
291
+ /**
292
+ * Values this instruction read off the page and then described in prose without
293
+ * naming them in `evidence.values`.
294
+ *
295
+ * These are the values `backfillReadValues` would name from their SELECTOR, and
296
+ * a selector is a bad name in a way that compounds. fwod24 recorded the odoo
297
+ * quotation reference as `02-create.h1`, because the model returned
298
+ * `evidence.values: {}` on five of nine instructions and every name in the flow
299
+ * came from the backfill. Eleven flow references pointed at `h1`; on both
300
+ * replays the bare `page.locator('h1')` read missed, nothing republished the
301
+ * output, and four of seven steps fell to the model with
302
+ * `unresolved reference(s): 02-create.h1`. The model had the right name — n3's
303
+ * own recovery report called it `quotation_reference` — but run 1's naming is
304
+ * permanent, so the good name never got in.
305
+ *
306
+ * Asking once, naming the values so the model only has to label them, costs one
307
+ * cheap turn on the RECORDING run and buys a name every later run reproduces.
308
+ * Strengthening the tool-schema wording did not work: this is the same ask made
309
+ * where it cannot be skimmed past.
310
+ */
311
+ /**
312
+ * What the loop says when it holds a report for naming. Exported so
313
+ * bench/naming-probe.mjs measures the text that actually ships rather than a
314
+ * copy of it that can drift out of agreement with this one.
315
+ */
316
+ /**
317
+ * Union of two reports' evidence values, keeping every value either one names.
318
+ *
319
+ * The naming retry asks for the report "unchanged except that evidence.values
320
+ * includes each of those values", and models do not honour the "unchanged"
321
+ * half. Traced over the recorded corpus, one retry went
322
+ *
323
+ * before ["contact_name","contact_city","sales_order_title","sales_order_status"]
324
+ * after ["contact_name","contact_city","order_reference","order_status"]
325
+ *
326
+ * — it added the order reference we asked for and silently dropped the title.
327
+ * Taking the second report wholesale meant the ask added and subtracted in
328
+ * equal measure, which is why firing it 8 times moved the score not at all.
329
+ *
330
+ * Union by VALUE, not by key: a model that renames `sales_order_status` to
331
+ * `order_status` has not lost anything, and carrying both would publish the
332
+ * same value twice under two names for later steps to choose between. The
333
+ * second report's naming wins; only values it dropped entirely come back.
334
+ */
335
+ export function mergeReportValues(first, second) {
336
+ const out = { ...(second ?? {}) };
337
+ const held = new Set(Object.values(out).map((v) => String(v).trim()));
338
+ for (const [k, v] of Object.entries(first ?? {})) {
339
+ if (held.has(String(v).trim()) || k in out)
340
+ continue;
341
+ out[k] = v;
342
+ }
343
+ return out;
344
+ }
345
+ export function namingAskMessage(unnamed) {
346
+ const it = unnamed.length === 1 ? 'it' : 'them';
347
+ return (`report not accepted yet — you read ${unnamed.map((v) => JSON.stringify(v)).join(', ')} off the page and described ${it} in the summary, but evidence.values does not name ${it}. ` +
348
+ 'Call report again, unchanged except that evidence.values includes each of those values under the name a person would use for it ' +
349
+ '(order_reference, unit_price, customer_name — not a selector fragment). Later work addresses records by these names; a value left only in prose cannot be used.');
350
+ }
351
+ export function unnamedReadValues(report, reads, opts = {}) {
352
+ if (report.status !== 'success')
353
+ return [];
354
+ const { requireCitation = false } = opts;
355
+ if (requireCitation)
356
+ return promotableReads(report, reads).slice(0, MAX_PROMOTED).map((p) => p.value);
357
+ // Key the ask on what the READS returned, not on what the prose happens to
358
+ // quote. The citation test earns its place in backfillReadValues, which
359
+ // invents a name unilaterally and needs proof the read mattered. As a gate on
360
+ // ASKING the author it is far too strict, and the probe priced it: over the
361
+ // recorded corpus the ask fired on 3 of 27 instructions and was answered 3
362
+ // times out of 3. A mechanism that works whenever it runs and runs on a ninth
363
+ // of cases is a trigger problem, not a mechanism problem — and a summary that
364
+ // says "created the quotation and confirmed it" without repeating S00021
365
+ // never tripped it, which is the common case rather than the odd one.
366
+ const present = new Set(Object.values(report.evidence?.values ?? {}).map((v) => String(v).trim()));
367
+ const out = [];
368
+ const seen = new Set();
369
+ for (const read of reads) {
370
+ // read_all is bulk by nature — a table of forty cells is not forty values
371
+ // the caller needs named, and asking about them would bury the one that
372
+ // matters. Its values still reach evidence through the backfill.
373
+ if (read.values.length > 1)
374
+ continue;
375
+ // A read the model labelled at call time is already named — promotion
376
+ // publishes it deterministically, so asking again would nag about work
377
+ // that is done.
378
+ if (read.label)
379
+ continue;
380
+ for (const raw of read.values) {
381
+ const v = raw.trim();
382
+ if (v.length < MIN_PROMOTED_LEN || v.length > VALUE_CHARS || present.has(v) || seen.has(v))
383
+ continue;
384
+ seen.add(v);
385
+ out.push(v);
386
+ }
387
+ }
388
+ return out.slice(0, MAX_PROMOTED);
389
+ }
390
+ /** A name derived from a read's target, or null when the target names nothing. */
391
+ function slug(target) {
392
+ const s = target.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '').slice(0, 24);
393
+ // A target that is a SNAPSHOT REF names nothing. `@e5322` slugged to
394
+ // `e5322`, buildFlow minted {{03-report.e5322}} into three later steps of
395
+ // fwgr10's flow, and no replay ever resolved it — a reference no human or
396
+ // model would write, pointing at a handle that expires with the snapshot.
397
+ // Same defect as the prose-identifier path, second site; fixing one and not
398
+ // looking for the other is why this survived.
399
+ //
400
+ // A selector-derived slug (`dashboard_title`, `price_cell`) is meaningful
401
+ // and is kept.
402
+ if (!s || /^e\d+$/.test(s))
403
+ return null;
404
+ return s;
405
+ }
406
+ function uniqueName(base, taken) {
407
+ if (!(base in taken))
408
+ return base;
409
+ for (let i = 2;; i++)
410
+ if (!(`${base}_${i}` in taken))
411
+ return `${base}_${i}`;
412
+ }
413
+ /**
414
+ * Does the prose quote this value? Internal whitespace is elastic.
415
+ *
416
+ * fwod25's instr 5 read "£ 1,599.00" off the totals and wrote "£1,599.00" in
417
+ * the summary. A verbatim test called that a miss, so the value was never
418
+ * promoted and never named — one space between a currency symbol and its
419
+ * digits. Models normalise spacing when they write prose; the page does not.
420
+ * Everything else stays strict: this matches the same characters in the same
421
+ * order, only tolerant about how much space sits between them.
422
+ */
423
+ function cites(prose, value) {
424
+ const body = escapeRegExp(value).replace(/\s+/g, '\\s*');
425
+ return new RegExp(`(?<![A-Za-z0-9])${body}(?![A-Za-z0-9])`).test(prose);
426
+ }
427
+ function escapeRegExp(s) {
428
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
429
+ }
430
+ /** Most scalars taken out of one composed value. A read_all dumped as JSON is a table, not evidence. */
431
+ const MAX_LEAVES = 8;
432
+ /**
433
+ * Split a report value the model COMPOSED out of several page values into the
434
+ * values it was made of.
435
+ *
436
+ * fwod17's 03-open reported two order lines as JSON blobs:
437
+ *
438
+ * line_1: {"product":"Customizable Desk","qty":"3.00","unit_price":"750.00",…}
439
+ *
440
+ * Nothing downstream can use that. `captureReadBack` pins evidence values on
441
+ * the page, and no element shows that string, so the six reads the run really
442
+ * did were recorded with no label; `publishedOutputs` keeps a report value
443
+ * only when it is a pure slot fill, and this one is a hand-built literal. So a
444
+ * tier-A replay correctly dropped it — and took `{{03-open.line_1#qty}}` with
445
+ * it, sending four steps of the flow to recovery for values sitting on screen.
446
+ *
447
+ * A composite is really several values, so make it several. Each leaf is a
448
+ * string a real element shows, which means read-back can pin it, the read gets
449
+ * a label, and the flow references `{{03-open.line_1_qty}}` — an output every
450
+ * zero-model replay republishes from its OWN page.
451
+ *
452
+ * The composite itself is dropped: keeping it would leave the unreferencable
453
+ * form available to reference. Mutates the report; returns the names added.
454
+ */
455
+ export function flattenComposedValues(report) {
456
+ const values = report.evidence?.values;
457
+ if (!values)
458
+ return [];
459
+ const added = [];
460
+ for (const [key, raw] of Object.entries(values)) {
461
+ if (typeof raw !== 'string' || !/^\s*[[{]/.test(raw))
462
+ continue;
463
+ let parsed;
464
+ try {
465
+ parsed = JSON.parse(raw);
466
+ }
467
+ catch {
468
+ continue; // prose that merely opens with a bracket
469
+ }
470
+ const leaves = leavesOf(parsed);
471
+ // Nothing to split, or a table rather than a record: leave it whole.
472
+ if (!leaves.length || leaves.length > MAX_LEAVES)
473
+ continue;
474
+ delete values[key];
475
+ for (const [path, value] of leaves) {
476
+ const name = uniqueName(`${key}_${slug(path)}`, values);
477
+ values[name] = value;
478
+ added.push(name);
479
+ }
480
+ }
481
+ return added;
482
+ }
483
+ /** Scalar leaves of a parsed value, two levels deep, as [path, text] pairs. */
484
+ function leavesOf(node, prefix = '', depth = 0) {
485
+ if (node === null || typeof node !== 'object') {
486
+ const text = String(node ?? '').trim();
487
+ return prefix && text ? [[prefix, text]] : [];
488
+ }
489
+ if (depth >= 2)
490
+ return [];
491
+ const entries = Array.isArray(node) ? node.map((v, i) => [String(i + 1), v]) : Object.entries(node);
492
+ return entries.flatMap(([k, v]) => leavesOf(v, prefix ? `${prefix}_${k}` : k, depth + 1));
493
+ }
494
+ /** Record identifiers cited in prose per report, and their shape. */
495
+ const MAX_PROSE_IDS = 3;
496
+ const MIN_PROSE_ID_LEN = 4;
497
+ const MAX_PROSE_ID_LEN = 40;
498
+ /**
499
+ * Identifier-like tokens the report's prose cites but `evidence.values` does
500
+ * not carry: an order reference (S00021), a ticket ref (RD-1015), a generated
501
+ * uid. Mixed letters AND digits is the test — it admits every app-minted
502
+ * reference seen across the bench targets while rejecting prices ("125.00"),
503
+ * counts, and ordinary words.
504
+ *
505
+ * These are the values later flow steps address the run's own record BY, so a
506
+ * step that leaves one unstructured strands every later step on the RECORDED
507
+ * run's record: fwod5-n2/n3 cancelled sales order S00021 — run n1's order —
508
+ * because the confirm step reported its reference only in prose and the flow
509
+ * had no reference to thread. The caller pins them on the live page (see
510
+ * captureReadBack) so a replay re-reads its own.
511
+ */
512
+ export function proseIdentifiers(report) {
513
+ const prose = `${report.summary} ${report.details ?? ''}`;
514
+ const present = new Set(Object.values(report.evidence?.values ?? {}).map((v) => String(v).trim()));
515
+ const out = [];
516
+ for (const m of prose.matchAll(/[A-Za-z0-9][A-Za-z0-9._-]*/g)) {
517
+ if (out.length >= MAX_PROSE_IDS)
518
+ break;
519
+ const v = m[0].replace(/[.\-_]+$/, '');
520
+ if (v.length < MIN_PROSE_ID_LEN || v.length > MAX_PROSE_ID_LEN)
521
+ continue;
522
+ if (!/[A-Za-z]/.test(v) || !/\d/.test(v))
523
+ continue;
524
+ // Not references, though they pass the letter+digit shape: a snapshot ref
525
+ // (e1234), an ordinal (10th), a measurement (100px, 30s). Each used to
526
+ // take one of the three slots and crowd out the real S00021.
527
+ if (/^e\d+$/.test(v) || /^\d+(st|nd|rd|th)$/i.test(v) || /^\d+(px|ms|s|m|h|d|kb|mb|gb|%)$/i.test(v))
528
+ continue;
529
+ if (present.has(v) || out.includes(v))
530
+ continue;
531
+ out.push(v);
532
+ }
533
+ return out;
534
+ }
535
+ /** Add a value to a report's evidence under a fresh name derived from `base`. */
536
+ export function addEvidenceValue(report, base, value) {
537
+ const values = { ...(report.evidence?.values ?? {}) };
538
+ // The caller vouched for this one by naming it explicitly ("ref"), so an
539
+ // unusable base falls back rather than dropping the value.
540
+ const name = uniqueName(slug(base) ?? 'value', values);
541
+ values[name] = value;
542
+ (report.evidence ??= {}).values = values;
543
+ return name;
544
+ }
545
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/agent/report.ts"],"names":[],"mappings":"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"}