@jobshimo/browser-link 0.23.14 → 0.25.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.
@@ -1,13 +1,22 @@
1
1
  /**
2
2
  * browser.flow step sequencing — the logic behind the composite action
3
3
  * tool. Runs a short, declarative list of find/click/type/press/wait_for/
4
- * drag steps strictly in order, fails fast on the first step that does
5
- * not succeed, and threads an "implicit target" from a `find` step into
6
- * the very next click/type/press step that omits its own `selector`. A
7
- * `drag` step stays OUT of that chain: both of its endpoints are always
8
- * explicit (selector or coords), so it neither consumes nor sets the
9
- * implicit target — a pending target survives a drag step untouched for
10
- * a later click/type/press, exactly like it survives a wait_for.
4
+ * drag/sleep steps strictly in order, fails fast on the first step that
5
+ * does not succeed, and threads an "implicit target" from a `find` step
6
+ * into the very next click/type/press step that omits its own
7
+ * `selector`. A `drag` step stays OUT of that chain: both of its
8
+ * endpoints are always explicit (selector or coords), so it neither
9
+ * consumes nor sets the implicit target — a pending target survives a
10
+ * drag step untouched for a later click/type/press, exactly like it
11
+ * survives a wait_for. A `sleep` step is a fixed pause and stays out of
12
+ * the chain for the same reason: it names no target at all.
13
+ *
14
+ * A `repeat` step runs a bounded sub-sequence up to `max_iterations`
15
+ * times, optionally stopping early while a `while_found` selector still
16
+ * matches. It does not nest, its inner steps count against the same
17
+ * 20-step ceiling, and each iteration starts with a FRESH implicit
18
+ * target — so nothing leaks across an iteration or across the repeat
19
+ * boundary in either direction.
11
20
  *
12
21
  * Deliberately decoupled from any specific transport: every side effect
13
22
  * goes through the `FlowDeps` the caller injects. The concrete wiring —
@@ -34,7 +43,32 @@
34
43
  * nor cdp-direct ever runs an oversized flow even if a future caller
35
44
  * bypasses the server's own check (e.g. a directly-wired test harness). */
36
45
  export const MAX_FLOW_STEPS = 20;
37
- const STEP_KINDS = ['find', 'click', 'type', 'press', 'wait_for', 'drag'];
46
+ /** Hard cap on one `sleep` step's `ms`. Matches the ceiling a single
47
+ * `wait_for` step may request, so no one step can park the flow longer
48
+ * than the longest wait already expressible. Out-of-range values are a
49
+ * validation ERROR rather than a silent clamp: a flow that asked to
50
+ * throttle by 60s and got 30s would hammer a backend at twice the
51
+ * intended rate without ever saying so. */
52
+ export const MAX_FLOW_SLEEP_MS = 30_000;
53
+ /** Hard cap on one `repeat` step's `max_iterations`. The real ceiling in
54
+ * practice is the flow's own worst-case time budget (a repeat's budget is
55
+ * `max_iterations × (inner steps + delay)`), which bites long before this
56
+ * does; this is the backstop that keeps a typo from producing an
57
+ * absurd projected budget. */
58
+ export const MAX_FLOW_REPEAT_ITERATIONS = 500;
59
+ /** Hard cap on a `repeat`'s inter-iteration `delay_ms` — same ceiling a
60
+ * standalone `sleep` step may request. */
61
+ export const MAX_FLOW_REPEAT_DELAY_MS = 30_000;
62
+ const STEP_KINDS = [
63
+ 'find',
64
+ 'click',
65
+ 'type',
66
+ 'press',
67
+ 'wait_for',
68
+ 'drag',
69
+ 'sleep',
70
+ 'repeat',
71
+ ];
38
72
  function isStepKind(key) {
39
73
  return STEP_KINDS.includes(key);
40
74
  }
@@ -104,6 +138,359 @@ function resolveTarget(explicit, implicit) {
104
138
  * document rather than genuinely missing its target. */
105
139
  const NAVIGATION_RACE_HINT = " (previous step's settle reported context-destroyed — the page likely navigated;" +
106
140
  ' insert a wait_for step after the navigating action so this step does not race the page load)';
141
+ /** Execute ONE non-repeat step against `state`, which it mutates. */
142
+ async function executeLeafStep(kind, stepRecord, state, deps) {
143
+ const raceHint = () => state.lastSettleReason === 'context-destroyed' ? NAVIGATION_RACE_HINT : '';
144
+ if (kind === 'find') {
145
+ const params = stepRecord.find;
146
+ const outcome = await deps.performFind(params);
147
+ if (!outcome.ok)
148
+ return { ok: false, error: outcome.error + raceHint() };
149
+ const r = outcome.result;
150
+ if (!r.matched) {
151
+ const candidateNote = r.reason === 'multiple-matches' && r.candidates
152
+ ? ` — candidates: ${JSON.stringify(r.candidates)}`
153
+ : '';
154
+ return { ok: false, error: `find: ${r.reason ?? 'not-found'}${candidateNote}${raceHint()}` };
155
+ }
156
+ if (r.ambiguous) {
157
+ return {
158
+ ok: false,
159
+ error: `find: selector "${r.selector ?? ''}" is ambiguous across shadow roots/iframes — refine text/role for a unique match`,
160
+ };
161
+ }
162
+ state.implicitTarget = r.selector;
163
+ state.lastSettleReason = undefined;
164
+ return { ok: true, entry: { selector: r.selector } };
165
+ }
166
+ if (kind === 'wait_for') {
167
+ const params = stepRecord.wait_for;
168
+ const outcome = await deps.performWaitFor(params);
169
+ if (!outcome.ok)
170
+ return { ok: false, error: outcome.error + raceHint() };
171
+ if (!outcome.result.matched) {
172
+ // No race hint here: a wait_for step IS the recommended remedy for
173
+ // a navigation race — a plain timeout is a genuine non-match.
174
+ return {
175
+ ok: false,
176
+ error: `wait_for: condition not met within timeout (${outcome.result.elapsed_ms}ms, ${outcome.result.checks} checks)`,
177
+ };
178
+ }
179
+ state.lastSettleReason = undefined;
180
+ return { ok: true, entry: { ok: true } };
181
+ }
182
+ if (kind === 'drag') {
183
+ const params = stepRecord.drag;
184
+ // No resolveTarget here ON PURPOSE: a drag names BOTH endpoints
185
+ // explicitly (selector or coords), so there is no single `selector`
186
+ // slot the implicit target could unambiguously fill — a pending
187
+ // implicit target survives this step untouched for a later
188
+ // click/type/press, exactly like it survives a wait_for.
189
+ const outcome = await deps.performDrag(params);
190
+ if (!outcome.ok)
191
+ return { ok: false, error: outcome.error + raceHint() };
192
+ // A successful drag resolved both endpoints via an in-page probe,
193
+ // which proves the document is reachable again after any earlier
194
+ // navigation — clear the race hint like find/wait_for do. (Drag has
195
+ // no settle phase, so there is no settle reason to carry instead.)
196
+ state.lastSettleReason = undefined;
197
+ return { ok: true, entry: compactActionResult(outcome.result) };
198
+ }
199
+ if (kind === 'sleep') {
200
+ const params = stepRecord.sleep;
201
+ const ms = params?.ms;
202
+ // Re-validated here even though the server already checked: this
203
+ // module is reachable from a directly-wired caller that never went
204
+ // through `validateFlowSteps` (see the runFlow doc comment).
205
+ if (typeof ms !== 'number' || !Number.isInteger(ms) || ms < 1 || ms > MAX_FLOW_SLEEP_MS) {
206
+ return {
207
+ ok: false,
208
+ error: `sleep: ms must be an integer between 1 and ${MAX_FLOW_SLEEP_MS}`,
209
+ };
210
+ }
211
+ // The guard above already REJECTED anything outside 1..MAX, so this
212
+ // Math.min can never actually reduce a value — it is not a silent
213
+ // clamp and does not weaken the reject-don't-clamp contract. It is
214
+ // here so the timer's upper bound is provable from this line alone:
215
+ // static analysis (CodeQL `js/resource-exhaustion`) cannot follow the
216
+ // bound through the compound guard, and an unbounded user-controlled
217
+ // timer duration is a finding worth keeping impossible BY SHAPE
218
+ // rather than by argument.
219
+ const delayMs = Math.min(ms, MAX_FLOW_SLEEP_MS);
220
+ await new Promise((resolve) => {
221
+ setTimeout(resolve, delayMs);
222
+ });
223
+ // Deliberately does NOT clear `lastSettleReason`: find/wait_for/drag
224
+ // clear it because each one probes the document and thereby PROVES
225
+ // it is reachable again. A sleep proves nothing — it just waits — so
226
+ // a pending navigation-race hint stays armed for the next failure.
227
+ // The implicit target likewise survives untouched, exactly as it
228
+ // survives a wait_for or a drag.
229
+ return { ok: true, entry: { slept_ms: ms } };
230
+ }
231
+ if (kind === 'click') {
232
+ const params = stepRecord.click;
233
+ const { resolved, consumed } = resolveTarget(params.selector, state.implicitTarget);
234
+ if (consumed)
235
+ state.implicitTarget = undefined;
236
+ if (resolved === undefined) {
237
+ return {
238
+ ok: false,
239
+ error: 'click: no selector provided and no implicit target from a preceding find',
240
+ };
241
+ }
242
+ const outcome = await deps.performClick({
243
+ force: params.force,
244
+ settle_ms: params.settle_ms,
245
+ selector: resolved,
246
+ });
247
+ if (!outcome.ok)
248
+ return { ok: false, error: outcome.error + raceHint() };
249
+ state.lastSettleReason = outcome.result.settle?.reason;
250
+ return { ok: true, entry: compactActionResult(outcome.result) };
251
+ }
252
+ if (kind === 'type') {
253
+ const params = stepRecord.type;
254
+ const { resolved, consumed } = resolveTarget(params.selector, state.implicitTarget);
255
+ if (consumed)
256
+ state.implicitTarget = undefined;
257
+ const outcome = await deps.performType({
258
+ text: params.text,
259
+ clear: params.clear,
260
+ settle_ms: params.settle_ms,
261
+ selector: resolved,
262
+ });
263
+ if (!outcome.ok)
264
+ return { ok: false, error: outcome.error + raceHint() };
265
+ state.lastSettleReason = outcome.result.settle?.reason;
266
+ return { ok: true, entry: compactActionResult(outcome.result) };
267
+ }
268
+ // press — the only kind left after the checks above.
269
+ const params = stepRecord.press;
270
+ const { resolved, consumed } = resolveTarget(params.selector, state.implicitTarget);
271
+ if (consumed)
272
+ state.implicitTarget = undefined;
273
+ const outcome = await deps.performPress({
274
+ key: params.key,
275
+ modifiers: params.modifiers,
276
+ settle_ms: params.settle_ms,
277
+ selector: resolved,
278
+ });
279
+ if (!outcome.ok)
280
+ return { ok: false, error: outcome.error + raceHint() };
281
+ state.lastSettleReason = outcome.result.settle?.reason;
282
+ return { ok: true, entry: compactActionResult(outcome.result) };
283
+ }
284
+ /** Validate a raw `repeat` body. Shared by the executor and the dry-run
285
+ * planner so a flow can never be projected under looser rules than it
286
+ * would actually run under. */
287
+ function normalizeRepeat(raw) {
288
+ const params = raw;
289
+ const innerSteps = params?.steps;
290
+ if (!Array.isArray(innerSteps) || innerSteps.length === 0) {
291
+ return { ok: false, error: 'repeat: steps must be a non-empty array' };
292
+ }
293
+ const maxIterations = params?.max_iterations;
294
+ if (typeof maxIterations !== 'number' ||
295
+ !Number.isInteger(maxIterations) ||
296
+ maxIterations < 1 ||
297
+ maxIterations > MAX_FLOW_REPEAT_ITERATIONS) {
298
+ return {
299
+ ok: false,
300
+ error: `repeat: max_iterations is required and must be an integer between 1 and ${MAX_FLOW_REPEAT_ITERATIONS}`,
301
+ };
302
+ }
303
+ const whileFound = params?.while_found;
304
+ if (whileFound !== undefined && (typeof whileFound !== 'string' || whileFound.length === 0)) {
305
+ return { ok: false, error: 'repeat: while_found must be a non-empty string' };
306
+ }
307
+ const delayRaw = params?.delay_ms;
308
+ if (delayRaw !== undefined &&
309
+ (typeof delayRaw !== 'number' ||
310
+ !Number.isInteger(delayRaw) ||
311
+ delayRaw < 0 ||
312
+ delayRaw > MAX_FLOW_REPEAT_DELAY_MS)) {
313
+ return {
314
+ ok: false,
315
+ error: `repeat: delay_ms must be an integer between 0 and ${MAX_FLOW_REPEAT_DELAY_MS}`,
316
+ };
317
+ }
318
+ for (let j = 0; j < innerSteps.length; j++) {
319
+ const innerKind = stepKind(innerSteps[j]);
320
+ if (!innerKind) {
321
+ return {
322
+ ok: false,
323
+ error: `repeat: step ${j}: each step must be exactly one of find | click | type | press | wait_for | drag | sleep`,
324
+ };
325
+ }
326
+ if (innerKind === 'repeat') {
327
+ return {
328
+ ok: false,
329
+ error: 'repeat: steps may not contain another repeat — nesting is not supported',
330
+ };
331
+ }
332
+ }
333
+ return {
334
+ ok: true,
335
+ value: {
336
+ steps: innerSteps,
337
+ maxIterations,
338
+ whileFound,
339
+ // Bounded with Math.min for the same reason `sleep` is: the guard
340
+ // above already rejected anything larger, so this cannot silently
341
+ // clamp — it makes the timer's ceiling provable from the call site.
342
+ delayMs: Math.min(delayRaw ?? 0, MAX_FLOW_REPEAT_DELAY_MS),
343
+ },
344
+ };
345
+ }
346
+ /**
347
+ * One-shot presence test for `while_found`.
348
+ *
349
+ * Deliberately reuses the existing `performWaitFor` seam instead of adding
350
+ * a new `FlowDeps` method: `timeout_ms: 0` makes its poll loop run exactly
351
+ * ONE check and return (it evaluates the condition BEFORE testing the
352
+ * deadline), so this is a single in-page probe with no new wiring and
353
+ * identical behaviour on both transports. `condition: 'visible'` matches
354
+ * what `browser.find` considers a real element, so a row that is merely
355
+ * hidden ends the loop just as a removed one does.
356
+ */
357
+ async function whileFoundStillMatches(selector, deps) {
358
+ const outcome = await deps.performWaitFor({ selector, condition: 'visible', timeout_ms: 0 });
359
+ if (!outcome.ok)
360
+ return { ok: false, error: outcome.error };
361
+ return { ok: true, matched: outcome.result.matched };
362
+ }
363
+ /** Run one `repeat` step to completion. */
364
+ async function executeRepeatStep(raw, deps) {
365
+ const normalized = normalizeRepeat(raw);
366
+ if (!normalized.ok)
367
+ return normalized;
368
+ const { steps: innerSteps, maxIterations, whileFound, delayMs } = normalized.value;
369
+ // Local, explicitly range-checked copy of the pause. `normalizeRepeat`
370
+ // already rejected anything outside 0..MAX, so the `else` is
371
+ // unreachable in practice — but the timer's ceiling has to be provable
372
+ // from an upper-bound COMPARISON inside this function. A `Math.min` is
373
+ // not enough here: the value reaches us through a property of the
374
+ // normalized object, and static analysis (CodeQL
375
+ // `js/resource-exhaustion`) does not carry the sanitizer across that
376
+ // hop. An unbounded user-controlled timer duration stays impossible by
377
+ // shape rather than by argument.
378
+ let iterationDelayMs = 0;
379
+ if (Number.isInteger(delayMs) && delayMs > 0 && delayMs <= MAX_FLOW_REPEAT_DELAY_MS) {
380
+ iterationDelayMs = delayMs;
381
+ }
382
+ const iterations = [];
383
+ let stoppedBy = 'max_iterations';
384
+ for (let iter = 0; iter < maxIterations; iter++) {
385
+ if (whileFound !== undefined) {
386
+ const probe = await whileFoundStillMatches(whileFound, deps);
387
+ if (!probe.ok) {
388
+ return { ok: false, error: `repeat: while_found probe failed — ${probe.error}` };
389
+ }
390
+ if (!probe.matched) {
391
+ stoppedBy = 'condition';
392
+ break;
393
+ }
394
+ }
395
+ // Fresh state per iteration: iteration N can never act on whatever
396
+ // iteration N-1's `find` happened to resolve.
397
+ const state = { implicitTarget: undefined, lastSettleReason: undefined };
398
+ const entries = [];
399
+ for (let j = 0; j < innerSteps.length; j++) {
400
+ const innerRaw = innerSteps[j];
401
+ // Re-derived per iteration rather than trusted from normalizeRepeat:
402
+ // same defense-in-depth every other step shape gets.
403
+ const innerKind = stepKind(innerRaw);
404
+ if (innerKind === null || innerKind === 'repeat') {
405
+ return {
406
+ ok: false,
407
+ error: `repeat: iteration ${iter}, step ${j}: invalid step shape`,
408
+ };
409
+ }
410
+ const outcome = await executeLeafStep(innerKind, innerRaw, state, deps);
411
+ if (!outcome.ok) {
412
+ return {
413
+ ok: false,
414
+ error: `repeat: iteration ${iter}, step ${j} (${innerKind}) failed — ${outcome.error}`,
415
+ };
416
+ }
417
+ entries.push(outcome.entry);
418
+ }
419
+ iterations.push(entries);
420
+ if (iterationDelayMs > 0) {
421
+ await new Promise((resolve) => {
422
+ setTimeout(resolve, iterationDelayMs);
423
+ });
424
+ }
425
+ }
426
+ const entry = {
427
+ iterations_completed: iterations.length,
428
+ stopped_by: stoppedBy,
429
+ iterations,
430
+ };
431
+ return { ok: true, entry };
432
+ }
433
+ /** Total step count INCLUDING a repeat's inner steps. A 20-step ceiling
434
+ * that only counted the outer array would let a single repeat smuggle in
435
+ * an arbitrarily long body. */
436
+ function countTotalSteps(steps) {
437
+ let total = 0;
438
+ // Walked as `unknown`, not as FlowStep: the array is typed for
439
+ // ergonomic test-writing but arrives as untrusted JSON cast at the wire
440
+ // boundary, so an entry can genuinely be null or a primitive. Narrowing
441
+ // from `unknown` keeps those guards meaningful instead of letting the
442
+ // declared type talk the compiler out of them.
443
+ for (const step of steps) {
444
+ total++;
445
+ if (typeof step === 'object' && step !== null && 'repeat' in step) {
446
+ const inner = step.repeat?.steps;
447
+ if (Array.isArray(inner))
448
+ total += inner.length;
449
+ }
450
+ }
451
+ return total;
452
+ }
453
+ /**
454
+ * Project a flow without executing it. Reads are allowed (a `while_found`
455
+ * probe is a read); nothing is ever dispatched.
456
+ */
457
+ async function planFlow(steps, deps) {
458
+ const results = [];
459
+ for (let i = 0; i < steps.length; i++) {
460
+ const raw = steps[i];
461
+ const kind = stepKind(raw);
462
+ if (!kind) {
463
+ return withRecoverySnapshot(deps, i, 'unknown', 'flow: each step must be exactly one of find | click | type | press | wait_for | drag | sleep | repeat', results.length);
464
+ }
465
+ if (kind !== 'repeat') {
466
+ results.push({ step: kind });
467
+ continue;
468
+ }
469
+ const stepRecord = raw;
470
+ const normalized = normalizeRepeat(stepRecord.repeat);
471
+ if (!normalized.ok) {
472
+ return withRecoverySnapshot(deps, i, kind, normalized.error, results.length);
473
+ }
474
+ const { maxIterations, whileFound, delayMs } = normalized.value;
475
+ let wouldStart = true;
476
+ if (whileFound !== undefined) {
477
+ const probe = await whileFoundStillMatches(whileFound, deps);
478
+ if (!probe.ok) {
479
+ return withRecoverySnapshot(deps, i, kind, `repeat: while_found probe failed — ${probe.error}`, results.length);
480
+ }
481
+ wouldStart = probe.matched;
482
+ }
483
+ results.push({
484
+ step: 'repeat',
485
+ max_iterations: maxIterations,
486
+ inner_steps: normalized.value.steps.length,
487
+ delay_ms: delayMs,
488
+ ...(whileFound === undefined ? {} : { while_found: whileFound }),
489
+ would_start: wouldStart,
490
+ });
491
+ }
492
+ return { ok: true, steps_completed: 0, results, dry_run: true };
493
+ }
107
494
  /**
108
495
  * Run a declarative sequence of steps strictly in order, stopping at the
109
496
  * first failure. See the module doc comment for the implicit-target and
@@ -114,138 +501,47 @@ const NAVIGATION_RACE_HINT = " (previous step's settle reported context-destroye
114
501
  * array may originate from an untrusted JSON payload cast at the wire
115
502
  * boundary in `background.ts` (extension) / `cdp/transport.ts` (server),
116
503
  * and a malformed entry must fail the flow cleanly rather than throw.
504
+ *
505
+ * With `options.dryRun`, the flow is validated and projected instead:
506
+ * nothing is dispatched, and each entry describes what WOULD run.
117
507
  */
118
- export async function runFlow(steps, deps) {
508
+ export async function runFlow(steps, deps, options = {}) {
119
509
  if (!Array.isArray(steps) || steps.length === 0) {
120
510
  return withRecoverySnapshot(deps, 0, 'none', 'flow: steps must be a non-empty array', 0);
121
511
  }
122
- if (steps.length > MAX_FLOW_STEPS) {
123
- return withRecoverySnapshot(deps, 0, 'none', `flow: at most ${MAX_FLOW_STEPS} steps allowed, got ${steps.length}`, 0);
512
+ const totalSteps = countTotalSteps(steps);
513
+ if (totalSteps > MAX_FLOW_STEPS) {
514
+ return withRecoverySnapshot(deps, 0, 'none', `flow: at most ${MAX_FLOW_STEPS} steps allowed, got ${totalSteps}`, 0);
124
515
  }
516
+ if (options.dryRun === true)
517
+ return planFlow(steps, deps);
125
518
  const results = [];
126
- let implicitTarget;
127
- /** `settle.reason` from the most recent SUCCESSFUL action step. When it
128
- * is 'context-destroyed', the next step failure gets the page-load-race
129
- * hint appended. Reset by any successful find/wait_for step — those
130
- * prove the page is reachable again. */
131
- let lastSettleReason;
132
- const raceHint = () => lastSettleReason === 'context-destroyed' ? NAVIGATION_RACE_HINT : '';
519
+ const state = { implicitTarget: undefined, lastSettleReason: undefined };
133
520
  for (let i = 0; i < steps.length; i++) {
134
521
  const raw = steps[i];
135
522
  const kind = stepKind(raw);
136
523
  if (!kind) {
137
- return withRecoverySnapshot(deps, i, 'unknown', 'flow: each step must be exactly one of find | click | type | press | wait_for | drag', results.length);
524
+ return withRecoverySnapshot(deps, i, 'unknown', 'flow: each step must be exactly one of find | click | type | press | wait_for | drag | sleep | repeat', results.length);
138
525
  }
139
526
  const stepRecord = raw;
140
- if (kind === 'find') {
141
- const params = stepRecord.find;
142
- const outcome = await deps.performFind(params);
143
- if (!outcome.ok) {
144
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
145
- }
146
- const r = outcome.result;
147
- if (!r.matched) {
148
- const candidateNote = r.reason === 'multiple-matches' && r.candidates
149
- ? ` — candidates: ${JSON.stringify(r.candidates)}`
150
- : '';
151
- return withRecoverySnapshot(deps, i, kind, `find: ${r.reason ?? 'not-found'}${candidateNote}${raceHint()}`, results.length);
152
- }
153
- if (r.ambiguous) {
154
- return withRecoverySnapshot(deps, i, kind, `find: selector "${r.selector ?? ''}" is ambiguous across shadow roots/iframes — refine text/role for a unique match`, results.length);
155
- }
156
- implicitTarget = r.selector;
157
- lastSettleReason = undefined;
158
- results.push({ selector: r.selector });
159
- continue;
160
- }
161
- if (kind === 'wait_for') {
162
- const params = stepRecord.wait_for;
163
- const outcome = await deps.performWaitFor(params);
164
- if (!outcome.ok) {
165
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
166
- }
167
- if (!outcome.result.matched) {
168
- // No race hint here: a wait_for step IS the recommended remedy for
169
- // a navigation race — a plain timeout is a genuine non-match.
170
- return withRecoverySnapshot(deps, i, kind, `wait_for: condition not met within timeout (${outcome.result.elapsed_ms}ms, ${outcome.result.checks} checks)`, results.length);
171
- }
172
- lastSettleReason = undefined;
173
- results.push({ ok: true });
174
- continue;
175
- }
176
- if (kind === 'drag') {
177
- const params = stepRecord.drag;
178
- // No resolveTarget here ON PURPOSE: a drag names BOTH endpoints
179
- // explicitly (selector or coords), so there is no single `selector`
180
- // slot the implicit target could unambiguously fill — a pending
181
- // implicit target survives this step untouched for a later
182
- // click/type/press, exactly like it survives a wait_for.
183
- const outcome = await deps.performDrag(params);
184
- if (!outcome.ok) {
185
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
186
- }
187
- // A successful drag resolved both endpoints via an in-page probe,
188
- // which proves the document is reachable again after any earlier
189
- // navigation — clear the race hint like find/wait_for do. (Drag has
190
- // no settle phase, so there is no settle reason to carry instead.)
191
- lastSettleReason = undefined;
192
- results.push(compactActionResult(outcome.result));
193
- continue;
194
- }
195
- if (kind === 'click') {
196
- const params = stepRecord.click;
197
- const { resolved, consumed } = resolveTarget(params.selector, implicitTarget);
198
- if (consumed)
199
- implicitTarget = undefined;
200
- if (resolved === undefined) {
201
- return withRecoverySnapshot(deps, i, kind, 'click: no selector provided and no implicit target from a preceding find', results.length);
202
- }
203
- const outcome = await deps.performClick({
204
- force: params.force,
205
- settle_ms: params.settle_ms,
206
- selector: resolved,
207
- });
208
- if (!outcome.ok) {
209
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
210
- }
211
- lastSettleReason = outcome.result.settle?.reason;
212
- results.push(compactActionResult(outcome.result));
213
- continue;
214
- }
215
- if (kind === 'type') {
216
- const params = stepRecord.type;
217
- const { resolved, consumed } = resolveTarget(params.selector, implicitTarget);
218
- if (consumed)
219
- implicitTarget = undefined;
220
- const outcome = await deps.performType({
221
- text: params.text,
222
- clear: params.clear,
223
- settle_ms: params.settle_ms,
224
- selector: resolved,
225
- });
527
+ if (kind === 'repeat') {
528
+ const outcome = await executeRepeatStep(stepRecord.repeat, deps);
226
529
  if (!outcome.ok) {
227
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
530
+ return withRecoverySnapshot(deps, i, kind, outcome.error, results.length);
228
531
  }
229
- lastSettleReason = outcome.result.settle?.reason;
230
- results.push(compactActionResult(outcome.result));
532
+ // A repeat body runs with its own state and does not leak one out:
533
+ // a pending implicit target from BEFORE the repeat also does not
534
+ // survive it, since the body may have navigated or re-rendered.
535
+ state.implicitTarget = undefined;
536
+ state.lastSettleReason = undefined;
537
+ results.push(outcome.entry);
231
538
  continue;
232
539
  }
233
- // press — the only kind left after the checks above.
234
- const params = stepRecord.press;
235
- const { resolved, consumed } = resolveTarget(params.selector, implicitTarget);
236
- if (consumed)
237
- implicitTarget = undefined;
238
- const outcome = await deps.performPress({
239
- key: params.key,
240
- modifiers: params.modifiers,
241
- settle_ms: params.settle_ms,
242
- selector: resolved,
243
- });
540
+ const outcome = await executeLeafStep(kind, stepRecord, state, deps);
244
541
  if (!outcome.ok) {
245
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
542
+ return withRecoverySnapshot(deps, i, kind, outcome.error, results.length);
246
543
  }
247
- lastSettleReason = outcome.result.settle?.reason;
248
- results.push(compactActionResult(outcome.result));
544
+ results.push(outcome.entry);
249
545
  }
250
546
  return { ok: true, steps_completed: results.length, results };
251
547
  }
@@ -1 +1 @@
1
- {"version":3,"file":"flow.js","sourceRoot":"","sources":["../src/flow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flow.js","sourceRoot":"","sources":["../src/flow.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "browser-link",
4
- "version": "0.23.14",
4
+ "version": "0.25.0",
5
5
  "description": "Bridge between Chrome and an MCP client (Claude Code, OpenCode, GitHub Copilot CLI, …). Per-tab manual activation.",
6
6
  "permissions": [
7
7
  "debugger",