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 @@
|
|
|
1
|
+
{"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/spec/repair.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { formatDiagnostic, rerecordFix } from './diagnostics.js';
|
|
4
|
+
/**
|
|
5
|
+
* `sitelooper rerecord <flow> <step>` — throw one step's recording away and
|
|
6
|
+
* let the agent make a new one.
|
|
7
|
+
*
|
|
8
|
+
* The failure this exists for is not drift. fwod34's 08-open is pinned to a
|
|
9
|
+
* skill whose FIRST action clicks a Cancel button that only existed on the
|
|
10
|
+
* recording run (step 06 had already cancelled the order by the time 08 ran),
|
|
11
|
+
* so the pin is demoted and every later run "passes" the step only because
|
|
12
|
+
* the engine quietly replays some other, read-only skill instead. Nothing in
|
|
13
|
+
* the app is broken and no locator has drifted: the recording is wrong. The
|
|
14
|
+
* only repair for a wrong recording is another recording, and this is the
|
|
15
|
+
* command that takes one — deterministically, against the real app, with the
|
|
16
|
+
* store's own re-pin rule (learn.ts `decideRepin`) as the judge of whether
|
|
17
|
+
* the new procedure is good enough to keep.
|
|
18
|
+
*
|
|
19
|
+
* The mechanism is deliberately small: unpin the step (below), run the flow a
|
|
20
|
+
* couple of times in learning mode, and read the verdict off the step's own
|
|
21
|
+
* run results. Everything that decides whether the new recording is trustworthy
|
|
22
|
+
* — the recovery ladder, skill compilation, lifecycle promotion, the re-pin
|
|
23
|
+
* gate — already exists and is exercised on every ordinary run.
|
|
24
|
+
*/
|
|
25
|
+
/** Raised for the caller's mistakes (unknown step, unwritable backup): exit 2, no daemon. */
|
|
26
|
+
export class RerecordError extends Error {
|
|
27
|
+
}
|
|
28
|
+
/** `<severity> <step>: <what>` + indented why/fix — the contracted block form. */
|
|
29
|
+
export const formatRerecordDiagnostic = formatDiagnostic;
|
|
30
|
+
/** The command that re-records one step, quoted so a path with spaces survives. */
|
|
31
|
+
export const rerecordCommand = rerecordFix;
|
|
32
|
+
/**
|
|
33
|
+
* The step, stripped back to "an instruction nobody has recorded yet".
|
|
34
|
+
*
|
|
35
|
+
* `adopted = true` is not decoration: it is the shape `decideRepin` pins on
|
|
36
|
+
* the FIRST clean recovery (an adopted step's incumbent is scaffolding, so a
|
|
37
|
+
* recovery that carried the whole step wins outright, provisional or not).
|
|
38
|
+
* Without it the new procedure would enter the store provisional and need two
|
|
39
|
+
* more clean runs before the pin moved, and a two-run rerecord would report
|
|
40
|
+
* "nothing was pinned" about a perfectly good recording.
|
|
41
|
+
*
|
|
42
|
+
* `params` and `outputEvidence` go with the pin because both describe the
|
|
43
|
+
* skill that is being discarded: params are ITS slot bindings, and evidence
|
|
44
|
+
* is cross-run agreement about values the old recording read. `outputs` stays
|
|
45
|
+
* — later steps reference this step's outputs by name, and renaming them
|
|
46
|
+
* would break the flow's threading. `recorded` is emptied rather than deleted:
|
|
47
|
+
* the field is required, and its recorded values are soft assertions made
|
|
48
|
+
* about the run this command exists to replace.
|
|
49
|
+
*
|
|
50
|
+
* Pure, and returns a new flow: the caller decides when (and whether) it hits
|
|
51
|
+
* disk, and the tests do not need one.
|
|
52
|
+
*/
|
|
53
|
+
export function unpinStep(flow, stepId, instruction) {
|
|
54
|
+
const idx = flow.steps.findIndex((s) => s.id === stepId);
|
|
55
|
+
if (idx < 0) {
|
|
56
|
+
throw new RerecordError(`flow "${flow.name}" has no step "${stepId}" — steps are: ${flow.steps.map((s) => s.id).join(', ')}`);
|
|
57
|
+
}
|
|
58
|
+
const old = flow.steps[idx];
|
|
59
|
+
const next = {
|
|
60
|
+
id: old.id,
|
|
61
|
+
instruction: instruction ?? old.instruction,
|
|
62
|
+
outputs: old.outputs,
|
|
63
|
+
recorded: {},
|
|
64
|
+
adopted: true,
|
|
65
|
+
};
|
|
66
|
+
const steps = flow.steps.slice();
|
|
67
|
+
steps[idx] = next;
|
|
68
|
+
return { ...flow, steps };
|
|
69
|
+
}
|
|
70
|
+
/** `<file>.bak-<stamp>.json` beside the flow — the recording this command discards. */
|
|
71
|
+
export function backupPath(file, stamp = Date.now().toString(36)) {
|
|
72
|
+
const dir = path.dirname(file);
|
|
73
|
+
const base = path.basename(file).replace(/\.json$/i, '');
|
|
74
|
+
return path.join(dir, `${base}.bak-${stamp}.json`);
|
|
75
|
+
}
|
|
76
|
+
/** Copy the flow file aside before patching it. Returns the backup's path. */
|
|
77
|
+
export function backupFlowFile(file, stamp) {
|
|
78
|
+
const to = backupPath(file, stamp);
|
|
79
|
+
try {
|
|
80
|
+
fs.copyFileSync(file, to);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
throw new RerecordError(`could not back up ${file}: ${err.message}`);
|
|
84
|
+
}
|
|
85
|
+
return to;
|
|
86
|
+
}
|
|
87
|
+
/** Does a daemon progress line concern this flow step? `[flow <name>] <step>: …` */
|
|
88
|
+
export function stepNote(line, stepId) {
|
|
89
|
+
const m = /^\[flow [^\]]+\] ([^:]+): (.*)$/.exec(line);
|
|
90
|
+
return m && m[1] === stepId ? m[2] : null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* The daemon's `replayed` is "<steps run>/<steps total>" for the skill the
|
|
94
|
+
* step actually ran; older results and repair's facts carry a skill id there
|
|
95
|
+
* instead. Only an id is evidence that a DIFFERENT skill covered the step.
|
|
96
|
+
*/
|
|
97
|
+
export function replayedSkillId(replayed) {
|
|
98
|
+
if (!replayed)
|
|
99
|
+
return null;
|
|
100
|
+
return /^\d+\s*\/\s*\d+$/.test(replayed) ? null : replayed;
|
|
101
|
+
}
|
|
102
|
+
/** `run 2: 08-open replay tier A (2/2)` / `run 1: 08-open agent (12 turns) re-pinned s_ab12cd` */
|
|
103
|
+
export function stepLine(stepId, run) {
|
|
104
|
+
const st = run.step;
|
|
105
|
+
if (!st)
|
|
106
|
+
return `${run.label}: ${stepId} not reached`;
|
|
107
|
+
const how = st.tier === 'A'
|
|
108
|
+
? `replay tier A${st.replayed ? ` (${st.replayed})` : ''}`
|
|
109
|
+
: st.replayed
|
|
110
|
+
? `replay ${st.replayed}${st.repaired ? ' + repair' : ''}${st.turns ? ` (${st.turns} turns)` : ''}`
|
|
111
|
+
: `agent${st.turns ? ` (${st.turns} turns)` : ''}`;
|
|
112
|
+
const mark = st.status === 'success' ? '' : ` [${st.status.toUpperCase()}]`;
|
|
113
|
+
return `${run.label}: ${stepId} ${how}${mark}${st.repinned ? ` re-pinned ${st.repinned}` : ''}`;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Did the re-recording take?
|
|
117
|
+
*
|
|
118
|
+
* The bar is the one the compiled spec has to clear, not "the run passed":
|
|
119
|
+
* the LAST run must have replayed this step at tier A — no model, no repair —
|
|
120
|
+
* with the skill this rerecord pinned. Anything else is the same failure mode
|
|
121
|
+
* the command was built to expose. A step that passes because the engine
|
|
122
|
+
* reached for a different skill is exactly fwod34/08-open, and reporting that
|
|
123
|
+
* as success would put the wrong recording straight back into a spec.
|
|
124
|
+
*/
|
|
125
|
+
export function rerecordVerdict(input) {
|
|
126
|
+
const { file, stepId, runs } = input;
|
|
127
|
+
const fix = rerecordCommand(file, stepId);
|
|
128
|
+
const trail = runs.map((r) => stepLine(stepId, r)).join('; ');
|
|
129
|
+
const notes = runs.flatMap((r) => (r.notes ?? []).map((n) => `${r.label}: ${n}`));
|
|
130
|
+
// The pin this rerecord made: the last re-pin any run reported. Later runs
|
|
131
|
+
// replay it and report no re-pin of their own, which is the success shape.
|
|
132
|
+
let pinned;
|
|
133
|
+
for (const r of runs)
|
|
134
|
+
if (r.step?.repinned)
|
|
135
|
+
pinned = r.step.repinned;
|
|
136
|
+
const bad = (what, why, extra) => ({
|
|
137
|
+
ok: false,
|
|
138
|
+
...(pinned ? { pinned } : {}),
|
|
139
|
+
diagnostic: { code: 'needs-rerecord', step: stepId, what, why, fix, severity: 'error', ...extra },
|
|
140
|
+
});
|
|
141
|
+
if (!runs.length) {
|
|
142
|
+
return bad(`${stepId} was not re-recorded — no run completed`, 'the flow never ran');
|
|
143
|
+
}
|
|
144
|
+
const last = runs[runs.length - 1];
|
|
145
|
+
if (!last.step) {
|
|
146
|
+
return bad(`${stepId} was not re-recorded — the last run never reached it`, `an earlier step halted the flow. ${trail}`);
|
|
147
|
+
}
|
|
148
|
+
if (!pinned) {
|
|
149
|
+
return bad(`${stepId} has no procedure after re-recording — nothing was pinned to it`, notes.length
|
|
150
|
+
? `the store's re-pin rule refused the result — ${notes.join('; ')}. ${trail}`
|
|
151
|
+
: `the agent ran the step but the store's re-pin rule refused the result (a recovery that needed model gestures beyond its replay, or a locator carrying a value this run minted). ${trail}`, { fix: `${fix} --instruction "<a clearer instruction for this step>"` });
|
|
152
|
+
}
|
|
153
|
+
if (last.step.status !== 'success') {
|
|
154
|
+
return bad(`${stepId} did not pass on its last run after re-recording`, `pinned ${pinned}, then ${last.label} reported ${last.step.status}${last.step.summary ? `: ${last.step.summary}` : ''}. ${trail}`, { fix: `${fix} --instruction "<a clearer instruction for this step>"` });
|
|
155
|
+
}
|
|
156
|
+
if (last.step.tier !== 'A') {
|
|
157
|
+
return bad(`${stepId} still needs the model after re-recording — its new procedure did not replay cleanly`, `pinned ${pinned}, but ${last.label} ran the step at tier ${last.step.tier ?? 'none'}${last.step.fellBack ? ` (${last.step.fellBack})` : ''}; a compiled spec has no model to fall back on. ${trail}`, { fix: `${fix} --runs 3` });
|
|
158
|
+
}
|
|
159
|
+
const covering = replayedSkillId(last.step.replayed);
|
|
160
|
+
if (covering && covering !== pinned) {
|
|
161
|
+
return bad(`${stepId} only passes because the engine replays ${covering} instead of its new pin ${pinned}`, `the re-recording pinned ${pinned}, but ${last.label} replayed ${covering}; a compiled spec emits the pin and halts here. ${trail}`, { fix: `${fix} --instruction "<an instruction that describes what this step should do>"` });
|
|
162
|
+
}
|
|
163
|
+
return { ok: true, pinned, runs: runs.length };
|
|
164
|
+
}
|
|
165
|
+
/** The step's result in one run, by id. */
|
|
166
|
+
export function stepOf(steps, stepId) {
|
|
167
|
+
return steps?.find((s) => s.id === stepId);
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=rerecord.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rerecord.js","sourceRoot":"","sources":["../../src/spec/rerecord.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-thread a flow step's literal params against its own instruction.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS. A flow step carries both an instruction with `{{...}}`
|
|
5
|
+
* references in it ("Open the confirmed sales order
|
|
6
|
+
* {{02-create.quotation_ref}} for customer '{{runid}} Bench Customer' ...")
|
|
7
|
+
* and the bindings for its pinned skill's `{{vN}}` slots. Those two are
|
|
8
|
+
* supposed to agree, but an adoption during replay binds the slots to THAT
|
|
9
|
+
* run's concrete values — the published odoo flow has 06-open pinned at
|
|
10
|
+
* `{"v1":"S00022","v2":"fwod34-n2"}` while every sibling step is threaded.
|
|
11
|
+
* A literal binding is stale on every later run: the compiled spec then
|
|
12
|
+
* drives the recording's record, its identity checks look for the wrong
|
|
13
|
+
* name, and replay falls back to the model on every run.
|
|
14
|
+
*
|
|
15
|
+
* WHAT IT DOES. The skill template and the step instruction are the same
|
|
16
|
+
* sentence with slots — `{{vN}}` in one, `{{ref}}` in the other — so reading
|
|
17
|
+
* the template as a pattern over the instruction (exactly as `bindSkill`
|
|
18
|
+
* reads it over a real instruction) puts each slot on the text that filled
|
|
19
|
+
* it. Where that text is (or contains) a reference, the literal is rebound
|
|
20
|
+
* to it. Where it is plain text the literal is left alone: a param like
|
|
21
|
+
* `v3: "Sales Order"` sitting on the words "Sales Order" is correctly bound,
|
|
22
|
+
* not debt. Ambiguity — a template that will not align, two occurrences of
|
|
23
|
+
* one slot disagreeing, adjacent slots with nothing between them — is left
|
|
24
|
+
* alone and reported, never guessed at.
|
|
25
|
+
*/
|
|
26
|
+
/** Same normalisation `skills/learn.ts` binds through: quote style and whitespace do not count. */
|
|
27
|
+
function squash(text) {
|
|
28
|
+
return text.replace(/[“”"]/g, "'").replace(/\s+/g, ' ').trim();
|
|
29
|
+
}
|
|
30
|
+
function escapeRe(text) {
|
|
31
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
32
|
+
}
|
|
33
|
+
const REF = /\{\{[\w.#:-]+\}\}/;
|
|
34
|
+
/**
|
|
35
|
+
* Align `template` against `instruction` and rebind literal params.
|
|
36
|
+
*
|
|
37
|
+
* Only literals are considered — a param that already carries `{{` is
|
|
38
|
+
* authoritative and is never touched. `stepId` only shapes the warnings.
|
|
39
|
+
*/
|
|
40
|
+
export function rethreadParams(stepId, instruction, template, params) {
|
|
41
|
+
const out = { params: { ...params }, warnings: [], rebound: {} };
|
|
42
|
+
const literals = Object.entries(params).filter(([, v]) => typeof v === 'string' && !v.includes('{{'));
|
|
43
|
+
// Nothing to repair unless the step has a literal AND an instruction that
|
|
44
|
+
// threads something: a flow whose instruction has no references has no
|
|
45
|
+
// better binding to offer than the literal it already carries.
|
|
46
|
+
if (!literals.length || !REF.test(instruction))
|
|
47
|
+
return out;
|
|
48
|
+
const align = alignSlots(template, instruction);
|
|
49
|
+
if (!align) {
|
|
50
|
+
for (const [slot, value] of literals) {
|
|
51
|
+
out.warnings.push(`step ${stepId} param ${slot} is bound to the literal ${JSON.stringify(value)}; it could not be rethreaded — the step will run against the recording's record`);
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
for (const [slot, value] of literals) {
|
|
56
|
+
const seen = align.get(slot);
|
|
57
|
+
if (seen === undefined)
|
|
58
|
+
continue; // the template has no such slot: nothing to align against
|
|
59
|
+
if (seen === null) {
|
|
60
|
+
out.warnings.push(`step ${stepId} param ${slot} is bound to the literal ${JSON.stringify(value)}; the alignment is ambiguous so it could not be rethreaded — the step will run against the recording's record`);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (REF.test(seen)) {
|
|
64
|
+
out.params[slot] = seen;
|
|
65
|
+
out.rebound[slot] = seen;
|
|
66
|
+
out.warnings.push(`step ${stepId} param ${slot} was bound to the literal ${JSON.stringify(value)}; rethreaded to ${seen} from the instruction`);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
// Plain text at the slot. Equal to the literal (modulo quote style and
|
|
70
|
+
// whitespace) means the binding is already right — silence is correct.
|
|
71
|
+
if (squash(seen).toLowerCase() === squash(value).toLowerCase())
|
|
72
|
+
continue;
|
|
73
|
+
out.warnings.push(`step ${stepId} param ${slot} is bound to the literal ${JSON.stringify(value)} but the instruction has plain text ${JSON.stringify(seen)} there; it could not be rethreaded — the step will run against the recording's record`);
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The instruction text sitting at each `{{vN}}` slot of the template.
|
|
79
|
+
*
|
|
80
|
+
* `null` for a slot whose occurrences disagree or that abuts another slot
|
|
81
|
+
* (nothing separates them, so the split between the two is a guess); the
|
|
82
|
+
* whole result is null when the template does not read as a pattern over the
|
|
83
|
+
* instruction at all. Exported for tests.
|
|
84
|
+
*/
|
|
85
|
+
export function alignSlots(template, instruction) {
|
|
86
|
+
const t = squash(template);
|
|
87
|
+
const names = [];
|
|
88
|
+
const pattern = escapeRe(t).replace(/\\\{\\\{(v\d+)\\\}\\\}/g, (_m, name) => {
|
|
89
|
+
names.push(name);
|
|
90
|
+
return '(.+?)';
|
|
91
|
+
});
|
|
92
|
+
if (!names.length)
|
|
93
|
+
return null;
|
|
94
|
+
const m = new RegExp(`^${pattern}$`, 'i').exec(squash(instruction));
|
|
95
|
+
if (!m)
|
|
96
|
+
return null;
|
|
97
|
+
// Slots with no literal text between them cannot be split reliably.
|
|
98
|
+
const adjacent = new Set();
|
|
99
|
+
const spans = [...t.matchAll(/\{\{(v\d+)\}\}/g)];
|
|
100
|
+
for (let i = 1; i < spans.length; i++) {
|
|
101
|
+
const prev = spans[i - 1];
|
|
102
|
+
const end = (prev.index ?? 0) + prev[0].length;
|
|
103
|
+
if (!t.slice(end, spans[i].index ?? 0).trim()) {
|
|
104
|
+
adjacent.add(prev[1]);
|
|
105
|
+
adjacent.add(spans[i][1]);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const seen = new Map();
|
|
109
|
+
names.forEach((name, i) => {
|
|
110
|
+
const text = m[i + 1].trim();
|
|
111
|
+
if (adjacent.has(name))
|
|
112
|
+
return seen.set(name, null);
|
|
113
|
+
if (seen.has(name) && squash(seen.get(name) ?? '') !== squash(text))
|
|
114
|
+
return seen.set(name, null);
|
|
115
|
+
if (!seen.has(name))
|
|
116
|
+
seen.set(name, text);
|
|
117
|
+
});
|
|
118
|
+
return seen;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=rethread.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rethread.js","sourceRoot":"","sources":["../../src/spec/rethread.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sitelooper",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Sitelooper: an agent-in-the-loop Playwright CLI that learns a flow once, then replays it with no model in the loop — zero-LLM, deterministic, verified.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"playwright",
|
|
7
|
+
"browser-automation",
|
|
8
|
+
"llm-agent",
|
|
9
|
+
"e2e-testing",
|
|
10
|
+
"record-replay",
|
|
11
|
+
"deterministic-replay",
|
|
12
|
+
"cli"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://sitelooper.io",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/restspace/sitelooper.git"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"type": "module",
|
|
21
|
+
"bin": {
|
|
22
|
+
"sitelooper": "bin/sitelooper.js"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"bin",
|
|
26
|
+
"dist",
|
|
27
|
+
"skills",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsc -p tsconfig.json",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"prepare": "npm run build"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"ajv": "^8.17.1",
|
|
41
|
+
"playwright-core": "^1.53.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@playwright/mcp": "^0.0.79",
|
|
45
|
+
"@playwright/test": "^1.61.1",
|
|
46
|
+
"@types/node": "^24.0.0",
|
|
47
|
+
"typescript": "^5.8.0",
|
|
48
|
+
"vitest": "^3.0.0"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sitelooper
|
|
3
|
+
description: Delegate a whole natural-language browser step — one with judgment or multiple assertions baked in — to an internal LLM agent loop that drives Playwright itself, instead of you clicking/filling/asserting element-by-element. Best for executing E2E test plans, multi-step flows, and app-specific verification against a written app briefing. Uses the `sitelooper` CLI. For low-level, deterministic single-action DOM poking (one click, one fill, one read), prefer the `browser-testing` skill / `agent-browser` CLI instead — cheaper and no LLM tokens spent per action.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# sitelooper: agent-in-the-loop browser automation
|
|
7
|
+
|
|
8
|
+
`sitelooper` takes one natural-language instruction and returns one concise
|
|
9
|
+
structured result — `{status, summary, details?, evidence?}` — instead of you
|
|
10
|
+
issuing 4-6 selector-aware, wait-aware calls per logical step. An internal LLM
|
|
11
|
+
agent (GLM 5.2 via novita by default — already configured, `NOVITA_API_KEY` is
|
|
12
|
+
set) translates the instruction into Playwright tool calls against a
|
|
13
|
+
persistent browser, verifies the result, and reports back. You never touch
|
|
14
|
+
selectors, waits, dialogs, or quoting for the delegated step.
|
|
15
|
+
|
|
16
|
+
Check availability: `sitelooper --help`. Already installed/linked on this
|
|
17
|
+
machine.
|
|
18
|
+
|
|
19
|
+
## Core loop
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
# deterministic verbs — no agent tokens spent
|
|
23
|
+
sitelooper open http://localhost:5173
|
|
24
|
+
sitelooper brief docs/AUTOMATION_GUIDE.md # load app-specific conventions/selectors into the session
|
|
25
|
+
sitelooper note "runid is k7x2" # record run state the agent must know
|
|
26
|
+
sitelooper peek [--selector css] [--interactive]
|
|
27
|
+
sitelooper screenshot [path]
|
|
28
|
+
|
|
29
|
+
# the core verb — anything requiring judgment or multi-part assertions
|
|
30
|
+
sitelooper do "log in as admin@example.com / pw123"
|
|
31
|
+
sitelooper do "create a supplier organisation named 'k7x2 MTP Supplies Ltd' and confirm it appears in the Organisations list with the count incremented" --json
|
|
32
|
+
|
|
33
|
+
# housekeeping — answered immediately, even while a `do` is running
|
|
34
|
+
sitelooper session list
|
|
35
|
+
sitelooper stop [--all] # prints video paths if the session was recorded
|
|
36
|
+
sitelooper config
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- Exit codes: `0` succeeded · `1` failed/blocked · `2` infra error (no key, no browser, LLM unreachable).
|
|
40
|
+
- `--json` gives `{report, turns, usage, model}`; on any bail-out it also carries `actions` (the
|
|
41
|
+
ordered tool calls that ran — check before blindly repeating a mutation), `transcriptTail`, and
|
|
42
|
+
`finalState` (where the browser was left).
|
|
43
|
+
- `--verbose` / `--progress` stream the internal agent's turn-by-turn activity to stderr.
|
|
44
|
+
|
|
45
|
+
| Flag | Default | |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| `--max-turns` | 30 | agent turn cap per instruction |
|
|
48
|
+
| `--timeout` | 300 | wall-clock seconds for the whole instruction |
|
|
49
|
+
| `--turn-timeout` | 90 | wall-clock seconds for one LLM call — see below |
|
|
50
|
+
|
|
51
|
+
## Turning a run into a Playwright spec
|
|
52
|
+
|
|
53
|
+
If the point of the run is to end up with a committed test, start the session with `--script`:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
sitelooper --session flow --script open http://localhost:5173
|
|
57
|
+
sitelooper --session flow do "log in as admin@example.com / pw123"
|
|
58
|
+
sitelooper --session flow script tests/login.spec.ts # standalone @playwright/test spec
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Every successful action is captured with a durable locator resolved from the live DOM (testid →
|
|
62
|
+
role+name → label → id → text → CSS path) and verified against the page, so no `@ref` handles leak
|
|
63
|
+
into the output. One `test.step` per `do`. `wait_for` becomes a real assertion; `read` becomes a
|
|
64
|
+
commented-out one; anything unresolvable is a `TODO`, never a wrong selector. Review before
|
|
65
|
+
committing — it replays the path the agent took, detours included. `script --clear` discards the
|
|
66
|
+
recording; adding `--clear` to a write starts a fresh one.
|
|
67
|
+
|
|
68
|
+
For a flow whose steps have already converged into stored procedures (via `--learn`, see below),
|
|
69
|
+
`sitelooper compile <flow-name-or-path> [--out <dir>] [--force]` is the other route to a spec: no
|
|
70
|
+
session, no daemon, no model call — it emits an owned `<name>.flow.ts` (the flow plus one generated
|
|
71
|
+
step function per `FlowStep`, compiled straight from the stored locator chains) and a `<name>.spec.ts`
|
|
72
|
+
scaffold written once and never overwritten. It is compile-time only: no live-page measurement, no
|
|
73
|
+
point-candidate clicks, and no runtime recovery if a locator has since drifted — a drifted step fails
|
|
74
|
+
the spec outright rather than reasoning its way to the moved control. `compile` exits 2 when a step
|
|
75
|
+
never converged to a stored procedure, and prints a `what`/`why`/`fix` diagnostic block, before
|
|
76
|
+
anything else, for any step whose pin is demoted — refusing to write unless you pass `--force`
|
|
77
|
+
(its recording, not the app, is what's broken; see step 6 below for the fix). When a compiled spec
|
|
78
|
+
later goes red or logs drift in CI, see "Repairing a compiled spec after a red CI run" below —
|
|
79
|
+
that's a `repair` job, not a `do`.
|
|
80
|
+
|
|
81
|
+
## Repairing a compiled spec after a red CI run
|
|
82
|
+
|
|
83
|
+
A compiled spec (`<name>.flow.ts` + `<name>.spec.ts`, from `compile` above) runs under plain
|
|
84
|
+
`@playwright/test` with no model in the loop — so when you land on a red run of one, don't reach
|
|
85
|
+
for `do`. Work the failure like this:
|
|
86
|
+
|
|
87
|
+
1. Read the Playwright report. Look for `[sitelooper drift] ...` lines (a locator's primary
|
|
88
|
+
candidate missed but a recorded fallback covered — the test may still be green) and, on an
|
|
89
|
+
actual failure, the `// @step <id> <segment>/<index>` anchor comment in the `.flow.ts` nearest
|
|
90
|
+
the failing line — that's the step and candidate to focus on, not the whole flow.
|
|
91
|
+
2. Dry-run the repair first: `sitelooper repair <name.flow.ts> --var k=v ... --dry-run`. This
|
|
92
|
+
performs the real triage and prints the change list without writing anything, so you can see
|
|
93
|
+
what it *would* do before it touches the file.
|
|
94
|
+
3. If the change list looks right, run it for real with a convergence check and a fresh identity
|
|
95
|
+
per run: `sitelooper repair <name.flow.ts> --var k=v --var runid=fix-{n} --converge 1`. `{n}`
|
|
96
|
+
in a `--var` value becomes the run number, so a record-creating flow doesn't collide with
|
|
97
|
+
itself across the repair run and the converge run(s).
|
|
98
|
+
4. Review the printed change list line by line ("candidate promoted", "new locator", "chain
|
|
99
|
+
reordered", "step re-pinned to variant ..."). This is the diff a human would otherwise have to
|
|
100
|
+
reconstruct from the `.flow.ts` diff by hand.
|
|
101
|
+
5. Refuse anything that weakens an expectation. `repair` already refuses this on its own — a
|
|
102
|
+
dropped assertion exits 1 rather than writing — but treat that refusal as final, not something
|
|
103
|
+
to work around by editing the flow yourself; an assertion that stopped holding is a real test
|
|
104
|
+
failure for a human to look at, not drift.
|
|
105
|
+
6. If `repair` (or `compile`) prints a **needs-rerecord** / **demoted-pin** / **noop-step** /
|
|
106
|
+
**contradicted-step** diagnostic rather than proposing a fix, don't try to hand-patch the
|
|
107
|
+
`.flow.ts` — it's regenerated in full on every `compile`/`repair` and hand edits are detected
|
|
108
|
+
and refused on the next repair anyway. Every such diagnostic names its own fix command:
|
|
109
|
+
`sitelooper rerecord <flow> <step-id> [--instruction "<text>"] [--var k=v ...] [--runs n]
|
|
110
|
+
[--reset-cmd "<cmd>"]`. It backs the flow file up, unpins just that step (optionally swapping in
|
|
111
|
+
a new instruction — the fix when the recorded ask no longer makes sense, e.g. "cancel an order a
|
|
112
|
+
previous step already cancelled"), and replays the flow `--runs` times (default 2) in learning
|
|
113
|
+
mode; it succeeds only when the last run replays the step at tier A on the newly recorded pin,
|
|
114
|
+
otherwise it prints why and exits 1. A `contradicted-step` diagnostic's `fix` points at the
|
|
115
|
+
*mutating* step (the one whose report a later read-only step disagreed with), not the step that
|
|
116
|
+
eventually failed because of it — re-record that one, not the one you saw fail.
|
|
117
|
+
7. Once `repair` has written the file (`converged: true` / "wrote ... (N change(s); the .spec.ts
|
|
118
|
+
was not touched)"), commit only the `.flow.ts` diff and open it as a PR, with the printed
|
|
119
|
+
change list as the PR description — that list is already the reviewer-facing summary of what
|
|
120
|
+
changed and why.
|
|
121
|
+
|
|
122
|
+
Never touch the `.spec.ts` for this: it's the user's file and `repair` never rewrites it.
|
|
123
|
+
|
|
124
|
+
A step whose printed line says `already satisfied` (a `run`) or whose emitted guard logs
|
|
125
|
+
`[sitelooper satisfied] ...` (a compiled spec) is not a bug: a mutating step derives a `goal` at
|
|
126
|
+
compile time — the visible text its own recording read back that was not there when it started —
|
|
127
|
+
and the engine checks the live page for both identity and that goal before acting. When both
|
|
128
|
+
already hold, the step succeeds having done nothing rather than repeating work (or failing to find
|
|
129
|
+
a control that a prior step's retry already removed). Nothing to fix here; it is the retry-safety
|
|
130
|
+
half of the same mechanism `contradicted-step` and `noop-step` flag the *unsafe* version of.
|
|
131
|
+
`repair` itself never touches anything outside a throwaway temp store until the very last
|
|
132
|
+
step (the file write) — the runs it performs against the live app to triage and converge are
|
|
133
|
+
real runs, so treat `--converge n` as `n` additional real executions against the app, same as
|
|
134
|
+
any other run.
|
|
135
|
+
|
|
136
|
+
## Learning mode — repeated work gets cheaper
|
|
137
|
+
|
|
138
|
+
If you will run the same kind of steps against a site more than once (a test plan you re-run, a flow
|
|
139
|
+
across many similar records), start the session with `--learn`. Every `do` that succeeds is compiled
|
|
140
|
+
into a stored, parameterised procedure; on later `do`s that start on the same page the internal agent
|
|
141
|
+
is offered those procedures, replays one deterministically, and only reasons about steps that no longer
|
|
142
|
+
work. A run that took 14 internal turns the first time typically takes 2–3 the next, with the same
|
|
143
|
+
report shape and every value still read back from the live page.
|
|
144
|
+
|
|
145
|
+
```sh
|
|
146
|
+
sitelooper --session t1 --learn open http://localhost:5173
|
|
147
|
+
sitelooper --session t1 do "sign in as admin@example.com / pw123 and create a project named 'k7 Demo'"
|
|
148
|
+
sitelooper skills list # what has been learned for each site
|
|
149
|
+
sitelooper skills show <id> # the steps, their fallbacks, what is a parameter
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Two habits make it work well: keep the *values* in the instruction text (a name, a cost, a url) — that
|
|
153
|
+
is how they become parameters rather than hard-coded literals — and keep instruction boundaries stable
|
|
154
|
+
across runs (one `do` = one whole outcome, as above), so the procedure learned last time matches the
|
|
155
|
+
outcome asked for this time. The store lives per site under `~/.sitelooper/skills/`; `skills rm`
|
|
156
|
+
removes anything you do not want replayed.
|
|
157
|
+
|
|
158
|
+
## When a `do` misbehaves
|
|
159
|
+
|
|
160
|
+
Control commands do **not** queue behind the running instruction, so you can always look and
|
|
161
|
+
intervene:
|
|
162
|
+
|
|
163
|
+
```sh
|
|
164
|
+
sitelooper session list # is the daemon alive? answers in ms, mid-instruction
|
|
165
|
+
sitelooper screenshot # what is the browser actually looking at right now
|
|
166
|
+
sitelooper stop --session <name> # aborts the in-flight instruction, then exits
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`stop` preempts rather than waits. The `do` you interrupted returns a `blocked` report with its
|
|
170
|
+
actions log — it does not hang, so a stuck run is always recoverable. If a control command *does*
|
|
171
|
+
hang, the daemon is genuinely wedged (kill the pid from `session list`); that is a bug worth
|
|
172
|
+
reporting, not the normal busy state.
|
|
173
|
+
|
|
174
|
+
A model that reasons without ever issuing a tool call is caught by a per-turn watchdog: the turn is
|
|
175
|
+
aborted at `--turn-timeout`, retried once with a nudge, and after three such turns the instruction
|
|
176
|
+
ends as `blocked` with the reasoning in `transcriptTail`. So a stall costs seconds, not the full
|
|
177
|
+
`--timeout`. If you see that report, the instruction was almost certainly too broad — split it.
|
|
178
|
+
|
|
179
|
+
## Writing good instructions
|
|
180
|
+
|
|
181
|
+
Scope each `do` to **one logical, verifiable step** — don't pack many independent assertions into
|
|
182
|
+
one instruction; that's what burns the turn budget and what makes the agent stall on planning.
|
|
183
|
+
Instructions asking for two unrelated artifacts at once ("report the console output *and* the
|
|
184
|
+
innerHTML of #root") are the classic failure case: ask for one, then the other. Put deterministic
|
|
185
|
+
sub-actions (navigation, screenshots, spot-checks) on `open`/`peek`/`screenshot` instead — free, no
|
|
186
|
+
agent tokens.
|
|
187
|
+
|
|
188
|
+
**Server response vs live DOM.** Every observation tool the agent has shows the live,
|
|
189
|
+
post-JavaScript DOM. It also has `fetch_source`, which returns the raw HTTP response body with no
|
|
190
|
+
JS executed, and it is instructed to call that before claiming anything about server-rendered
|
|
191
|
+
output — so an SSR bug (element absent from the source) is distinguished from a hydration bug
|
|
192
|
+
(present in the source, missing live). Reports name their source: "the live DOM contains…" vs "the
|
|
193
|
+
server response contains…". If a distinction matters to you, ask for it explicitly, and treat any
|
|
194
|
+
unattributed claim in a summary as an inference rather than an observation.
|
|
195
|
+
|
|
196
|
+
## Sessions
|
|
197
|
+
|
|
198
|
+
`--session <name>` (default `default`) owns a detached daemon with a persistent Chrome profile
|
|
199
|
+
under `~/.sitelooper/sessions/<name>/` — logins and conversation history survive daemon
|
|
200
|
+
restarts. `brief` and `note` content survives history trimming. `stop` kills the daemon; the
|
|
201
|
+
profile stays.
|
|
202
|
+
|
|
203
|
+
## Recording a session
|
|
204
|
+
|
|
205
|
+
`--record` on the first call of a session (the one that launches the browser) records the whole
|
|
206
|
+
session to webm, one file per tab, under `~/.sitelooper/sessions/<name>/video/`:
|
|
207
|
+
|
|
208
|
+
```sh
|
|
209
|
+
sitelooper open http://localhost:5173 --session run1 --record
|
|
210
|
+
sitelooper do "..." --session run1
|
|
211
|
+
sitelooper stop --session run1 # prints: video: .../video/page@<hash>.webm
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Playwright only writes the video out when the browser context closes, so: it cannot be started or
|
|
215
|
+
stopped mid-session, nothing is readable until `stop`, and killing the daemon any other way loses
|
|
216
|
+
the recording entirely. `sitelooper config` reports `recording` so you can check which mode a
|
|
217
|
+
running session is actually in — passing `--record` to an already-running session does nothing.
|
|
218
|
+
|
|
219
|
+
Use it when you need to show a human what happened, or to debug a flow that fails intermittently.
|
|
220
|
+
For a single moment, `screenshot` is cheaper and readable immediately.
|
|
221
|
+
|
|
222
|
+
## Design boundary — this tool is app-agnostic
|
|
223
|
+
|
|
224
|
+
`sitelooper` itself has no knowledge of any specific app under test. All app-specific knowledge
|
|
225
|
+
(selectors, class names, gestures, URLs, workflow assumptions) belongs in the `brief` you load or
|
|
226
|
+
the instruction text you write — never assume the tool "knows" an app's UI. See the project README
|
|
227
|
+
(`C:\dev\sitelooper\README.md`) for the full design rationale and the complete tool/provider
|
|
228
|
+
reference if you need more than this skill covers.
|