pi-agent-browser-native 0.2.48 → 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 +17 -0
  2. package/README.md +16 -6
  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/RELEASE.md +22 -11
  95. package/docs/SUPPORT_MATRIX.md +4 -3
  96. package/package.json +9 -5
  97. package/scripts/config.mjs +8 -2
  98. package/scripts/doctor.mjs +8 -7
  99. package/extensions/agent-browser/index.ts +0 -961
  100. package/extensions/agent-browser/lib/argv-descriptor.ts +0 -90
  101. package/extensions/agent-browser/lib/argv-grammar.ts +0 -128
  102. package/extensions/agent-browser/lib/bash-guard.ts +0 -205
  103. package/extensions/agent-browser/lib/command-policy.ts +0 -71
  104. package/extensions/agent-browser/lib/command-taxonomy.ts +0 -336
  105. package/extensions/agent-browser/lib/config-policy.js +0 -690
  106. package/extensions/agent-browser/lib/config.ts +0 -211
  107. package/extensions/agent-browser/lib/electron/cdp.ts +0 -69
  108. package/extensions/agent-browser/lib/electron/cleanup.ts +0 -235
  109. package/extensions/agent-browser/lib/electron/discovery.ts +0 -710
  110. package/extensions/agent-browser/lib/electron/launch.ts +0 -499
  111. package/extensions/agent-browser/lib/executable-path.ts +0 -19
  112. package/extensions/agent-browser/lib/fs-utils.ts +0 -18
  113. package/extensions/agent-browser/lib/input-modes/electron.ts +0 -170
  114. package/extensions/agent-browser/lib/input-modes/job.ts +0 -527
  115. package/extensions/agent-browser/lib/input-modes/lookups.ts +0 -447
  116. package/extensions/agent-browser/lib/input-modes/params.ts +0 -205
  117. package/extensions/agent-browser/lib/input-modes/semantic-action.ts +0 -127
  118. package/extensions/agent-browser/lib/input-modes/shared.ts +0 -46
  119. package/extensions/agent-browser/lib/input-modes/types.ts +0 -225
  120. package/extensions/agent-browser/lib/input-modes.ts +0 -45
  121. package/extensions/agent-browser/lib/json-schema.ts +0 -73
  122. package/extensions/agent-browser/lib/launch-scoped-flags.ts +0 -67
  123. package/extensions/agent-browser/lib/navigation-policy.ts +0 -95
  124. package/extensions/agent-browser/lib/orchestration/batch-stdin.ts +0 -65
  125. package/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.ts +0 -44
  126. package/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.ts +0 -280
  127. package/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.ts +0 -914
  128. package/extensions/agent-browser/lib/orchestration/browser-run/final-result.ts +0 -521
  129. package/extensions/agent-browser/lib/orchestration/browser-run/index.ts +0 -53
  130. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/direct-anchor-download.ts +0 -158
  131. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.ts +0 -116
  132. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.ts +0 -147
  133. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.ts +0 -183
  134. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.ts +0 -58
  135. package/extensions/agent-browser/lib/orchestration/browser-run/prepare.ts +0 -847
  136. package/extensions/agent-browser/lib/orchestration/browser-run/process-output.ts +0 -559
  137. package/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.ts +0 -47
  138. package/extensions/agent-browser/lib/orchestration/browser-run/session-artifacts.ts +0 -8
  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 -565
  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 -267
  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 -728
  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
+ }