@enricai/barnacle 1.6.12 → 1.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +113 -9
  2. package/dist/api/schemas/submissions.d.ts +14 -0
  3. package/dist/api/schemas/submissions.d.ts.map +1 -1
  4. package/dist/api/schemas/submissions.js +1 -0
  5. package/dist/api/schemas/submissions.js.map +1 -1
  6. package/dist/config.d.ts +33 -0
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +4 -0
  9. package/dist/config.js.map +1 -1
  10. package/dist/lib/bedrock.d.ts +8 -5
  11. package/dist/lib/bedrock.d.ts.map +1 -1
  12. package/dist/lib/bedrock.js +8 -5
  13. package/dist/lib/bedrock.js.map +1 -1
  14. package/dist/lib/http.d.ts +4 -3
  15. package/dist/lib/http.d.ts.map +1 -1
  16. package/dist/lib/http.js +25 -3
  17. package/dist/lib/http.js.map +1 -1
  18. package/dist/lib/telemetry/beacon-capture.d.ts +45 -2
  19. package/dist/lib/telemetry/beacon-capture.d.ts.map +1 -1
  20. package/dist/lib/telemetry/beacon-capture.js +36 -0
  21. package/dist/lib/telemetry/beacon-capture.js.map +1 -1
  22. package/dist/lib/telemetry/reconciliation-record.d.ts +41 -1
  23. package/dist/lib/telemetry/reconciliation-record.d.ts.map +1 -1
  24. package/dist/lib/telemetry/reconciliation-record.js +29 -2
  25. package/dist/lib/telemetry/reconciliation-record.js.map +1 -1
  26. package/dist/lib/telemetry/reconciliation-source.d.ts +7 -1
  27. package/dist/lib/telemetry/reconciliation-source.d.ts.map +1 -1
  28. package/dist/lib/telemetry/reconciliation-source.js +21 -5
  29. package/dist/lib/telemetry/reconciliation-source.js.map +1 -1
  30. package/dist/lib/telemetry/run-telemetry.d.ts +67 -0
  31. package/dist/lib/telemetry/run-telemetry.d.ts.map +1 -0
  32. package/dist/lib/telemetry/run-telemetry.js +55 -0
  33. package/dist/lib/telemetry/run-telemetry.js.map +1 -0
  34. package/dist/lib/telemetry/submission-capture.d.ts +11 -4
  35. package/dist/lib/telemetry/submission-capture.d.ts.map +1 -1
  36. package/dist/lib/telemetry/submission-capture.js +1 -0
  37. package/dist/lib/telemetry/submission-capture.js.map +1 -1
  38. package/dist/lib/telemetry/submission-reader.d.ts +11 -3
  39. package/dist/lib/telemetry/submission-reader.d.ts.map +1 -1
  40. package/dist/lib/telemetry/submission-reader.js +32 -8
  41. package/dist/lib/telemetry/submission-reader.js.map +1 -1
  42. package/dist/lib/tracking-click.d.ts.map +1 -1
  43. package/dist/lib/tracking-click.js +19 -0
  44. package/dist/lib/tracking-click.js.map +1 -1
  45. package/dist/plugins/config-plugin.js +3 -3
  46. package/dist/plugins/loader.d.ts +20 -0
  47. package/dist/plugins/loader.d.ts.map +1 -1
  48. package/dist/plugins/loader.js +94 -17
  49. package/dist/plugins/loader.js.map +1 -1
  50. package/dist/scraper/deep-locator-actuate.d.ts +94 -0
  51. package/dist/scraper/deep-locator-actuate.d.ts.map +1 -0
  52. package/dist/scraper/deep-locator-actuate.js +216 -0
  53. package/dist/scraper/deep-locator-actuate.js.map +1 -0
  54. package/dist/scraper/deep-locator-candidates.d.ts +105 -18
  55. package/dist/scraper/deep-locator-candidates.d.ts.map +1 -1
  56. package/dist/scraper/deep-locator-candidates.js +238 -46
  57. package/dist/scraper/deep-locator-candidates.js.map +1 -1
  58. package/dist/scraper/deep-locator-click.d.ts +71 -0
  59. package/dist/scraper/deep-locator-click.d.ts.map +1 -0
  60. package/dist/scraper/deep-locator-click.js +71 -0
  61. package/dist/scraper/deep-locator-click.js.map +1 -0
  62. package/dist/scraper/deep-locator-fake.d.ts +344 -14
  63. package/dist/scraper/deep-locator-fake.d.ts.map +1 -1
  64. package/dist/scraper/deep-locator-fake.js +509 -7
  65. package/dist/scraper/deep-locator-fake.js.map +1 -1
  66. package/dist/scraper/deep-locator-scan.d.ts +220 -0
  67. package/dist/scraper/deep-locator-scan.d.ts.map +1 -0
  68. package/dist/scraper/deep-locator-scan.js +386 -0
  69. package/dist/scraper/deep-locator-scan.js.map +1 -0
  70. package/dist/scraper/fake-timer-advance.d.ts +47 -0
  71. package/dist/scraper/fake-timer-advance.d.ts.map +1 -0
  72. package/dist/scraper/fake-timer-advance.js +44 -0
  73. package/dist/scraper/fake-timer-advance.js.map +1 -0
  74. package/dist/scraper/flow-runner.d.ts +80 -9
  75. package/dist/scraper/flow-runner.d.ts.map +1 -1
  76. package/dist/scraper/flow-runner.js +417 -63
  77. package/dist/scraper/flow-runner.js.map +1 -1
  78. package/dist/scraper/frame-target.d.ts +28 -0
  79. package/dist/scraper/frame-target.d.ts.map +1 -1
  80. package/dist/scraper/frame-target.js +30 -0
  81. package/dist/scraper/frame-target.js.map +1 -1
  82. package/dist/scraper/session-browserbase.d.ts +13 -0
  83. package/dist/scraper/session-browserbase.d.ts.map +1 -1
  84. package/dist/scraper/session-browserbase.js +29 -0
  85. package/dist/scraper/session-browserbase.js.map +1 -1
  86. package/dist/scraper/session-ip.d.ts +69 -0
  87. package/dist/scraper/session-ip.d.ts.map +1 -0
  88. package/dist/scraper/session-ip.js +88 -0
  89. package/dist/scraper/session-ip.js.map +1 -0
  90. package/dist/scraper/session-shared.d.ts +9 -0
  91. package/dist/scraper/session-shared.d.ts.map +1 -1
  92. package/dist/scraper/session-shared.js.map +1 -1
  93. package/dist/scraper/submit-control.d.ts +14 -2
  94. package/dist/scraper/submit-control.d.ts.map +1 -1
  95. package/dist/scraper/submit-control.js +33 -2
  96. package/dist/scraper/submit-control.js.map +1 -1
  97. package/dist/scripts/recon-browser.d.ts +1 -1
  98. package/dist/scripts/recon-browser.d.ts.map +1 -1
  99. package/dist/scripts/recon-browser.js +48 -16
  100. package/dist/scripts/recon-browser.js.map +1 -1
  101. package/dist/scripts/recon-generate.js +3 -3
  102. package/dist/scripts/recon-generate.js.map +1 -1
  103. package/dist/site-plugin.d.ts +20 -0
  104. package/dist/site-plugin.d.ts.map +1 -1
  105. package/dist/testing/integration-runner.d.ts.map +1 -1
  106. package/dist/testing/integration-runner.js +6 -7
  107. package/dist/testing/integration-runner.js.map +1 -1
  108. package/package.json +3 -2
package/README.md CHANGED
@@ -428,12 +428,48 @@ export const myPlugin: SitePlugin<MyPayload, MyResponse> = {
428
428
  };
429
429
  ```
430
430
 
431
- `dispatch()` (`src/plugins/loader.ts`) calls this once per submission and
432
- stamps the opaque `Record<string, unknown>` result onto the submission
433
- envelope and the beacon-fire record verbatim, under a `joinKeys` field
434
- core never inspects its contents. A plugin with no reconciliation needs
431
+ `dispatch()` (`src/plugins/loader.ts`) calls this once per submission,
432
+ resolving `extractJoinKeys(payload)` from the inbound payload alone core
433
+ never inspects the result's contents. A plugin with no reconciliation needs
435
434
  simply omits `extractJoinKeys`.
436
435
 
436
+ #### Mid-run attach point (`context.telemetry.addJoinKeys`)
437
+
438
+ `extractJoinKeys` only ever sees the payload a plugin received up front, so
439
+ it has no way to attach a field the plugin only discovers *during* the run
440
+ — a token minted mid-flow, a value read from the page after navigation, a
441
+ value observed on a response. For that, call the mid-run attach point,
442
+ `context.telemetry.addJoinKeys()`, from anywhere inside `execute()` or
443
+ `executeHttp()`:
444
+
445
+ ```ts
446
+ async execute(payload: MyPayload, session, context: SitePluginContext) {
447
+ const mintedToken = await readTokenFromPage(session);
448
+ context.telemetry.addJoinKeys({ mintedToken });
449
+ // ...
450
+ },
451
+ ```
452
+
453
+ `context.telemetry` is a per-dispatch `RunTelemetry` accumulator
454
+ (`src/lib/telemetry/run-telemetry.ts`), constructed fresh for every
455
+ dispatch by `buildPluginContext` (`src/plugins/loader.ts`) alongside
456
+ `recordBeaconOutcome` below. Successive `addJoinKeys()` calls within the
457
+ same run merge, later calls winning on key collision. Once the plugin call
458
+ resolves — on both the success and error paths — `dispatch()` snapshots the
459
+ accumulator and merges it over the earlier `extractJoinKeys(payload)`
460
+ result, run-discovered keys winning on collision, before stamping the
461
+ combined bag onto the submission envelope's and beacon-fire record's
462
+ `joinKeys` field. `joinKeys` stays `null` only when neither source ever
463
+ produced anything.
464
+
465
+ **A config-only `*.plugin.json` manifest can reach
466
+ `context.telemetry.addJoinKeys()` only through the same `spec.httpModule`
467
+ escape hatch documented below for `context.recordBeaconOutcome`** —
468
+ `executeHttp(payload, context)` receives the same `SitePluginContext`, so an
469
+ `httpModule` can call it exactly like `execute()` does above; the
470
+ manifest's declarative browser flow cannot, since `runHealingFlow` is
471
+ data-driven with no imperative call site for either seam to live in.
472
+
437
473
  **Declaring `extractJoinKeys` also opts the plugin out of core's automatic
438
474
  `TrackingUrl` fire.** If the site returns a post-submission click-tracking
439
475
  URL, declare it on the plugin's `bodySchema` by composing `JobTrackingSchema`
@@ -446,6 +482,63 @@ navs must share one browser session for a vendor's device-cookie
446
482
  attribution to work) and skips its own fire — firing both would open two
447
483
  independent sessions against the same URL.
448
484
 
485
+ By default a self-managing plugin's beacon-fire telemetry is stuck at
486
+ `beaconStatus: "skipped"`, since core has no visibility into a navigation the
487
+ plugin drives itself. To report the real outcome, call
488
+ `context.recordBeaconOutcome` — passed on `SitePluginContext` alongside
489
+ `baseUrl`/`logger`/`requestId`, bound to this run — from `execute()`,
490
+ `executeHttp()`, or an extra-route handler:
491
+
492
+ ```ts
493
+ import type { SitePlugin, SitePluginContext } from "@enricai/barnacle/site-plugin";
494
+
495
+ export const myPlugin: SitePlugin<MyPayload, MyResponse> = {
496
+ extractJoinKeys: (payload) =>
497
+ payload.someVendorClickId ? { vendorClickId: payload.someVendorClickId } : null,
498
+ async execute(payload, session, context: SitePluginContext) {
499
+ const t0 = Date.now();
500
+ const fired = await runMySiteBeaconNav(session, payload.TrackingUrl);
501
+ await context.recordBeaconOutcome({
502
+ beaconStatus: fired ? "fired" : "failed",
503
+ joinKeys: { vendorClickId: payload.someVendorClickId },
504
+ trackingUrl: payload.TrackingUrl,
505
+ durationMs: Date.now() - t0,
506
+ });
507
+ // ...
508
+ },
509
+ };
510
+ ```
511
+
512
+ Core binds the run's `requestId` and the plugin's own `siteId` for you, so
513
+ `recordBeaconOutcome`'s input carries only `beaconStatus` (`"fired"` |
514
+ `"failed"` — `"skipped"` stays an engine-owned outcome), the opaque `joinKeys`
515
+ bag (same shape returned from `extractJoinKeys`), and optional `trackingUrl`/
516
+ `durationMs`. It never throws — a telemetry-sink hiccup cannot fail the
517
+ request. A `fired`/`failed` line recorded this way outranks the automatic
518
+ `skipped` line for the same `requestId` when the two are folded together
519
+ (see [Telemetry & LLM judging](docs/telemetry-and-judging.md)). A plugin that
520
+ never calls it keeps today's unchanged `skipped` default. Import
521
+ `BeaconOutcomeInput` from `@enricai/barnacle/site-plugin` if you want to type
522
+ the input object explicitly — that's the published subpath an out-of-tree
523
+ plugin resolves against its own `node_modules`; in-tree code under `src/`
524
+ uses the `@/site-plugin` alias instead.
525
+
526
+ **A config-only `*.plugin.json` manifest can reach `context.recordBeaconOutcome`
527
+ only through the `spec.httpModule` escape hatch** — `executeHttp(payload,
528
+ context)` receives the same `SitePluginContext` a module plugin's does, so an
529
+ `httpModule` can call it exactly like `execute()` does above. The manifest's
530
+ declarative browser flow cannot: `runHealingFlow` is data-driven, with no
531
+ imperative call site for a call like this to live in. One consequence to know
532
+ before adopting it: `buildConfigPlugin` never synthesizes `extractJoinKeys`,
533
+ so a config-only plugin is never `managesOwnTracking` — when the response
534
+ carries a `TrackingUrl`, core still fires it itself via `fireTrackingClick`,
535
+ and a manifest-recorded `fired`/`failed` line for that `requestId` ranks
536
+ equal to core's own line under `beaconRank()`, so the fold resolves by write
537
+ order (last line wins) rather than the manifest's line automatically
538
+ outranking core's. Only when no `TrackingUrl` is present — so core's own
539
+ write is the `skipped` default — does the manifest's recorded line
540
+ deterministically outrank it.
541
+
449
542
  ### Static fixtures
450
543
 
451
544
  If Phase 3b (auxiliary fixture detection) found static JSON endpoints (markets, currencies, labels), `recon:generate` copies them to `src/sites/<id>/fixtures/`. Load them at module init via `loadFixture()` — zero per-request overhead, fails fast on deploy if the fixture is missing or stale:
@@ -670,17 +763,23 @@ in `src/lib/telemetry/reconciliation-record.ts`):
670
763
  | `kind` | `"submit"` | Discriminates this record from a `"beacon"` conversion-event record sharing the same sink; defaults to `"submit"` so lines written before this field existed still parse. |
671
764
  | `siteId` | `string` | Which plugin handled the request — the cohort dimension for reconciliation. |
672
765
  | `requestId` | `string` | Fastify-issued correlation ID; joins a later `"beacon"` record to this one by matching `requestId`. |
673
- | `joinKeys` | `Record<string, unknown> \| null` | Opaque, plugin-owned reconciliation join keys, resolved once by the plugin's `extractJoinKeys` hook (see [Reconciliation join keys](#reconciliation-join-keys-extractjoinkeys) above); `null` when the plugin has no `extractJoinKeys` or it resolved nothing. |
766
+ | `joinKeys` | `Record<string, unknown> \| null` | Opaque, plugin-owned reconciliation join keys: the plugin's `extractJoinKeys` hook resolved once from the inbound payload, merged with anything the plugin attached mid-run via `context.telemetry.addJoinKeys()` (run-discovered keys win on collision — see [Reconciliation join keys](#reconciliation-join-keys-extractjoinkeys) above); `null` when neither source produced anything. |
674
767
  | `inboundPayload` | `unknown` | The request body the caller posted, unredacted. |
675
768
  | `status` | `"submitted" \| "error"` | Submit outcome. |
676
769
  | `auditPayload` | `unknown` | The plugin's `SitePluginResult.auditPayload`, or `data` when absent; `null` on errors. |
677
770
  | `errorMessage` | `string \| null` | Failure message on errors; `null` on success. |
678
771
  | `durationMs` | `number` | Total dispatch wall time in milliseconds. |
679
772
  | `ts` | `string` | ISO-8601 timestamp at write time. |
773
+ | `session` | `{ id, provider, ip, ipCapturedAt } \| null` | Identity and outbound IP of the Browserbase session that served this run; `null` on the direct-HTTP hot path where no session is ever acquired. See [Submission-envelope sink](docs/telemetry-and-judging.md#submission-envelope-sink) for capture details. |
680
774
 
681
775
  A `"beacon"`-kind record shares the same sink to record a later, independent
682
- beacon-fire outcome for the same `requestId`see
683
- [Submission-envelope sink](docs/telemetry-and-judging.md#submission-envelope-sink)
776
+ beacon-fire outcome for the same `requestId`. Core writes one itself either
777
+ a `fired`/`failed` line once `fireTrackingClick` resolves, or a `skipped` line
778
+ when there is no `TrackingUrl` to fire or the plugin declared
779
+ `extractJoinKeys` — but a plugin managing its own tracking nav can also emit
780
+ one directly via `context.recordBeaconOutcome` (see
781
+ [Reconciliation join keys](#reconciliation-join-keys-extractjoinkeys) above).
782
+ See [Submission-envelope sink](docs/telemetry-and-judging.md#submission-envelope-sink)
684
783
  for the full schema and the `GET /v1/submissions` read path.
685
784
 
686
785
  #### Tailing call samples with jq
@@ -742,6 +841,10 @@ process to exit on missing values; optional ones have safe defaults.
742
841
  | `FRAME_READY_TIMEOUT_MS` | `20000` | No | How long `resolveFrameTarget` polls for a child iframe to attach before falling back to the main frame (ms). Raise further for cross-origin OOPIFs that attach slowly under advancedStealth + proxied CDP. |
743
842
  | `FRAME_DOCUMENT_READY_TIMEOUT_MS` | `5000` | No | How long `waitForChildFrameReady` polls a resolved child frame's `document.readyState` before proceeding anyway (ms). Independent of `FRAME_READY_TIMEOUT_MS` — this wait settles in well under a second once attached. |
744
843
  | `FRAME_EVALUATE_TIMEOUT_MS` | `30000` | No | Watchdog budget for a single frame-scoped evaluate/candidate-probe call (ms), so a call against a racy frame fails the attempt instead of hanging indefinitely. |
844
+ | `FRAME_PRESENCE_PROBE_FLOOR_MS` | `3000` | No | Per-probe watchdog floor for `probeAttachedFrameTarget`'s single non-polling presence check (ms) — a real budget a genuine CDP round-trip can land within, instead of the `timeoutMs: 0` zero-budget pattern that always loses that race. |
845
+ | `SCRAPER_CAPTURE_SESSION_IP` | `true` | No | Master switch for the outbound-IP echo navigation; `false` yields `session: null` / `sessionIp: null` everywhere without touching the rest of the submit/beacon record. |
846
+ | `SCRAPER_SESSION_IP_ECHO_URL` | `https://api.ipify.org?format=json` | No | The IP-echo endpoint the session's own short-lived tab navigates to. Operators can point this at a self-hosted echo endpoint. |
847
+ | `SCRAPER_SESSION_IP_TIMEOUT_MS` | `10000` | No | Watchdog bound on the echo navigation; a page that never resolves is cut off and yields `null` rather than blocking the submission. |
745
848
 
746
849
  ### AWS Bedrock (alternative LLM provider)
747
850
 
@@ -823,7 +926,7 @@ http/net/dns. Metrics have no such constraint.
823
926
  | `TELEMETRY_ENABLED` | `true` | Master switch — set `false` to disable all NDJSON telemetry writes. |
824
927
  | `TELEMETRY_EVENTS_DIR` | `.barnacle/events` | Directory for per-run NDJSON event stream files (`<eventsDir>/<runId>.ndjson`). |
825
928
  | `CALLS_NDJSON_PATH` | `.barnacle/calls.ndjson` | Append-only NDJSON sink for LLM/Stagehand call samples. One line per call; feed to the judge and self-heal skills. |
826
- | `SUBMISSIONS_NDJSON_PATH` | `.barnacle/submissions.ndjson` | Append-only NDJSON sink for dispatch submission envelopes and beacon-fire outcomes. `kind:"submit"` lines (null/`"submit"`-defaulted on legacy lines) capture siteId, requestId, inbound payload, status, audit payload, and duration, plus the opaque `joinKeys` bag a plugin's `extractJoinKeys` hook resolved — the durable source-of-truth for "what did we submit for jobId X and did it succeed." `kind:"beacon"` lines record a later (or, for `beaconStatus: "skipped"`, immediate) independent beacon-fire outcome (`beaconStatus`: `fired`/`failed`/`skipped`, truncated `trackingUrl`) for the same `requestId`, so "submitted but the beacon did not fire" is measurable. A reader folds both kinds together by `requestId`, so a plugin can join runs to its own attribution provider's report without re-parsing `inboundPayload`. |
929
+ | `SUBMISSIONS_NDJSON_PATH` | `.barnacle/submissions.ndjson` | Append-only NDJSON sink for dispatch submission envelopes and beacon-fire outcomes. `kind:"submit"` lines (null/`"submit"`-defaulted on legacy lines) capture siteId, requestId, inbound payload, status, audit payload, and duration, plus the opaque `joinKeys` bag a plugin's `extractJoinKeys` hook resolved, merged with anything attached mid-run via `context.telemetry.addJoinKeys()` — the durable source-of-truth for "what did we submit for jobId X and did it succeed." `kind:"beacon"` lines record a later (or, for `beaconStatus: "skipped"`, immediate) independent beacon-fire outcome (`beaconStatus`: `fired`/`failed`/`skipped`, truncated `trackingUrl`) for the same `requestId`, so "submitted but the beacon did not fire" is measurable — the `skipped` line is always written by `dispatch()` itself, but a plugin managing its own tracking nav can call `context.recordBeaconOutcome` to append a real `fired`/`failed` line for the same `requestId`, which outranks `skipped` when the two are folded (see [Reconciliation join keys](#reconciliation-join-keys-extractjoinkeys)). A reader folds both kinds together by `requestId`, so a plugin can join runs to its own attribution provider's report without re-parsing `inboundPayload`. |
827
930
  | `TELEMETRY_MAX_FILE_SIZE_BYTES` | `104857600` (100 MB) | Rotate/drop the calls NDJSON once it exceeds this byte count. |
828
931
  | `TELEMETRY_MAX_RETENTION_MS` | `2592000000` (30 days) | Drop event-stream files older than this many milliseconds. |
829
932
  | `TELEMETRY_S3_BUCKET` | — | Optional — destination bucket for the buffered S3 telemetry mirror. Sink is entirely inert (no client, no network calls) when unset. Credentials/region resolve the same way as Bedrock (`AWS_REGION`, standard SDK credential order). |
@@ -1017,7 +1120,7 @@ Operational routes:
1017
1120
  - `GET /readyz` — readiness probe (checks scraper credentials, queue depth)
1018
1121
  - `GET /docs` — Swagger UI (when `ENABLE_DOCS=true`)
1019
1122
  - `GET /v1/plugins` — authenticated plugin load report (see [Out-of-tree plugins](#out-of-tree-plugins))
1020
- - `GET /v1/submissions` — authenticated, queryable submit+beacon reconciliation rows (filter by `siteId`, `requestId`, `status`, `beaconStatus`, `from`/`to`; each row's opaque `joinKeys` bag is a plugin-owned field, not filterable at this layer; see [Submission-envelope sink](docs/telemetry-and-judging.md#submission-envelope-sink))
1123
+ - `GET /v1/submissions` — authenticated, queryable submit+beacon reconciliation rows (filter by `siteId`, `requestId`, `status`, `beaconStatus`, `from`/`to`; each row also carries the submit session block `session` (`{ id, provider, ip, ipCapturedAt }`) and the beacon-fire `beaconSessionIp`, neither of which is filterable at this layer, same as the opaque `joinKeys` bag; see [Submission-envelope sink](docs/telemetry-and-judging.md#submission-envelope-sink))
1021
1124
 
1022
1125
  ## Commands
1023
1126
 
@@ -1077,6 +1180,7 @@ src/
1077
1180
  │ ├── navigate.ts # shared awaitActivePage + goto(networkidle) helper
1078
1181
  │ ├── behavioral-signals.ts # CDP synthetic mouse-move + scroll dispatcher for bot-detection warmup
1079
1182
  │ ├── session-warmup.ts # generic pRetry browser-session runner: acquire → callback → close, with caller-supplied exhaustion mapping
1183
+ │ ├── session-ip.ts # resolves a session's outbound IP via a throwaway tab + IP-echo navigation
1080
1184
  │ └── require-response-field.ts # shared helpers for extracting required fields from HTTP response objects (HttpSchemaError on missing/null)
1081
1185
  ├── cache/
1082
1186
  │ ├── response-cache.ts # lru-cache wrapper for deduplicating concurrent identical scraper requests
@@ -44,6 +44,12 @@ export declare const reconciliationRowSchema: z.ZodObject<{
44
44
  siteId: z.ZodString;
45
45
  requestId: z.ZodString;
46
46
  joinKeys: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
47
+ session: z.ZodDefault<z.ZodNullable<z.ZodObject<{
48
+ id: z.ZodString;
49
+ provider: z.ZodString;
50
+ ip: z.ZodNullable<z.ZodString>;
51
+ ipCapturedAt: z.ZodNullable<z.ZodString>;
52
+ }, z.core.$strip>>>;
47
53
  status: z.ZodEnum<{
48
54
  error: "error";
49
55
  submitted: "submitted";
@@ -58,6 +64,7 @@ export declare const reconciliationRowSchema: z.ZodObject<{
58
64
  skipped: "skipped";
59
65
  }>;
60
66
  trackingUrl: z.ZodNullable<z.ZodString>;
67
+ beaconSessionIp: z.ZodDefault<z.ZodNullable<z.ZodString>>;
61
68
  }, z.core.$strip>;
62
69
  export type ReconciliationRow = z.infer<typeof reconciliationRowSchema>;
63
70
  /**
@@ -89,6 +96,12 @@ export declare const submissionsResponseSchema: z.ZodObject<{
89
96
  siteId: z.ZodString;
90
97
  requestId: z.ZodString;
91
98
  joinKeys: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
99
+ session: z.ZodDefault<z.ZodNullable<z.ZodObject<{
100
+ id: z.ZodString;
101
+ provider: z.ZodString;
102
+ ip: z.ZodNullable<z.ZodString>;
103
+ ipCapturedAt: z.ZodNullable<z.ZodString>;
104
+ }, z.core.$strip>>>;
92
105
  status: z.ZodEnum<{
93
106
  error: "error";
94
107
  submitted: "submitted";
@@ -103,6 +116,7 @@ export declare const submissionsResponseSchema: z.ZodObject<{
103
116
  skipped: "skipped";
104
117
  }>;
105
118
  trackingUrl: z.ZodNullable<z.ZodString>;
119
+ beaconSessionIp: z.ZodDefault<z.ZodNullable<z.ZodString>>;
106
120
  }, z.core.$strip>>;
107
121
  total: z.ZodNumber;
108
122
  }, z.core.$strip>;
@@ -1 +1 @@
1
- {"version":3,"file":"submissions.d.ts","sourceRoot":"","sources":["../../../src/api/schemas/submissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAK3B;;;GAGG;AACH,eAAO,MAAM,2BAA2B,OAAO,CAAC;AA6BhD;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;iBAevC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;iBAKhC,CAAC;AAEL,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;;GAGG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
1
+ {"version":3,"file":"submissions.d.ts","sourceRoot":"","sources":["../../../src/api/schemas/submissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAK3B;;;GAGG;AACH,eAAO,MAAM,2BAA2B,OAAO,CAAC;AA6BhD;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;iBAevC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;iBAMhC,CAAC;AAEL,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;;GAGG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
@@ -64,6 +64,7 @@ exports.reconciliationRowSchema = reconciliation_record_1.submitRecordSchema
64
64
  .extend({
65
65
  beaconStatus: reconciliationBeaconStatusSchema,
66
66
  trackingUrl: v4_1.z.string().nullable(),
67
+ beaconSessionIp: reconciliation_record_1.beaconEventSchema.shape.sessionIp,
67
68
  });
68
69
  /**
69
70
  * Response contract for the submissions read route: the standard envelope
@@ -1 +1 @@
1
- {"version":3,"file":"submissions.js","sourceRoot":"","sources":["../../../src/api/schemas/submissions.ts"],"names":[],"mappings":";;;AAAA,+BAA2B;AAE3B,iDAAoD;AACpD,iFAA8F;AAE9F;;;GAGG;AACU,QAAA,2BAA2B,GAAG,IAAI,CAAC;AAEhD,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1C,CAAC;AAED,MAAM,qBAAqB,GAAG,GAAG,EAAE,CAAC,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,MAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;AAE1F;;;;;;GAMG;AACH,MAAM,gCAAgC,GAAG,MAAC,CAAC,IAAI,CAAC;IAC9C,GAAG,yCAAiB,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO;IAC/C,WAAW;CACZ,CAAC,CAAC;AAEH;;;;;;GAMG;AACU,QAAA,4BAA4B,GAAG,MAAC,CAAC,MAAM,CAAC;IACnD,MAAM,EAAE,qBAAqB,EAAE;IAC/B,SAAS,EAAE,qBAAqB,EAAE;IAClC,MAAM,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,0CAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAClF,YAAY,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,gCAAgC,CAAC,QAAQ,EAAE,CAAC;IACzF,IAAI,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,MAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjF,EAAE,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,MAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC/E,KAAK,EAAE,MAAC,CAAC,UAAU,CACjB,gBAAgB,EAChB,MAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,QAAA,2BAA2B,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAC3F;IACD,MAAM,EAAE,MAAC,CAAC,UAAU,CAClB,gBAAgB,EAChB,MAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,CAC9D;CACF,CAAC,CAAC;AAIH;;;;;;;;;GASG;AACU,QAAA,uBAAuB,GAAG,0CAAkB;KACtD,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;KAC9D,MAAM,CAAC;IACN,YAAY,EAAE,gCAAgC;IAC9C,WAAW,EAAE,MAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAIL;;;GAGG;AACU,QAAA,yBAAyB,GAAG,MAAC,CAAC,MAAM,CAAC;IAChD,MAAM,EAAE,qBAAY;IACpB,WAAW,EAAE,MAAC,CAAC,KAAK,CAAC,QAAA,uBAAuB,CAAC;IAC7C,KAAK,EAAE,MAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CACtC,CAAC,CAAC"}
1
+ {"version":3,"file":"submissions.js","sourceRoot":"","sources":["../../../src/api/schemas/submissions.ts"],"names":[],"mappings":";;;AAAA,+BAA2B;AAE3B,iDAAoD;AACpD,iFAA8F;AAE9F;;;GAGG;AACU,QAAA,2BAA2B,GAAG,IAAI,CAAC;AAEhD,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1C,CAAC;AAED,MAAM,qBAAqB,GAAG,GAAG,EAAE,CAAC,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,MAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;AAE1F;;;;;;GAMG;AACH,MAAM,gCAAgC,GAAG,MAAC,CAAC,IAAI,CAAC;IAC9C,GAAG,yCAAiB,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO;IAC/C,WAAW;CACZ,CAAC,CAAC;AAEH;;;;;;GAMG;AACU,QAAA,4BAA4B,GAAG,MAAC,CAAC,MAAM,CAAC;IACnD,MAAM,EAAE,qBAAqB,EAAE;IAC/B,SAAS,EAAE,qBAAqB,EAAE;IAClC,MAAM,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,0CAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAClF,YAAY,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,gCAAgC,CAAC,QAAQ,EAAE,CAAC;IACzF,IAAI,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,MAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjF,EAAE,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,MAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC/E,KAAK,EAAE,MAAC,CAAC,UAAU,CACjB,gBAAgB,EAChB,MAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,QAAA,2BAA2B,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAC3F;IACD,MAAM,EAAE,MAAC,CAAC,UAAU,CAClB,gBAAgB,EAChB,MAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,CAC9D;CACF,CAAC,CAAC;AAIH;;;;;;;;;GASG;AACU,QAAA,uBAAuB,GAAG,0CAAkB;KACtD,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;KAC9D,MAAM,CAAC;IACN,YAAY,EAAE,gCAAgC;IAC9C,WAAW,EAAE,MAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,eAAe,EAAE,yCAAiB,CAAC,KAAK,CAAC,SAAS;CACnD,CAAC,CAAC;AAIL;;;GAGG;AACU,QAAA,yBAAyB,GAAG,MAAC,CAAC,MAAM,CAAC;IAChD,MAAM,EAAE,qBAAY;IACpB,WAAW,EAAE,MAAC,CAAC,KAAK,CAAC,QAAA,uBAAuB,CAAC;IAC7C,KAAK,EAAE,MAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CACtC,CAAC,CAAC"}
package/dist/config.d.ts CHANGED
@@ -82,6 +82,39 @@ export interface AppConfig {
82
82
  * racy OOPIF fails the attempt instead of hanging the step indefinitely.
83
83
  */
84
84
  frameEvaluateTimeoutMs: number;
85
+ /**
86
+ * Per-probe watchdog floor for `probeAttachedFrameTarget`'s single
87
+ * non-polling presence check (`frame-target.ts`). That probe's deadline
88
+ * is `Date.now() + framePresenceProbeFloorMs`, not `Date.now() + 0` —
89
+ * `resolveFrameTarget(page, sel, { timeoutMs: 0 })`'s zero-budget pass
90
+ * clamps every probe to `Math.min(evaluateTimeoutMs, remainingBudgetMs())
91
+ * === 0`, so a `setTimeout(reject, 0)` macrotask always wins the race
92
+ * against a genuinely awaited CDP round-trip and the probe can never
93
+ * observe an already-attached frame in production. Kept well under
94
+ * `frameReadyTimeoutMs` since the probe never polls — at most two
95
+ * round-trips (the top-level iframe-src read plus one candidate
96
+ * `location.href` read, per `tryResolveChildFrame`'s existing
97
+ * `index > 0 && remainingBudgetMs() <= 0` bound) — so a single call costs
98
+ * at most ~2x this floor.
99
+ */
100
+ framePresenceProbeFloorMs: number;
101
+ /**
102
+ * Master switch for the outbound-IP echo navigation. False yields
103
+ * `session: null` / `sessionIp: null` in the submit/beacon telemetry
104
+ * without disturbing the rest of the record.
105
+ */
106
+ captureSessionIp: boolean;
107
+ /**
108
+ * IP-echo endpoint the session's own short-lived tab navigates to.
109
+ * Overridable so operators can point this at a self-hosted echo
110
+ * endpoint instead of depending on a third party.
111
+ */
112
+ sessionIpEchoUrl: string;
113
+ /**
114
+ * Watchdog bound on the echo navigation; a page that never resolves is
115
+ * cut off and yields `null` rather than blocking the submission.
116
+ */
117
+ sessionIpTimeoutMs: number;
85
118
  };
86
119
  bedrock: {
87
120
  region: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -70,6 +70,10 @@ function loadConfig() {
70
70
  frameReadyTimeoutMs: (0, env_1.getNumericEnv)("FRAME_READY_TIMEOUT_MS", 20_000),
71
71
  frameDocumentReadyTimeoutMs: (0, env_1.getNumericEnv)("FRAME_DOCUMENT_READY_TIMEOUT_MS", 5_000),
72
72
  frameEvaluateTimeoutMs: (0, env_1.getNumericEnv)("FRAME_EVALUATE_TIMEOUT_MS", 30_000),
73
+ framePresenceProbeFloorMs: (0, env_1.getNumericEnv)("FRAME_PRESENCE_PROBE_FLOOR_MS", 3_000),
74
+ captureSessionIp: (0, env_1.getBoolEnv)("SCRAPER_CAPTURE_SESSION_IP", true),
75
+ sessionIpEchoUrl: (0, env_1.getEnv)("SCRAPER_SESSION_IP_ECHO_URL", "https://api.ipify.org?format=json"),
76
+ sessionIpTimeoutMs: (0, env_1.getNumericEnv)("SCRAPER_SESSION_IP_TIMEOUT_MS", 10_000),
73
77
  },
74
78
  bedrock: {
75
79
  region: (0, env_1.getEnv)("AWS_REGION", "us-east-1"),
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -6,11 +6,14 @@ type StagehandModel = ConstructorParameters<typeof AISdkClient>[0]["model"];
6
6
  * Stagehand's `llmClient`. Centralises all @ai-sdk/amazon-bedrock imports here
7
7
  * so no other module touches the AWS SDK.
8
8
  *
9
- * Bedrock v4 emits a `LanguageModelV3` (provider spec v3) but Stagehand's
10
- * `AISdkClient` still types its `model` as `LanguageModelV2`. The two specs
11
- * are runtime-compatible for Stagehand's use, so we cast at this single
12
- * boundary rather than letting the version mismatch leak into call sites.
13
- * Remove the cast once Stagehand accepts `LanguageModelV3`.
9
+ * Pinned to the @ai-sdk/amazon-bedrock 3.x line, not the latest 5.x: 5.x
10
+ * emits `LanguageModelV4`, but the `ai` version Stagehand's `AISdkClient`
11
+ * depends on only accepts `specificationVersion: "v2"` and throws
12
+ * `AI_UnsupportedModelVersionError` otherwise. 3.x emits `LanguageModelV2`,
13
+ * matching both Stagehand's dependency and `ai`'s runtime check exactly —
14
+ * the same provider-spec version Stagehand itself pins as an optional
15
+ * dependency. Bump past 3.x only once Stagehand's `ai` dependency accepts
16
+ * newer provider specs.
14
17
  *
15
18
  * When accessKeyId/secretAccessKey are set, uses explicit static credentials.
16
19
  * When omitted, region-only config lets the SDK fall through to its default
@@ -1 +1 @@
1
- {"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../src/lib/bedrock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,KAAK,cAAc,GAAG,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,cAAc,CAgBtF"}
1
+ {"version":3,"file":"bedrock.d.ts","sourceRoot":"","sources":["../../src/lib/bedrock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,KAAK,cAAc,GAAG,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,cAAc,CAgBtF"}
@@ -7,11 +7,14 @@ const amazon_bedrock_1 = require("@ai-sdk/amazon-bedrock");
7
7
  * Stagehand's `llmClient`. Centralises all @ai-sdk/amazon-bedrock imports here
8
8
  * so no other module touches the AWS SDK.
9
9
  *
10
- * Bedrock v4 emits a `LanguageModelV3` (provider spec v3) but Stagehand's
11
- * `AISdkClient` still types its `model` as `LanguageModelV2`. The two specs
12
- * are runtime-compatible for Stagehand's use, so we cast at this single
13
- * boundary rather than letting the version mismatch leak into call sites.
14
- * Remove the cast once Stagehand accepts `LanguageModelV3`.
10
+ * Pinned to the @ai-sdk/amazon-bedrock 3.x line, not the latest 5.x: 5.x
11
+ * emits `LanguageModelV4`, but the `ai` version Stagehand's `AISdkClient`
12
+ * depends on only accepts `specificationVersion: "v2"` and throws
13
+ * `AI_UnsupportedModelVersionError` otherwise. 3.x emits `LanguageModelV2`,
14
+ * matching both Stagehand's dependency and `ai`'s runtime check exactly —
15
+ * the same provider-spec version Stagehand itself pins as an optional
16
+ * dependency. Bump past 3.x only once Stagehand's `ai` dependency accepts
17
+ * newer provider specs.
15
18
  *
16
19
  * When accessKeyId/secretAccessKey are set, uses explicit static credentials.
17
20
  * When omitted, region-only config lets the SDK fall through to its default
@@ -1 +1 @@
1
- {"version":3,"file":"bedrock.js","sourceRoot":"","sources":["../../src/lib/bedrock.ts"],"names":[],"mappings":";;;AAAA,2DAA6D;AAO7D;;;;;;;;;;;;;;;GAeG;AACH,4BAAmC,aAAmC;IACpE,MAAM,sBAAsB,GAC1B,aAAa,CAAC,WAAW,KAAK,SAAS,IAAI,aAAa,CAAC,eAAe,KAAK,SAAS,CAAC;IAEzF,MAAM,QAAQ,GAAG,IAAA,oCAAmB,EAAC;QACnC,MAAM,EAAE,aAAa,CAAC,MAAM;QAC5B,GAAG,CAAC,sBAAsB;YACxB,CAAC,CAAC;gBACE,WAAW,EAAE,aAAa,CAAC,WAAqB;gBAChD,eAAe,EAAE,aAAa,CAAC,eAAyB;gBACxD,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,aAAa,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC,aAAa,CAAC,KAAK,CAA8B,CAAC;AACpE,CAAC"}
1
+ {"version":3,"file":"bedrock.js","sourceRoot":"","sources":["../../src/lib/bedrock.ts"],"names":[],"mappings":";;;AAAA,2DAA6D;AAO7D;;;;;;;;;;;;;;;;;;GAkBG;AACH,4BAAmC,aAAmC;IACpE,MAAM,sBAAsB,GAC1B,aAAa,CAAC,WAAW,KAAK,SAAS,IAAI,aAAa,CAAC,eAAe,KAAK,SAAS,CAAC;IAEzF,MAAM,QAAQ,GAAG,IAAA,oCAAmB,EAAC;QACnC,MAAM,EAAE,aAAa,CAAC,MAAM;QAC5B,GAAG,CAAC,sBAAsB;YACxB,CAAC,CAAC;gBACE,WAAW,EAAE,aAAa,CAAC,WAAqB;gBAChD,eAAe,EAAE,aAAa,CAAC,eAAyB;gBACxD,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,aAAa,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC"}
@@ -1,7 +1,8 @@
1
1
  /**
2
- * Raises undici's TCP connect timeout from its 10 s hardcoded default.
3
- * Must be called once at process startup in every entry point that makes
4
- * outbound fetch calls (server.ts, scripts, etc.).
2
+ * Raises undici's TCP connect timeout from its 10 s hardcoded default, and
3
+ * patches around a @browserbasehq/sdk header-collision bug the custom
4
+ * dispatcher triggers. Must be called once at process startup in every entry
5
+ * point that makes outbound fetch calls (server.ts, scripts, etc.).
5
6
  */
6
7
  export declare function configureHttpDispatcher(): void;
7
8
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AA2BA;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAG9C"}
package/dist/lib/http.js CHANGED
@@ -1,14 +1,36 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.configureHttpDispatcher = configureHttpDispatcher;
7
+ const sdk_1 = __importDefault(require("@browserbasehq/sdk"));
4
8
  const undici_1 = require("undici");
5
9
  const config_1 = require("../config");
6
10
  /**
7
- * Raises undici's TCP connect timeout from its 10 s hardcoded default.
8
- * Must be called once at process startup in every entry point that makes
9
- * outbound fetch calls (server.ts, scripts, etc.).
11
+ * @browserbasehq/sdk sets an explicit `content-length` header, then hands the
12
+ * request to Node's native fetch. Under the custom global dispatcher installed
13
+ * below, undici's Request constructor folds that caller-supplied header
14
+ * together with its own computed one into a comma-joined value (e.g.
15
+ * "52, 52"), which fails undici's digit-only validation with
16
+ * `InvalidArgumentError: invalid content-length header`. Dropping the SDK's
17
+ * explicit header lets undici compute it once, itself.
18
+ */
19
+ function patchBrowserbaseContentLengthHeader() {
20
+ const apiClientPrototype = Object.getPrototypeOf(sdk_1.default.prototype);
21
+ const originalBuildHeaders = apiClientPrototype.buildHeaders;
22
+ apiClientPrototype.buildHeaders = function (args) {
23
+ return originalBuildHeaders.call(this, { ...args, contentLength: null });
24
+ };
25
+ }
26
+ /**
27
+ * Raises undici's TCP connect timeout from its 10 s hardcoded default, and
28
+ * patches around a @browserbasehq/sdk header-collision bug the custom
29
+ * dispatcher triggers. Must be called once at process startup in every entry
30
+ * point that makes outbound fetch calls (server.ts, scripts, etc.).
10
31
  */
11
32
  function configureHttpDispatcher() {
12
33
  (0, undici_1.setGlobalDispatcher)(new undici_1.Agent({ connect: { timeout: config_1.config.scraper.connectTimeoutMs } }));
34
+ patchBrowserbaseContentLengthHeader();
13
35
  }
14
36
  //# sourceMappingURL=http.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":";;;AAAA,mCAAoD;AAEpD,qCAAkC;AAElC;;;;GAIG;AACH;IACE,IAAA,4BAAmB,EAAC,IAAI,cAAK,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,eAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC;AAC5F,CAAC"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":";;;;;;AAAA,6DAA6C;AAC7C,mCAAoD;AAEpD,qCAAkC;AAElC;;;;;;;;GAQG;AACH,SAAS,mCAAmC;IAC1C,MAAM,kBAAkB,GAAG,MAAM,CAAC,cAAc,CAAC,aAAW,CAAC,SAAS,CAErE,CAAC;IACF,MAAM,oBAAoB,GAAG,kBAAkB,CAAC,YAAY,CAAC;IAC7D,kBAAkB,CAAC,YAAY,GAAG,UAEhC,IAA6B;QAE7B,OAAO,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH;IACE,IAAA,4BAAmB,EAAC,IAAI,cAAK,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,eAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1F,mCAAmC,EAAE,CAAC;AACxC,CAAC"}
@@ -11,6 +11,10 @@
11
11
  * Writes to the SAME sink as submit lines (`appendSubmissionSinkLine`,
12
12
  * feat-003), which is what lets the S3 mirror carry beacon lines for free
13
13
  * with zero `s3-sink.ts` changes.
14
+ *
15
+ * `createBeaconOutcomeRecorder` builds on top of `captureBeaconEvent` to
16
+ * give a plugin that manages its own beacon navigation a bound, never-
17
+ * throwing way to report a real `fired`/`failed` outcome for its own run.
14
18
  */
15
19
  import type { z } from "zod/v4";
16
20
  import type { beaconEventSchema } from "../../lib/telemetry/reconciliation-record";
@@ -18,9 +22,13 @@ import type { beaconEventSchema } from "../../lib/telemetry/reconciliation-recor
18
22
  export type BeaconEventSample = z.infer<typeof beaconEventSchema>;
19
23
  /**
20
24
  * Input to `captureBeaconEvent` — `ts` and `kind` are derived internally so
21
- * callers omit them.
25
+ * callers omit them. `sessionIp` is optional so existing call sites that
26
+ * don't yet resolve it keep compiling unchanged; an omitted value is
27
+ * persisted as `null`, not left undefined.
22
28
  */
23
- export type BeaconEventInput = Omit<BeaconEventSample, "ts" | "kind">;
29
+ export type BeaconEventInput = Omit<BeaconEventSample, "ts" | "kind" | "sessionIp"> & {
30
+ sessionIp?: BeaconEventSample["sessionIp"];
31
+ };
24
32
  /** Options for `captureBeaconEvent`. */
25
33
  export interface CaptureBeaconEventOptions {
26
34
  /** Override the sink path; used in tests to avoid touching the real file. */
@@ -34,4 +42,39 @@ export interface CaptureBeaconEventOptions {
34
42
  * beacon caller (tracking-click) is already fire-and-forget.
35
43
  */
36
44
  export declare function captureBeaconEvent(input: BeaconEventInput, opts?: CaptureBeaconEventOptions): Promise<void>;
45
+ /** A run's identity, bound once by `createBeaconOutcomeRecorder` so a plugin never supplies it itself. */
46
+ export interface BeaconOutcomeRecorderBinding {
47
+ requestId: string;
48
+ siteId: string;
49
+ }
50
+ /**
51
+ * Plugin-facing input to a bound beacon-outcome recorder — `requestId` and
52
+ * `siteId` are omitted (bound by the factory) and `beaconStatus` excludes
53
+ * `"skipped"`, which stays an engine-owned outcome written by `dispatch()`
54
+ * itself (see `loader.ts`'s `emitBeaconSafely` call). `trackingUrl` and
55
+ * `durationMs` are optional here (unlike `BeaconEventInput`) since a plugin
56
+ * managing its own nav may not have a URL or duration to report.
57
+ */
58
+ export interface BeaconOutcomeInput {
59
+ beaconStatus: Extract<BeaconEventInput["beaconStatus"], "fired" | "failed">;
60
+ joinKeys: BeaconEventInput["joinKeys"];
61
+ trackingUrl?: BeaconEventInput["trackingUrl"];
62
+ durationMs?: BeaconEventInput["durationMs"];
63
+ }
64
+ /** A plugin-callable recorder bound to one run's `requestId`/`siteId`. */
65
+ export type BeaconOutcomeRecorder = (input: BeaconOutcomeInput, opts?: CaptureBeaconEventOptions) => Promise<void>;
66
+ /**
67
+ * Builds a plugin-callable recorder bound to a run's `requestId`/`siteId`,
68
+ * so a plugin that manages its own beacon navigation can report a real
69
+ * `fired`/`failed` outcome without touching `captureBeaconEvent`'s raw input
70
+ * shape or its `ts`/`kind` derivation — `joinKeys` is passed through
71
+ * uninterpreted, matching the opaque, plugin-owned shape precedent in
72
+ * `src/site-plugin.ts`. Wraps the delegated call in the same belt-and-braces
73
+ * try/catch every other beacon call site applies (`emitBeaconSafely` in
74
+ * `loader.ts`, `captureBeaconOutcomeSafely` in `tracking-click.ts`), so a
75
+ * synchronous throw that reaches `captureBeaconEvent` before its own
76
+ * internal try/catch opens can still never escape into the plugin's own
77
+ * execute path.
78
+ */
79
+ export declare function createBeaconOutcomeRecorder(binding: BeaconOutcomeRecorderBinding): BeaconOutcomeRecorder;
37
80
  //# sourceMappingURL=beacon-capture.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"beacon-capture.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/beacon-capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAO/E,kDAAkD;AAClD,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC;AAEtE,wCAAwC;AACxC,MAAM,WAAW,yBAAyB;IACxC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,gBAAgB,EACvB,IAAI,GAAE,yBAA8B,GACnC,OAAO,CAAC,IAAI,CAAC,CAef"}
1
+ {"version":3,"file":"beacon-capture.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/beacon-capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAO/E,kDAAkD;AAClD,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,CAAC,GAAG;IACpF,SAAS,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;CAC5C,CAAC;AAEF,wCAAwC;AACxC,MAAM,WAAW,yBAAyB;IACxC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,gBAAgB,EACvB,IAAI,GAAE,yBAA8B,GACnC,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,0GAA0G;AAC1G,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,OAAO,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC,CAAC;IAC5E,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;IAC9C,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;CAC7C;AAED,0EAA0E;AAC1E,MAAM,MAAM,qBAAqB,GAAG,CAClC,KAAK,EAAE,kBAAkB,EACzB,IAAI,CAAC,EAAE,yBAAyB,KAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,qBAAqB,CAkBvB"}
@@ -12,9 +12,14 @@
12
12
  * Writes to the SAME sink as submit lines (`appendSubmissionSinkLine`,
13
13
  * feat-003), which is what lets the S3 mirror carry beacon lines for free
14
14
  * with zero `s3-sink.ts` changes.
15
+ *
16
+ * `createBeaconOutcomeRecorder` builds on top of `captureBeaconEvent` to
17
+ * give a plugin that manages its own beacon navigation a bound, never-
18
+ * throwing way to report a real `fired`/`failed` outcome for its own run.
15
19
  */
16
20
  Object.defineProperty(exports, "__esModule", { value: true });
17
21
  exports.captureBeaconEvent = captureBeaconEvent;
22
+ exports.createBeaconOutcomeRecorder = createBeaconOutcomeRecorder;
18
23
  const date_fns_1 = require("date-fns");
19
24
  const config_1 = require("../../config");
20
25
  const logging_1 = require("../../lib/logging");
@@ -34,6 +39,7 @@ async function captureBeaconEvent(input, opts = {}) {
34
39
  ...input,
35
40
  kind: "beacon",
36
41
  trackingUrl: input.trackingUrl?.slice(0, TRACKING_URL_MAX_LENGTH) ?? null,
42
+ sessionIp: input.sessionIp ?? null,
37
43
  ts: (0, date_fns_1.formatISO)(new Date()),
38
44
  };
39
45
  try {
@@ -44,4 +50,34 @@ async function captureBeaconEvent(input, opts = {}) {
44
50
  logger.error(`captureBeaconEvent: failed to write to ${sinkPath}: ${String(err)}`);
45
51
  }
46
52
  }
53
+ /**
54
+ * Builds a plugin-callable recorder bound to a run's `requestId`/`siteId`,
55
+ * so a plugin that manages its own beacon navigation can report a real
56
+ * `fired`/`failed` outcome without touching `captureBeaconEvent`'s raw input
57
+ * shape or its `ts`/`kind` derivation — `joinKeys` is passed through
58
+ * uninterpreted, matching the opaque, plugin-owned shape precedent in
59
+ * `src/site-plugin.ts`. Wraps the delegated call in the same belt-and-braces
60
+ * try/catch every other beacon call site applies (`emitBeaconSafely` in
61
+ * `loader.ts`, `captureBeaconOutcomeSafely` in `tracking-click.ts`), so a
62
+ * synchronous throw that reaches `captureBeaconEvent` before its own
63
+ * internal try/catch opens can still never escape into the plugin's own
64
+ * execute path.
65
+ */
66
+ function createBeaconOutcomeRecorder(binding) {
67
+ return async (input, opts = {}) => {
68
+ try {
69
+ await captureBeaconEvent({
70
+ requestId: binding.requestId,
71
+ siteId: binding.siteId,
72
+ joinKeys: input.joinKeys,
73
+ beaconStatus: input.beaconStatus,
74
+ trackingUrl: input.trackingUrl ?? null,
75
+ durationMs: input.durationMs ?? 0,
76
+ }, opts);
77
+ }
78
+ catch (err) {
79
+ logger.error(`createBeaconOutcomeRecorder: capture failed: ${String(err)}`);
80
+ }
81
+ };
82
+ }
47
83
  //# sourceMappingURL=beacon-capture.js.map