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.
- package/LICENSE +21 -0
- package/README.md +625 -0
- package/bin/sitelooper.js +6 -0
- package/dist/agent/llm.js +460 -0
- package/dist/agent/llm.js.map +1 -0
- package/dist/agent/loop.js +870 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/prompt.js +40 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/agent/report.js +545 -0
- package/dist/agent/report.js.map +1 -0
- package/dist/agent/tools.js +1147 -0
- package/dist/agent/tools.js.map +1 -0
- package/dist/cli.js +1692 -0
- package/dist/cli.js.map +1 -0
- package/dist/daemon/browser.js +218 -0
- package/dist/daemon/browser.js.map +1 -0
- package/dist/daemon/codegen.js +241 -0
- package/dist/daemon/codegen.js.map +1 -0
- package/dist/daemon/dialogs.js +57 -0
- package/dist/daemon/dialogs.js.map +1 -0
- package/dist/daemon/diff.js +198 -0
- package/dist/daemon/diff.js.map +1 -0
- package/dist/daemon/fingerprint.js +98 -0
- package/dist/daemon/fingerprint.js.map +1 -0
- package/dist/daemon/inputs.js +134 -0
- package/dist/daemon/inputs.js.map +1 -0
- package/dist/daemon/recorder.js +1232 -0
- package/dist/daemon/recorder.js.map +1 -0
- package/dist/daemon/refs.js +194 -0
- package/dist/daemon/refs.js.map +1 -0
- package/dist/daemon/server.js +1724 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/state.js +239 -0
- package/dist/daemon/state.js.map +1 -0
- package/dist/doctor.js +90 -0
- package/dist/doctor.js.map +1 -0
- package/dist/shared/paths.js +80 -0
- package/dist/shared/paths.js.map +1 -0
- package/dist/shared/protocol.js +28 -0
- package/dist/shared/protocol.js.map +1 -0
- package/dist/shared/secrets.js +92 -0
- package/dist/shared/secrets.js.map +1 -0
- package/dist/shared/text.js +39 -0
- package/dist/shared/text.js.map +1 -0
- package/dist/skills/compile.js +1420 -0
- package/dist/skills/compile.js.map +1 -0
- package/dist/skills/components.js +456 -0
- package/dist/skills/components.js.map +1 -0
- package/dist/skills/flow.js +1041 -0
- package/dist/skills/flow.js.map +1 -0
- package/dist/skills/learn.js +406 -0
- package/dist/skills/learn.js.map +1 -0
- package/dist/skills/ledger.js +304 -0
- package/dist/skills/ledger.js.map +1 -0
- package/dist/skills/relabel.js +206 -0
- package/dist/skills/relabel.js.map +1 -0
- package/dist/skills/repair.js +570 -0
- package/dist/skills/repair.js.map +1 -0
- package/dist/skills/replay.js +1281 -0
- package/dist/skills/replay.js.map +1 -0
- package/dist/skills/store.js +147 -0
- package/dist/skills/store.js.map +1 -0
- package/dist/spec/check.js +428 -0
- package/dist/spec/check.js.map +1 -0
- package/dist/spec/diagnostics.js +58 -0
- package/dist/spec/diagnostics.js.map +1 -0
- package/dist/spec/emit.js +2084 -0
- package/dist/spec/emit.js.map +1 -0
- package/dist/spec/index.js +62 -0
- package/dist/spec/index.js.map +1 -0
- package/dist/spec/ir.js +216 -0
- package/dist/spec/ir.js.map +1 -0
- package/dist/spec/lift.js +162 -0
- package/dist/spec/lift.js.map +1 -0
- package/dist/spec/locators.js +270 -0
- package/dist/spec/locators.js.map +1 -0
- package/dist/spec/lower.js +124 -0
- package/dist/spec/lower.js.map +1 -0
- package/dist/spec/repair.js +657 -0
- package/dist/spec/repair.js.map +1 -0
- package/dist/spec/rerecord.js +169 -0
- package/dist/spec/rerecord.js.map +1 -0
- package/dist/spec/rethread.js +120 -0
- package/dist/spec/rethread.js.map +1 -0
- package/package.json +50 -0
- package/skills/sitelooper/SKILL.md +228 -0
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
import { candidateExpr, makeLocator, positionalExpr } from '../daemon/recorder.js';
|
|
2
|
+
import { fillParams } from './compile.js';
|
|
3
|
+
import { newSkillId } from './store.js';
|
|
4
|
+
/**
|
|
5
|
+
* Below this start-page similarity a drift is treated as a redesign: the page
|
|
6
|
+
* the skill was recorded on no longer exists in recognisable form, so patching
|
|
7
|
+
* individual selectors is selector-archaeology — the segment needs a fresh
|
|
8
|
+
* record run instead. Chosen from the flow benches, where healthy replays sat
|
|
9
|
+
* ≥0.95 and template changes dropped well below 0.8. A ticket with no
|
|
10
|
+
* similarity (no stored fingerprint) is treated as localized, because the
|
|
11
|
+
* cheap actions below are safe either way.
|
|
12
|
+
*/
|
|
13
|
+
export const LOCALIZED_SIMILARITY = 0.8;
|
|
14
|
+
/**
|
|
15
|
+
* Classify a run's drift tickets into repair work. Pure and deterministic —
|
|
16
|
+
* the model is only ever involved later, in executing `patch-segment`.
|
|
17
|
+
*/
|
|
18
|
+
export function triage(tickets, store) {
|
|
19
|
+
const seen = new Set();
|
|
20
|
+
const out = [];
|
|
21
|
+
// Loop iterations ("2.1.1", "2.4.1") all share one body step — canonicalise
|
|
22
|
+
// the tag so a loop that missed on every iteration yields ONE action, not
|
|
23
|
+
// one per iteration (repeat splices with stale indices would scramble the
|
|
24
|
+
// chain).
|
|
25
|
+
const canon = (tag) => (tag && tag.split('.').length === 3 ? tag.replace(/\.\d+\./, '.*.') : tag);
|
|
26
|
+
for (const t of tickets) {
|
|
27
|
+
const dedupe = `${t.skill}|${canon(t.atStep) ?? ''}|${t.key ?? ''}|${t.missedLocator ?? ''}`;
|
|
28
|
+
if (seen.has(dedupe))
|
|
29
|
+
continue;
|
|
30
|
+
seen.add(dedupe);
|
|
31
|
+
const localized = t.similarity === null || t.similarity >= LOCALIZED_SIMILARITY;
|
|
32
|
+
if (!localized) {
|
|
33
|
+
out.push({ kind: 're-record', ticket: t, why: `similarity ${t.similarity} < ${LOCALIZED_SIMILARITY}: the page template changed too much to patch selectors` });
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (t.fallbackUsed !== null && !positionalExpr(t.fallbackUsed)) {
|
|
37
|
+
out.push({ kind: 'promote-fallback', ticket: t });
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (t.missedLocator !== null) {
|
|
41
|
+
// An observation step that waits for or reads TEXT is not repairable by
|
|
42
|
+
// proposing a control: see notAControlWhy. Routed here, with the store
|
|
43
|
+
// to hand, so no proposer is ever asked for a locator for it.
|
|
44
|
+
const notAControl = store ? notAControlWhy(store.get(t.skill), t) : null;
|
|
45
|
+
if (notAControl) {
|
|
46
|
+
out.push({ kind: 'skip', ticket: t, why: notAControl });
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
// A POSITIONAL fallback that worked is a symptom, not a self-heal:
|
|
50
|
+
// promoting it would put "wherever sorted into that slot" first in the
|
|
51
|
+
// chain and enshrine exactly what verify-artifacts flags (fwgr17-n3's
|
|
52
|
+
// 03-open). The semantic locator moved — re-derive it.
|
|
53
|
+
out.push({ kind: 'patch-segment', ticket: t });
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
// Recovery with no locator to blame (unresolved reference, missing chain
|
|
57
|
+
// segment, ...): nothing a selector patch can fix.
|
|
58
|
+
out.push({ kind: 'skip', ticket: t, why: t.reason ? `no locator to patch (${t.reason})` : 'no locator to patch' });
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
/** Resolve a skill-internal step tag ("5" / "9.2.1" inside a loop) to the step holding the locator chain. */
|
|
63
|
+
export function stepByTag(skill, tag) {
|
|
64
|
+
if (!tag)
|
|
65
|
+
return null;
|
|
66
|
+
const parts = tag.split('.').map((n) => Number(n));
|
|
67
|
+
const top = skill.steps[parts[0] - 1];
|
|
68
|
+
if (!top)
|
|
69
|
+
return null;
|
|
70
|
+
if (parts.length === 1)
|
|
71
|
+
return top;
|
|
72
|
+
// "n.iter.k": a loop body step — the iteration index does not matter, the body is shared.
|
|
73
|
+
return top.body?.[parts[2] - 1] ?? null;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The cheap, no-model repair: the replay already proved a fallback resolves,
|
|
77
|
+
* so make it the primary. Mutates the stored skill in place — same
|
|
78
|
+
* candidates, new order, nothing invented — and keeps the old primary in the
|
|
79
|
+
* chain (drift can revert). Returns false when the ticket does not map onto
|
|
80
|
+
* the stored skill any more (skill gone, step gone, index out of range).
|
|
81
|
+
*/
|
|
82
|
+
export function promoteFallback(store, ticket) {
|
|
83
|
+
const skill = store.get(ticket.skill);
|
|
84
|
+
if (!skill || ticket.fallbackIndex === undefined || ticket.fallbackIndex < 1)
|
|
85
|
+
return false;
|
|
86
|
+
const step = stepByTag(skill, ticket.atStep);
|
|
87
|
+
const chain = step?.locators[ticket.key ?? 'target'];
|
|
88
|
+
if (!chain || ticket.fallbackIndex >= chain.length)
|
|
89
|
+
return false;
|
|
90
|
+
// The index was observed on a param-filled chain; make sure it still names
|
|
91
|
+
// the candidate the ticket promoted (a prior promotion, or a chain edit,
|
|
92
|
+
// may have moved it). Parameterised candidates can only be index-checked.
|
|
93
|
+
const expr = candidateExpr(chain[ticket.fallbackIndex]);
|
|
94
|
+
if (ticket.fallbackUsed && !expr.includes('{{') && expr !== ticket.fallbackUsed)
|
|
95
|
+
return false;
|
|
96
|
+
const [used] = chain.splice(ticket.fallbackIndex, 1);
|
|
97
|
+
chain.unshift(used);
|
|
98
|
+
store.put(skill);
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
const ROLE_FAMILY = {
|
|
102
|
+
textbox: 'text-input', searchbox: 'text-input', spinbutton: 'text-input',
|
|
103
|
+
combobox: 'select', listbox: 'select',
|
|
104
|
+
checkbox: 'toggle', radio: 'toggle', switch: 'toggle',
|
|
105
|
+
button: 'command', link: 'command', tab: 'command', option: 'command',
|
|
106
|
+
menuitem: 'command', menuitemcheckbox: 'command', menuitemradio: 'command',
|
|
107
|
+
};
|
|
108
|
+
const TAG_FAMILY = {
|
|
109
|
+
input: 'text-input', textarea: 'text-input', select: 'select',
|
|
110
|
+
button: 'command', a: 'command', summary: 'command',
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* The family a role/tag belongs to. An unknown role is its own family
|
|
114
|
+
* (`role:heading`), so it still compares equal to itself and unequal to
|
|
115
|
+
* everything else - unknown must not mean "matches anything".
|
|
116
|
+
*/
|
|
117
|
+
export function kindFamily(k) {
|
|
118
|
+
if (k.role)
|
|
119
|
+
return ROLE_FAMILY[k.role] ?? `role:${k.role}`;
|
|
120
|
+
if (k.tag)
|
|
121
|
+
return TAG_FAMILY[k.tag] ?? `tag:${k.tag}`;
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
/** What the step's tool alone implies about its target, when the chain says nothing. */
|
|
125
|
+
const TOOL_KIND = {
|
|
126
|
+
// A combobox in the ARIA sense is often a typed-into autocomplete, so a fill
|
|
127
|
+
// may legitimately land on either.
|
|
128
|
+
fill: { label: 'text input', families: ['text-input', 'select'] },
|
|
129
|
+
type: { label: 'text input', families: ['text-input', 'select'] },
|
|
130
|
+
select: { label: 'combobox', families: ['select'] },
|
|
131
|
+
check: { label: 'checkbox', families: ['toggle'] },
|
|
132
|
+
uncheck: { label: 'checkbox', families: ['toggle'] },
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* What kind of control the drifted step named - the whole point of the
|
|
136
|
+
* soundness check in patchSegment. In order of how much the recording
|
|
137
|
+
* actually knows: the `point` candidate carries the recorded element's own
|
|
138
|
+
* role and tag (the recorder reads them off the element at record time); a
|
|
139
|
+
* `role` candidate carries the role it was matched by; and failing both, the
|
|
140
|
+
* tool implies a shape (you do not `fill` a button). Null when nothing says -
|
|
141
|
+
* a click on a css path, say.
|
|
142
|
+
*/
|
|
143
|
+
export function recordedKindOf(step, chain) {
|
|
144
|
+
const point = chain.find((c) => c.kind === 'point');
|
|
145
|
+
if (point) {
|
|
146
|
+
const label = point.role ?? point.tag;
|
|
147
|
+
const family = kindFamily({ role: point.role, tag: point.tag });
|
|
148
|
+
if (label && family)
|
|
149
|
+
return { label, families: [family], source: 'point' };
|
|
150
|
+
}
|
|
151
|
+
const role = chain.find((c) => c.kind === 'role');
|
|
152
|
+
if (role)
|
|
153
|
+
return { label: role.role, families: [kindFamily({ role: role.role })], source: 'role' };
|
|
154
|
+
const byTool = step ? TOOL_KIND[step.tool] : undefined;
|
|
155
|
+
return byTool ? { ...byTool, source: 'tool' } : null;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The role/tag of the element a candidate resolves to on the LIVE page, read
|
|
159
|
+
* the way the recorder reads it (recorder.ts's `implicitRole`, and markPoint's
|
|
160
|
+
* `kindOf`): an explicit role attribute, else the tag's implicit role.
|
|
161
|
+
* Mirrored here rather than imported because both copies live inside
|
|
162
|
+
* page.evaluate bodies in recorder.ts and are not exported.
|
|
163
|
+
*/
|
|
164
|
+
export async function liveKind(page, c) {
|
|
165
|
+
try {
|
|
166
|
+
return await makeLocator(page, c).evaluate((el) => {
|
|
167
|
+
const tag = el.tagName.toLowerCase();
|
|
168
|
+
const type = (el.getAttribute('type') || '').toLowerCase();
|
|
169
|
+
const implicit = () => {
|
|
170
|
+
if (tag === 'button')
|
|
171
|
+
return 'button';
|
|
172
|
+
if (tag === 'a')
|
|
173
|
+
return el.hasAttribute('href') ? 'link' : null;
|
|
174
|
+
if (tag === 'select')
|
|
175
|
+
return el.hasAttribute('multiple') ? 'listbox' : 'combobox';
|
|
176
|
+
if (tag === 'textarea')
|
|
177
|
+
return 'textbox';
|
|
178
|
+
if (tag === 'img')
|
|
179
|
+
return 'img';
|
|
180
|
+
if (/^h[1-6]$/.test(tag))
|
|
181
|
+
return 'heading';
|
|
182
|
+
if (tag === 'input') {
|
|
183
|
+
if (type === 'checkbox')
|
|
184
|
+
return 'checkbox';
|
|
185
|
+
if (type === 'radio')
|
|
186
|
+
return 'radio';
|
|
187
|
+
if (type === 'submit' || type === 'button' || type === 'reset')
|
|
188
|
+
return 'button';
|
|
189
|
+
if (type === 'search')
|
|
190
|
+
return 'searchbox';
|
|
191
|
+
if (type === 'number')
|
|
192
|
+
return 'spinbutton';
|
|
193
|
+
if (['text', 'email', 'tel', 'url', 'password', ''].includes(type))
|
|
194
|
+
return 'textbox';
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
return null;
|
|
198
|
+
};
|
|
199
|
+
return { role: el.getAttribute('role') || implicit(), tag };
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Why this ticket cannot be repaired by proposing a CONTROL, or null when it
|
|
208
|
+
* can.
|
|
209
|
+
*
|
|
210
|
+
* A `wait_for` (or `read`) whose target names TEXT is an EXPECTATION, not a
|
|
211
|
+
* control that moved: "wait until the page shows 'Screen protector'". When it
|
|
212
|
+
* stops resolving, the honest reading is that the page no longer shows that
|
|
213
|
+
* text - the thing was deleted, or renamed, or never got created - and asking
|
|
214
|
+
* a model for "the element that serves the same purpose" invites exactly the
|
|
215
|
+
* answer a live repair gave: `getByTestId('archive')`, the Archive BUTTON,
|
|
216
|
+
* offered as the replacement for the text of a part that had just been
|
|
217
|
+
* deleted. Resolution is not intent. This is a failed expectation for a human
|
|
218
|
+
* to look at, not drift for a machine to patch.
|
|
219
|
+
*/
|
|
220
|
+
export function notAControlWhy(skill, ticket) {
|
|
221
|
+
const step = skill ? stepByTag(skill, ticket.atStep) : null;
|
|
222
|
+
const chain = step?.locators[ticket.key ?? 'target'];
|
|
223
|
+
if (!step || !chain)
|
|
224
|
+
return null;
|
|
225
|
+
// A step recorded with NO locator at all was never findable: the agent read
|
|
226
|
+
// something back without naming an element ("(read-back)"), so there is
|
|
227
|
+
// nothing that drifted and nothing a proposal could replace. Without this the
|
|
228
|
+
// model was asked for "the control" of an unlabelled read and, having no
|
|
229
|
+
// recorded kind to be checked against, its guess (a search box) was stored.
|
|
230
|
+
if (!chain.length) {
|
|
231
|
+
return `step ${ticket.atStep ?? '?'} (${step.tool}) was recorded without a locator, so nothing drifted - there is nothing to patch`;
|
|
232
|
+
}
|
|
233
|
+
if (!['wait_for', 'read', 'read_all'].includes(step.tool))
|
|
234
|
+
return null;
|
|
235
|
+
const primary = chain[0];
|
|
236
|
+
const namesText = (primary?.kind === 'text' && !!primary.text) ||
|
|
237
|
+
(primary?.kind === 'scoped' && !!primary.hasText && !primary.selector) ||
|
|
238
|
+
(step.tool === 'wait_for' && /^text_/.test(String(step.args.state ?? '')));
|
|
239
|
+
if (!namesText)
|
|
240
|
+
return null;
|
|
241
|
+
const what = primary?.kind === 'text' ? JSON.stringify(primary.text)
|
|
242
|
+
: primary?.kind === 'scoped' ? JSON.stringify(primary.hasText)
|
|
243
|
+
: JSON.stringify(String(step.args.text ?? ''));
|
|
244
|
+
const verb = step.tool === 'wait_for' ? 'waits for' : 'reads';
|
|
245
|
+
return `step ${ticket.atStep ?? '?'} ${verb} the text ${what}, which the page no longer shows: a failed expectation for a human to look at, not a control that drifted - there is no control to propose`;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The SLOW-MODE model repair for one localized-drift ticket: ask `propose`
|
|
249
|
+
* (a smart model, or a test stub) for the moved control's new locator on the
|
|
250
|
+
* live page, verify it actually resolves there, and store the patched chain
|
|
251
|
+
* as a NEW provisional variant of the drifted skill. The variant must EARN
|
|
252
|
+
* adoption through the normal promote/demote lifecycle — the original is
|
|
253
|
+
* left untouched until the variant validates and supersedes it.
|
|
254
|
+
*/
|
|
255
|
+
export async function patchSegment(store, ticket, page, propose, now = new Date().toISOString()) {
|
|
256
|
+
const skill = store.get(ticket.skill);
|
|
257
|
+
const step = skill ? stepByTag(skill, ticket.atStep) : null;
|
|
258
|
+
const chain = step?.locators[ticket.key ?? 'target'];
|
|
259
|
+
if (!skill || !step || !chain)
|
|
260
|
+
return { ticket, outcome: 'not-applicable', detail: 'the ticket no longer maps onto a stored skill step' };
|
|
261
|
+
// Before any model is asked anything: some steps have no control to
|
|
262
|
+
// re-derive at all. Asking anyway is what produced the Archive button as the
|
|
263
|
+
// replacement for a deleted part's text.
|
|
264
|
+
const notAControl = notAControlWhy(skill, ticket);
|
|
265
|
+
if (notAControl)
|
|
266
|
+
return { ticket, outcome: 'not-a-control', detail: notAControl };
|
|
267
|
+
const recorded = recordedKindOf(step, chain);
|
|
268
|
+
const snapshot = await interactiveSnapshot(page);
|
|
269
|
+
const proposed = await propose({ skill, ticket, chain, snapshot, recordedKind: recorded?.label, tool: step.tool });
|
|
270
|
+
if (!proposed)
|
|
271
|
+
return { ticket, outcome: 'no-proposal' };
|
|
272
|
+
// Verify against the live page before adopting anything.
|
|
273
|
+
let count = 0;
|
|
274
|
+
try {
|
|
275
|
+
count = await makeLocator(page, proposed).count();
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
count = 0;
|
|
279
|
+
}
|
|
280
|
+
if (count !== 1) {
|
|
281
|
+
return { ticket, outcome: 'proposal-does-not-resolve', detail: `${candidateExpr(proposed)} matched ${count} element(s)` };
|
|
282
|
+
}
|
|
283
|
+
// RESOLVING IS NOT INTENT. A locator that finds exactly one element on the
|
|
284
|
+
// live page has proved only that the element exists - not that it is the
|
|
285
|
+
// control the step was about. Ask the live element what kind of thing it is,
|
|
286
|
+
// the same way the recorder asked at record time, and refuse a proposal of a
|
|
287
|
+
// different kind outright.
|
|
288
|
+
const live = await liveKind(page, proposed);
|
|
289
|
+
const liveFamily = live ? kindFamily(live) : null;
|
|
290
|
+
let unverifiedKind = false;
|
|
291
|
+
if (!recorded || !live || !liveFamily) {
|
|
292
|
+
// Nothing to check against (a click on a bare css path, or an element
|
|
293
|
+
// whose role could not be read). Take the proposal, but say so.
|
|
294
|
+
unverifiedKind = true;
|
|
295
|
+
}
|
|
296
|
+
else if (!recorded.families.includes(liveFamily)) {
|
|
297
|
+
const liveLabel = live.role ?? live.tag;
|
|
298
|
+
return {
|
|
299
|
+
ticket,
|
|
300
|
+
outcome: 'wrong-kind',
|
|
301
|
+
detail: `${candidateExpr(proposed)} proposed a ${liveLabel}, the recorded control was a ${recorded.label}`,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const variant = structuredClone(skill);
|
|
305
|
+
const vstep = stepByTag(variant, ticket.atStep);
|
|
306
|
+
vstep.locators[ticket.key ?? 'target'] = [proposed, ...chain];
|
|
307
|
+
// The control changed, so the step's recorded page-change expectations are
|
|
308
|
+
// stale by construction (they name the OLD control — e.g. its accessible
|
|
309
|
+
// label — and would hard-fail the patched replay). Drop them on the
|
|
310
|
+
// variant; safety comes from the lifecycle, which makes the variant earn
|
|
311
|
+
// validation across runs before it supersedes the original.
|
|
312
|
+
delete vstep.expect;
|
|
313
|
+
variant.id = newSkillId(variant.origin, `${variant.template}~repair`, now);
|
|
314
|
+
variant.status = 'provisional';
|
|
315
|
+
variant.variantOf = skill.id;
|
|
316
|
+
variant.stats = { uses: 0, successes: 0, partial: 0, created: now, failedAtStep: {}, fallthroughs: 0 };
|
|
317
|
+
variant.provenance = { ...variant.provenance, session: 'post-session-repair', created: now };
|
|
318
|
+
store.put(variant);
|
|
319
|
+
return { ticket, variant: variant.id, outcome: 'patched', detail: candidateExpr(proposed), ...(unverifiedKind ? { unverifiedKind } : {}) };
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* The interactive elements of the live page, one per line, in the shapes a
|
|
323
|
+
* proposer can turn straight into a LocatorCandidate: role+name, label,
|
|
324
|
+
* placeholder, testid, id.
|
|
325
|
+
*/
|
|
326
|
+
export async function interactiveSnapshot(page, limit = 120) {
|
|
327
|
+
const rows = await page
|
|
328
|
+
.evaluate((max) => {
|
|
329
|
+
const out = [];
|
|
330
|
+
const els = document.querySelectorAll('a, button, input, select, textarea, [role], [tabindex], label');
|
|
331
|
+
for (const el of Array.from(els).slice(0, max * 2)) {
|
|
332
|
+
if (out.length >= max)
|
|
333
|
+
break;
|
|
334
|
+
const h = el;
|
|
335
|
+
if (h.offsetParent === null && h.tagName !== 'OPTION')
|
|
336
|
+
continue;
|
|
337
|
+
const bits = [h.tagName.toLowerCase()];
|
|
338
|
+
const role = h.getAttribute('role');
|
|
339
|
+
if (role)
|
|
340
|
+
bits.push(`role=${role}`);
|
|
341
|
+
const id = h.id;
|
|
342
|
+
if (id)
|
|
343
|
+
bits.push(`id=${id}`);
|
|
344
|
+
const testid = h.getAttribute('data-testid');
|
|
345
|
+
if (testid)
|
|
346
|
+
bits.push(`testid=${testid}`);
|
|
347
|
+
const label = (h.closest('label')?.textContent ?? h.getAttribute('aria-label') ?? '').trim().replace(/\s+/g, ' ').slice(0, 60);
|
|
348
|
+
if (label)
|
|
349
|
+
bits.push(`label=${JSON.stringify(label)}`);
|
|
350
|
+
const placeholder = h.getAttribute('placeholder');
|
|
351
|
+
if (placeholder)
|
|
352
|
+
bits.push(`placeholder=${JSON.stringify(placeholder)}`);
|
|
353
|
+
const text = (h.textContent ?? '').trim().replace(/\s+/g, ' ').slice(0, 60);
|
|
354
|
+
if (text && text !== label)
|
|
355
|
+
bits.push(`text=${JSON.stringify(text)}`);
|
|
356
|
+
out.push(bits.join(' '));
|
|
357
|
+
}
|
|
358
|
+
return out;
|
|
359
|
+
}, limit)
|
|
360
|
+
.catch(() => []);
|
|
361
|
+
return rows.join('\n');
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Fold a replay's per-candidate outcomes onto the stored skill.
|
|
365
|
+
*
|
|
366
|
+
* Only from a run that SUCCEEDED past the step, the same rule the url
|
|
367
|
+
* `generalisations` follow: a miss inside a run that then failed says more
|
|
368
|
+
* about the run than about the locator.
|
|
369
|
+
*
|
|
370
|
+
* This is the answer to "is this id real or ephemeral?" that does not guess
|
|
371
|
+
* from its shape. Grafana's `_r8b_` is a React-minted id matching no id-shaped
|
|
372
|
+
* pattern we have; two replays where it misses while a sibling resolves say so
|
|
373
|
+
* outright. Nothing is deleted — `retired` sorts it last, so if the app
|
|
374
|
+
* changes back it can still win on a later pass.
|
|
375
|
+
*/
|
|
376
|
+
export function recordCandidateEvidence(store, skillId, evidence) {
|
|
377
|
+
const skill = store.get(skillId);
|
|
378
|
+
if (!skill || !evidence.length)
|
|
379
|
+
return false;
|
|
380
|
+
let touched = false;
|
|
381
|
+
for (const e of evidence) {
|
|
382
|
+
const step = stepByTag(skill, e.step);
|
|
383
|
+
const chain = step?.locators[e.key];
|
|
384
|
+
if (!chain)
|
|
385
|
+
continue;
|
|
386
|
+
const bump = (i, field) => {
|
|
387
|
+
const c = chain[i];
|
|
388
|
+
if (!c)
|
|
389
|
+
return;
|
|
390
|
+
c.seen = { hit: c.seen?.hit ?? 0, miss: c.seen?.miss ?? 0 };
|
|
391
|
+
c.seen[field] += 1;
|
|
392
|
+
touched = true;
|
|
393
|
+
};
|
|
394
|
+
bump(e.hit, 'hit');
|
|
395
|
+
for (const i of e.missed)
|
|
396
|
+
bump(i, 'miss');
|
|
397
|
+
}
|
|
398
|
+
if (touched)
|
|
399
|
+
store.put(skill);
|
|
400
|
+
return touched;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Demonstrated volatile: it has missed at least twice with the element
|
|
404
|
+
* present, and has never once resolved.
|
|
405
|
+
*
|
|
406
|
+
* Twice, not once — a single miss can be a transient (a slow paint the
|
|
407
|
+
* poll happened to lose, a modal in the way). Two independent runs is the
|
|
408
|
+
* cheapest evidence that is not one bad afternoon.
|
|
409
|
+
*/
|
|
410
|
+
export function retired(c) {
|
|
411
|
+
return (c.seen?.hit ?? 0) === 0 && (c.seen?.miss ?? 0) >= MIN_MISSES_TO_RETIRE;
|
|
412
|
+
}
|
|
413
|
+
const MIN_MISSES_TO_RETIRE = 2;
|
|
414
|
+
/** ProposeLocator backed by the repair model: strict-JSON locator proposals from the live-page snapshot. */
|
|
415
|
+
export function llmProposer(provider) {
|
|
416
|
+
const propose = async ({ skill, ticket, chain, snapshot, recordedKind, tool }) => {
|
|
417
|
+
const prompt = [
|
|
418
|
+
"A stored browser procedure has drifted: one step's locator no longer resolves on the live page.",
|
|
419
|
+
`Procedure template: ${skill.template}`,
|
|
420
|
+
`Step ${ticket.atStep ?? '?'} (${ticket.key ?? 'target'}); its known locators, best first, ALL of which failed to resolve:`,
|
|
421
|
+
...chain.map((c) => ` - ${candidateExpr(c)}`),
|
|
422
|
+
// The kind is the one fact that rules out the plausible-looking wrong
|
|
423
|
+
// answer: a live repair once offered the Archive BUTTON in place of a
|
|
424
|
+
// textbox. A proposal of a different kind is rejected after the fact,
|
|
425
|
+
// so saying it up front saves the round trip.
|
|
426
|
+
...(recordedKind ? [`The control was a ${recordedKind}${tool ? ` (the step ${tool}s it)` : ''}; propose an element of that same kind and nothing else.`] : []),
|
|
427
|
+
'',
|
|
428
|
+
'Interactive elements currently on the page, one per line:',
|
|
429
|
+
snapshot || '(none found)',
|
|
430
|
+
'',
|
|
431
|
+
'Pick the ONE element that serves the same purpose the dead locators described (the control probably moved or was renamed).',
|
|
432
|
+
'Do NOT offer a nearby element of a different kind just because it exists: if the control itself is gone, that is not a rename.',
|
|
433
|
+
'Reply with ONLY a JSON object, no prose, in one of these shapes:',
|
|
434
|
+
'{"kind":"role","role":"button","name":"..."} {"kind":"label","label":"..."} {"kind":"placeholder","placeholder":"..."}',
|
|
435
|
+
'{"kind":"testid","attr":"data-testid","value":"..."} {"kind":"id","selector":"#..."} {"kind":"text","text":"..."} {"kind":"css","selector":"..."}',
|
|
436
|
+
'If no element on the page serves that purpose, reply with exactly: null',
|
|
437
|
+
].join('\n');
|
|
438
|
+
const completion = await provider.complete([{ role: 'user', content: prompt }], []);
|
|
439
|
+
const text = (completion.text ?? '').trim().replace(/^```(?:json)?\s*|\s*```$/g, '');
|
|
440
|
+
propose.last = {
|
|
441
|
+
snapshotRows: snapshot ? snapshot.split('\n').length : 0,
|
|
442
|
+
snapshotBytes: snapshot.length,
|
|
443
|
+
reply: text.slice(0, 300),
|
|
444
|
+
};
|
|
445
|
+
if (!text || text === 'null')
|
|
446
|
+
return null;
|
|
447
|
+
try {
|
|
448
|
+
const parsed = JSON.parse(text);
|
|
449
|
+
if (parsed && typeof parsed === 'object' && typeof parsed.kind === 'string')
|
|
450
|
+
return parsed;
|
|
451
|
+
}
|
|
452
|
+
catch {
|
|
453
|
+
/* not JSON */
|
|
454
|
+
}
|
|
455
|
+
return null;
|
|
456
|
+
};
|
|
457
|
+
return propose;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* A url the drifted page can be revisited at, or null when it cannot.
|
|
461
|
+
*
|
|
462
|
+
* The concrete url the ticket carries wins outright: it is where the miss
|
|
463
|
+
* actually happened. The patterns behind it are a fallback for tickets filed
|
|
464
|
+
* before `pageUrl` existed (and for the standalone `skills repair --drift`
|
|
465
|
+
* path, whose sidecar may be old), and they are refused the moment they still
|
|
466
|
+
* carry a slot or a `:id` — a generalised url cannot be filled back in from
|
|
467
|
+
* the store when the id was minted by the run that drifted.
|
|
468
|
+
*/
|
|
469
|
+
export function repairPageUrl(store, ticket) {
|
|
470
|
+
if (ticket.pageUrl && !ticket.pageUrl.includes('{{'))
|
|
471
|
+
return ticket.pageUrl;
|
|
472
|
+
const skill = store.get(ticket.skill);
|
|
473
|
+
if (!skill)
|
|
474
|
+
return null;
|
|
475
|
+
const candidates = [ticket.pageUrlPattern, skill.preconditions.urlPattern];
|
|
476
|
+
for (const c of candidates) {
|
|
477
|
+
if (!c)
|
|
478
|
+
continue;
|
|
479
|
+
const filled = fillParams(c, Object.fromEntries(Object.entries(skill.params).map(([k, p]) => [k, p.example])));
|
|
480
|
+
if (!filled.includes(':id') && !filled.includes('{{'))
|
|
481
|
+
return filled;
|
|
482
|
+
}
|
|
483
|
+
return null;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Drain a run's drift tickets onto `store`: triage, then the cheap codemod
|
|
487
|
+
* (promote-fallback), then the model-and-live-page one (patch-segment).
|
|
488
|
+
* Re-record is REPORTED, never attempted — a broad redesign is a fresh
|
|
489
|
+
* recording, and guessing at it is how a spec quietly stops testing what it
|
|
490
|
+
* says it tests (PLAN-self-updating-spec.md, "what the agent is allowed to
|
|
491
|
+
* change").
|
|
492
|
+
*
|
|
493
|
+
* Takes the store, the page opener and the proposer as arguments rather than
|
|
494
|
+
* building them, because the three callers differ in exactly those: the
|
|
495
|
+
* daemon drains in-session on its live page, `sitelooper repair` asks the
|
|
496
|
+
* daemon to, and `skills repair --drift` opens a cold browser of its own.
|
|
497
|
+
* The triage and the summary shape are identical for all three.
|
|
498
|
+
*/
|
|
499
|
+
export async function drainDrift(store, tickets, opts) {
|
|
500
|
+
const actions = triage(tickets, store);
|
|
501
|
+
const summary = { promoted: [], patched: [], reRecord: [], skipped: [] };
|
|
502
|
+
for (const a of actions) {
|
|
503
|
+
if (a.kind === 'promote-fallback') {
|
|
504
|
+
const ok = opts.dryRun ? true : promoteFallback(store, a.ticket);
|
|
505
|
+
(ok ? summary.promoted : summary.skipped).push({
|
|
506
|
+
skill: a.ticket.skill, step: a.ticket.atStep, from: a.ticket.missedLocator, to: a.ticket.fallbackUsed,
|
|
507
|
+
...(opts.dryRun ? { dryRun: true } : {}), ...(ok ? {} : { why: 'ticket no longer maps onto the stored skill' }),
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
else if (a.kind === 're-record') {
|
|
511
|
+
summary.reRecord.push({ flow: a.ticket.flow, step: a.ticket.step, skill: a.ticket.skill, why: a.why });
|
|
512
|
+
}
|
|
513
|
+
else if (a.kind === 'skip') {
|
|
514
|
+
summary.skipped.push({ skill: a.ticket.skill, step: a.ticket.step, why: a.why });
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
const patches = actions.filter((x) => x.kind === 'patch-segment');
|
|
518
|
+
if (!patches.length)
|
|
519
|
+
return summary;
|
|
520
|
+
if (opts.dryRun || !opts.openPage || !opts.propose) {
|
|
521
|
+
for (const a of patches) {
|
|
522
|
+
summary.skipped.push({
|
|
523
|
+
skill: a.ticket.skill, step: a.ticket.atStep,
|
|
524
|
+
why: opts.dryRun ? 'patch-segment (dry run: needs the repair model + live page)' : 'patch-segment (no live page or repair model available here)',
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
return summary;
|
|
528
|
+
}
|
|
529
|
+
const propose = opts.propose;
|
|
530
|
+
for (const a of patches) {
|
|
531
|
+
const url = repairPageUrl(store, a.ticket);
|
|
532
|
+
if (!url) {
|
|
533
|
+
summary.reRecord.push({ flow: a.ticket.flow, step: a.ticket.step, skill: a.ticket.skill, why: 'the drifted page cannot be revisited (its url needs run-specific ids)' });
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
const page = await opts.openPage(url).catch(() => null);
|
|
537
|
+
if (!page) {
|
|
538
|
+
summary.skipped.push({ skill: a.ticket.skill, step: a.ticket.atStep, why: `could not reopen ${url}` });
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
// A proposer that cannot run at all (no key, no balance, a provider
|
|
542
|
+
// outage) is a REPORTABLE outcome, not a crash: the promotions this pass
|
|
543
|
+
// already made are real work, and losing them to an unhandled 403 would
|
|
544
|
+
// make the whole repair look like a tool bug.
|
|
545
|
+
let res;
|
|
546
|
+
try {
|
|
547
|
+
res = await patchSegment(store, a.ticket, page, propose);
|
|
548
|
+
}
|
|
549
|
+
catch (err) {
|
|
550
|
+
summary.skipped.push({ skill: a.ticket.skill, step: a.ticket.atStep, why: `the repair model could not be reached (${err.message.slice(0, 200)})` });
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
const diagnostic = 'last' in propose ? propose.last : undefined;
|
|
554
|
+
if (res.outcome === 'patched') {
|
|
555
|
+
summary.patched.push({ skill: a.ticket.skill, step: a.ticket.atStep, key: a.ticket.key ?? 'target', variant: res.variant, locator: res.detail, url, model: opts.model, ...(res.unverifiedKind ? { unverifiedKind: true } : {}) });
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
summary.skipped.push({
|
|
559
|
+
skill: a.ticket.skill, step: a.ticket.atStep,
|
|
560
|
+
why: `${res.outcome}${res.detail ? `: ${res.detail}` : ''}`,
|
|
561
|
+
// What the model was actually looking at. A `no-proposal` on a page
|
|
562
|
+
// with 6 interactive rows is a navigation failure wearing a modelling
|
|
563
|
+
// failure's clothes; with 40 rows it is a genuine "nothing here fits".
|
|
564
|
+
...(diagnostic ? { url, snapshotRows: diagnostic.snapshotRows, snapshotBytes: diagnostic.snapshotBytes, modelReply: diagnostic.reply } : { url }),
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return summary;
|
|
569
|
+
}
|
|
570
|
+
//# sourceMappingURL=repair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/skills/repair.ts"],"names":[],"mappings":"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"}
|