pi-agent-browser-native 0.3.0 → 0.6.5

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 (89) hide show
  1. package/CHANGELOG.md +265 -0
  2. package/README.md +130 -54
  3. package/dist/extensions/agent-browser/index.js +781 -169
  4. package/dist/extensions/agent-browser/lib/argv-descriptor.js +35 -3
  5. package/dist/extensions/agent-browser/lib/argv-grammar.js +50 -2
  6. package/dist/extensions/agent-browser/lib/batch-lifecycle.js +71 -0
  7. package/dist/extensions/agent-browser/lib/command-policy.js +5 -8
  8. package/dist/extensions/agent-browser/lib/command-taxonomy.js +53 -12
  9. package/dist/extensions/agent-browser/lib/config-policy.js +25 -1
  10. package/dist/extensions/agent-browser/lib/config.js +1 -1
  11. package/dist/extensions/agent-browser/lib/input-modes/job.js +61 -13
  12. package/dist/extensions/agent-browser/lib/input-modes/lookups.js +2 -2
  13. package/dist/extensions/agent-browser/lib/input-modes/params.js +23 -24
  14. package/dist/extensions/agent-browser/lib/input-modes/script.js +462 -0
  15. package/dist/extensions/agent-browser/lib/input-modes/semantic-action.js +51 -12
  16. package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +26 -4
  17. package/dist/extensions/agent-browser/lib/managed-session-policy-lock.js +6 -139
  18. package/dist/extensions/agent-browser/lib/managed-session-restore.js +26 -116
  19. package/dist/extensions/agent-browser/lib/managed-session-snapshots.js +2 -4
  20. package/dist/extensions/agent-browser/lib/managed-session-storage.js +54 -25
  21. package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +26 -5
  22. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.js +110 -30
  23. package/dist/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.js +2 -1
  24. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +54 -48
  25. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +71 -5
  26. package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +2 -1
  27. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-policy.js +6 -7
  28. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +119 -2
  29. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +7 -6
  30. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +152 -64
  31. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +244 -102
  32. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +63 -37
  33. package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +20 -21
  34. package/dist/extensions/agent-browser/lib/orchestration/input-plan.js +36 -18
  35. package/dist/extensions/agent-browser/lib/orchestration/output-file.js +41 -21
  36. package/dist/extensions/agent-browser/lib/orchestration/script-mode.js +299 -0
  37. package/dist/extensions/agent-browser/lib/page-target-validation.js +270 -0
  38. package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +32 -10
  39. package/dist/extensions/agent-browser/lib/playbook.js +29 -25
  40. package/dist/extensions/agent-browser/lib/process-environment.js +14 -0
  41. package/dist/extensions/agent-browser/lib/process-identity.js +5 -12
  42. package/dist/extensions/agent-browser/lib/process.js +130 -104
  43. package/dist/extensions/agent-browser/lib/recording-reservations.js +116 -0
  44. package/dist/extensions/agent-browser/lib/results/action-recommendations.js +63 -6
  45. package/dist/extensions/agent-browser/lib/results/artifact-manifest.js +62 -4
  46. package/dist/extensions/agent-browser/lib/results/categories.js +6 -1
  47. package/dist/extensions/agent-browser/lib/results/next-actions.js +19 -5
  48. package/dist/extensions/agent-browser/lib/results/presentation/artifacts.js +85 -38
  49. package/dist/extensions/agent-browser/lib/results/presentation/batch.js +86 -18
  50. package/dist/extensions/agent-browser/lib/results/presentation/common.js +38 -2
  51. package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +18 -17
  52. package/dist/extensions/agent-browser/lib/results/presentation/errors.js +2 -1
  53. package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +38 -20
  54. package/dist/extensions/agent-browser/lib/results/presentation/registry.js +60 -15
  55. package/dist/extensions/agent-browser/lib/results/presentation/semantic-action.js +1 -10
  56. package/dist/extensions/agent-browser/lib/results/presentation.js +36 -6
  57. package/dist/extensions/agent-browser/lib/results/recovery-actions.js +3 -1
  58. package/dist/extensions/agent-browser/lib/results/recovery-next-actions.js +9 -0
  59. package/dist/extensions/agent-browser/lib/results/selector-recovery.js +54 -11
  60. package/dist/extensions/agent-browser/lib/results/snapshot-high-value-controls.js +13 -7
  61. package/dist/extensions/agent-browser/lib/results/snapshot-spill.js +2 -1
  62. package/dist/extensions/agent-browser/lib/results/snapshot.js +4 -4
  63. package/dist/extensions/agent-browser/lib/runtime.js +186 -108
  64. package/dist/extensions/agent-browser/lib/session-page-state.js +71 -10
  65. package/dist/extensions/agent-browser/lib/temp.js +1 -2
  66. package/dist/extensions/agent-browser/lib/upstream-version.js +14 -0
  67. package/dist/extensions/agent-browser/lib/web-search.js +108 -24
  68. package/dist/extensions/agent-browser/script-worker.js +169 -0
  69. package/dist/scripts/agent-browser-target.mjs +21 -0
  70. package/docs/ARCHITECTURE.md +57 -34
  71. package/docs/COMMAND_REFERENCE.md +255 -68
  72. package/docs/ELECTRON.md +2 -2
  73. package/docs/RELEASE.md +12 -10
  74. package/docs/REQUIREMENTS.md +11 -8
  75. package/docs/SUPPORT_MATRIX.md +36 -24
  76. package/docs/TOOL_CONTRACT.md +169 -95
  77. package/package.json +3 -1
  78. package/platform-smoke.config.mjs +2 -2
  79. package/scripts/agent-browser-capability-baseline.mjs +87 -9
  80. package/scripts/agent-browser-target.mjs +21 -0
  81. package/scripts/build.mjs +41 -0
  82. package/scripts/config.mjs +1 -0
  83. package/scripts/doctor.mjs +16 -9
  84. package/scripts/platform-smoke/browser-dogfood-windows.ps1 +9 -3
  85. package/scripts/platform-smoke/targets.mjs +12 -6
  86. package/dist/extensions/agent-browser/lib/managed-session-capabilities.js +0 -20
  87. package/dist/extensions/agent-browser/lib/managed-session-state-policy.js +0 -583
  88. package/dist/extensions/agent-browser/lib/navigation-policy.js +0 -78
  89. package/dist/extensions/agent-browser/lib/results/presentation/managed-list-filter.js +0 -37
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-agent-browser-native",
3
- "version": "0.3.0",
3
+ "version": "0.6.5",
4
4
  "description": "pi extension that exposes agent-browser as a native tool for browser automation",
5
5
  "type": "module",
6
6
  "author": "Mitch Fultz (https://github.com/fitchmultz)",
@@ -36,7 +36,9 @@
36
36
  "scripts/config.mjs",
37
37
  "scripts/doctor.mjs",
38
38
  "scripts/prepare.mjs",
39
+ "scripts/build.mjs",
39
40
  "scripts/agent-browser-capability-baseline.mjs",
41
+ "scripts/agent-browser-target.mjs",
40
42
  "scripts/platform-smoke.mjs",
41
43
  "scripts/platform-smoke",
42
44
  "README.md",
@@ -22,9 +22,9 @@ export default {
22
22
  ubuntuContainerImage: PLATFORM_SMOKE_UBUNTU_IMAGE,
23
23
  windowsParallels: {
24
24
  sourceVm: "pi-extension-windows-template",
25
- // Shared template snapshot; refresh when the Windows image moves past agent-browser 0.33.0.
25
+ // Shared template snapshot; refresh when the Windows image moves past agent-browser 0.34.0.
26
26
  // Parent crabbox-ready remains for other projects' linked clones.
27
- snapshot: "crabbox-ready-ab-0.33.0",
27
+ snapshot: "crabbox-ready-ab-0.34.0-d",
28
28
  },
29
29
  nodeValidationMajor: 22,
30
30
  agentBrowserVersion: PLATFORM_SMOKE_AGENT_BROWSER_VERSION,
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * Purpose: Define the canonical upstream agent-browser capability baseline targeted by this package.
3
- * Responsibilities: Store the target upstream version, sampled help commands, and verifier/doc token expectations in one importable metadata object.
3
+ * Responsibilities: Combine the canonical target from agent-browser-target.mjs with sampled help commands and verifier/doc token expectations.
4
4
  * Scope: Versioned capability metadata only; it does not execute agent-browser or validate documentation by itself.
5
- * Usage: Imported by command-reference verifier, generated docs checker, and tests when upstream agent-browser is re-baselined.
6
- * Invariants/Assumptions: This package targets the current installed upstream agent-browser only and does not keep compatibility shims for older versions.
5
+ * Usage: Imported by command-reference verifier, generated docs checker, and tests when upstream agent-browser is re-baselined; runtime imports only agent-browser-target.mjs.
6
+ * Invariants/Assumptions: This package documents the current recommended upstream release, accepts stable runtimes at or above the configured floor, and does not add version-specific compatibility shims.
7
7
  * Related: `docs/SUPPORT_MATRIX.md` maps `CAPABILITY_BASELINE.inventorySections` to human docs, runtime behavior, tests, and verification gates; refresh that matrix whenever this baseline changes.
8
8
  */
9
9
 
10
+ import { TARGET_AGENT_BROWSER_VERSION } from "./agent-browser-target.mjs";
11
+
10
12
  export const CAPABILITY_BASELINE_SOURCE = "scripts/agent-browser-capability-baseline.mjs";
11
13
  export const COMMAND_REFERENCE_DOC_PATH = "docs/COMMAND_REFERENCE.md";
12
14
  export const CAPABILITY_BASELINE_BLOCK_MARKER_PREFIX = "agent-browser-capability-baseline";
@@ -14,8 +16,8 @@ export const COMMAND_REFERENCE_BASELINE_BLOCK_IDS = Object.freeze(["upstream-bas
14
16
 
15
17
  const sourceEvidence = Object.freeze({
16
18
  repository: "vercel-labs/agent-browser",
17
- upstreamHead: "93cdda5709e8861c0c26b0b955d8d746e9fda0d7",
18
- upstreamPackageVersion: "0.33.2",
19
+ upstreamHead: "eb05921bad874cd2a1b4fa5d1149f1ed26576cae",
20
+ upstreamPackageVersion: "0.36.0",
19
21
  inspectedSources: Object.freeze([
20
22
  "agent-browser --version",
21
23
  "agent-browser --help",
@@ -26,25 +28,41 @@ const sourceEvidence = Object.freeze({
26
28
  "agent-browser skills list",
27
29
  "agent-browser skills get core --full",
28
30
  "agent-browser skills get derive-client --full",
31
+ "agent-browser skills get webmcp-gen --full",
29
32
  "README.md",
30
33
  "CHANGELOG.md",
31
34
  "agent-browser.schema.json",
35
+ "bin/agent-browser.js",
36
+ "cli/src/ca_bundle.rs",
32
37
  "cli/src/commands.rs",
38
+ "cli/src/mcp.rs",
33
39
  "cli/src/flags.rs",
34
40
  "cli/src/read.rs",
35
41
  "cli/src/doctor/webgpu.rs",
36
42
  "cli/src/native/actions.rs",
37
43
  "cli/src/native/a11y/mod.rs",
38
44
  "cli/src/native/browser.rs",
45
+ "cli/src/native/tab_binding.rs",
39
46
  "cli/src/native/daemon.rs",
47
+ "cli/src/native/element.rs",
48
+ "cli/src/native/stream/cdp_loop.rs",
49
+ "cli/src/native/stream/dashboard.rs",
50
+ "cli/src/native/test_fixtures/webmcp_frame_probe.html",
51
+ "cli/src/native/test_fixtures/webmcp_probe.html",
52
+ "cli/src/native/webmcp.rs",
40
53
  "cli/src/output.rs",
41
54
  "docs/src/app/webgpu/page.mdx",
55
+ "docs/src/app/webmcp/page.mdx",
42
56
  "docs/src/app/network/page.mdx",
57
+ "docs/src/app/proxy/page.mdx",
43
58
  "docs/src/app/selectors/page.mdx",
44
59
  "docs/src/app/skills/page.mdx",
45
60
  "docs/src/app/commands/page.mdx",
46
61
  "skill-data/derive-client/SKILL.md",
47
62
  "skill-data/core/SKILL.md",
63
+ "skill-data/protected-vercel-deployments/SKILL.md",
64
+ "skill-data/webmcp-gen/SKILL.md",
65
+ "test/launcher.test.mjs",
48
66
  "packages/@agent-browser/eve/README.md",
49
67
  "packages/@agent-browser/eve/package.json",
50
68
  "packages/@agent-browser/eve/test/extension.test.mjs",
@@ -72,6 +90,8 @@ const helpCommands = Object.freeze([
72
90
  helpCommand("skills list", ["skills", "list"]),
73
91
  helpCommand("core skill full", ["skills", "get", "core", "--full"]),
74
92
  helpCommand("vercel sandbox skill full", ["skills", "get", "vercel-sandbox", "--full"]),
93
+ helpCommand("protected Vercel deployments skill full", ["skills", "get", "protected-vercel-deployments", "--full"]),
94
+ helpCommand("WebMCP generation skill full", ["skills", "get", "webmcp-gen", "--full"]),
75
95
  helpCommand("open help", ["open", "--help"]),
76
96
  helpCommand("read help", ["read", "--help"]),
77
97
  helpCommand("click help", ["click", "--help"]),
@@ -140,8 +160,11 @@ const inventorySections = Object.freeze([
140
160
  "skills get slack",
141
161
  "skills get dogfood",
142
162
  "skills get vercel-sandbox",
163
+ "skills get protected-vercel-deployments",
143
164
  "skills get agentcore",
144
165
  "skills get derive-client",
166
+ "skills get webmcp-gen",
167
+ "webmcp.init.js",
145
168
  "@agent-browser/sandbox",
146
169
  "installSystemDependencies: false",
147
170
  "skills path [name]",
@@ -157,10 +180,16 @@ const inventorySections = Object.freeze([
157
180
  ["skills list", "slack"],
158
181
  ["skills list", "dogfood"],
159
182
  ["skills list", "vercel-sandbox"],
183
+ ["skills list", "protected-vercel-deployments"],
160
184
  ["skills list", "agentcore"],
161
185
  ["skills list", "derive-client"],
186
+ ["skills list", "webmcp-gen"],
187
+ ["WebMCP generation skill full", "webmcp.init.js"],
188
+ ["WebMCP generation skill full", "agent-browser webmcp invoke <tool> --params @fixture.json"],
162
189
  ["vercel sandbox skill full", "@agent-browser/sandbox"],
163
190
  ["vercel sandbox skill full", "installSystemDependencies: false"],
191
+ ["protected Vercel deployments skill full", "x-vercel-trusted-oidc-idp-token"],
192
+ ["protected Vercel deployments skill full", "vc project token"],
164
193
  ["core skill full", "agent-browser frame @e3"],
165
194
  ["core skill full", "agent-browser dialog accept"],
166
195
  ["core skill full", "agent-browser --session \"$SESSION\" --restore open https://app.example.com"],
@@ -365,6 +394,10 @@ const inventorySections = Object.freeze([
365
394
  "tab new --label <name> [url]",
366
395
  "tab close [target]",
367
396
  "tab <t<N>|label>",
397
+ "tab_gone",
398
+ "data.targetId",
399
+ "data.lastUrl",
400
+ "CDP target ids",
368
401
  "frame <selector|main>",
369
402
  "dialog accept [text]",
370
403
  "dialog dismiss",
@@ -387,8 +420,13 @@ const inventorySections = Object.freeze([
387
420
  ["state help", "clean --older-than <days>"],
388
421
  ["tab help", "new [url]"],
389
422
  ["tab help", "new --label <name> [url]"],
390
- ["tab help", "close [t<N>|label]"],
423
+ ["tab help", "close [t<N>|label|target]"],
391
424
  ["tab help", "Stable tab ids"],
425
+ ["tab help", "tab_gone"],
426
+ ["tab help", "data.targetId"],
427
+ ["tab help", "data.lastUrl"],
428
+ ["core skill full", "--pin-tab"],
429
+ ["core skill full", "tab_gone"],
392
430
  ["frame help", "frame <selector|main>"],
393
431
  ["dialog help", "dialog <accept|dismiss|status> [text]"],
394
432
  ["window help", "window <operation>"],
@@ -412,6 +450,14 @@ const inventorySections = Object.freeze([
412
450
  "cookies set <name> <value> --url <url> --domain <domain> --path <path> --httpOnly --secure --sameSite <Strict|Lax|None> --expires <timestamp>",
413
451
  "cookies set --curl <file>",
414
452
  "storage <local|session>",
453
+ "webmcp list",
454
+ "webmcp invoke <tool>",
455
+ "webmcp invoke <tool> --params <json|@file>",
456
+ "webmcp invoke <tool> --frame <frame-id>",
457
+ "webmcp invoke <tool> --detach",
458
+ "webmcp invoke <tool> --timeout <ms>",
459
+ "webmcp result <id>",
460
+ "webmcp cancel <id>",
415
461
  "diff snapshot",
416
462
  "diff snapshot --baseline <file> --selector <sel> --compact --depth <n>",
417
463
  "diff screenshot --baseline",
@@ -459,6 +505,13 @@ const inventorySections = Object.freeze([
459
505
  root("cookies [get|set|clear]"),
460
506
  root("cookies set --curl <file>"),
461
507
  root("storage <local|session>"),
508
+ root("webmcp list"),
509
+ root("webmcp invoke <tool>"),
510
+ root("--params <json|@file>"),
511
+ root("--frame <frame-id>"),
512
+ root("--detach"),
513
+ root("webmcp result <id>"),
514
+ root("webmcp cancel <id>"),
462
515
  root("diff snapshot"),
463
516
  root("diff screenshot --baseline"),
464
517
  root("trace start"),
@@ -530,6 +583,8 @@ const inventorySections = Object.freeze([
530
583
  "chat <message>",
531
584
  "dashboard [start]",
532
585
  "dashboard start --port <n>",
586
+ "dashboard start --allowed-origins <origins>",
587
+ "AGENT_BROWSER_DASHBOARD_ALLOWED_ORIGINS",
533
588
  "dashboard stop",
534
589
  "device list",
535
590
  "install",
@@ -542,6 +597,7 @@ const inventorySections = Object.freeze([
542
597
  "doctor --webgpu --headed",
543
598
  "doctor --json",
544
599
  "mcp",
600
+ "mcp --tools core,webmcp",
545
601
  "plugin add <ref>",
546
602
  "plugin [list]",
547
603
  "plugin show <name>",
@@ -557,6 +613,9 @@ const inventorySections = Object.freeze([
557
613
  root("deny <id>"),
558
614
  root("chat <message>"),
559
615
  root("dashboard start --port <n>"),
616
+ root("dashboard start --allowed-origins <origins>"),
617
+ ["dashboard help", "--allowed-origins <origins>"],
618
+ ["dashboard help", "AGENT_BROWSER_DASHBOARD_ALLOWED_ORIGINS"],
560
619
  ["device help", "device list"],
561
620
  root("install --with-deps"),
562
621
  ["install help", "fails if deps fail"],
@@ -615,6 +674,9 @@ const inventorySections = Object.freeze([
615
674
  "AGENT_BROWSER_STATE",
616
675
  "--auto-connect",
617
676
  "AGENT_BROWSER_AUTO_CONNECT",
677
+ "--pin-tab",
678
+ "--no-pin-tab",
679
+ "AGENT_BROWSER_PIN_TAB",
618
680
  "--headers <json>",
619
681
  "--init-script <path>",
620
682
  "AGENT_BROWSER_INIT_SCRIPTS",
@@ -638,6 +700,10 @@ const inventorySections = Object.freeze([
638
700
  "NO_PROXY",
639
701
  "--ignore-https-errors",
640
702
  "AGENT_BROWSER_IGNORE_HTTPS_ERRORS",
703
+ "--ca-cert <path>",
704
+ "--no-ca-cert",
705
+ "AGENT_BROWSER_CA_CERT",
706
+ "AGENT_BROWSER_CLEAR_CA_CERT",
641
707
  "--allow-file-access",
642
708
  "AGENT_BROWSER_ALLOW_FILE_ACCESS",
643
709
  "--hide-scrollbars <bool>",
@@ -645,9 +711,12 @@ const inventorySections = Object.freeze([
645
711
  "AGENT_BROWSER_HEADED",
646
712
  "--webgpu",
647
713
  "AGENT_BROWSER_WEBGPU",
714
+ "--no-webmcp",
715
+ "AGENT_BROWSER_NO_WEBMCP",
716
+ "noWebmcp",
648
717
  "AGENT_BROWSER_NO_XVFB",
649
718
  "\"webgpu\": true",
650
- "--cdp <port>",
719
+ "--cdp <port|url>",
651
720
  "--color-scheme <scheme>",
652
721
  "AGENT_BROWSER_COLOR_SCHEME",
653
722
  "--download-path <path>",
@@ -759,6 +828,9 @@ const inventorySections = Object.freeze([
759
828
  root("AGENT_BROWSER_STATE"),
760
829
  root("--auto-connect"),
761
830
  root("AGENT_BROWSER_AUTO_CONNECT"),
831
+ root("--pin-tab"),
832
+ root("--no-pin-tab"),
833
+ root("AGENT_BROWSER_PIN_TAB"),
762
834
  root("--headers <json>"),
763
835
  root("--init-script <path>"),
764
836
  root("AGENT_BROWSER_INIT_SCRIPTS"),
@@ -781,6 +853,10 @@ const inventorySections = Object.freeze([
781
853
  root("NO_PROXY"),
782
854
  root("--ignore-https-errors"),
783
855
  root("AGENT_BROWSER_IGNORE_HTTPS_ERRORS"),
856
+ root("--ca-cert <path>"),
857
+ root("--no-ca-cert"),
858
+ root("AGENT_BROWSER_CA_CERT"),
859
+ root("AGENT_BROWSER_CLEAR_CA_CERT"),
784
860
  root("--allow-file-access"),
785
861
  root("AGENT_BROWSER_ALLOW_FILE_ACCESS"),
786
862
  root("--hide-scrollbars <bool>"),
@@ -788,7 +864,9 @@ const inventorySections = Object.freeze([
788
864
  root("AGENT_BROWSER_HEADED"),
789
865
  root("--webgpu"),
790
866
  root("AGENT_BROWSER_WEBGPU"),
791
- root("--cdp <port>"),
867
+ root("--no-webmcp"),
868
+ root("AGENT_BROWSER_NO_WEBMCP"),
869
+ root("--cdp <port|url>"),
792
870
  root("--color-scheme <scheme>"),
793
871
  root("AGENT_BROWSER_COLOR_SCHEME"),
794
872
  root("--download-path <path>"),
@@ -852,7 +930,7 @@ const inventorySections = Object.freeze([
852
930
  ]);
853
931
 
854
932
  export const CAPABILITY_BASELINE = Object.freeze({
855
- targetVersion: "0.33.2",
933
+ targetVersion: TARGET_AGENT_BROWSER_VERSION,
856
934
  sourceEvidence,
857
935
  helpCommands,
858
936
  inventorySections,
@@ -0,0 +1,21 @@
1
+ export const TARGET_AGENT_BROWSER_SOURCE = "scripts/agent-browser-target.mjs";
2
+ export const TARGET_AGENT_BROWSER_VERSION = "0.36.0";
3
+ export const TARGET_AGENT_BROWSER_VERSION_LABEL = `agent-browser ${TARGET_AGENT_BROWSER_VERSION}`;
4
+ export const MINIMUM_AGENT_BROWSER_VERSION = "0.35.0";
5
+ export const MINIMUM_AGENT_BROWSER_VERSION_LABEL = `agent-browser ${MINIMUM_AGENT_BROWSER_VERSION}`;
6
+ export const SUPPORTED_AGENT_BROWSER_VERSION_LABEL = `${MINIMUM_AGENT_BROWSER_VERSION_LABEL} or newer`;
7
+
8
+ function stableVersionParts(version) {
9
+ const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(version);
10
+ return match?.slice(1).map(Number);
11
+ }
12
+
13
+ export function isSupportedAgentBrowserVersion(version) {
14
+ const actual = stableVersionParts(version);
15
+ const minimum = stableVersionParts(MINIMUM_AGENT_BROWSER_VERSION);
16
+ if (!actual || !minimum) return false;
17
+ for (let index = 0; index < minimum.length; index += 1) {
18
+ if (actual[index] !== minimum[index]) return actual[index] > minimum[index];
19
+ }
20
+ return true;
21
+ }
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Purpose: Produce the compiled runtime files that the published Pi package loads.
4
+ * Responsibilities: Remove stale dist output, run TypeScript emit through the local compiler, and fail with clear build output.
5
+ * Scope: Maintainer/package build only; runtime behavior remains in extensions/agent-browser TypeScript sources.
6
+ * Usage: `npm run build` before package verification, lifecycle validation, and npm pack/publish.
7
+ * Invariants/Assumptions: `node_modules` is installed and provides `typescript`; deleting `dist/` is safe because it is generated output.
8
+ */
9
+
10
+ import { execFile as execFileCallback } from "node:child_process";
11
+ import { rm } from "node:fs/promises";
12
+ import { join } from "node:path";
13
+ import process from "node:process";
14
+ import { promisify } from "node:util";
15
+
16
+ const execFile = promisify(execFileCallback);
17
+ const binSuffix = process.platform === "win32" ? ".cmd" : "";
18
+ const tscPath = join(process.cwd(), "node_modules", ".bin", `tsc${binSuffix}`);
19
+
20
+ async function main() {
21
+ await rm(join(process.cwd(), "dist"), { force: true, maxRetries: 5, recursive: true, retryDelay: 100 });
22
+ const options = process.platform === "win32" ? { shell: true } : {};
23
+ try {
24
+ const { stderr, stdout } = await execFile(tscPath, ["-p", "tsconfig.build.json"], {
25
+ ...options,
26
+ cwd: process.cwd(),
27
+ maxBuffer: 10 * 1024 * 1024,
28
+ });
29
+ if (stdout) process.stdout.write(stdout);
30
+ if (stderr) process.stderr.write(stderr);
31
+ } catch (error) {
32
+ if (error?.stdout) process.stdout.write(error.stdout);
33
+ if (error?.stderr) process.stderr.write(error.stderr);
34
+ throw error;
35
+ }
36
+ }
37
+
38
+ main().catch((error) => {
39
+ console.error(error instanceof Error ? error.message : String(error));
40
+ process.exitCode = 1;
41
+ });
@@ -169,6 +169,7 @@ function printStatus() {
169
169
  console.log("Effective config:");
170
170
  console.log(` webSearch.enabled: ${state.webSearchEnabled ? "true" : "false"}`);
171
171
  console.log(` webSearch.preferredProvider: ${state.config.webSearch?.preferredProvider ?? `auto (default ${DEFAULT_WEB_SEARCH_PROVIDER})`}`);
172
+ console.log(` webSearch.defaultSearchType: ${state.config.webSearch?.defaultSearchType ?? "not configured (Exa auto)"}`);
172
173
  for (const provider of WEB_SEARCH_PROVIDERS) {
173
174
  const field = getWebSearchProviderConfigKey(provider);
174
175
  console.log(` webSearch.${field}: ${getCredentialSourceSummary(state.webSearchCredentialSources[provider], provider)}`);
@@ -4,7 +4,7 @@
4
4
  * Responsibilities: Check upstream agent-browser PATH/version, inspect Pi settings for duplicate package/checkout sources, and print actionable remediation.
5
5
  * Scope: Read-only package diagnostics only; upstream browser runtime health remains the responsibility of upstream `agent-browser doctor`.
6
6
  * Usage: Run via `pi-agent-browser-doctor`, `npm exec --package pi-agent-browser-native -- pi-agent-browser-doctor`, or `npm run doctor` from this repository.
7
- * Invariants/Assumptions: The wrapper targets CAPABILITY_BASELINE.targetVersion, does not bundle agent-browser, and must not edit Pi settings or run fixing commands.
7
+ * Invariants/Assumptions: The wrapper recommends TARGET_AGENT_BROWSER_VERSION, enforces the configured stable version floor, does not bundle agent-browser, and must not edit Pi settings or run fixing commands.
8
8
  */
9
9
 
10
10
  import { execFile as execFileCallback } from "node:child_process";
@@ -15,7 +15,8 @@ import { dirname, resolve, sep } from "node:path";
15
15
  import { fileURLToPath } from "node:url";
16
16
  import { promisify } from "node:util";
17
17
 
18
- import { CAPABILITY_BASELINE, CAPABILITY_BASELINE_SOURCE } from "./agent-browser-capability-baseline.mjs";
18
+ import { CAPABILITY_BASELINE_SOURCE } from "./agent-browser-capability-baseline.mjs";
19
+ import { MINIMUM_AGENT_BROWSER_VERSION, TARGET_AGENT_BROWSER_SOURCE, TARGET_AGENT_BROWSER_VERSION, isSupportedAgentBrowserVersion } from "./agent-browser-target.mjs";
19
20
 
20
21
  const execFile = promisify(execFileCallback);
21
22
  const PACKAGE_NAME = "pi-agent-browser-native";
@@ -24,7 +25,7 @@ const EXTENSION_ENTRYPOINTS = Object.freeze([
24
25
  "extensions/agent-browser/index.ts",
25
26
  "dist/extensions/agent-browser/index.js",
26
27
  ]);
27
- const EXPECTED_VERSION = CAPABILITY_BASELINE.targetVersion;
28
+ const RECOMMENDED_VERSION = TARGET_AGENT_BROWSER_VERSION;
28
29
  const MINIMUM_PI_VERSION = "0.84.0";
29
30
  const DEFAULT_AGENT_DIR = resolve(homedir(), ".pi/agent");
30
31
  const THIS_PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
@@ -69,7 +70,7 @@ Options:
69
70
 
70
71
  Checks:
71
72
  1. agent-browser is installed on PATH.
72
- 2. agent-browser --version matches the package capability baseline.
73
+ 2. agent-browser --version is supported by this package.
73
74
  3. pi --version is at least the minimum Pi runtime version for this release.
74
75
  4. Pi settings and repo-local autoload locations do not point at multiple active pi-agent-browser-native sources.
75
76
 
@@ -340,17 +341,23 @@ async function checkAgentBrowserVersion({ runAgentBrowser }) {
340
341
  try {
341
342
  const rawOutput = await runAgentBrowser(["--version"]);
342
343
  const version = normalizeAgentBrowserVersion(rawOutput);
343
- if (version !== EXPECTED_VERSION) {
344
+ if (!isSupportedAgentBrowserVersion(version)) {
344
345
  return {
345
346
  status: "fail",
346
- title: `agent-browser version drift: expected ${EXPECTED_VERSION}, found ${version || "<empty>"}.`,
347
+ title: `agent-browser version drift: minimum supported ${MINIMUM_AGENT_BROWSER_VERSION}; found ${version || "<empty>"}.`,
347
348
  lines: [
348
- `This wrapper targets the current baseline from ${CAPABILITY_BASELINE_SOURCE} and does not provide backwards-compatibility shims.`,
349
- `Update upstream agent-browser to ${EXPECTED_VERSION}, or if you intentionally re-baselined upstream, update ${CAPABILITY_BASELINE_SOURCE}, run \`npm run docs -- command-reference write\`, refresh docs/COMMAND_REFERENCE.md, and rerun \`npm run verify -- command-reference\` plus \`npm run verify -- real-upstream\` with test/fixtures/agent-browser-real-output-shapes.json aligned to the new target version.`,
349
+ `This wrapper supports stable agent-browser versions at or above ${MINIMUM_AGENT_BROWSER_VERSION}; ${RECOMMENDED_VERSION} is the current recommendation from ${TARGET_AGENT_BROWSER_SOURCE}.`,
350
+ `Update upstream agent-browser to ${RECOMMENDED_VERSION}, or if you intentionally re-baselined upstream, update ${TARGET_AGENT_BROWSER_SOURCE} plus ${CAPABILITY_BASELINE_SOURCE}, run \`npm run docs -- command-reference write\`, refresh docs/COMMAND_REFERENCE.md, and rerun \`npm run verify -- command-reference\` plus \`npm run verify -- real-upstream\` with test/fixtures/agent-browser-real-output-shapes.json aligned to the new target version.`,
350
351
  ],
351
352
  };
352
353
  }
353
- return { status: "pass", title: `agent-browser version matches baseline: ${version}`, lines: [] };
354
+ return {
355
+ status: "pass",
356
+ title: version === RECOMMENDED_VERSION
357
+ ? `agent-browser version matches recommended baseline: ${version}`
358
+ : `agent-browser version meets supported floor: ${version} (recommended ${RECOMMENDED_VERSION})`,
359
+ lines: [],
360
+ };
354
361
  } catch (error) {
355
362
  const code = error && typeof error === "object" ? error.code : undefined;
356
363
  return {
@@ -1,5 +1,6 @@
1
1
  param(
2
- [Parameter(Mandatory=$true)][string]$AgentBrowserVersion
2
+ [Parameter(Mandatory=$true)][string]$AgentBrowserVersion,
3
+ [switch]$SkipNpmCi
3
4
  )
4
5
 
5
6
  $ErrorActionPreference = "Continue"
@@ -90,8 +91,13 @@ Write-Output "PLATFORM_DOGFOOD_ARTIFACT_DIR=$DogfoodArtifactDir"
90
91
  $NodeVersion = (& node --version 2>$null)
91
92
  Write-Output "PLATFORM_NODE_VERSION=$NodeVersion"
92
93
 
93
- & npm ci 2>&1
94
- $NpmCiExit = $LASTEXITCODE
94
+ if ($SkipNpmCi -and (Test-Path (Join-Path $SourceRoot "node_modules"))) {
95
+ Write-Output "PLATFORM_NPM_CI_SKIPPED=1"
96
+ $NpmCiExit = 0
97
+ } else {
98
+ & npm ci 2>&1
99
+ $NpmCiExit = $LASTEXITCODE
100
+ }
95
101
  Write-Output "PLATFORM_NPM_CI_EXIT=$NpmCiExit"
96
102
 
97
103
  $AgentBrowserPath = Get-AgentBrowserCommandPath
@@ -305,9 +305,9 @@ export function buildPlatformBuildCommand(targetName, packageName = "pi-agent-br
305
305
  return lines.join("\n");
306
306
  }
307
307
 
308
- export function buildBrowserDogfoodCommand(targetName, agentBrowserVersion = CAPABILITY_BASELINE.targetVersion) {
308
+ export function buildBrowserDogfoodCommand(targetName, agentBrowserVersion = CAPABILITY_BASELINE.targetVersion, dependenciesReady = false) {
309
309
  if (platformFor(targetName) === "powershell") {
310
- return `powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\\scripts\\platform-smoke\\browser-dogfood-windows.ps1 -AgentBrowserVersion ${psSingleQuote(agentBrowserVersion)}`;
310
+ return `powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File .\\scripts\\platform-smoke\\browser-dogfood-windows.ps1 -AgentBrowserVersion ${psSingleQuote(agentBrowserVersion)}${dependenciesReady ? " -SkipNpmCi" : ""}`;
311
311
  }
312
312
 
313
313
  const lines = [];
@@ -329,8 +329,12 @@ export function buildBrowserDogfoodCommand(targetName, agentBrowserVersion = CAP
329
329
  lines.push(`echo "PLATFORM_AGENT_BROWSER_VERSION=$AGENT_BROWSER_VERSION_OUTPUT"`);
330
330
  lines.push(`if [ "$AGENT_BROWSER_VERSION_COMMAND_EXIT" -eq 0 ] && [ "$AGENT_BROWSER_VERSION_OUTPUT" = "$EXPECTED_AGENT_BROWSER_VERSION" ]; then AGENT_BROWSER_READY_EXIT=0; else AGENT_BROWSER_READY_EXIT=1; fi`);
331
331
  lines.push(`echo "PLATFORM_AGENT_BROWSER_READY_EXIT=$AGENT_BROWSER_READY_EXIT"`);
332
- lines.push(`npm ci 2>&1`);
333
- lines.push(`NPM_CI_EXIT=$?`);
332
+ if (dependenciesReady) {
333
+ lines.push(`if [ -d node_modules ]; then echo "PLATFORM_NPM_CI_SKIPPED=1"; NPM_CI_EXIT=0; else npm ci 2>&1; NPM_CI_EXIT=$?; fi`);
334
+ } else {
335
+ lines.push(`npm ci 2>&1`);
336
+ lines.push(`NPM_CI_EXIT=$?`);
337
+ }
334
338
  lines.push(`echo "PLATFORM_NPM_CI_EXIT=$NPM_CI_EXIT"`);
335
339
  lines.push(`TSX_CLI="$SOURCE_ROOT/node_modules/.bin/tsx"`);
336
340
  lines.push(`if [ ! -x "$TSX_CLI" ]; then TSX_CLI="$(command -v tsx || true)"; fi`);
@@ -349,7 +353,7 @@ async function runBrowserDogfoodSuite(config, targetName, suiteName, leaseSessio
349
353
  const startedAt = Date.now();
350
354
  const platform = platformFor(targetName);
351
355
  const slug = `${config.packageName}-${targetName}`;
352
- const command = buildBrowserDogfoodCommand(targetName, config.agentBrowserVersion);
356
+ const command = buildBrowserDogfoodCommand(targetName, config.agentBrowserVersion, leaseSession?.dependenciesReady === true);
353
357
  writeFileSync(resolve(suiteDir, "target.json"), JSON.stringify(targetEvidence(config, targetName, runId, slug), null, 2));
354
358
  writeFileSync(resolve(suiteDir, "suite.json"), JSON.stringify({ suiteName, modelCalls: 0, realBrowser: true }, null, 2));
355
359
  writeCommand(suiteDir, command);
@@ -496,12 +500,14 @@ export async function runTargetSuites(config, targetName, suiteNames) {
496
500
  let staleCleanupResult;
497
501
  try {
498
502
  let sync = true;
503
+ let dependenciesReady = false;
499
504
  for (const suiteName of suiteNames) {
500
505
  console.log(` Suite: ${suiteName}`);
501
- const result = await runTargetSuite(config, targetName, suiteName, { ...lease, sync }, runId);
506
+ const result = await runTargetSuite(config, targetName, suiteName, { ...lease, dependenciesReady, sync }, runId);
502
507
  results.push(result);
503
508
  console.log(` ${result.ok ? "PASS" : "FAIL"} ${suiteName} on ${targetName}`);
504
509
  sync = false;
510
+ if (result.ok && suiteName === "platform-build") dependenciesReady = true;
505
511
  if (!result.ok) break;
506
512
  }
507
513
  } finally {
@@ -1,20 +0,0 @@
1
- const MANAGED_SESSION_RESTORE_KEY_PATTERN = /piab-r(?:2)?-[a-f\d]{32}/gi;
2
- const MANAGED_SESSION_RESTORE_KEY_EXACT_PATTERN = /^piab-r2-[a-f\d]{32}$/i;
3
- const WRAPPER_MANAGED_SESSION_PREFIX = "piab-";
4
- export function isWrapperManagedSessionName(value) {
5
- return typeof value === "string" && value.toLowerCase().startsWith(WRAPPER_MANAGED_SESSION_PREFIX);
6
- }
7
- export function isManagedSessionRestoreKey(value) {
8
- return typeof value === "string" && MANAGED_SESSION_RESTORE_KEY_EXACT_PATTERN.test(value);
9
- }
10
- export function extractManagedSessionRestoreKeys(value) {
11
- return [...new Set(value.match(MANAGED_SESSION_RESTORE_KEY_PATTERN)?.map((key) => key.toLowerCase()) ?? [])];
12
- }
13
- export function containsManagedSessionRestoreKey(value) {
14
- MANAGED_SESSION_RESTORE_KEY_PATTERN.lastIndex = 0;
15
- return MANAGED_SESSION_RESTORE_KEY_PATTERN.test(value);
16
- }
17
- export function redactManagedSessionRestoreKeys(value) {
18
- MANAGED_SESSION_RESTORE_KEY_PATTERN.lastIndex = 0;
19
- return value.replace(MANAGED_SESSION_RESTORE_KEY_PATTERN, "[REDACTED MANAGED STATE]");
20
- }