pi-agent-browser-native 0.2.48 → 0.2.50

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 (189) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +21 -11
  3. package/dist/extensions/agent-browser/index.js +808 -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 +669 -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 +363 -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 +956 -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 +855 -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 +5 -5
  95. package/docs/COMMAND_REFERENCE.md +4 -4
  96. package/docs/RELEASE.md +22 -11
  97. package/docs/REQUIREMENTS.md +1 -1
  98. package/docs/SUPPORT_MATRIX.md +5 -4
  99. package/docs/TOOL_CONTRACT.md +1 -1
  100. package/package.json +9 -5
  101. package/scripts/config.mjs +14 -20
  102. package/scripts/doctor.mjs +8 -7
  103. package/extensions/agent-browser/index.ts +0 -961
  104. package/extensions/agent-browser/lib/argv-descriptor.ts +0 -90
  105. package/extensions/agent-browser/lib/argv-grammar.ts +0 -128
  106. package/extensions/agent-browser/lib/bash-guard.ts +0 -205
  107. package/extensions/agent-browser/lib/command-policy.ts +0 -71
  108. package/extensions/agent-browser/lib/command-taxonomy.ts +0 -336
  109. package/extensions/agent-browser/lib/config-policy.js +0 -690
  110. package/extensions/agent-browser/lib/config.ts +0 -211
  111. package/extensions/agent-browser/lib/electron/cdp.ts +0 -69
  112. package/extensions/agent-browser/lib/electron/cleanup.ts +0 -235
  113. package/extensions/agent-browser/lib/electron/discovery.ts +0 -710
  114. package/extensions/agent-browser/lib/electron/launch.ts +0 -499
  115. package/extensions/agent-browser/lib/executable-path.ts +0 -19
  116. package/extensions/agent-browser/lib/fs-utils.ts +0 -18
  117. package/extensions/agent-browser/lib/input-modes/electron.ts +0 -170
  118. package/extensions/agent-browser/lib/input-modes/job.ts +0 -527
  119. package/extensions/agent-browser/lib/input-modes/lookups.ts +0 -447
  120. package/extensions/agent-browser/lib/input-modes/params.ts +0 -205
  121. package/extensions/agent-browser/lib/input-modes/semantic-action.ts +0 -127
  122. package/extensions/agent-browser/lib/input-modes/shared.ts +0 -46
  123. package/extensions/agent-browser/lib/input-modes/types.ts +0 -225
  124. package/extensions/agent-browser/lib/input-modes.ts +0 -45
  125. package/extensions/agent-browser/lib/json-schema.ts +0 -73
  126. package/extensions/agent-browser/lib/launch-scoped-flags.ts +0 -67
  127. package/extensions/agent-browser/lib/navigation-policy.ts +0 -95
  128. package/extensions/agent-browser/lib/orchestration/batch-stdin.ts +0 -65
  129. package/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.ts +0 -44
  130. package/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.ts +0 -280
  131. package/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.ts +0 -914
  132. package/extensions/agent-browser/lib/orchestration/browser-run/final-result.ts +0 -521
  133. package/extensions/agent-browser/lib/orchestration/browser-run/index.ts +0 -53
  134. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/direct-anchor-download.ts +0 -158
  135. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.ts +0 -116
  136. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.ts +0 -147
  137. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.ts +0 -183
  138. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.ts +0 -58
  139. package/extensions/agent-browser/lib/orchestration/browser-run/prepare.ts +0 -847
  140. package/extensions/agent-browser/lib/orchestration/browser-run/process-output.ts +0 -559
  141. package/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.ts +0 -47
  142. package/extensions/agent-browser/lib/orchestration/browser-run/session-artifacts.ts +0 -8
  143. package/extensions/agent-browser/lib/orchestration/browser-run/session-state.ts +0 -868
  144. package/extensions/agent-browser/lib/orchestration/browser-run/types.ts +0 -565
  145. package/extensions/agent-browser/lib/orchestration/electron-host/index.ts +0 -855
  146. package/extensions/agent-browser/lib/orchestration/input-plan.ts +0 -375
  147. package/extensions/agent-browser/lib/orchestration/output-file.ts +0 -86
  148. package/extensions/agent-browser/lib/pi-tool-rendering.ts +0 -267
  149. package/extensions/agent-browser/lib/playbook.ts +0 -142
  150. package/extensions/agent-browser/lib/process.ts +0 -516
  151. package/extensions/agent-browser/lib/prompt-policy.ts +0 -105
  152. package/extensions/agent-browser/lib/results/action-recommendations.ts +0 -264
  153. package/extensions/agent-browser/lib/results/artifact-manifest.ts +0 -111
  154. package/extensions/agent-browser/lib/results/categories.ts +0 -106
  155. package/extensions/agent-browser/lib/results/confirmation.ts +0 -76
  156. package/extensions/agent-browser/lib/results/contracts.ts +0 -241
  157. package/extensions/agent-browser/lib/results/editable-ref-evidence.ts +0 -72
  158. package/extensions/agent-browser/lib/results/envelope.ts +0 -195
  159. package/extensions/agent-browser/lib/results/network-routes.ts +0 -83
  160. package/extensions/agent-browser/lib/results/network.ts +0 -78
  161. package/extensions/agent-browser/lib/results/next-actions.ts +0 -117
  162. package/extensions/agent-browser/lib/results/presentation/artifacts.ts +0 -588
  163. package/extensions/agent-browser/lib/results/presentation/batch.ts +0 -450
  164. package/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.ts +0 -67
  165. package/extensions/agent-browser/lib/results/presentation/common.ts +0 -53
  166. package/extensions/agent-browser/lib/results/presentation/content.ts +0 -36
  167. package/extensions/agent-browser/lib/results/presentation/diagnostics.ts +0 -923
  168. package/extensions/agent-browser/lib/results/presentation/errors.ts +0 -227
  169. package/extensions/agent-browser/lib/results/presentation/large-output.ts +0 -182
  170. package/extensions/agent-browser/lib/results/presentation/navigation.ts +0 -184
  171. package/extensions/agent-browser/lib/results/presentation/registry.ts +0 -242
  172. package/extensions/agent-browser/lib/results/presentation/semantic-action.ts +0 -131
  173. package/extensions/agent-browser/lib/results/presentation/skills.ts +0 -143
  174. package/extensions/agent-browser/lib/results/presentation.ts +0 -257
  175. package/extensions/agent-browser/lib/results/recovery-actions.ts +0 -139
  176. package/extensions/agent-browser/lib/results/recovery-next-actions.ts +0 -71
  177. package/extensions/agent-browser/lib/results/selector-recovery.ts +0 -320
  178. package/extensions/agent-browser/lib/results/snapshot-high-value-controls.ts +0 -273
  179. package/extensions/agent-browser/lib/results/snapshot-refs.ts +0 -100
  180. package/extensions/agent-browser/lib/results/snapshot-segments.ts +0 -366
  181. package/extensions/agent-browser/lib/results/snapshot-spill.ts +0 -63
  182. package/extensions/agent-browser/lib/results/snapshot.ts +0 -329
  183. package/extensions/agent-browser/lib/results/text.ts +0 -40
  184. package/extensions/agent-browser/lib/runtime.ts +0 -988
  185. package/extensions/agent-browser/lib/session-page-state.ts +0 -512
  186. package/extensions/agent-browser/lib/string-enum-schema.ts +0 -20
  187. package/extensions/agent-browser/lib/temp.ts +0 -577
  188. package/extensions/agent-browser/lib/web-search.ts +0 -728
  189. /package/{extensions/agent-browser/lib/orchestration/browser-run.ts → dist/extensions/agent-browser/lib/orchestration/browser-run.js} +0 -0
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Purpose: Parse raw agent-browser argv once into a stable command descriptor for planners and policy.
3
+ * Responsibilities: Own command-token extraction, command/subcommand identification, and descriptor construction.
4
+ * Scope: Pure argv parsing; runtime planning and session policy consume descriptors instead of re-parsing tokens.
5
+ */
6
+ import { GLOBAL_BOOLEAN_FLAGS_WITH_OPTIONAL_VALUES, VALUE_FLAGS } from "./argv-grammar.js";
7
+ import { isOpenNavigationCommand } from "./command-taxonomy.js";
8
+ function isBooleanLiteral(token) {
9
+ const normalized = token?.trim().toLowerCase();
10
+ return normalized === "true" || normalized === "false";
11
+ }
12
+ export function findCommandStartIndex(args) {
13
+ for (let index = 0; index < args.length; index += 1) {
14
+ const token = args[index];
15
+ if (token.startsWith("--session=")) {
16
+ continue;
17
+ }
18
+ if (token.startsWith("-")) {
19
+ const normalizedToken = token.split("=", 1)[0] ?? token;
20
+ if (VALUE_FLAGS.has(normalizedToken) && !token.includes("=")) {
21
+ index += 1;
22
+ }
23
+ else if (GLOBAL_BOOLEAN_FLAGS_WITH_OPTIONAL_VALUES.has(normalizedToken) &&
24
+ !token.includes("=") &&
25
+ isBooleanLiteral(args[index + 1])) {
26
+ index += 1;
27
+ }
28
+ continue;
29
+ }
30
+ return index;
31
+ }
32
+ return undefined;
33
+ }
34
+ export function extractCommandTokens(args) {
35
+ const commandStartIndex = findCommandStartIndex(args);
36
+ return commandStartIndex === undefined ? [] : args.slice(commandStartIndex);
37
+ }
38
+ function getOpenCommandTarget(commandTokens) {
39
+ for (let index = 1; index < commandTokens.length; index += 1) {
40
+ const token = commandTokens[index];
41
+ if (token === "--init-script" || token === "--enable") {
42
+ index += 1;
43
+ continue;
44
+ }
45
+ if (token.startsWith("--init-script=") || token.startsWith("--enable=")) {
46
+ continue;
47
+ }
48
+ if (token.startsWith("-")) {
49
+ continue;
50
+ }
51
+ return token;
52
+ }
53
+ return undefined;
54
+ }
55
+ export function parseCommandInfoFromTokens(commandTokens) {
56
+ const command = commandTokens[0];
57
+ return {
58
+ command,
59
+ subcommand: isOpenNavigationCommand(command) ? getOpenCommandTarget(commandTokens) : commandTokens[1],
60
+ };
61
+ }
62
+ export function parseCommandInfo(args) {
63
+ return parseCommandInfoFromTokens(extractCommandTokens(args));
64
+ }
65
+ export function parseArgvDescriptor(args) {
66
+ const commandTokens = extractCommandTokens(args);
67
+ return {
68
+ commandInfo: parseCommandInfoFromTokens(commandTokens),
69
+ commandTokens,
70
+ };
71
+ }
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Purpose: Shared argv flag-shape metadata and helpers for command discovery and sessionless policy checks.
3
+ * Responsibilities: Own global/command value-flag sets and boolean/value-flag validation used during argv parsing.
4
+ * Scope: Pure token grammar; command semantics and subprocess execution live elsewhere.
5
+ */
6
+ export const GLOBAL_VALUE_FLAGS = [
7
+ "--session",
8
+ "--cdp",
9
+ "--config",
10
+ "--profile",
11
+ "--session-name",
12
+ "--proxy",
13
+ "--proxy-bypass",
14
+ "--headers",
15
+ "--executable-path",
16
+ "--extension",
17
+ "--init-script",
18
+ "--enable",
19
+ "--provider",
20
+ "-p",
21
+ "--engine",
22
+ "--state",
23
+ "--download-path",
24
+ "--screenshot-dir",
25
+ "--screenshot-format",
26
+ "--screenshot-quality",
27
+ "--color-scheme",
28
+ "--device",
29
+ "--args",
30
+ "--user-agent",
31
+ "--allowed-domains",
32
+ "--action-policy",
33
+ "--confirm-actions",
34
+ "--max-output",
35
+ "--model",
36
+ "--idle-timeout",
37
+ ];
38
+ export const COMMAND_VALUE_FLAGS = [
39
+ "--baseline",
40
+ "--body",
41
+ "--categories",
42
+ "--curl",
43
+ "--depth",
44
+ "-d",
45
+ "--domain",
46
+ "--expires",
47
+ "--filter",
48
+ "--fn",
49
+ "--label",
50
+ "--load",
51
+ "--method",
52
+ "--name",
53
+ "--older-than",
54
+ "--output",
55
+ "--path",
56
+ "--port",
57
+ "--resource-type",
58
+ "--resource-types",
59
+ "--sameSite",
60
+ "--selector",
61
+ "-s",
62
+ "--status",
63
+ "--text",
64
+ "--threshold",
65
+ "--timeout",
66
+ "--type",
67
+ "--url",
68
+ "--username",
69
+ "--password",
70
+ "--wait-until",
71
+ ];
72
+ export const VALUE_FLAGS = new Set([...GLOBAL_VALUE_FLAGS, ...COMMAND_VALUE_FLAGS]);
73
+ export const PREVALIDATED_VALUE_FLAGS = new Set(GLOBAL_VALUE_FLAGS);
74
+ export const GLOBAL_VALUE_FLAGS_ALLOWING_DASH_VALUE = new Set(["--args"]);
75
+ export const GLOBAL_BOOLEAN_FLAGS_WITH_OPTIONAL_VALUES = new Set([
76
+ "--allow-file-access",
77
+ "--annotate",
78
+ "--auto-connect",
79
+ "--confirm-interactive",
80
+ "--content-boundaries",
81
+ "--debug",
82
+ "--headed",
83
+ "--ignore-https-errors",
84
+ "--json",
85
+ "--no-auto-dialog",
86
+ "--quiet",
87
+ "-q",
88
+ "--verbose",
89
+ "-v",
90
+ ]);
91
+ export function getFlagName(token) {
92
+ return token.split("=", 1)[0] ?? token;
93
+ }
94
+ export function isNonFlagToken(token) {
95
+ return typeof token === "string" && !token.startsWith("-");
96
+ }
97
+ export function hasOnlyBooleanFlags(tokens, allowedFlags) {
98
+ return tokens.every((token) => token.startsWith("-") && allowedFlags.has(getFlagName(token)));
99
+ }
100
+ export function hasOnlyOptionFlags(tokens, allowedBooleanFlags, allowedValueFlags) {
101
+ for (let index = 0; index < tokens.length; index += 1) {
102
+ const token = tokens[index];
103
+ if (!token.startsWith("-"))
104
+ return false;
105
+ const flagName = getFlagName(token);
106
+ if (allowedBooleanFlags.has(flagName))
107
+ continue;
108
+ if (!allowedValueFlags.has(flagName))
109
+ return false;
110
+ if (token.includes("="))
111
+ continue;
112
+ const value = tokens[index + 1];
113
+ if (!isNonFlagToken(value))
114
+ return false;
115
+ index += 1;
116
+ }
117
+ return true;
118
+ }
119
+ export function stripSessionlessShapeGlobalFlags(commandTokens) {
120
+ return commandTokens.filter((token) => token !== "--json");
121
+ }
@@ -0,0 +1,190 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ const DIRECT_AGENT_BROWSER_BASH_BYPASS_ENV = "PI_AGENT_BROWSER_ALLOW_DIRECT_BASH";
4
+ const DIRECT_AGENT_BROWSER_EXECUTABLE_PATTERN = /^(?:[.~]|\.\.?|\/)?(?:[^\s;&|]+\/)?agent-browser$/;
5
+ const HARMLESS_AGENT_BROWSER_INSPECTION_PATTERN = /^\s*(?:command\s+-v|which|type\s+-P)\s+agent-browser\s*$/;
6
+ const PACKAGE_NAME = "pi-agent-browser-native";
7
+ function isShellAssignmentToken(token) {
8
+ return /^[A-Za-z_][A-Za-z0-9_]*=/.test(token);
9
+ }
10
+ function stripOuterQuotes(token) {
11
+ if (token.length >= 2 && ((token.startsWith('"') && token.endsWith('"')) || (token.startsWith("'") && token.endsWith("'")))) {
12
+ return token.slice(1, -1);
13
+ }
14
+ return token;
15
+ }
16
+ function segmentLaunchesAgentBrowser(tokens) {
17
+ let index = 0;
18
+ while (index < tokens.length && isShellAssignmentToken(tokens[index])) {
19
+ index += 1;
20
+ }
21
+ if (index >= tokens.length) {
22
+ return false;
23
+ }
24
+ let executableToken = tokens[index];
25
+ if (executableToken === "env") {
26
+ index += 1;
27
+ while (index < tokens.length && isShellAssignmentToken(tokens[index])) {
28
+ index += 1;
29
+ }
30
+ executableToken = tokens[index] ?? "";
31
+ }
32
+ if (executableToken === "npx" || executableToken === "bunx") {
33
+ index += 1;
34
+ while (index < tokens.length && tokens[index].startsWith("-")) {
35
+ index += 1;
36
+ }
37
+ executableToken = tokens[index] ?? "";
38
+ }
39
+ if (executableToken === "pnpm" || executableToken === "yarn") {
40
+ index += 1;
41
+ if (tokens[index] !== "dlx") {
42
+ return false;
43
+ }
44
+ index += 1;
45
+ while (index < tokens.length && tokens[index].startsWith("-")) {
46
+ index += 1;
47
+ }
48
+ executableToken = tokens[index] ?? "";
49
+ }
50
+ return DIRECT_AGENT_BROWSER_EXECUTABLE_PATTERN.test(executableToken);
51
+ }
52
+ // Best-effort detection for common direct launches only. This is an ergonomics guard,
53
+ // not a general-purpose bash parser or security boundary.
54
+ export function looksLikeDirectAgentBrowserBash(command) {
55
+ let currentToken = "";
56
+ let quoteState;
57
+ let awaitingHeredocDelimiter;
58
+ let pendingHeredoc;
59
+ let pendingHeredocLine = "";
60
+ let segmentTokens = [];
61
+ const acceptToken = (token) => {
62
+ if (token.length === 0) {
63
+ return;
64
+ }
65
+ if (awaitingHeredocDelimiter) {
66
+ pendingHeredoc = {
67
+ delimiter: stripOuterQuotes(token),
68
+ stripTabs: awaitingHeredocDelimiter.stripTabs,
69
+ };
70
+ awaitingHeredocDelimiter = undefined;
71
+ return;
72
+ }
73
+ segmentTokens.push(token);
74
+ };
75
+ const flushToken = () => {
76
+ acceptToken(currentToken);
77
+ currentToken = "";
78
+ };
79
+ const flushSegment = () => {
80
+ const launchesAgentBrowser = segmentLaunchesAgentBrowser(segmentTokens);
81
+ segmentTokens = [];
82
+ return launchesAgentBrowser;
83
+ };
84
+ for (let index = 0; index < command.length; index += 1) {
85
+ const char = command[index];
86
+ if (pendingHeredoc) {
87
+ if (char === "\n") {
88
+ const candidate = pendingHeredoc.stripTabs ? pendingHeredocLine.replace(/^\t+/, "") : pendingHeredocLine;
89
+ if (candidate === pendingHeredoc.delimiter) {
90
+ pendingHeredoc = undefined;
91
+ }
92
+ pendingHeredocLine = "";
93
+ continue;
94
+ }
95
+ pendingHeredocLine += char;
96
+ continue;
97
+ }
98
+ if (quoteState === "single") {
99
+ currentToken += char;
100
+ if (char === "'") {
101
+ quoteState = undefined;
102
+ }
103
+ continue;
104
+ }
105
+ if (quoteState === "double") {
106
+ currentToken += char;
107
+ if (char === "\\" && index + 1 < command.length) {
108
+ currentToken += command[index + 1];
109
+ index += 1;
110
+ continue;
111
+ }
112
+ if (char === '"') {
113
+ quoteState = undefined;
114
+ }
115
+ continue;
116
+ }
117
+ if (char === "'" || char === '"') {
118
+ currentToken += char;
119
+ quoteState = char === "'" ? "single" : "double";
120
+ continue;
121
+ }
122
+ if (char === "\\" && index + 1 < command.length) {
123
+ currentToken += char;
124
+ currentToken += command[index + 1];
125
+ index += 1;
126
+ continue;
127
+ }
128
+ if (char === "\n") {
129
+ flushToken();
130
+ if (flushSegment()) {
131
+ return true;
132
+ }
133
+ continue;
134
+ }
135
+ if (/\s/.test(char)) {
136
+ flushToken();
137
+ continue;
138
+ }
139
+ const threeCharOperator = command.slice(index, index + 3);
140
+ if (threeCharOperator === "<<-") {
141
+ flushToken();
142
+ awaitingHeredocDelimiter = { stripTabs: true };
143
+ index += 2;
144
+ continue;
145
+ }
146
+ const twoCharOperator = command.slice(index, index + 2);
147
+ if (twoCharOperator === "<<") {
148
+ flushToken();
149
+ awaitingHeredocDelimiter = { stripTabs: false };
150
+ index += 1;
151
+ continue;
152
+ }
153
+ if (twoCharOperator === "&&" || twoCharOperator === "||") {
154
+ flushToken();
155
+ if (flushSegment()) {
156
+ return true;
157
+ }
158
+ index += 1;
159
+ continue;
160
+ }
161
+ if (char === "|" || char === ";" || char === "&") {
162
+ flushToken();
163
+ if (flushSegment()) {
164
+ return true;
165
+ }
166
+ continue;
167
+ }
168
+ currentToken += char;
169
+ }
170
+ flushToken();
171
+ return flushSegment();
172
+ }
173
+ export function isHarmlessAgentBrowserInspectionCommand(command) {
174
+ return HARMLESS_AGENT_BROWSER_INSPECTION_PATTERN.test(command);
175
+ }
176
+ function isTruthyEnvValue(value) {
177
+ return value === "1" || value?.toLowerCase() === "true" || value?.toLowerCase() === "yes";
178
+ }
179
+ async function isPackageDevelopmentCwd(cwd) {
180
+ try {
181
+ const packageJson = JSON.parse(await readFile(join(cwd, "package.json"), "utf8"));
182
+ return packageJson.name === PACKAGE_NAME;
183
+ }
184
+ catch {
185
+ return false;
186
+ }
187
+ }
188
+ export async function isDirectAgentBrowserBashAllowed(cwd) {
189
+ return isTruthyEnvValue(process.env[DIRECT_AGENT_BROWSER_BASH_BYPASS_ENV]) || await isPackageDevelopmentCwd(cwd);
190
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Purpose: Own upstream command-shape policies that decide whether the wrapper should allocate a managed browser session.
3
+ * Responsibilities: Keep local/sessionless command grammar out of the runtime execution planner while preserving exact upstream shapes.
4
+ * Scope: Pure argv-token policy; command discovery, subprocess execution, and presentation live in focused modules.
5
+ */
6
+ import { hasOnlyBooleanFlags, hasOnlyOptionFlags, isNonFlagToken, stripSessionlessShapeGlobalFlags } from "./argv-grammar.js";
7
+ const SESSIONLESS_AUTH_SUBCOMMANDS = new Set(["save", "list", "show", "delete", "remove"]);
8
+ const EMPTY_BOOLEAN_FLAGS = new Set();
9
+ const JSON_BOOLEAN_FLAGS = new Set(["--json"]);
10
+ const AUTH_SAVE_BOOLEAN_FLAGS = new Set(["--json", "--password-stdin"]);
11
+ const AUTH_SAVE_VALUE_FLAGS = new Set(["--password", "--password-selector", "--submit-selector", "--url", "--username", "--username-selector"]);
12
+ const DASHBOARD_SUBCOMMANDS = new Set(["start", "stop"]);
13
+ const DASHBOARD_START_VALUE_FLAGS = new Set(["--port"]);
14
+ const DOCTOR_BOOLEAN_FLAGS = new Set(["--fix", "--json", "--offline", "--quick"]);
15
+ const INSTALL_BOOLEAN_FLAGS = new Set(["--with-deps", "-d"]);
16
+ const STATE_SESSIONLESS_SUBCOMMANDS = new Set(["list", "show", "clear", "clean", "rename"]);
17
+ const STATE_CLEAN_VALUE_FLAGS = new Set(["--older-than"]);
18
+ function isSessionlessAuthCommand(commandTokens) {
19
+ const [, subcommand, target, ...rest] = commandTokens;
20
+ if (!SESSIONLESS_AUTH_SUBCOMMANDS.has(subcommand ?? ""))
21
+ return false;
22
+ if (subcommand === "list")
23
+ return target === undefined;
24
+ if (!isNonFlagToken(target))
25
+ return false;
26
+ if (subcommand === "save")
27
+ return hasOnlyOptionFlags(rest, AUTH_SAVE_BOOLEAN_FLAGS, AUTH_SAVE_VALUE_FLAGS);
28
+ return rest.length === 0;
29
+ }
30
+ function isSessionlessDashboardCommand(commandTokens) {
31
+ const [, subcommand, ...rest] = commandTokens;
32
+ if (subcommand === undefined)
33
+ return true;
34
+ if (!DASHBOARD_SUBCOMMANDS.has(subcommand))
35
+ return false;
36
+ return subcommand === "start" ? hasOnlyOptionFlags(rest, JSON_BOOLEAN_FLAGS, DASHBOARD_START_VALUE_FLAGS) : rest.length === 0;
37
+ }
38
+ function isSessionlessStateCommand(commandTokens) {
39
+ const [, subcommand, firstArg, secondArg, ...rest] = commandTokens;
40
+ if (!STATE_SESSIONLESS_SUBCOMMANDS.has(subcommand ?? ""))
41
+ return false;
42
+ if (subcommand === "list")
43
+ return firstArg === undefined;
44
+ if (subcommand === "show")
45
+ return isNonFlagToken(firstArg) && secondArg === undefined;
46
+ if (subcommand === "rename")
47
+ return isNonFlagToken(firstArg) && isNonFlagToken(secondArg) && rest.length === 0;
48
+ if (subcommand === "clean") {
49
+ const optionTokens = commandTokens.slice(2);
50
+ return optionTokens.length > 0 && hasOnlyOptionFlags(optionTokens, EMPTY_BOOLEAN_FLAGS, STATE_CLEAN_VALUE_FLAGS);
51
+ }
52
+ if (subcommand !== "clear")
53
+ return false;
54
+ if ((firstArg === "--all" || firstArg === "-a") && secondArg === undefined)
55
+ return true;
56
+ if (!isNonFlagToken(firstArg))
57
+ return false;
58
+ return secondArg === undefined || (secondArg === "--all" && rest.length === 0);
59
+ }
60
+ function isSessionlessCommand(commandTokens) {
61
+ const normalizedTokens = stripSessionlessShapeGlobalFlags(commandTokens);
62
+ const [command, subcommand] = normalizedTokens;
63
+ if (command === "skills")
64
+ return ["list", "get", "path"].includes(subcommand ?? "");
65
+ if (command === "auth")
66
+ return isSessionlessAuthCommand(normalizedTokens);
67
+ if (command === "dashboard")
68
+ return isSessionlessDashboardCommand(normalizedTokens);
69
+ if (command === "device")
70
+ return normalizedTokens.length === 2 && subcommand === "list";
71
+ if (command === "doctor")
72
+ return hasOnlyBooleanFlags(normalizedTokens.slice(1), DOCTOR_BOOLEAN_FLAGS);
73
+ if (command === "install")
74
+ return hasOnlyBooleanFlags(normalizedTokens.slice(1), INSTALL_BOOLEAN_FLAGS);
75
+ if (command === "profiles" || command === "upgrade")
76
+ return normalizedTokens.length === 1;
77
+ if (command === "session")
78
+ return normalizedTokens.length === 2 && subcommand === "list";
79
+ if (command === "state")
80
+ return isSessionlessStateCommand(normalizedTokens);
81
+ return false;
82
+ }
83
+ export function needsManagedSession(descriptor) {
84
+ return !isSessionlessCommand(descriptor.commandTokens);
85
+ }