pi-agent-browser-native 0.2.47 → 0.2.49

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 (185) hide show
  1. package/CHANGELOG.md +63 -19
  2. package/README.md +52 -19
  3. package/dist/extensions/agent-browser/index.js +785 -0
  4. package/dist/extensions/agent-browser/lib/argv-descriptor.js +71 -0
  5. package/dist/extensions/agent-browser/lib/argv-grammar.js +121 -0
  6. package/dist/extensions/agent-browser/lib/bash-guard.js +190 -0
  7. package/dist/extensions/agent-browser/lib/command-policy.js +85 -0
  8. package/dist/extensions/agent-browser/lib/command-taxonomy.js +302 -0
  9. package/dist/extensions/agent-browser/lib/config-policy.js +686 -0
  10. package/dist/extensions/agent-browser/lib/config.js +122 -0
  11. package/dist/extensions/agent-browser/lib/electron/cdp.js +51 -0
  12. package/dist/extensions/agent-browser/lib/electron/cleanup.js +212 -0
  13. package/dist/extensions/agent-browser/lib/electron/discovery.js +633 -0
  14. package/dist/extensions/agent-browser/lib/electron/launch.js +351 -0
  15. package/{extensions/agent-browser/lib/electron/text.ts → dist/extensions/agent-browser/lib/electron/text.js} +5 -5
  16. package/dist/extensions/agent-browser/lib/executable-path.js +20 -0
  17. package/dist/extensions/agent-browser/lib/fs-utils.js +18 -0
  18. package/dist/extensions/agent-browser/lib/input-modes/electron.js +165 -0
  19. package/dist/extensions/agent-browser/lib/input-modes/job.js +519 -0
  20. package/dist/extensions/agent-browser/lib/input-modes/lookups.js +440 -0
  21. package/dist/extensions/agent-browser/lib/input-modes/params.js +164 -0
  22. package/dist/extensions/agent-browser/lib/input-modes/semantic-action.js +119 -0
  23. package/dist/extensions/agent-browser/lib/input-modes/shared.js +42 -0
  24. package/dist/extensions/agent-browser/lib/input-modes/types.js +21 -0
  25. package/dist/extensions/agent-browser/lib/input-modes.js +10 -0
  26. package/dist/extensions/agent-browser/lib/json-schema.js +58 -0
  27. package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +59 -0
  28. package/dist/extensions/agent-browser/lib/navigation-policy.js +83 -0
  29. package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +62 -0
  30. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.js +39 -0
  31. package/dist/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.js +276 -0
  32. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +909 -0
  33. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +443 -0
  34. package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +47 -0
  35. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/direct-anchor-download.js +141 -0
  36. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.js +108 -0
  37. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js +112 -0
  38. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +158 -0
  39. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +54 -0
  40. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +762 -0
  41. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +491 -0
  42. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.js +40 -0
  43. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-artifacts.js +5 -0
  44. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +731 -0
  45. package/dist/extensions/agent-browser/lib/orchestration/browser-run/types.js +1 -0
  46. package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +718 -0
  47. package/dist/extensions/agent-browser/lib/orchestration/input-plan.js +247 -0
  48. package/dist/extensions/agent-browser/lib/orchestration/output-file.js +68 -0
  49. package/{extensions/agent-browser/lib/parsing.ts → dist/extensions/agent-browser/lib/parsing.js} +12 -11
  50. package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +241 -0
  51. package/dist/extensions/agent-browser/lib/playbook.js +121 -0
  52. package/dist/extensions/agent-browser/lib/process.js +448 -0
  53. package/dist/extensions/agent-browser/lib/prompt-policy.js +91 -0
  54. package/dist/extensions/agent-browser/lib/results/action-recommendations.js +220 -0
  55. package/dist/extensions/agent-browser/lib/results/artifact-manifest.js +111 -0
  56. package/{extensions/agent-browser/lib/results/artifact-state.ts → dist/extensions/agent-browser/lib/results/artifact-state.js} +4 -8
  57. package/dist/extensions/agent-browser/lib/results/categories.js +76 -0
  58. package/dist/extensions/agent-browser/lib/results/confirmation.js +63 -0
  59. package/dist/extensions/agent-browser/lib/results/contracts.js +8 -0
  60. package/dist/extensions/agent-browser/lib/results/editable-ref-evidence.js +74 -0
  61. package/dist/extensions/agent-browser/lib/results/envelope.js +166 -0
  62. package/dist/extensions/agent-browser/lib/results/network-routes.js +92 -0
  63. package/dist/extensions/agent-browser/lib/results/network.js +73 -0
  64. package/dist/extensions/agent-browser/lib/results/next-actions.js +72 -0
  65. package/dist/extensions/agent-browser/lib/results/presentation/artifacts.js +515 -0
  66. package/dist/extensions/agent-browser/lib/results/presentation/batch.js +397 -0
  67. package/dist/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.js +55 -0
  68. package/dist/extensions/agent-browser/lib/results/presentation/common.js +46 -0
  69. package/dist/extensions/agent-browser/lib/results/presentation/content.js +24 -0
  70. package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +960 -0
  71. package/dist/extensions/agent-browser/lib/results/presentation/errors.js +205 -0
  72. package/dist/extensions/agent-browser/lib/results/presentation/large-output.js +134 -0
  73. package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +159 -0
  74. package/dist/extensions/agent-browser/lib/results/presentation/registry.js +216 -0
  75. package/dist/extensions/agent-browser/lib/results/presentation/semantic-action.js +104 -0
  76. package/dist/extensions/agent-browser/lib/results/presentation/skills.js +152 -0
  77. package/dist/extensions/agent-browser/lib/results/presentation.js +177 -0
  78. package/dist/extensions/agent-browser/lib/results/recovery-actions.js +107 -0
  79. package/dist/extensions/agent-browser/lib/results/recovery-next-actions.js +50 -0
  80. package/dist/extensions/agent-browser/lib/results/selector-recovery.js +225 -0
  81. package/{extensions/agent-browser/lib/results/shared.ts → dist/extensions/agent-browser/lib/results/shared.js} +0 -1
  82. package/dist/extensions/agent-browser/lib/results/snapshot-high-value-controls.js +208 -0
  83. package/dist/extensions/agent-browser/lib/results/snapshot-refs.js +78 -0
  84. package/dist/extensions/agent-browser/lib/results/snapshot-segments.js +331 -0
  85. package/dist/extensions/agent-browser/lib/results/snapshot-spill.js +40 -0
  86. package/dist/extensions/agent-browser/lib/results/snapshot.js +264 -0
  87. package/dist/extensions/agent-browser/lib/results/text.js +40 -0
  88. package/{extensions/agent-browser/lib/results.ts → dist/extensions/agent-browser/lib/results.js} +2 -32
  89. package/dist/extensions/agent-browser/lib/runtime.js +816 -0
  90. package/dist/extensions/agent-browser/lib/session-page-state.js +411 -0
  91. package/dist/extensions/agent-browser/lib/string-enum-schema.js +13 -0
  92. package/dist/extensions/agent-browser/lib/temp.js +498 -0
  93. package/dist/extensions/agent-browser/lib/web-search.js +562 -0
  94. package/docs/ARCHITECTURE.md +10 -10
  95. package/docs/COMMAND_REFERENCE.md +35 -21
  96. package/docs/ELECTRON.md +3 -3
  97. package/docs/RELEASE.md +46 -26
  98. package/docs/REQUIREMENTS.md +1 -1
  99. package/docs/SUPPORT_MATRIX.md +35 -106
  100. package/docs/TOOL_CONTRACT.md +23 -21
  101. package/package.json +12 -8
  102. package/scripts/agent-browser-capability-baseline.mjs +6 -3
  103. package/scripts/config.mjs +8 -2
  104. package/scripts/doctor.mjs +19 -17
  105. package/scripts/platform-smoke.mjs +1 -1
  106. package/extensions/agent-browser/index.ts +0 -952
  107. package/extensions/agent-browser/lib/argv-descriptor.ts +0 -90
  108. package/extensions/agent-browser/lib/argv-grammar.ts +0 -128
  109. package/extensions/agent-browser/lib/bash-guard.ts +0 -205
  110. package/extensions/agent-browser/lib/command-policy.ts +0 -71
  111. package/extensions/agent-browser/lib/command-taxonomy.ts +0 -336
  112. package/extensions/agent-browser/lib/config-policy.js +0 -690
  113. package/extensions/agent-browser/lib/config.ts +0 -209
  114. package/extensions/agent-browser/lib/electron/cdp.ts +0 -69
  115. package/extensions/agent-browser/lib/electron/cleanup.ts +0 -235
  116. package/extensions/agent-browser/lib/electron/discovery.ts +0 -710
  117. package/extensions/agent-browser/lib/electron/launch.ts +0 -499
  118. package/extensions/agent-browser/lib/executable-path.ts +0 -19
  119. package/extensions/agent-browser/lib/fs-utils.ts +0 -18
  120. package/extensions/agent-browser/lib/input-modes/electron.ts +0 -170
  121. package/extensions/agent-browser/lib/input-modes/job.ts +0 -451
  122. package/extensions/agent-browser/lib/input-modes/lookups.ts +0 -447
  123. package/extensions/agent-browser/lib/input-modes/params.ts +0 -205
  124. package/extensions/agent-browser/lib/input-modes/semantic-action.ts +0 -127
  125. package/extensions/agent-browser/lib/input-modes/shared.ts +0 -46
  126. package/extensions/agent-browser/lib/input-modes/types.ts +0 -225
  127. package/extensions/agent-browser/lib/input-modes.ts +0 -45
  128. package/extensions/agent-browser/lib/json-schema.ts +0 -73
  129. package/extensions/agent-browser/lib/launch-scoped-flags.ts +0 -67
  130. package/extensions/agent-browser/lib/navigation-policy.ts +0 -95
  131. package/extensions/agent-browser/lib/orchestration/batch-stdin.ts +0 -65
  132. package/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.ts +0 -257
  133. package/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.ts +0 -912
  134. package/extensions/agent-browser/lib/orchestration/browser-run/final-result.ts +0 -512
  135. package/extensions/agent-browser/lib/orchestration/browser-run/index.ts +0 -53
  136. package/extensions/agent-browser/lib/orchestration/browser-run/prepare.ts +0 -1481
  137. package/extensions/agent-browser/lib/orchestration/browser-run/process-output.ts +0 -564
  138. package/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.ts +0 -47
  139. package/extensions/agent-browser/lib/orchestration/browser-run/session-state.ts +0 -868
  140. package/extensions/agent-browser/lib/orchestration/browser-run/types.ts +0 -564
  141. package/extensions/agent-browser/lib/orchestration/electron-host/index.ts +0 -855
  142. package/extensions/agent-browser/lib/orchestration/input-plan.ts +0 -375
  143. package/extensions/agent-browser/lib/orchestration/output-file.ts +0 -86
  144. package/extensions/agent-browser/lib/pi-tool-rendering.ts +0 -252
  145. package/extensions/agent-browser/lib/playbook.ts +0 -142
  146. package/extensions/agent-browser/lib/process.ts +0 -516
  147. package/extensions/agent-browser/lib/prompt-policy.ts +0 -105
  148. package/extensions/agent-browser/lib/results/action-recommendations.ts +0 -264
  149. package/extensions/agent-browser/lib/results/artifact-manifest.ts +0 -111
  150. package/extensions/agent-browser/lib/results/categories.ts +0 -106
  151. package/extensions/agent-browser/lib/results/confirmation.ts +0 -76
  152. package/extensions/agent-browser/lib/results/contracts.ts +0 -241
  153. package/extensions/agent-browser/lib/results/editable-ref-evidence.ts +0 -72
  154. package/extensions/agent-browser/lib/results/envelope.ts +0 -195
  155. package/extensions/agent-browser/lib/results/network-routes.ts +0 -83
  156. package/extensions/agent-browser/lib/results/network.ts +0 -78
  157. package/extensions/agent-browser/lib/results/next-actions.ts +0 -117
  158. package/extensions/agent-browser/lib/results/presentation/artifacts.ts +0 -588
  159. package/extensions/agent-browser/lib/results/presentation/batch.ts +0 -450
  160. package/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.ts +0 -67
  161. package/extensions/agent-browser/lib/results/presentation/common.ts +0 -53
  162. package/extensions/agent-browser/lib/results/presentation/content.ts +0 -36
  163. package/extensions/agent-browser/lib/results/presentation/diagnostics.ts +0 -923
  164. package/extensions/agent-browser/lib/results/presentation/errors.ts +0 -227
  165. package/extensions/agent-browser/lib/results/presentation/large-output.ts +0 -182
  166. package/extensions/agent-browser/lib/results/presentation/navigation.ts +0 -184
  167. package/extensions/agent-browser/lib/results/presentation/registry.ts +0 -242
  168. package/extensions/agent-browser/lib/results/presentation/semantic-action.ts +0 -131
  169. package/extensions/agent-browser/lib/results/presentation/skills.ts +0 -143
  170. package/extensions/agent-browser/lib/results/presentation.ts +0 -257
  171. package/extensions/agent-browser/lib/results/recovery-actions.ts +0 -139
  172. package/extensions/agent-browser/lib/results/recovery-next-actions.ts +0 -71
  173. package/extensions/agent-browser/lib/results/selector-recovery.ts +0 -320
  174. package/extensions/agent-browser/lib/results/snapshot-high-value-controls.ts +0 -273
  175. package/extensions/agent-browser/lib/results/snapshot-refs.ts +0 -100
  176. package/extensions/agent-browser/lib/results/snapshot-segments.ts +0 -366
  177. package/extensions/agent-browser/lib/results/snapshot-spill.ts +0 -63
  178. package/extensions/agent-browser/lib/results/snapshot.ts +0 -329
  179. package/extensions/agent-browser/lib/results/text.ts +0 -40
  180. package/extensions/agent-browser/lib/runtime.ts +0 -988
  181. package/extensions/agent-browser/lib/session-page-state.ts +0 -512
  182. package/extensions/agent-browser/lib/string-enum-schema.ts +0 -20
  183. package/extensions/agent-browser/lib/temp.ts +0 -577
  184. package/extensions/agent-browser/lib/web-search.ts +0 -721
  185. /package/{extensions/agent-browser/lib/orchestration/browser-run.ts → dist/extensions/agent-browser/lib/orchestration/browser-run.js} +0 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Purpose: Compile semanticAction shorthand inputs into upstream agent-browser commands.
3
+ * Responsibilities: Validate shorthand locator/action fields and expose compiled-command helpers.
4
+ * Scope: semanticAction mode only.
5
+ */
6
+ import { isRecord } from "../parsing.js";
7
+ import { getSelectValues } from "./shared.js";
8
+ import { AGENT_BROWSER_SEMANTIC_ACTIONS, AGENT_BROWSER_SEMANTIC_LOCATORS, } from "./types.js";
9
+ export function getCompiledSemanticActionCommandIndex(compiled) {
10
+ return compiled.args[0] === "--session" ? 2 : 0;
11
+ }
12
+ export function getCompiledSemanticActionSessionPrefix(compiled) {
13
+ const commandIndex = getCompiledSemanticActionCommandIndex(compiled);
14
+ return commandIndex > 0 ? compiled.args.slice(0, commandIndex) : [];
15
+ }
16
+ export function isCompiledSemanticActionFindCommand(compiled) {
17
+ if (!compiled)
18
+ return false;
19
+ return compiled.args[getCompiledSemanticActionCommandIndex(compiled)] === "find";
20
+ }
21
+ export function compileAgentBrowserSemanticAction(input) {
22
+ if (!isRecord(input)) {
23
+ return { error: "semanticAction must be an object." };
24
+ }
25
+ const action = input.action;
26
+ const locator = input.locator;
27
+ const value = input.value;
28
+ const values = input.values;
29
+ const selector = input.selector;
30
+ const text = input.text;
31
+ const role = input.role;
32
+ const name = input.name;
33
+ const session = input.session;
34
+ if (typeof action !== "string" || !AGENT_BROWSER_SEMANTIC_ACTIONS.includes(action)) {
35
+ return { error: `semanticAction.action must be one of: ${AGENT_BROWSER_SEMANTIC_ACTIONS.join(", ")}.` };
36
+ }
37
+ if (session !== undefined && (typeof session !== "string" || session.trim().length === 0)) {
38
+ return { error: "semanticAction.session must be a non-empty string when provided." };
39
+ }
40
+ if (action === "select") {
41
+ if (locator !== undefined || role !== undefined || name !== undefined) {
42
+ return { error: "semanticAction.locator, role, and name are not supported for select; use selector plus value or values." };
43
+ }
44
+ if (text !== undefined) {
45
+ return { error: "semanticAction.text is not supported for select; use value or values for option values." };
46
+ }
47
+ if (typeof selector !== "string" || selector.trim().length === 0) {
48
+ return { error: "semanticAction.selector is required for select." };
49
+ }
50
+ const selectedValues = getSelectValues(input, "semanticAction");
51
+ if (selectedValues.error)
52
+ return { error: selectedValues.error };
53
+ const args = typeof session === "string" ? ["--session", session, "select", selector, ...selectedValues.values] : ["select", selector, ...selectedValues.values];
54
+ return { compiled: { action: "select", selector, values: selectedValues.values, args } };
55
+ }
56
+ if (values !== undefined) {
57
+ return { error: "semanticAction.values is only supported for select actions." };
58
+ }
59
+ if (selector !== undefined) {
60
+ if (typeof selector !== "string" || selector.trim().length === 0) {
61
+ return { error: "semanticAction.selector must be a non-empty string when provided." };
62
+ }
63
+ if (locator !== undefined || value !== undefined || role !== undefined || name !== undefined) {
64
+ return { error: "semanticAction.selector cannot be combined with locator, value, role, or name; use selector for a direct click/check/fill target or locator fields for find-based actions." };
65
+ }
66
+ if (text !== undefined && typeof text !== "string") {
67
+ return { error: "semanticAction.text must be a string when provided." };
68
+ }
69
+ if (action === "fill" && (typeof text !== "string" || text.length === 0)) {
70
+ return { error: `semanticAction.text is required for ${action}.` };
71
+ }
72
+ if (action !== "fill" && text !== undefined) {
73
+ return { error: "semanticAction.text is only supported for fill actions." };
74
+ }
75
+ const directArgs = typeof session === "string" ? ["--session", session, action, selector] : [action, selector];
76
+ if (action === "fill")
77
+ directArgs.push(text);
78
+ return { compiled: { action: action, selector, args: directArgs } };
79
+ }
80
+ if (typeof locator !== "string" || !AGENT_BROWSER_SEMANTIC_LOCATORS.includes(locator)) {
81
+ return { error: `semanticAction.locator must be one of: ${AGENT_BROWSER_SEMANTIC_LOCATORS.join(", ")}.` };
82
+ }
83
+ if (value !== undefined && (typeof value !== "string" || value.trim().length === 0)) {
84
+ return { error: "semanticAction.value must be a non-empty string when provided." };
85
+ }
86
+ if (role !== undefined && (typeof role !== "string" || role.trim().length === 0)) {
87
+ return { error: "semanticAction.role must be a non-empty string when provided." };
88
+ }
89
+ const locatorValue = locator === "role" && typeof role === "string" ? role : value;
90
+ if (typeof locatorValue !== "string" || locatorValue.trim().length === 0) {
91
+ return { error: locator === "role" ? "semanticAction.value or semanticAction.role must be a non-empty string for locator=role." : "semanticAction.value must be a non-empty string." };
92
+ }
93
+ if (text !== undefined && typeof text !== "string") {
94
+ return { error: "semanticAction.text must be a string when provided." };
95
+ }
96
+ if (action === "fill" && (typeof text !== "string" || text.length === 0)) {
97
+ return { error: `semanticAction.text is required for ${action}.` };
98
+ }
99
+ if (action !== "fill" && text !== undefined) {
100
+ return { error: "semanticAction.text is only supported for fill actions." };
101
+ }
102
+ if (role !== undefined && locator !== "role") {
103
+ return { error: "semanticAction.role is only supported for locator=role." };
104
+ }
105
+ if (role !== undefined && value !== undefined && role !== value) {
106
+ return { error: "semanticAction.role must match value when both are provided for locator=role." };
107
+ }
108
+ if (name !== undefined && (locator !== "role" || typeof name !== "string" || name.length === 0)) {
109
+ return { error: "semanticAction.name is only supported as a non-empty string for locator=role." };
110
+ }
111
+ const args = typeof session === "string" ? ["--session", session, "find", locator, locatorValue, action] : ["find", locator, locatorValue, action];
112
+ if (action === "fill") {
113
+ args.push(text);
114
+ }
115
+ if (locator === "role" && typeof name === "string") {
116
+ args.push("--name", name);
117
+ }
118
+ return { compiled: { action: action, locator: locator, args } };
119
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Purpose: Hold tiny shared parsing helpers for structured agent_browser input modes.
3
+ * Responsibilities: Normalize common select values, batch result rows, and workspace scan limits.
4
+ * Scope: Generic input-mode helpers only; mode-specific policy stays in the owning module.
5
+ */
6
+ import { isRecord } from "../parsing.js";
7
+ import { SOURCE_LOOKUP_DEFAULT_MAX_WORKSPACE_FILES, SOURCE_LOOKUP_MAX_WORKSPACE_FILES } from "./types.js";
8
+ export function getSelectValues(input, context) {
9
+ const rawValue = input.value;
10
+ const rawValues = input.values;
11
+ if (rawValue !== undefined && rawValues !== undefined) {
12
+ return { error: `${context}.value and ${context}.values cannot both be provided for select.` };
13
+ }
14
+ if (rawValues !== undefined) {
15
+ if (!Array.isArray(rawValues) || rawValues.length === 0 || rawValues.some((value) => typeof value !== "string" || value.trim().length === 0)) {
16
+ return { error: `${context}.values must be a non-empty array of non-empty strings for select.` };
17
+ }
18
+ return { values: rawValues };
19
+ }
20
+ if (typeof rawValue === "string" && rawValue.trim().length > 0) {
21
+ return { values: [rawValue] };
22
+ }
23
+ return { error: `${context}.value or ${context}.values is required for select.` };
24
+ }
25
+ export function getBatchResultItems(data) {
26
+ return Array.isArray(data) ? data.filter(isRecord) : [];
27
+ }
28
+ export function getCommandNameFromBatchItem(item) {
29
+ const command = item.command;
30
+ return Array.isArray(command) && typeof command[0] === "string" ? command[0] : undefined;
31
+ }
32
+ export function validateLookupMaxWorkspaceFiles(value, fieldName) {
33
+ if (value === undefined)
34
+ return { value: SOURCE_LOOKUP_DEFAULT_MAX_WORKSPACE_FILES };
35
+ if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) {
36
+ return { error: `${fieldName} must be a positive integer when provided.` };
37
+ }
38
+ if (value > SOURCE_LOOKUP_MAX_WORKSPACE_FILES) {
39
+ return { error: `${fieldName} must be ${SOURCE_LOOKUP_MAX_WORKSPACE_FILES} or less.` };
40
+ }
41
+ return { value };
42
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Purpose: Define structured agent_browser input-mode constants and TypeScript contracts.
3
+ * Responsibilities: Share schema enums and compiled input-mode result types across input-mode modules.
4
+ * Scope: Types and constants only; validation and compilation live in sibling modules.
5
+ */
6
+ export const DEFAULT_SESSION_MODE = "auto";
7
+ export const AGENT_BROWSER_SEMANTIC_ACTIONS = ["check", "click", "fill", "select"];
8
+ export const AGENT_BROWSER_SEMANTIC_LOCATORS = ["alt", "label", "placeholder", "role", "testid", "text", "title"];
9
+ export const AGENT_BROWSER_JOB_TYPE_DELAYED_TEXT_MAX_CHARACTERS = 200;
10
+ export const AGENT_BROWSER_JOB_STEP_ACTIONS = ["open", "click", "fill", "type", "select", "wait", "assertText", "assertUrl", "waitForDownload", "screenshot", "snapshot"];
11
+ export const AGENT_BROWSER_QA_LOAD_STATES = ["domcontentloaded", "load", "networkidle"];
12
+ export const AGENT_BROWSER_ELECTRON_ACTIONS = ["list", "launch", "status", "cleanup", "probe"];
13
+ export const AGENT_BROWSER_ELECTRON_HANDOFFS = ["connect", "tabs", "snapshot"];
14
+ export const AGENT_BROWSER_ELECTRON_TARGET_TYPES = ["page", "webview", "any"];
15
+ export const AGENT_BROWSER_ELECTRON_LIST_FIELDS = new Set(["action", "query", "maxResults"]);
16
+ export const AGENT_BROWSER_ELECTRON_PROBE_FIELDS = new Set(["action", "launchId", "timeoutMs"]);
17
+ export const AGENT_BROWSER_ELECTRON_RESERVED_APP_ARGS = ["--user-data-dir", "--remote-debugging-port", "--remote-debugging-address", "--remote-debugging-pipe"];
18
+ export const SOURCE_LOOKUP_WORKSPACE_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx"]);
19
+ export const SOURCE_LOOKUP_IGNORED_DIRECTORIES = new Set([".git", "node_modules", "dist", "build", "coverage", ".next", "out", "tmp", "temp"]);
20
+ export const SOURCE_LOOKUP_DEFAULT_MAX_WORKSPACE_FILES = 2_000;
21
+ export const SOURCE_LOOKUP_MAX_WORKSPACE_FILES = 5_000;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Purpose: Re-export focused input-mode schema, compiler, and analysis modules for the agent_browser wrapper.
3
+ * Responsibilities: Preserve the extension entrypoint's import surface while keeping input-mode code split by concern.
4
+ * Scope: Barrel only; add behavior to focused files under ./input-modes/.
5
+ */
6
+ export { AGENT_BROWSER_PARAMS } from "./input-modes/params.js";
7
+ export { analyzeQaPresetResults, analyzeQaPresetTimeout, buildQaCompactPassText, compileAgentBrowserJob, compileAgentBrowserQaPreset, extractQaPageContext, isHttpOrHttpsUrl, } from "./input-modes/job.js";
8
+ export { analyzeNetworkSourceLookupResults, analyzeSourceLookupResults, compileAgentBrowserNetworkSourceLookup, compileAgentBrowserSourceLookup, redactNetworkSourceLookupAnalysis, redactNetworkSourceLookupArgs, redactNetworkSourceLookupSurface, redactNetworkSourceLookupUrl, } from "./input-modes/lookups.js";
9
+ export { compileAgentBrowserElectron } from "./input-modes/electron.js";
10
+ export { compileAgentBrowserSemanticAction, getCompiledSemanticActionCommandIndex, getCompiledSemanticActionSessionPrefix, isCompiledSemanticActionFindCommand, } from "./input-modes/semantic-action.js";
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Purpose: Build the small JSON Schema subset used by Pi tool schemas without importing TypeBox at runtime.
3
+ * Responsibilities: Preserve plain JSON Schema objects Pi consumes while keeping extension startup cheap.
4
+ * Scope: Schema construction only; runtime validation still belongs to Pi and the tool input compilers.
5
+ */
6
+ const OPTIONAL_SCHEMA = Symbol("pi-agent-browser-optional-schema");
7
+ function withOptions(schema, options) {
8
+ return { ...schema, ...(options ?? {}) };
9
+ }
10
+ function literalType(value) {
11
+ const valueType = typeof value;
12
+ return valueType === "string" || valueType === "number" || valueType === "boolean" ? valueType : undefined;
13
+ }
14
+ function propertySchema(schema) {
15
+ const clone = { ...schema };
16
+ delete clone[OPTIONAL_SCHEMA];
17
+ return clone;
18
+ }
19
+ export const JsonSchema = {
20
+ Array(items, options) {
21
+ return withOptions({ type: "array", items }, options);
22
+ },
23
+ Boolean(options) {
24
+ return withOptions({ type: "boolean" }, options);
25
+ },
26
+ Integer(options) {
27
+ return withOptions({ type: "integer" }, options);
28
+ },
29
+ Literal(value, options) {
30
+ const type = literalType(value);
31
+ return withOptions(type ? { type, const: value } : { const: value }, options);
32
+ },
33
+ Number(options) {
34
+ return withOptions({ type: "number" }, options);
35
+ },
36
+ Object(properties, options) {
37
+ const required = globalThis.Object.entries(properties)
38
+ .filter(([, schema]) => schema[OPTIONAL_SCHEMA] !== true)
39
+ .map(([key]) => key);
40
+ return withOptions({
41
+ type: "object",
42
+ properties: globalThis.Object.fromEntries(globalThis.Object.entries(properties).map(([key, schema]) => [key, propertySchema(schema)])),
43
+ ...(required.length > 0 ? { required } : {}),
44
+ }, options);
45
+ },
46
+ Optional(schema) {
47
+ return { ...schema, [OPTIONAL_SCHEMA]: true };
48
+ },
49
+ String(options) {
50
+ return withOptions({ type: "string" }, options);
51
+ },
52
+ Union(types, options) {
53
+ return withOptions({ anyOf: types }, options);
54
+ },
55
+ Unsafe(schema) {
56
+ return schema;
57
+ },
58
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Purpose: Canonical launch-scoped agent-browser flag metadata shared by runtime planning and agent-facing guidance.
3
+ * Responsibilities: Define which upstream flags require a fresh launch, explain why, and expose stable guidance labels.
4
+ * Scope: Metadata only; argv parsing and execution planning live in runtime.ts.
5
+ */
6
+ export const LAUNCH_SCOPED_FLAG_DEFINITIONS = [
7
+ {
8
+ flag: "--auto-connect",
9
+ reason: "attaches to an already-running browser at launch time instead of reusing an existing named session",
10
+ },
11
+ {
12
+ flag: "--cdp",
13
+ reason: "selects the browser/CDP endpoint used when an upstream session is launched",
14
+ },
15
+ {
16
+ flag: "--enable",
17
+ reason: "selects built-in page init scripts before the upstream browser session is launched",
18
+ },
19
+ {
20
+ flag: "--executable-path",
21
+ reason: "selects the browser executable used for the upstream launch",
22
+ },
23
+ {
24
+ flag: "--init-script",
25
+ reason: "registers page init scripts before the upstream browser session is launched",
26
+ },
27
+ {
28
+ flag: "--device",
29
+ reason: "selects the provider device for the upstream launch",
30
+ },
31
+ {
32
+ flag: "--profile",
33
+ reason: "selects Chrome profile state for the upstream launch",
34
+ },
35
+ {
36
+ flag: "--provider",
37
+ reason: "selects the upstream browser provider for the launch",
38
+ },
39
+ {
40
+ flag: "-p",
41
+ reason: "selects the upstream browser provider for the launch",
42
+ },
43
+ {
44
+ flag: "--session-name",
45
+ reason: "selects upstream saved auth/session state for the launch",
46
+ },
47
+ {
48
+ flag: "--state",
49
+ reason: "loads persisted upstream browser/auth state at launch time",
50
+ },
51
+ ];
52
+ export const LAUNCH_SCOPED_FLAGS = LAUNCH_SCOPED_FLAG_DEFINITIONS.map((definition) => definition.flag);
53
+ export const LAUNCH_SCOPED_FLAG_LABEL = LAUNCH_SCOPED_FLAGS.join(", ");
54
+ /**
55
+ * The subset of launch-scoped flags that can restore browser/auth state with pre-existing tabs
56
+ * and are plausible wrong-active-tab sources after a fresh launch. These trigger post-open
57
+ * tab-correction (the `tab list` + re-select cycle).
58
+ */
59
+ export const LAUNCH_SCOPED_TAB_CORRECTION_FLAGS = new Set(["--profile", "--session-name", "--state"]);
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Purpose: Keep wrapper-side navigation policy parsing and evaluation small and explicit.
3
+ * Responsibilities: Parse allowed-domain argv values and detect final-page host escapes.
4
+ * Scope: Wrapper diagnostics only; upstream remains responsible for browser-time enforcement.
5
+ */
6
+ function normalizeDomainEntry(value) {
7
+ let candidate = value.trim().toLowerCase();
8
+ if (!candidate)
9
+ return undefined;
10
+ try {
11
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(candidate)) {
12
+ candidate = new URL(candidate).hostname;
13
+ }
14
+ }
15
+ catch {
16
+ return undefined;
17
+ }
18
+ candidate = candidate.replace(/^\*\./, "").replace(/\.$/, "");
19
+ if (candidate.includes("/"))
20
+ candidate = candidate.split("/")[0] ?? "";
21
+ if (candidate.includes(":"))
22
+ candidate = candidate.split(":")[0] ?? "";
23
+ return candidate.length > 0 ? candidate : undefined;
24
+ }
25
+ function splitAllowedDomainsValue(value) {
26
+ return value.split(/[,\s]+/).map((entry) => entry.trim()).filter(Boolean);
27
+ }
28
+ export function parseAllowedDomainsPolicyFromArgs(args) {
29
+ const domains = [];
30
+ for (let index = 0; index < args.length; index += 1) {
31
+ const arg = args[index];
32
+ if (arg === "--allowed-domains") {
33
+ const value = args[index + 1];
34
+ if (value && !value.startsWith("-")) {
35
+ domains.push(...splitAllowedDomainsValue(value));
36
+ index += 1;
37
+ }
38
+ continue;
39
+ }
40
+ if (arg?.startsWith("--allowed-domains=")) {
41
+ domains.push(...splitAllowedDomainsValue(arg.slice("--allowed-domains=".length)));
42
+ }
43
+ }
44
+ const allowedDomains = [...new Set(domains.flatMap((domain) => {
45
+ const normalized = normalizeDomainEntry(domain);
46
+ return normalized ? [normalized] : [];
47
+ }))];
48
+ if (allowedDomains.length === 0)
49
+ return undefined;
50
+ return { allowedDomains, display: allowedDomains.join(", ") };
51
+ }
52
+ function normalizeObservedHost(url) {
53
+ try {
54
+ const parsed = new URL(url);
55
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
56
+ return undefined;
57
+ return parsed.hostname.toLowerCase().replace(/\.$/, "");
58
+ }
59
+ catch {
60
+ return undefined;
61
+ }
62
+ }
63
+ export function isHostAllowedByDomains(host, allowedDomains) {
64
+ const normalizedHost = host.toLowerCase().replace(/\.$/, "");
65
+ return allowedDomains.some((domain) => normalizedHost === domain || normalizedHost.endsWith(`.${domain}`));
66
+ }
67
+ export function getAllowedDomainsViolation(options) {
68
+ if (!options.policy || !options.url)
69
+ return undefined;
70
+ const observedHost = normalizeObservedHost(options.url);
71
+ if (!observedHost)
72
+ return undefined;
73
+ if (isHostAllowedByDomains(observedHost, options.policy.allowedDomains))
74
+ return undefined;
75
+ const summary = `Navigation policy blocked: --allowed-domains ${options.policy.display} does not allow ${observedHost} (${options.url}).`;
76
+ return {
77
+ allowedDomains: options.policy.allowedDomains,
78
+ allowedDisplay: options.policy.display,
79
+ observedHost,
80
+ observedUrl: options.url,
81
+ summary,
82
+ };
83
+ }
@@ -0,0 +1,62 @@
1
+ function validateUserBatchStep(step, index) {
2
+ if (!Array.isArray(step)) {
3
+ return {
4
+ error: `agent_browser batch stdin step ${index} must be a non-empty array of string command tokens.`,
5
+ ok: false,
6
+ };
7
+ }
8
+ if (step.length === 0) {
9
+ return {
10
+ error: `agent_browser batch stdin step ${index} must not be empty.`,
11
+ ok: false,
12
+ };
13
+ }
14
+ const invalidTokenIndex = step.findIndex((token) => typeof token !== "string");
15
+ if (invalidTokenIndex !== -1) {
16
+ return {
17
+ error: `agent_browser batch stdin step ${index} token ${invalidTokenIndex} must be a string.`,
18
+ ok: false,
19
+ };
20
+ }
21
+ return { ok: true, step: step };
22
+ }
23
+ export function parseBatchStdinJsonArray(stdin) {
24
+ if (stdin === undefined) {
25
+ return { steps: [] };
26
+ }
27
+ try {
28
+ const parsed = JSON.parse(stdin);
29
+ if (!Array.isArray(parsed)) {
30
+ return { error: "agent_browser batch stdin must be a JSON array of command steps." };
31
+ }
32
+ return { steps: parsed };
33
+ }
34
+ catch (error) {
35
+ const message = error instanceof Error ? error.message : String(error);
36
+ return { error: `agent_browser batch stdin could not be parsed as JSON: ${message}` };
37
+ }
38
+ }
39
+ export function parseUserBatchStdin(stdin) {
40
+ const parsed = parseBatchStdinJsonArray(stdin);
41
+ if (parsed.error || parsed.steps === undefined) {
42
+ return parsed.error ? { error: parsed.error } : { steps: [] };
43
+ }
44
+ const steps = [];
45
+ for (const [index, rawStep] of parsed.steps.entries()) {
46
+ const validated = validateUserBatchStep(rawStep, index);
47
+ if (!validated.ok) {
48
+ return { error: validated.error };
49
+ }
50
+ steps.push(validated.step);
51
+ }
52
+ return { steps };
53
+ }
54
+ export function parseValidBatchStepEntries(stdin) {
55
+ const parsed = parseBatchStdinJsonArray(stdin);
56
+ if (parsed.error || parsed.steps === undefined)
57
+ return [];
58
+ return parsed.steps.flatMap((step, index) => {
59
+ const validated = validateUserBatchStep(step, index);
60
+ return validated.ok ? [{ index, step: validated.step }] : [];
61
+ });
62
+ }
@@ -0,0 +1,39 @@
1
+ import { extname, isAbsolute } from "node:path";
2
+ const SCREENSHOT_VALUE_FLAGS = new Set(["--screenshot-dir", "--screenshot-format", "--screenshot-quality"]);
3
+ const SCREENSHOT_IMAGE_EXTENSIONS = new Set([".jpeg", ".jpg", ".png", ".webp"]);
4
+ function isImagePathToken(token) {
5
+ const extension = extname(token).toLowerCase();
6
+ return SCREENSHOT_IMAGE_EXTENSIONS.has(extension);
7
+ }
8
+ export function getScreenshotPathTokenIndex(commandTokens) {
9
+ if (commandTokens[0] !== "screenshot") {
10
+ return undefined;
11
+ }
12
+ const positionalIndices = [];
13
+ for (let index = 1; index < commandTokens.length; index += 1) {
14
+ const token = commandTokens[index];
15
+ if (token === "--") {
16
+ for (let positionalIndex = index + 1; positionalIndex < commandTokens.length; positionalIndex += 1) {
17
+ positionalIndices.push(positionalIndex);
18
+ }
19
+ break;
20
+ }
21
+ if (token.startsWith("-")) {
22
+ const normalizedToken = token.split("=", 1)[0] ?? token;
23
+ if (SCREENSHOT_VALUE_FLAGS.has(normalizedToken) && !token.includes("=")) {
24
+ index += 1;
25
+ }
26
+ continue;
27
+ }
28
+ positionalIndices.push(index);
29
+ }
30
+ if (positionalIndices.length === 0) {
31
+ return undefined;
32
+ }
33
+ const candidateIndex = positionalIndices[positionalIndices.length - 1];
34
+ const candidate = commandTokens[candidateIndex];
35
+ if (positionalIndices.length >= 2 || isImagePathToken(candidate) || isAbsolute(candidate) || candidate.startsWith("./") || candidate.startsWith("../")) {
36
+ return candidateIndex;
37
+ }
38
+ return undefined;
39
+ }