@machina.ai/cell-cli-core 1.36.0-rc1 → 1.38.1-rc2

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 (733) hide show
  1. package/dist/docs/AFTER_MERGE_PROMPT.md +3 -10
  2. package/dist/docs/assets/theme-tokyonight-dark.png +0 -0
  3. package/dist/docs/changelogs/index.md +49 -0
  4. package/dist/docs/changelogs/latest.md +355 -458
  5. package/dist/docs/changelogs/preview.md +402 -363
  6. package/dist/docs/cli/acp-mode.md +126 -0
  7. package/dist/docs/cli/cli-reference.md +1 -1
  8. package/dist/docs/cli/notifications.md +5 -5
  9. package/dist/docs/cli/plan-mode.md +26 -10
  10. package/dist/docs/cli/sandbox.md +53 -1
  11. package/dist/docs/cli/settings.md +52 -48
  12. package/dist/docs/cli/themes.md +5 -0
  13. package/dist/docs/core/index.md +2 -2
  14. package/dist/docs/core/remote-agents.md +14 -18
  15. package/dist/docs/core/subagents.md +194 -47
  16. package/dist/docs/get-started/authentication.md +2 -2
  17. package/dist/docs/get-started/gemini-3.md +1 -1
  18. package/dist/docs/get-started/index.md +127 -1
  19. package/dist/docs/get-started/installation.md +7 -0
  20. package/dist/docs/hooks/index.md +6 -6
  21. package/dist/docs/ide-integration/index.md +99 -24
  22. package/dist/docs/index.md +0 -2
  23. package/dist/docs/redirects.json +1 -0
  24. package/dist/docs/reference/commands.md +1 -3
  25. package/dist/docs/reference/configuration.md +220 -99
  26. package/dist/docs/reference/keyboard-shortcuts.md +21 -8
  27. package/dist/docs/reference/policy-engine.md +36 -31
  28. package/dist/docs/reference/tools.md +56 -23
  29. package/dist/docs/release-confidence.md +0 -6
  30. package/dist/docs/releases.md +4 -0
  31. package/dist/docs/resources/quota-and-pricing.md +23 -9
  32. package/dist/docs/sidebar.json +11 -4
  33. package/dist/docs/tools/mcp-server.md +3 -3
  34. package/dist/docs/tools/planning.md +6 -4
  35. package/dist/docs/tools/web-fetch.md +3 -0
  36. package/dist/package.json +2 -1
  37. package/dist/src/agent/agent-session.test.js +14 -6
  38. package/dist/src/agent/agent-session.test.js.map +1 -1
  39. package/dist/src/agent/event-translator.js +2 -1
  40. package/dist/src/agent/event-translator.js.map +1 -1
  41. package/dist/src/agent/event-translator.test.js +1 -0
  42. package/dist/src/agent/event-translator.test.js.map +1 -1
  43. package/dist/src/agent/legacy-agent-session.d.ts +47 -4
  44. package/dist/src/agent/legacy-agent-session.js +38 -15
  45. package/dist/src/agent/legacy-agent-session.js.map +1 -1
  46. package/dist/src/agent/legacy-agent-session.test.js +60 -73
  47. package/dist/src/agent/legacy-agent-session.test.js.map +1 -1
  48. package/dist/src/agent/mock.js +7 -1
  49. package/dist/src/agent/mock.js.map +1 -1
  50. package/dist/src/agent/mock.test.js +1 -1
  51. package/dist/src/agent/mock.test.js.map +1 -1
  52. package/dist/src/agent/types.d.ts +34 -1
  53. package/dist/src/agents/a2a-client-manager.js +3 -3
  54. package/dist/src/agents/a2a-client-manager.js.map +1 -1
  55. package/dist/src/agents/agent-scheduler.js +6 -1
  56. package/dist/src/agents/agent-scheduler.js.map +1 -1
  57. package/dist/src/agents/agent-scheduler.test.js +38 -0
  58. package/dist/src/agents/agent-scheduler.test.js.map +1 -1
  59. package/dist/src/agents/agentLoader.d.ts +12 -12
  60. package/dist/src/agents/agentLoader.js +1 -0
  61. package/dist/src/agents/agentLoader.js.map +1 -1
  62. package/dist/src/agents/auth-provider/api-key-provider.test.js +18 -2
  63. package/dist/src/agents/auth-provider/api-key-provider.test.js.map +1 -1
  64. package/dist/src/agents/auth-provider/value-resolver.test.js +30 -0
  65. package/dist/src/agents/auth-provider/value-resolver.test.js.map +1 -1
  66. package/dist/src/agents/browser/analyzeScreenshot.js +36 -6
  67. package/dist/src/agents/browser/analyzeScreenshot.js.map +1 -1
  68. package/dist/src/agents/browser/analyzeScreenshot.test.js +35 -3
  69. package/dist/src/agents/browser/analyzeScreenshot.test.js.map +1 -1
  70. package/dist/src/agents/browser/automationOverlay.js +2 -10
  71. package/dist/src/agents/browser/automationOverlay.js.map +1 -1
  72. package/dist/src/agents/browser/browserAgentDefinition.js +10 -3
  73. package/dist/src/agents/browser/browserAgentDefinition.js.map +1 -1
  74. package/dist/src/agents/browser/browserAgentFactory.d.ts +11 -3
  75. package/dist/src/agents/browser/browserAgentFactory.js +171 -129
  76. package/dist/src/agents/browser/browserAgentFactory.js.map +1 -1
  77. package/dist/src/agents/browser/browserAgentFactory.test.js +99 -13
  78. package/dist/src/agents/browser/browserAgentFactory.test.js.map +1 -1
  79. package/dist/src/agents/browser/browserAgentInvocation.d.ts +1 -0
  80. package/dist/src/agents/browser/browserAgentInvocation.js +87 -27
  81. package/dist/src/agents/browser/browserAgentInvocation.js.map +1 -1
  82. package/dist/src/agents/browser/browserAgentInvocation.test.js +107 -7
  83. package/dist/src/agents/browser/browserAgentInvocation.test.js.map +1 -1
  84. package/dist/src/agents/browser/browserManager.d.ts +89 -8
  85. package/dist/src/agents/browser/browserManager.js +357 -74
  86. package/dist/src/agents/browser/browserManager.js.map +1 -1
  87. package/dist/src/agents/browser/browserManager.test.js +540 -19
  88. package/dist/src/agents/browser/browserManager.test.js.map +1 -1
  89. package/dist/src/agents/browser/inputBlocker.d.ts +4 -4
  90. package/dist/src/agents/browser/inputBlocker.js +8 -18
  91. package/dist/src/agents/browser/inputBlocker.js.map +1 -1
  92. package/dist/src/agents/browser/inputBlocker.test.js +31 -3
  93. package/dist/src/agents/browser/inputBlocker.test.js.map +1 -1
  94. package/dist/src/agents/browser/mcpToolWrapper.d.ts +1 -1
  95. package/dist/src/agents/browser/mcpToolWrapper.js +9 -6
  96. package/dist/src/agents/browser/mcpToolWrapper.js.map +1 -1
  97. package/dist/src/agents/browser/mcpToolWrapper.test.js +2 -2
  98. package/dist/src/agents/browser/mcpToolWrapper.test.js.map +1 -1
  99. package/dist/src/agents/browser/modelAvailability.d.ts +5 -0
  100. package/dist/src/agents/browser/modelAvailability.js +12 -0
  101. package/dist/src/agents/browser/modelAvailability.js.map +1 -1
  102. package/dist/src/agents/browser/snapshotSuperseder.d.ts +31 -0
  103. package/dist/src/agents/browser/snapshotSuperseder.js +101 -0
  104. package/dist/src/agents/browser/snapshotSuperseder.js.map +1 -0
  105. package/dist/src/agents/browser/snapshotSuperseder.test.js +158 -0
  106. package/dist/src/agents/browser/snapshotSuperseder.test.js.map +1 -0
  107. package/dist/src/agents/local-executor.d.ts +9 -0
  108. package/dist/src/agents/local-executor.js +144 -200
  109. package/dist/src/agents/local-executor.js.map +1 -1
  110. package/dist/src/agents/local-executor.test.js +500 -115
  111. package/dist/src/agents/local-executor.test.js.map +1 -1
  112. package/dist/src/agents/local-invocation.d.ts +1 -0
  113. package/dist/src/agents/local-invocation.js +19 -9
  114. package/dist/src/agents/local-invocation.js.map +1 -1
  115. package/dist/src/agents/local-invocation.test.js +24 -0
  116. package/dist/src/agents/local-invocation.test.js.map +1 -1
  117. package/dist/src/agents/memory-manager-agent.js +1 -0
  118. package/dist/src/agents/memory-manager-agent.js.map +1 -1
  119. package/dist/src/agents/memory-manager-agent.test.js +6 -0
  120. package/dist/src/agents/memory-manager-agent.test.js.map +1 -1
  121. package/dist/src/agents/registry.js +19 -11
  122. package/dist/src/agents/registry.js.map +1 -1
  123. package/dist/src/agents/registry.test.js +67 -0
  124. package/dist/src/agents/registry.test.js.map +1 -1
  125. package/dist/src/agents/skill-extraction-agent.d.ts +24 -0
  126. package/dist/src/agents/skill-extraction-agent.js +269 -0
  127. package/dist/src/agents/skill-extraction-agent.js.map +1 -0
  128. package/dist/src/agents/types.d.ts +20 -0
  129. package/dist/src/agents/types.js.map +1 -1
  130. package/dist/src/availability/policyCatalog.d.ts +2 -1
  131. package/dist/src/availability/policyCatalog.js +1 -1
  132. package/dist/src/availability/policyCatalog.js.map +1 -1
  133. package/dist/src/availability/policyHelpers.js +43 -32
  134. package/dist/src/availability/policyHelpers.js.map +1 -1
  135. package/dist/src/availability/policyHelpers.test.js +12 -1
  136. package/dist/src/availability/policyHelpers.test.js.map +1 -1
  137. package/dist/src/code_assist/admin/admin_controls.js +1 -1
  138. package/dist/src/code_assist/admin/admin_controls.js.map +1 -1
  139. package/dist/src/code_assist/experiments/flagNames.d.ts +1 -0
  140. package/dist/src/code_assist/experiments/flagNames.js +1 -0
  141. package/dist/src/code_assist/experiments/flagNames.js.map +1 -1
  142. package/dist/src/code_assist/oauth2.js +8 -3
  143. package/dist/src/code_assist/oauth2.js.map +1 -1
  144. package/dist/src/code_assist/oauth2.test.js +57 -0
  145. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  146. package/dist/src/code_assist/server.js +1 -1
  147. package/dist/src/code_assist/server.js.map +1 -1
  148. package/dist/src/code_assist/setup.js +5 -2
  149. package/dist/src/code_assist/setup.js.map +1 -1
  150. package/dist/src/code_assist/setup.test.js +27 -1
  151. package/dist/src/code_assist/setup.test.js.map +1 -1
  152. package/dist/src/code_assist/types.d.ts +80 -80
  153. package/dist/src/commands/memory.js +1 -1
  154. package/dist/src/commands/memory.js.map +1 -1
  155. package/dist/src/config/agent-loop-context.d.ts +2 -0
  156. package/dist/src/config/config.d.ts +91 -23
  157. package/dist/src/config/config.js +238 -79
  158. package/dist/src/config/config.js.map +1 -1
  159. package/dist/src/config/config.test.js +189 -15
  160. package/dist/src/config/config.test.js.map +1 -1
  161. package/dist/src/config/defaultModelConfigs.js +9 -0
  162. package/dist/src/config/defaultModelConfigs.js.map +1 -1
  163. package/dist/src/config/extensions/integrity.js +1 -1
  164. package/dist/src/config/extensions/integrity.js.map +1 -1
  165. package/dist/src/config/memory.d.ts +1 -0
  166. package/dist/src/config/memory.js +6 -0
  167. package/dist/src/config/memory.js.map +1 -1
  168. package/dist/src/config/projectRegistry.js +5 -3
  169. package/dist/src/config/projectRegistry.js.map +1 -1
  170. package/dist/src/config/scoped-config.d.ts +30 -0
  171. package/dist/src/config/scoped-config.js +69 -0
  172. package/dist/src/config/scoped-config.js.map +1 -0
  173. package/dist/src/config/scoped-config.test.d.ts +6 -0
  174. package/dist/src/config/scoped-config.test.js +161 -0
  175. package/dist/src/config/scoped-config.test.js.map +1 -0
  176. package/dist/src/config/storage.d.ts +3 -0
  177. package/dist/src/config/storage.js +9 -0
  178. package/dist/src/config/storage.js.map +1 -1
  179. package/dist/src/config/storage.test.js +10 -5
  180. package/dist/src/config/storage.test.js.map +1 -1
  181. package/dist/src/config/topicState.d.ts +21 -0
  182. package/dist/src/config/topicState.js +41 -0
  183. package/dist/src/config/topicState.js.map +1 -0
  184. package/dist/src/confirmation-bus/types.d.ts +13 -4
  185. package/dist/src/confirmation-bus/types.js +2 -0
  186. package/dist/src/confirmation-bus/types.js.map +1 -1
  187. package/dist/src/context/agentHistoryProvider.d.ts +45 -0
  188. package/dist/src/context/agentHistoryProvider.js +294 -0
  189. package/dist/src/context/agentHistoryProvider.js.map +1 -0
  190. package/dist/src/context/agentHistoryProvider.test.d.ts +6 -0
  191. package/dist/src/context/agentHistoryProvider.test.js +357 -0
  192. package/dist/src/context/agentHistoryProvider.test.js.map +1 -0
  193. package/dist/src/context/chatCompressionService.js.map +1 -0
  194. package/dist/src/context/chatCompressionService.test.js.map +1 -0
  195. package/dist/src/context/contextCompressionService.d.ts +30 -0
  196. package/dist/src/context/contextCompressionService.js +405 -0
  197. package/dist/src/context/contextCompressionService.js.map +1 -0
  198. package/dist/src/context/contextCompressionService.test.js +253 -0
  199. package/dist/src/context/contextCompressionService.test.js.map +1 -0
  200. package/dist/src/{services/contextManager.d.ts → context/memoryContextManager.d.ts} +3 -1
  201. package/dist/src/{services/contextManager.js → context/memoryContextManager.js} +20 -11
  202. package/dist/src/context/memoryContextManager.js.map +1 -0
  203. package/dist/src/{services/contextManager.test.js → context/memoryContextManager.test.js} +42 -33
  204. package/dist/src/context/memoryContextManager.test.js.map +1 -0
  205. package/dist/src/context/profiles.d.ts +7 -0
  206. package/dist/src/context/profiles.js +21 -0
  207. package/dist/src/context/profiles.js.map +1 -0
  208. package/dist/src/context/toolDistillationService.d.ts +38 -0
  209. package/dist/src/context/toolDistillationService.js +170 -0
  210. package/dist/src/context/toolDistillationService.js.map +1 -0
  211. package/dist/src/context/toolDistillationService.test.d.ts +6 -0
  212. package/dist/src/context/toolDistillationService.test.js +86 -0
  213. package/dist/src/context/toolDistillationService.test.js.map +1 -0
  214. package/dist/src/{services → context}/toolOutputMaskingService.d.ts +2 -2
  215. package/dist/src/{services → context}/toolOutputMaskingService.js +7 -7
  216. package/dist/src/context/toolOutputMaskingService.js.map +1 -0
  217. package/dist/src/context/toolOutputMaskingService.test.d.ts +6 -0
  218. package/dist/src/{services → context}/toolOutputMaskingService.test.js +4 -5
  219. package/dist/src/context/toolOutputMaskingService.test.js.map +1 -0
  220. package/dist/src/context/truncation.d.ts +26 -0
  221. package/dist/src/context/truncation.js +102 -0
  222. package/dist/src/context/truncation.js.map +1 -0
  223. package/dist/src/context/types.d.ts +36 -0
  224. package/dist/src/context/types.js +7 -0
  225. package/dist/src/context/types.js.map +1 -0
  226. package/dist/src/core/AuthenticatedContentGenerator.js +9 -1
  227. package/dist/src/core/AuthenticatedContentGenerator.js.map +1 -1
  228. package/dist/src/core/baseLlmClient.js +1 -1
  229. package/dist/src/core/baseLlmClient.js.map +1 -1
  230. package/dist/src/core/baseLlmClient.test.js +1 -0
  231. package/dist/src/core/baseLlmClient.test.js.map +1 -1
  232. package/dist/src/core/client.d.ts +3 -1
  233. package/dist/src/core/client.js +24 -14
  234. package/dist/src/core/client.js.map +1 -1
  235. package/dist/src/core/client.test.js +36 -40
  236. package/dist/src/core/client.test.js.map +1 -1
  237. package/dist/src/core/contentGenerator.d.ts +0 -1
  238. package/dist/src/core/contentGenerator.js +2 -28
  239. package/dist/src/core/contentGenerator.js.map +1 -1
  240. package/dist/src/core/contentGenerator.test.js +1 -101
  241. package/dist/src/core/contentGenerator.test.js.map +1 -1
  242. package/dist/src/core/geminiChat.js +12 -5
  243. package/dist/src/core/geminiChat.js.map +1 -1
  244. package/dist/src/core/geminiChat.test.js +72 -18
  245. package/dist/src/core/geminiChat.test.js.map +1 -1
  246. package/dist/src/core/geminiChat_network_retry.test.js +1 -0
  247. package/dist/src/core/geminiChat_network_retry.test.js.map +1 -1
  248. package/dist/src/core/logger.js +4 -4
  249. package/dist/src/core/logger.js.map +1 -1
  250. package/dist/src/core/logger.test.js +1 -1
  251. package/dist/src/core/logger.test.js.map +1 -1
  252. package/dist/src/core/loggingContentGenerator.js +1 -1
  253. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  254. package/dist/src/core/prompts-substitution.test.js +5 -0
  255. package/dist/src/core/prompts-substitution.test.js.map +1 -1
  256. package/dist/src/core/prompts.test.js +3 -0
  257. package/dist/src/core/prompts.test.js.map +1 -1
  258. package/dist/src/generated/git-commit.d.ts +2 -2
  259. package/dist/src/generated/git-commit.js +2 -2
  260. package/dist/src/hooks/hookEventHandler.js +8 -0
  261. package/dist/src/hooks/hookEventHandler.js.map +1 -1
  262. package/dist/src/hooks/hookRunner.js +9 -5
  263. package/dist/src/hooks/hookRunner.js.map +1 -1
  264. package/dist/src/hooks/hookRunner.test.js +20 -3
  265. package/dist/src/hooks/hookRunner.test.js.map +1 -1
  266. package/dist/src/hooks/hookSystem.d.ts +2 -0
  267. package/dist/src/hooks/hookSystem.js +1 -0
  268. package/dist/src/hooks/hookSystem.js.map +1 -1
  269. package/dist/src/hooks/hookTranslator.js +20 -13
  270. package/dist/src/hooks/hookTranslator.js.map +1 -1
  271. package/dist/src/hooks/hookTranslator.test.js +36 -0
  272. package/dist/src/hooks/hookTranslator.test.js.map +1 -1
  273. package/dist/src/hooks/types.d.ts +2 -0
  274. package/dist/src/ide/ide-client.js +3 -3
  275. package/dist/src/ide/ide-client.js.map +1 -1
  276. package/dist/src/ide/ide-connection-utils.js +1 -1
  277. package/dist/src/ide/ide-connection-utils.js.map +1 -1
  278. package/dist/src/ide/ide-installer.js +5 -4
  279. package/dist/src/ide/ide-installer.js.map +1 -1
  280. package/dist/src/ide/process-utils.js +3 -3
  281. package/dist/src/ide/process-utils.js.map +1 -1
  282. package/dist/src/index.d.ts +10 -3
  283. package/dist/src/index.js +13 -5
  284. package/dist/src/index.js.map +1 -1
  285. package/dist/src/mcp/mcpLauncher.js +1 -1
  286. package/dist/src/output/json-formatter.js +2 -1
  287. package/dist/src/output/json-formatter.js.map +1 -1
  288. package/dist/src/policy/config.d.ts +1 -1
  289. package/dist/src/policy/config.js +61 -24
  290. package/dist/src/policy/config.js.map +1 -1
  291. package/dist/src/policy/config.test.js +21 -20
  292. package/dist/src/policy/config.test.js.map +1 -1
  293. package/dist/src/policy/persistence.test.js +42 -0
  294. package/dist/src/policy/persistence.test.js.map +1 -1
  295. package/dist/src/policy/policies/discovered.toml +7 -0
  296. package/dist/src/policy/policies/memory-manager.toml +11 -1
  297. package/dist/src/policy/policies/non-interactive.toml +7 -0
  298. package/dist/src/policy/policies/plan.toml +36 -2
  299. package/dist/src/policy/policies/read-only.toml +12 -0
  300. package/dist/src/policy/policies/sandbox-default.toml +4 -4
  301. package/dist/src/policy/policies/write.toml +21 -0
  302. package/dist/src/policy/policies/yolo.toml +1 -1
  303. package/dist/src/policy/policy-engine.d.ts +2 -4
  304. package/dist/src/policy/policy-engine.js +47 -37
  305. package/dist/src/policy/policy-engine.js.map +1 -1
  306. package/dist/src/policy/policy-engine.test.js +236 -30
  307. package/dist/src/policy/policy-engine.test.js.map +1 -1
  308. package/dist/src/policy/sandboxPolicyManager.d.ts +26 -1
  309. package/dist/src/policy/sandboxPolicyManager.js +41 -12
  310. package/dist/src/policy/sandboxPolicyManager.js.map +1 -1
  311. package/dist/src/policy/sandboxPolicyManager.test.d.ts +6 -0
  312. package/dist/src/policy/sandboxPolicyManager.test.js +61 -0
  313. package/dist/src/policy/sandboxPolicyManager.test.js.map +1 -0
  314. package/dist/src/policy/topic-policy.test.d.ts +6 -0
  315. package/dist/src/policy/topic-policy.test.js +48 -0
  316. package/dist/src/policy/topic-policy.test.js.map +1 -0
  317. package/dist/src/policy/types.d.ts +9 -6
  318. package/dist/src/policy/types.js +11 -0
  319. package/dist/src/policy/types.js.map +1 -1
  320. package/dist/src/policy/workspace-policy.test.js +18 -15
  321. package/dist/src/policy/workspace-policy.test.js.map +1 -1
  322. package/dist/src/prompts/promptProvider.js +20 -4
  323. package/dist/src/prompts/promptProvider.js.map +1 -1
  324. package/dist/src/prompts/promptProvider.test.js +84 -1
  325. package/dist/src/prompts/promptProvider.test.js.map +1 -1
  326. package/dist/src/prompts/snippets-memory-manager.test.js +1 -1
  327. package/dist/src/prompts/snippets-memory-manager.test.js.map +1 -1
  328. package/dist/src/prompts/snippets.d.ts +3 -4
  329. package/dist/src/prompts/snippets.js +37 -52
  330. package/dist/src/prompts/snippets.js.map +1 -1
  331. package/dist/src/prompts/snippets.legacy.d.ts +6 -4
  332. package/dist/src/prompts/snippets.legacy.js +36 -7
  333. package/dist/src/prompts/snippets.legacy.js.map +1 -1
  334. package/dist/src/prompts/utils.test.js +7 -5
  335. package/dist/src/prompts/utils.test.js.map +1 -1
  336. package/dist/src/safety/built-in.js +1 -1
  337. package/dist/src/safety/built-in.js.map +1 -1
  338. package/dist/src/sandbox/linux/LinuxSandboxManager.d.ts +11 -1
  339. package/dist/src/sandbox/linux/LinuxSandboxManager.js +131 -41
  340. package/dist/src/sandbox/linux/LinuxSandboxManager.js.map +1 -1
  341. package/dist/src/sandbox/linux/LinuxSandboxManager.test.js +82 -139
  342. package/dist/src/sandbox/linux/LinuxSandboxManager.test.js.map +1 -1
  343. package/dist/src/sandbox/linux/bwrapArgsBuilder.d.ts +24 -0
  344. package/dist/src/sandbox/linux/bwrapArgsBuilder.js +200 -0
  345. package/dist/src/sandbox/linux/bwrapArgsBuilder.js.map +1 -0
  346. package/dist/src/sandbox/linux/bwrapArgsBuilder.test.d.ts +6 -0
  347. package/dist/src/sandbox/linux/bwrapArgsBuilder.test.js +247 -0
  348. package/dist/src/sandbox/linux/bwrapArgsBuilder.test.js.map +1 -0
  349. package/dist/src/sandbox/macos/MacOsSandboxManager.d.ts +10 -22
  350. package/dist/src/sandbox/macos/MacOsSandboxManager.js +67 -59
  351. package/dist/src/sandbox/macos/MacOsSandboxManager.js.map +1 -1
  352. package/dist/src/sandbox/macos/MacOsSandboxManager.test.js +168 -103
  353. package/dist/src/sandbox/macos/MacOsSandboxManager.test.js.map +1 -1
  354. package/dist/src/sandbox/macos/baseProfile.d.ts +1 -1
  355. package/dist/src/sandbox/macos/baseProfile.js +26 -8
  356. package/dist/src/sandbox/macos/baseProfile.js.map +1 -1
  357. package/dist/src/sandbox/macos/seatbeltArgsBuilder.d.ts +10 -10
  358. package/dist/src/sandbox/macos/seatbeltArgsBuilder.js +81 -93
  359. package/dist/src/sandbox/macos/seatbeltArgsBuilder.js.map +1 -1
  360. package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.js +136 -99
  361. package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.js.map +1 -1
  362. package/dist/src/sandbox/{macos → utils}/commandSafety.d.ts +11 -0
  363. package/dist/src/sandbox/{macos → utils}/commandSafety.js +47 -14
  364. package/dist/src/sandbox/utils/commandSafety.js.map +1 -0
  365. package/dist/src/sandbox/utils/commandUtils.d.ts +9 -0
  366. package/dist/src/sandbox/utils/commandUtils.js +57 -0
  367. package/dist/src/sandbox/utils/commandUtils.js.map +1 -0
  368. package/dist/src/sandbox/utils/fsUtils.d.ts +11 -0
  369. package/dist/src/sandbox/utils/fsUtils.js +84 -0
  370. package/dist/src/sandbox/utils/fsUtils.js.map +1 -0
  371. package/dist/src/sandbox/utils/fsUtils.test.d.ts +6 -0
  372. package/dist/src/sandbox/utils/fsUtils.test.js +43 -0
  373. package/dist/src/sandbox/utils/fsUtils.test.js.map +1 -0
  374. package/dist/src/sandbox/utils/proactivePermissions.d.ts +19 -0
  375. package/dist/src/sandbox/utils/proactivePermissions.js +163 -0
  376. package/dist/src/sandbox/utils/proactivePermissions.js.map +1 -0
  377. package/dist/src/sandbox/utils/proactivePermissions.test.d.ts +6 -0
  378. package/dist/src/sandbox/utils/proactivePermissions.test.js +145 -0
  379. package/dist/src/sandbox/utils/proactivePermissions.test.js.map +1 -0
  380. package/dist/src/sandbox/utils/sandboxDenialUtils.d.ts +27 -0
  381. package/dist/src/sandbox/utils/sandboxDenialUtils.js +142 -0
  382. package/dist/src/sandbox/utils/sandboxDenialUtils.js.map +1 -0
  383. package/dist/src/sandbox/utils/sandboxDenialUtils.test.d.ts +6 -0
  384. package/dist/src/sandbox/utils/sandboxDenialUtils.test.js +188 -0
  385. package/dist/src/sandbox/utils/sandboxDenialUtils.test.js.map +1 -0
  386. package/dist/src/sandbox/utils/sandboxReadWriteUtils.d.ts +5 -0
  387. package/dist/src/sandbox/utils/sandboxReadWriteUtils.js +64 -0
  388. package/dist/src/sandbox/utils/sandboxReadWriteUtils.js.map +1 -0
  389. package/dist/src/sandbox/windows/GeminiSandbox.cs +312 -223
  390. package/dist/src/sandbox/windows/WindowsSandboxManager.d.ts +16 -2
  391. package/dist/src/sandbox/windows/WindowsSandboxManager.js +261 -44
  392. package/dist/src/sandbox/windows/WindowsSandboxManager.js.map +1 -1
  393. package/dist/src/sandbox/windows/WindowsSandboxManager.test.js +379 -17
  394. package/dist/src/sandbox/windows/WindowsSandboxManager.test.js.map +1 -1
  395. package/dist/src/sandbox/windows/commandSafety.d.ts +19 -0
  396. package/dist/src/sandbox/windows/commandSafety.js +128 -0
  397. package/dist/src/sandbox/windows/commandSafety.js.map +1 -0
  398. package/dist/src/sandbox/windows/commandSafety.test.d.ts +6 -0
  399. package/dist/src/sandbox/windows/commandSafety.test.js +42 -0
  400. package/dist/src/sandbox/windows/commandSafety.test.js.map +1 -0
  401. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.d.ts +13 -0
  402. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.js +69 -0
  403. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.js.map +1 -0
  404. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.test.d.ts +6 -0
  405. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.test.js +68 -0
  406. package/dist/src/sandbox/windows/windowsSandboxDenialUtils.test.js.map +1 -0
  407. package/dist/src/scheduler/policy.js +20 -5
  408. package/dist/src/scheduler/policy.js.map +1 -1
  409. package/dist/src/scheduler/policy.test.js +80 -0
  410. package/dist/src/scheduler/policy.test.js.map +1 -1
  411. package/dist/src/scheduler/scheduler.js +13 -3
  412. package/dist/src/scheduler/scheduler.js.map +1 -1
  413. package/dist/src/scheduler/scheduler.test.js +52 -0
  414. package/dist/src/scheduler/scheduler.test.js.map +1 -1
  415. package/dist/src/scheduler/scheduler_hooks.test.js +1 -0
  416. package/dist/src/scheduler/scheduler_hooks.test.js.map +1 -1
  417. package/dist/src/scheduler/state-manager.js +1 -1
  418. package/dist/src/scheduler/state-manager.js.map +1 -1
  419. package/dist/src/scheduler/state-manager.test.js +10 -0
  420. package/dist/src/scheduler/state-manager.test.js.map +1 -1
  421. package/dist/src/scheduler/tool-executor.js +7 -2
  422. package/dist/src/scheduler/tool-executor.js.map +1 -1
  423. package/dist/src/scheduler/tool-executor.test.js +38 -0
  424. package/dist/src/scheduler/tool-executor.test.js.map +1 -1
  425. package/dist/src/scheduler/types.d.ts +4 -2
  426. package/dist/src/services/chatRecordingService.d.ts +1 -13
  427. package/dist/src/services/chatRecordingService.js +45 -46
  428. package/dist/src/services/chatRecordingService.js.map +1 -1
  429. package/dist/src/services/chatRecordingService.test.js +79 -10
  430. package/dist/src/services/chatRecordingService.test.js.map +1 -1
  431. package/dist/src/services/executionLifecycleService.d.ts +44 -6
  432. package/dist/src/services/executionLifecycleService.js +52 -12
  433. package/dist/src/services/executionLifecycleService.js.map +1 -1
  434. package/dist/src/services/executionLifecycleService.test.js +157 -3
  435. package/dist/src/services/executionLifecycleService.test.js.map +1 -1
  436. package/dist/src/services/fileDiscoveryService.d.ts +17 -2
  437. package/dist/src/services/fileDiscoveryService.js +84 -20
  438. package/dist/src/services/fileDiscoveryService.js.map +1 -1
  439. package/dist/src/services/fileDiscoveryService.test.js +67 -1
  440. package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
  441. package/dist/src/services/gitService.js +1 -1
  442. package/dist/src/services/gitService.js.map +1 -1
  443. package/dist/src/services/memoryService.d.ts +65 -0
  444. package/dist/src/services/memoryService.js +511 -0
  445. package/dist/src/services/memoryService.js.map +1 -0
  446. package/dist/src/services/memoryService.test.d.ts +6 -0
  447. package/dist/src/services/memoryService.test.js +563 -0
  448. package/dist/src/services/memoryService.test.js.map +1 -0
  449. package/dist/src/services/modelConfigService.d.ts +11 -0
  450. package/dist/src/services/modelConfigService.js +67 -0
  451. package/dist/src/services/modelConfigService.js.map +1 -1
  452. package/dist/src/services/modelConfigService.test.js +30 -0
  453. package/dist/src/services/modelConfigService.test.js.map +1 -1
  454. package/dist/src/services/sandboxManager.d.ts +107 -8
  455. package/dist/src/services/sandboxManager.integration.test.d.ts +1 -0
  456. package/dist/src/services/sandboxManager.integration.test.js +445 -0
  457. package/dist/src/services/sandboxManager.integration.test.js.map +1 -0
  458. package/dist/src/services/sandboxManager.js +176 -13
  459. package/dist/src/services/sandboxManager.js.map +1 -1
  460. package/dist/src/services/sandboxManager.test.js +401 -117
  461. package/dist/src/services/sandboxManager.test.js.map +1 -1
  462. package/dist/src/services/sandboxManagerFactory.d.ts +2 -3
  463. package/dist/src/services/sandboxManagerFactory.js +12 -22
  464. package/dist/src/services/sandboxManagerFactory.js.map +1 -1
  465. package/dist/src/services/sandboxedFileSystemService.d.ts +1 -0
  466. package/dist/src/services/sandboxedFileSystemService.js +43 -3
  467. package/dist/src/services/sandboxedFileSystemService.js.map +1 -1
  468. package/dist/src/services/sandboxedFileSystemService.test.js +97 -11
  469. package/dist/src/services/sandboxedFileSystemService.test.js.map +1 -1
  470. package/dist/src/services/shellExecutionService.d.ts +18 -1
  471. package/dist/src/services/shellExecutionService.js +115 -26
  472. package/dist/src/services/shellExecutionService.js.map +1 -1
  473. package/dist/src/services/shellExecutionService.test.js +70 -8
  474. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  475. package/dist/src/services/test-data/resolved-aliases-retry.golden.json +4 -0
  476. package/dist/src/services/test-data/resolved-aliases.golden.json +4 -0
  477. package/dist/src/services/worktreeService.test.js +7 -7
  478. package/dist/src/services/worktreeService.test.js.map +1 -1
  479. package/dist/src/skills/skillLoader.d.ts +8 -0
  480. package/dist/src/skills/skillLoader.js +1 -1
  481. package/dist/src/skills/skillLoader.js.map +1 -1
  482. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +29 -1
  483. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +107 -0
  484. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  485. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +172 -1
  486. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  487. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +10 -1
  488. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +22 -1
  489. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  490. package/dist/src/telemetry/loggers.d.ts +22 -0
  491. package/dist/src/telemetry/loggers.js +41 -2
  492. package/dist/src/telemetry/loggers.js.map +1 -1
  493. package/dist/src/telemetry/loggers.test.js +8 -3
  494. package/dist/src/telemetry/loggers.test.js.map +1 -1
  495. package/dist/src/telemetry/metrics.d.ts +118 -1
  496. package/dist/src/telemetry/metrics.js +196 -4
  497. package/dist/src/telemetry/metrics.js.map +1 -1
  498. package/dist/src/telemetry/metrics.test.js +298 -0
  499. package/dist/src/telemetry/metrics.test.js.map +1 -1
  500. package/dist/src/telemetry/types.d.ts +3 -3
  501. package/dist/src/telemetry/types.js +9 -4
  502. package/dist/src/telemetry/types.js.map +1 -1
  503. package/dist/src/test-utils/mock-message-bus.d.ts +1 -1
  504. package/dist/src/test-utils/mock-message-bus.js +1 -1
  505. package/dist/src/test-utils/mock-message-bus.js.map +1 -1
  506. package/dist/src/tools/complete-task.d.ts +29 -0
  507. package/dist/src/tools/complete-task.js +123 -0
  508. package/dist/src/tools/complete-task.js.map +1 -0
  509. package/dist/src/tools/complete-task.test.d.ts +6 -0
  510. package/dist/src/tools/complete-task.test.js +114 -0
  511. package/dist/src/tools/complete-task.test.js.map +1 -0
  512. package/dist/src/tools/definitions/base-declarations.d.ts +8 -0
  513. package/dist/src/tools/definitions/base-declarations.js +10 -0
  514. package/dist/src/tools/definitions/base-declarations.js.map +1 -1
  515. package/dist/src/tools/definitions/coreTools.d.ts +2 -1
  516. package/dist/src/tools/definitions/coreTools.js +9 -3
  517. package/dist/src/tools/definitions/coreTools.js.map +1 -1
  518. package/dist/src/tools/definitions/dynamic-declaration-helpers.d.ts +4 -0
  519. package/dist/src/tools/definitions/dynamic-declaration-helpers.js +33 -2
  520. package/dist/src/tools/definitions/dynamic-declaration-helpers.js.map +1 -1
  521. package/dist/src/tools/definitions/model-family-sets/default-legacy.js +14 -9
  522. package/dist/src/tools/definitions/model-family-sets/default-legacy.js.map +1 -1
  523. package/dist/src/tools/definitions/model-family-sets/gemini-3.js +13 -7
  524. package/dist/src/tools/definitions/model-family-sets/gemini-3.js.map +1 -1
  525. package/dist/src/tools/definitions/trackerTools.js +3 -3
  526. package/dist/src/tools/definitions/trackerTools.js.map +1 -1
  527. package/dist/src/tools/definitions/types.d.ts +1 -0
  528. package/dist/src/tools/enter-plan-mode.js +15 -0
  529. package/dist/src/tools/enter-plan-mode.js.map +1 -1
  530. package/dist/src/tools/enter-plan-mode.test.js +25 -0
  531. package/dist/src/tools/enter-plan-mode.test.js.map +1 -1
  532. package/dist/src/tools/grep-utils.d.ts +2 -1
  533. package/dist/src/tools/grep-utils.js +22 -3
  534. package/dist/src/tools/grep-utils.js.map +1 -1
  535. package/dist/src/tools/grep.js +16 -3
  536. package/dist/src/tools/grep.js.map +1 -1
  537. package/dist/src/tools/grep.test.js +36 -8
  538. package/dist/src/tools/grep.test.js.map +1 -1
  539. package/dist/src/tools/jit-context.js +3 -3
  540. package/dist/src/tools/jit-context.js.map +1 -1
  541. package/dist/src/tools/jit-context.test.js +15 -13
  542. package/dist/src/tools/jit-context.test.js.map +1 -1
  543. package/dist/src/tools/ls.js +6 -4
  544. package/dist/src/tools/ls.js.map +1 -1
  545. package/dist/src/tools/ls.test.js +22 -7
  546. package/dist/src/tools/ls.test.js.map +1 -1
  547. package/dist/src/tools/mcp-client-manager.js +6 -3
  548. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  549. package/dist/src/tools/mcp-client-manager.test.js +35 -0
  550. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  551. package/dist/src/tools/mcp-client.js +1 -1
  552. package/dist/src/tools/mcp-client.js.map +1 -1
  553. package/dist/src/tools/mcp-tool.test.js +1 -1
  554. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  555. package/dist/src/tools/memoryTool.d.ts +9 -2
  556. package/dist/src/tools/memoryTool.js +39 -15
  557. package/dist/src/tools/memoryTool.js.map +1 -1
  558. package/dist/src/tools/memoryTool.test.js +61 -2
  559. package/dist/src/tools/memoryTool.test.js.map +1 -1
  560. package/dist/src/tools/read-many-files.js +12 -4
  561. package/dist/src/tools/read-many-files.js.map +1 -1
  562. package/dist/src/tools/read-many-files.test.js +17 -17
  563. package/dist/src/tools/read-many-files.test.js.map +1 -1
  564. package/dist/src/tools/ripGrep.js +14 -1
  565. package/dist/src/tools/ripGrep.js.map +1 -1
  566. package/dist/src/tools/ripGrep.test.js +10 -10
  567. package/dist/src/tools/ripGrep.test.js.map +1 -1
  568. package/dist/src/tools/shell.d.ts +17 -4
  569. package/dist/src/tools/shell.js +342 -151
  570. package/dist/src/tools/shell.js.map +1 -1
  571. package/dist/src/tools/shell.test.js +204 -11
  572. package/dist/src/tools/shell.test.js.map +1 -1
  573. package/dist/src/tools/shellBackgroundTools.d.ts +38 -0
  574. package/dist/src/tools/shellBackgroundTools.integration.test.d.ts +6 -0
  575. package/dist/src/tools/shellBackgroundTools.integration.test.js +86 -0
  576. package/dist/src/tools/shellBackgroundTools.integration.test.js.map +1 -0
  577. package/dist/src/tools/shellBackgroundTools.js +186 -0
  578. package/dist/src/tools/shellBackgroundTools.js.map +1 -0
  579. package/dist/src/tools/shellBackgroundTools.test.d.ts +6 -0
  580. package/dist/src/tools/shellBackgroundTools.test.js +230 -0
  581. package/dist/src/tools/shellBackgroundTools.test.js.map +1 -0
  582. package/dist/src/tools/shell_proactive.test.d.ts +6 -0
  583. package/dist/src/tools/shell_proactive.test.js +122 -0
  584. package/dist/src/tools/shell_proactive.test.js.map +1 -0
  585. package/dist/src/tools/tool-names.d.ts +4 -4
  586. package/dist/src/tools/tool-names.js +6 -3
  587. package/dist/src/tools/tool-names.js.map +1 -1
  588. package/dist/src/tools/tool-registry.js +11 -1
  589. package/dist/src/tools/tool-registry.js.map +1 -1
  590. package/dist/src/tools/tool-registry.test.js +43 -1
  591. package/dist/src/tools/tool-registry.test.js.map +1 -1
  592. package/dist/src/tools/tools.d.ts +12 -1
  593. package/dist/src/tools/tools.js +16 -1
  594. package/dist/src/tools/tools.js.map +1 -1
  595. package/dist/src/tools/tools.test.js +42 -1
  596. package/dist/src/tools/tools.test.js.map +1 -1
  597. package/dist/src/tools/topicTool.d.ts +29 -0
  598. package/dist/src/tools/topicTool.js +72 -0
  599. package/dist/src/tools/topicTool.js.map +1 -0
  600. package/dist/src/tools/topicTool.test.d.ts +6 -0
  601. package/dist/src/tools/topicTool.test.js +105 -0
  602. package/dist/src/tools/topicTool.test.js.map +1 -0
  603. package/dist/src/tools/web-fetch.js +40 -22
  604. package/dist/src/tools/web-fetch.js.map +1 -1
  605. package/dist/src/tools/web-fetch.test.js +28 -0
  606. package/dist/src/tools/web-fetch.test.js.map +1 -1
  607. package/dist/src/tools/xcode-mcp-fix-transport.js +1 -1
  608. package/dist/src/tools/xcode-mcp-fix-transport.js.map +1 -1
  609. package/dist/src/utils/bfsFileSearch.js +3 -6
  610. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  611. package/dist/src/utils/checkpointUtils.d.ts +4 -4
  612. package/dist/src/utils/checkpointUtils.js +11 -8
  613. package/dist/src/utils/checkpointUtils.js.map +1 -1
  614. package/dist/src/utils/compatibility.js +0 -7
  615. package/dist/src/utils/compatibility.js.map +1 -1
  616. package/dist/src/utils/compatibility.test.js +0 -9
  617. package/dist/src/utils/compatibility.test.js.map +1 -1
  618. package/dist/src/utils/editor.js +3 -0
  619. package/dist/src/utils/editor.js.map +1 -1
  620. package/dist/src/utils/errorParsing.js +2 -2
  621. package/dist/src/utils/errorParsing.js.map +1 -1
  622. package/dist/src/utils/errors.d.ts +3 -0
  623. package/dist/src/utils/errors.js +28 -6
  624. package/dist/src/utils/errors.js.map +1 -1
  625. package/dist/src/utils/errors.test.js +23 -0
  626. package/dist/src/utils/errors.test.js.map +1 -1
  627. package/dist/src/utils/events.d.ts +12 -0
  628. package/dist/src/utils/events.js +7 -0
  629. package/dist/src/utils/events.js.map +1 -1
  630. package/dist/src/utils/fetch.d.ts +1 -0
  631. package/dist/src/utils/fetch.js +22 -6
  632. package/dist/src/utils/fetch.js.map +1 -1
  633. package/dist/src/utils/fetch.test.js +26 -1
  634. package/dist/src/utils/fetch.test.js.map +1 -1
  635. package/dist/src/utils/fileUtils.js +1 -1
  636. package/dist/src/utils/fileUtils.js.map +1 -1
  637. package/dist/src/utils/filesearch/crawler.js +1 -1
  638. package/dist/src/utils/filesearch/crawler.js.map +1 -1
  639. package/dist/src/utils/filesearch/fileSearch.test.js +7 -2
  640. package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -1
  641. package/dist/src/utils/getFolderStructure.js +1 -1
  642. package/dist/src/utils/getFolderStructure.js.map +1 -1
  643. package/dist/src/utils/getPty.js +2 -2
  644. package/dist/src/utils/getPty.js.map +1 -1
  645. package/dist/src/utils/gitIgnoreParser.d.ts +2 -2
  646. package/dist/src/utils/gitIgnoreParser.js +30 -52
  647. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  648. package/dist/src/utils/gitIgnoreParser.test.js +51 -185
  649. package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
  650. package/dist/src/utils/gitUtils.js +2 -2
  651. package/dist/src/utils/gitUtils.js.map +1 -1
  652. package/dist/src/utils/googleErrors.js +5 -5
  653. package/dist/src/utils/googleErrors.js.map +1 -1
  654. package/dist/src/utils/ignoreFileParser.d.ts +2 -2
  655. package/dist/src/utils/ignoreFileParser.js +7 -18
  656. package/dist/src/utils/ignoreFileParser.js.map +1 -1
  657. package/dist/src/utils/ignoreFileParser.test.js +40 -132
  658. package/dist/src/utils/ignoreFileParser.test.js.map +1 -1
  659. package/dist/src/utils/ignorePathUtils.d.ts +11 -0
  660. package/dist/src/utils/ignorePathUtils.js +39 -0
  661. package/dist/src/utils/ignorePathUtils.js.map +1 -0
  662. package/dist/src/utils/ignorePathUtils.test.d.ts +6 -0
  663. package/dist/src/utils/ignorePathUtils.test.js +70 -0
  664. package/dist/src/utils/ignorePathUtils.test.js.map +1 -0
  665. package/dist/src/utils/memoryDiscovery.d.ts +6 -4
  666. package/dist/src/utils/memoryDiscovery.js +69 -48
  667. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  668. package/dist/src/utils/memoryDiscovery.test.js +40 -0
  669. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  670. package/dist/src/utils/memoryImportProcessor.d.ts +1 -1
  671. package/dist/src/utils/memoryImportProcessor.js +24 -15
  672. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  673. package/dist/src/utils/paths.d.ts +8 -0
  674. package/dist/src/utils/paths.js +37 -6
  675. package/dist/src/utils/paths.js.map +1 -1
  676. package/dist/src/utils/paths.test.js +61 -3
  677. package/dist/src/utils/paths.test.js.map +1 -1
  678. package/dist/src/utils/process-utils.js +2 -2
  679. package/dist/src/utils/process-utils.js.map +1 -1
  680. package/dist/src/utils/retry.js +7 -0
  681. package/dist/src/utils/retry.js.map +1 -1
  682. package/dist/src/utils/retry.test.js +41 -0
  683. package/dist/src/utils/retry.test.js.map +1 -1
  684. package/dist/src/utils/secure-browser-launcher.js +1 -1
  685. package/dist/src/utils/secure-browser-launcher.js.map +1 -1
  686. package/dist/src/utils/sessionOperations.d.ts +19 -0
  687. package/dist/src/utils/sessionOperations.js +101 -0
  688. package/dist/src/utils/sessionOperations.js.map +1 -0
  689. package/dist/src/utils/sessionOperations.test.d.ts +6 -0
  690. package/dist/src/utils/sessionOperations.test.js +92 -0
  691. package/dist/src/utils/sessionOperations.test.js.map +1 -0
  692. package/dist/src/utils/shell-utils.d.ts +24 -0
  693. package/dist/src/utils/shell-utils.integration.test.js +1 -1
  694. package/dist/src/utils/shell-utils.integration.test.js.map +1 -1
  695. package/dist/src/utils/shell-utils.js +86 -6
  696. package/dist/src/utils/shell-utils.js.map +1 -1
  697. package/dist/src/utils/shell-utils.test.js +13 -1
  698. package/dist/src/utils/shell-utils.test.js.map +1 -1
  699. package/dist/src/utils/systemEncoding.js +1 -1
  700. package/dist/src/utils/systemEncoding.js.map +1 -1
  701. package/dist/src/utils/terminalSerializer.d.ts +1 -0
  702. package/dist/src/utils/terminalSerializer.js +31 -8
  703. package/dist/src/utils/terminalSerializer.js.map +1 -1
  704. package/dist/src/utils/terminalSerializer.test.js +3 -2
  705. package/dist/src/utils/terminalSerializer.test.js.map +1 -1
  706. package/dist/src/utils/textUtils.d.ts +8 -0
  707. package/dist/src/utils/textUtils.js +16 -0
  708. package/dist/src/utils/textUtils.js.map +1 -1
  709. package/dist/src/utils/tokenCalculation.d.ts +2 -0
  710. package/dist/src/utils/tokenCalculation.js +2 -2
  711. package/dist/src/utils/tokenCalculation.js.map +1 -1
  712. package/dist/src/utils/workspaceContext.js +2 -2
  713. package/dist/src/utils/workspaceContext.js.map +1 -1
  714. package/dist/tsconfig.tsbuildinfo +1 -1
  715. package/package.json +2 -1
  716. package/dist/docs/CONTRIBUTING.md +0 -566
  717. package/dist/docs/get-started/examples.md +0 -141
  718. package/dist/src/sandbox/macos/MacOsSandboxManager.integration.test.js +0 -164
  719. package/dist/src/sandbox/macos/MacOsSandboxManager.integration.test.js.map +0 -1
  720. package/dist/src/sandbox/macos/commandSafety.js.map +0 -1
  721. package/dist/src/services/chatCompressionService.js.map +0 -1
  722. package/dist/src/services/chatCompressionService.test.js.map +0 -1
  723. package/dist/src/services/contextManager.js.map +0 -1
  724. package/dist/src/services/contextManager.test.js.map +0 -1
  725. package/dist/src/services/toolOutputMaskingService.js.map +0 -1
  726. package/dist/src/services/toolOutputMaskingService.test.js.map +0 -1
  727. /package/dist/src/{services/toolOutputMaskingService.test.d.ts → agents/browser/snapshotSuperseder.test.d.ts} +0 -0
  728. /package/dist/src/{services → context}/chatCompressionService.d.ts +0 -0
  729. /package/dist/src/{services → context}/chatCompressionService.js +0 -0
  730. /package/dist/src/{services → context}/chatCompressionService.test.d.ts +0 -0
  731. /package/dist/src/{services → context}/chatCompressionService.test.js +0 -0
  732. /package/dist/src/{sandbox/macos/MacOsSandboxManager.integration.test.d.ts → context/contextCompressionService.test.d.ts} +0 -0
  733. /package/dist/src/{services/contextManager.test.d.ts → context/memoryContextManager.test.d.ts} +0 -0
@@ -4,9 +4,10 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
7
- import { BrowserManager } from './browserManager.js';
7
+ import { BrowserManager, DomainNotAllowedError } from './browserManager.js';
8
8
  import { makeFakeConfig } from '../../test-utils/config.js';
9
9
  import { injectAutomationOverlay } from './automationOverlay.js';
10
+ import { injectInputBlocker } from './inputBlocker.js';
10
11
  import { coreEvents } from '../../utils/events.js';
11
12
  // Mock the MCP SDK
12
13
  vi.mock('@modelcontextprotocol/sdk/client/index.js', () => ({
@@ -39,6 +40,9 @@ vi.mock('../../utils/debugLogger.js', () => ({
39
40
  error: vi.fn(),
40
41
  },
41
42
  }));
43
+ vi.mock('../../telemetry/metrics.js', () => ({
44
+ recordBrowserAgentConnection: vi.fn(),
45
+ }));
42
46
  // Mock browser consent to always grant consent by default
43
47
  vi.mock('../../utils/browserConsent.js', () => ({
44
48
  getBrowserConsentIfNeeded: vi.fn().mockResolvedValue(true),
@@ -46,6 +50,12 @@ vi.mock('../../utils/browserConsent.js', () => ({
46
50
  vi.mock('./automationOverlay.js', () => ({
47
51
  injectAutomationOverlay: vi.fn().mockResolvedValue(undefined),
48
52
  }));
53
+ vi.mock('./inputBlocker.js', () => ({
54
+ injectInputBlocker: vi.fn().mockResolvedValue(undefined),
55
+ removeInputBlocker: vi.fn().mockResolvedValue(undefined),
56
+ suspendInputBlocker: vi.fn().mockResolvedValue(undefined),
57
+ resumeInputBlocker: vi.fn().mockResolvedValue(undefined),
58
+ }));
49
59
  vi.mock('node:fs', async (importOriginal) => {
50
60
  const actual = await importOriginal();
51
61
  return {
@@ -61,12 +71,15 @@ vi.mock('node:fs', async (importOriginal) => {
61
71
  import * as fs from 'node:fs';
62
72
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
63
73
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
74
+ import { recordBrowserAgentConnection } from '../../telemetry/metrics.js';
64
75
  import { getBrowserConsentIfNeeded } from '../../utils/browserConsent.js';
76
+ import { debugLogger } from '../../utils/debugLogger.js';
65
77
  describe('BrowserManager', () => {
66
78
  let mockConfig;
67
79
  beforeEach(() => {
68
80
  vi.resetAllMocks();
69
81
  vi.mocked(injectAutomationOverlay).mockClear();
82
+ vi.mocked(injectInputBlocker).mockClear();
70
83
  vi.spyOn(coreEvents, 'emitFeedback').mockImplementation(() => { });
71
84
  // Re-establish consent mock after resetAllMocks
72
85
  vi.mocked(getBrowserConsentIfNeeded).mockResolvedValue(true);
@@ -99,9 +112,17 @@ describe('BrowserManager', () => {
99
112
  content: [{ type: 'text', text: 'Tool result' }],
100
113
  }),
101
114
  }));
115
+ vi.mocked(StdioClientTransport).mockImplementation(() => ({
116
+ close: vi.fn().mockResolvedValue(undefined),
117
+ stderr: {
118
+ on: vi.fn(),
119
+ },
120
+ }));
102
121
  });
103
- afterEach(() => {
122
+ afterEach(async () => {
104
123
  vi.restoreAllMocks();
124
+ // Clear singleton cache to avoid cross-test leakage
125
+ await BrowserManager.resetAll();
105
126
  });
106
127
  describe('MCP bundled path resolution', () => {
107
128
  it('should use bundled path if it exists (handles bundled CLI)', async () => {
@@ -111,7 +132,7 @@ describe('BrowserManager', () => {
111
132
  expect(StdioClientTransport).toHaveBeenCalledWith(expect.objectContaining({
112
133
  command: 'node',
113
134
  args: expect.arrayContaining([
114
- expect.stringMatching(/bundled\/chrome-devtools-mcp\.mjs$/),
135
+ expect.stringMatching(/(dist[\\/])?bundled[\\/]chrome-devtools-mcp\.mjs$/),
115
136
  ]),
116
137
  }));
117
138
  });
@@ -122,7 +143,7 @@ describe('BrowserManager', () => {
122
143
  expect(StdioClientTransport).toHaveBeenCalledWith(expect.objectContaining({
123
144
  command: 'node',
124
145
  args: expect.arrayContaining([
125
- expect.stringMatching(/(dist\/)?bundled\/chrome-devtools-mcp\.mjs$/),
146
+ expect.stringMatching(/(dist[\\/])?bundled[\\/]chrome-devtools-mcp\.mjs$/),
126
147
  ]),
127
148
  }));
128
149
  });
@@ -174,11 +195,7 @@ describe('BrowserManager', () => {
174
195
  },
175
196
  });
176
197
  const manager = new BrowserManager(restrictedConfig);
177
- const result = await manager.callTool('navigate_page', {
178
- url: 'https://evil.com',
179
- });
180
- expect(result.isError).toBe(true);
181
- expect((result.content || [])[0]?.text).toContain('not permitted');
198
+ await expect(manager.callTool('navigate_page', { url: 'https://evil.com' })).rejects.toThrow(DomainNotAllowedError);
182
199
  expect(Client).not.toHaveBeenCalled();
183
200
  });
184
201
  it('should allow navigate_page to allowed domain', async () => {
@@ -220,14 +237,74 @@ describe('BrowserManager', () => {
220
237
  },
221
238
  });
222
239
  const manager = new BrowserManager(restrictedConfig);
240
+ await expect(manager.callTool('new_page', { url: 'https://evil.com' })).rejects.toThrow(DomainNotAllowedError);
241
+ });
242
+ it('should block proxy URL with embedded disallowed domain in query params', async () => {
243
+ const restrictedConfig = makeFakeConfig({
244
+ agents: {
245
+ browser: {
246
+ allowedDomains: ['*.google.com'],
247
+ },
248
+ },
249
+ });
250
+ const manager = new BrowserManager(restrictedConfig);
251
+ await expect(manager.callTool('new_page', {
252
+ url: 'https://translate.google.com/translate?sl=en&tl=en&u=https://blocked.org/page',
253
+ })).rejects.toThrow(DomainNotAllowedError);
254
+ });
255
+ it('should block proxy URL with embedded disallowed domain in URL fragment (hash)', async () => {
256
+ const restrictedConfig = makeFakeConfig({
257
+ agents: {
258
+ browser: {
259
+ allowedDomains: ['*.google.com'],
260
+ },
261
+ },
262
+ });
263
+ const manager = new BrowserManager(restrictedConfig);
264
+ await expect(manager.callTool('new_page', {
265
+ url: 'https://translate.google.com/#view=home&op=translate&sl=en&tl=zh-CN&u=https://blocked.org',
266
+ })).rejects.toThrow(DomainNotAllowedError);
267
+ });
268
+ it('should allow proxy URL when embedded domain is also allowed', async () => {
269
+ const restrictedConfig = makeFakeConfig({
270
+ agents: {
271
+ browser: {
272
+ allowedDomains: ['*.google.com', 'github.com'],
273
+ },
274
+ },
275
+ });
276
+ const manager = new BrowserManager(restrictedConfig);
223
277
  const result = await manager.callTool('new_page', {
224
- url: 'https://evil.com',
278
+ url: 'https://translate.google.com/translate?u=https://github.com/repo',
225
279
  });
226
- expect(result.isError).toBe(true);
227
- expect((result.content || [])[0]?.text).toContain('not permitted');
280
+ expect(result.isError).toBe(false);
281
+ });
282
+ it('should allow navigation to allowed domain without proxy params', async () => {
283
+ const restrictedConfig = makeFakeConfig({
284
+ agents: {
285
+ browser: {
286
+ allowedDomains: ['*.google.com'],
287
+ },
288
+ },
289
+ });
290
+ const manager = new BrowserManager(restrictedConfig);
291
+ const result = await manager.callTool('new_page', {
292
+ url: 'https://translate.google.com/?sl=en&tl=zh',
293
+ });
294
+ expect(result.isError).toBe(false);
228
295
  });
229
296
  });
230
297
  describe('MCP connection', () => {
298
+ it('should record connection success metrics', async () => {
299
+ const manager = new BrowserManager(mockConfig);
300
+ await manager.ensureConnection();
301
+ expect(recordBrowserAgentConnection).toHaveBeenCalledWith(mockConfig, expect.any(Number), {
302
+ session_mode: 'persistent',
303
+ headless: false,
304
+ success: true,
305
+ tool_count: 4,
306
+ });
307
+ });
231
308
  it('should spawn npx chrome-devtools-mcp with --experimental-vision (persistent mode by default)', async () => {
232
309
  const manager = new BrowserManager(mockConfig);
233
310
  await manager.ensureConnection();
@@ -262,7 +339,7 @@ describe('BrowserManager', () => {
262
339
  await manager.ensureConnection();
263
340
  const args = vi.mocked(StdioClientTransport).mock.calls[0]?.[0]
264
341
  ?.args;
265
- expect(args).toContain('--chromeArg="--host-rules=MAP * 127.0.0.1, EXCLUDE google.com, EXCLUDE *.openai.com, EXCLUDE 127.0.0.1"');
342
+ expect(args).toContain('--chromeArg="--host-rules=MAP * ~NOTFOUND, EXCLUDE google.com, EXCLUDE *.openai.com"');
266
343
  });
267
344
  it('should throw error when invalid domain is configured in allowedDomains', async () => {
268
345
  const invalidConfig = makeFakeConfig({
@@ -378,6 +455,12 @@ describe('BrowserManager', () => {
378
455
  });
379
456
  const manager = new BrowserManager(existingConfig);
380
457
  await expect(manager.ensureConnection()).rejects.toThrow(/Failed to connect to existing Chrome instance/);
458
+ expect(recordBrowserAgentConnection).toHaveBeenCalledWith(existingConfig, expect.any(Number), {
459
+ session_mode: 'existing',
460
+ headless: false,
461
+ success: false,
462
+ error_type: 'connection_refused',
463
+ });
381
464
  // Create a fresh manager to verify the error message includes remediation steps
382
465
  const manager2 = new BrowserManager(existingConfig);
383
466
  await expect(manager2.ensureConnection()).rejects.toThrow(/chrome:\/\/inspect\/#remote-debugging/);
@@ -394,6 +477,12 @@ describe('BrowserManager', () => {
394
477
  // Default config = persistent mode
395
478
  const manager = new BrowserManager(mockConfig);
396
479
  await expect(manager.ensureConnection()).rejects.toThrow(/Close all Chrome windows using this profile/);
480
+ expect(recordBrowserAgentConnection).toHaveBeenCalledWith(mockConfig, expect.any(Number), {
481
+ session_mode: 'persistent',
482
+ headless: false,
483
+ success: false,
484
+ error_type: 'profile_locked',
485
+ });
397
486
  const manager2 = new BrowserManager(mockConfig);
398
487
  await expect(manager2.ensureConnection()).rejects.toThrow(/Set sessionMode to "isolated"/);
399
488
  });
@@ -408,6 +497,12 @@ describe('BrowserManager', () => {
408
497
  }));
409
498
  const manager = new BrowserManager(mockConfig);
410
499
  await expect(manager.ensureConnection()).rejects.toThrow(/Chrome is not installed/);
500
+ expect(recordBrowserAgentConnection).toHaveBeenCalledWith(mockConfig, expect.any(Number), {
501
+ session_mode: 'persistent',
502
+ headless: false,
503
+ success: false,
504
+ error_type: 'timeout',
505
+ });
411
506
  });
412
507
  it('should include sessionMode in generic fallback error', async () => {
413
508
  vi.mocked(Client).mockImplementation(() => ({
@@ -420,6 +515,42 @@ describe('BrowserManager', () => {
420
515
  }));
421
516
  const manager = new BrowserManager(mockConfig);
422
517
  await expect(manager.ensureConnection()).rejects.toThrow(/sessionMode: persistent/);
518
+ expect(recordBrowserAgentConnection).toHaveBeenCalledWith(mockConfig, expect.any(Number), {
519
+ session_mode: 'persistent',
520
+ headless: false,
521
+ success: false,
522
+ error_type: 'unknown',
523
+ });
524
+ });
525
+ it('should classify non-connection-refused errors in existing mode as unknown', async () => {
526
+ vi.mocked(Client).mockImplementation(() => ({
527
+ connect: vi
528
+ .fn()
529
+ .mockRejectedValue(new Error('Some unexpected error')),
530
+ close: vi.fn().mockResolvedValue(undefined),
531
+ listTools: vi.fn(),
532
+ callTool: vi.fn(),
533
+ }));
534
+ const existingConfig = makeFakeConfig({
535
+ agents: {
536
+ overrides: {
537
+ browser_agent: {
538
+ enabled: true,
539
+ },
540
+ },
541
+ browser: {
542
+ sessionMode: 'existing',
543
+ },
544
+ },
545
+ });
546
+ const manager = new BrowserManager(existingConfig);
547
+ await expect(manager.ensureConnection()).rejects.toThrow(/Failed to connect to existing Chrome instance/);
548
+ expect(recordBrowserAgentConnection).toHaveBeenCalledWith(existingConfig, expect.any(Number), {
549
+ session_mode: 'existing',
550
+ headless: false,
551
+ success: false,
552
+ error_type: 'unknown',
553
+ });
423
554
  });
424
555
  it('should pass --no-usage-statistics and --no-performance-crux when privacy is disabled', async () => {
425
556
  const privacyDisabledConfig = makeFakeConfig({
@@ -474,23 +605,279 @@ describe('BrowserManager', () => {
474
605
  describe('close', () => {
475
606
  it('should close MCP connections', async () => {
476
607
  const manager = new BrowserManager(mockConfig);
477
- const client = await manager.getRawMcpClient();
608
+ await manager.getRawMcpClient();
609
+ await manager.close();
610
+ expect(manager.isConnected()).toBe(false);
611
+ });
612
+ it('should NOT log error when transport closes during intentional close()', async () => {
613
+ const manager = new BrowserManager(mockConfig);
614
+ await manager.ensureConnection();
615
+ const transportInstance = vi.mocked(StdioClientTransport).mock.results[0]?.value;
616
+ // Trigger onclose during close()
617
+ vi.spyOn(transportInstance, 'close').mockImplementation(async () => {
618
+ transportInstance.onclose?.();
619
+ });
620
+ await manager.close();
621
+ expect(debugLogger.error).not.toHaveBeenCalledWith(expect.stringContaining('transport closed unexpectedly'));
622
+ });
623
+ });
624
+ describe('getInstance', () => {
625
+ it('should return the same instance for the same session mode', () => {
626
+ const instance1 = BrowserManager.getInstance(mockConfig);
627
+ const instance2 = BrowserManager.getInstance(mockConfig);
628
+ expect(instance1).toBe(instance2);
629
+ });
630
+ it('should return different instances for different session modes', () => {
631
+ const isolatedConfig = makeFakeConfig({
632
+ agents: {
633
+ overrides: { browser_agent: { enabled: true } },
634
+ browser: { sessionMode: 'isolated' },
635
+ },
636
+ });
637
+ const instance1 = BrowserManager.getInstance(mockConfig);
638
+ const instance2 = BrowserManager.getInstance(isolatedConfig);
639
+ expect(instance1).not.toBe(instance2);
640
+ });
641
+ it('should return different instances for different profile paths', () => {
642
+ const config1 = makeFakeConfig({
643
+ agents: {
644
+ overrides: { browser_agent: { enabled: true } },
645
+ browser: { profilePath: '/path/a' },
646
+ },
647
+ });
648
+ const config2 = makeFakeConfig({
649
+ agents: {
650
+ overrides: { browser_agent: { enabled: true } },
651
+ browser: { profilePath: '/path/b' },
652
+ },
653
+ });
654
+ const instance1 = BrowserManager.getInstance(config1);
655
+ const instance2 = BrowserManager.getInstance(config2);
656
+ expect(instance1).not.toBe(instance2);
657
+ });
658
+ it('should throw when acquired instance is requested in persistent mode', () => {
659
+ // mockConfig defaults to persistent mode
660
+ const instance1 = BrowserManager.getInstance(mockConfig);
661
+ instance1.acquire();
662
+ expect(() => BrowserManager.getInstance(mockConfig)).toThrow(/Cannot launch a concurrent browser agent in "persistent" session mode/);
663
+ });
664
+ it('should throw when acquired instance is requested in existing mode', () => {
665
+ const existingConfig = makeFakeConfig({
666
+ agents: {
667
+ overrides: { browser_agent: { enabled: true } },
668
+ browser: { sessionMode: 'existing' },
669
+ },
670
+ });
671
+ const instance1 = BrowserManager.getInstance(existingConfig);
672
+ instance1.acquire();
673
+ expect(() => BrowserManager.getInstance(existingConfig)).toThrow(/Cannot launch a concurrent browser agent in "existing" session mode/);
674
+ });
675
+ it('should return a different instance when the primary is acquired in isolated mode', () => {
676
+ const isolatedConfig = makeFakeConfig({
677
+ agents: {
678
+ overrides: { browser_agent: { enabled: true } },
679
+ browser: { sessionMode: 'isolated' },
680
+ },
681
+ });
682
+ const instance1 = BrowserManager.getInstance(isolatedConfig);
683
+ instance1.acquire();
684
+ const instance2 = BrowserManager.getInstance(isolatedConfig);
685
+ expect(instance2).not.toBe(instance1);
686
+ expect(instance1.isAcquired()).toBe(true);
687
+ expect(instance2.isAcquired()).toBe(false);
688
+ });
689
+ it('should reuse the primary when it has been released', () => {
690
+ const instance1 = BrowserManager.getInstance(mockConfig);
691
+ instance1.acquire();
692
+ instance1.release();
693
+ const instance2 = BrowserManager.getInstance(mockConfig);
694
+ expect(instance2).toBe(instance1);
695
+ expect(instance1.isAcquired()).toBe(false);
696
+ });
697
+ it('should reuse a released parallel instance in isolated mode', () => {
698
+ const isolatedConfig = makeFakeConfig({
699
+ agents: {
700
+ overrides: { browser_agent: { enabled: true } },
701
+ browser: { sessionMode: 'isolated' },
702
+ },
703
+ });
704
+ const instance1 = BrowserManager.getInstance(isolatedConfig);
705
+ instance1.acquire();
706
+ const instance2 = BrowserManager.getInstance(isolatedConfig);
707
+ instance2.acquire();
708
+ instance2.release();
709
+ // Primary is still acquired, parallel is released — should reuse parallel
710
+ const instance3 = BrowserManager.getInstance(isolatedConfig);
711
+ expect(instance3).toBe(instance2);
712
+ });
713
+ it('should create multiple parallel instances in isolated mode', () => {
714
+ const isolatedConfig = makeFakeConfig({
715
+ agents: {
716
+ overrides: { browser_agent: { enabled: true } },
717
+ browser: { sessionMode: 'isolated' },
718
+ },
719
+ });
720
+ const instance1 = BrowserManager.getInstance(isolatedConfig);
721
+ instance1.acquire();
722
+ const instance2 = BrowserManager.getInstance(isolatedConfig);
723
+ instance2.acquire();
724
+ const instance3 = BrowserManager.getInstance(isolatedConfig);
725
+ expect(instance1).not.toBe(instance2);
726
+ expect(instance2).not.toBe(instance3);
727
+ expect(instance1).not.toBe(instance3);
728
+ });
729
+ it('should throw when MAX_PARALLEL_INSTANCES is reached in isolated mode', () => {
730
+ const isolatedConfig = makeFakeConfig({
731
+ agents: {
732
+ overrides: { browser_agent: { enabled: true } },
733
+ browser: { sessionMode: 'isolated' },
734
+ },
735
+ });
736
+ // Acquire MAX_PARALLEL_INSTANCES instances
737
+ for (let i = 0; i < BrowserManager.MAX_PARALLEL_INSTANCES; i++) {
738
+ const instance = BrowserManager.getInstance(isolatedConfig);
739
+ instance.acquire();
740
+ }
741
+ // Next call should throw
742
+ expect(() => BrowserManager.getInstance(isolatedConfig)).toThrow(/Maximum number of parallel browser instances/);
743
+ });
744
+ });
745
+ describe('resetAll', () => {
746
+ it('should close all instances and clear the cache', async () => {
747
+ const instance1 = BrowserManager.getInstance(mockConfig);
748
+ await instance1.ensureConnection();
749
+ const isolatedConfig = makeFakeConfig({
750
+ agents: {
751
+ overrides: { browser_agent: { enabled: true } },
752
+ browser: { sessionMode: 'isolated' },
753
+ },
754
+ });
755
+ const instance2 = BrowserManager.getInstance(isolatedConfig);
756
+ await instance2.ensureConnection();
757
+ await BrowserManager.resetAll();
758
+ // After resetAll, getInstance should return new instances
759
+ const instance3 = BrowserManager.getInstance(mockConfig);
760
+ expect(instance3).not.toBe(instance1);
761
+ });
762
+ it('should handle errors during cleanup gracefully', async () => {
763
+ const instance = BrowserManager.getInstance(mockConfig);
764
+ await instance.ensureConnection();
765
+ // Make close throw by overriding the client's close method
766
+ const client = await instance.getRawMcpClient();
767
+ vi.mocked(client.close).mockRejectedValueOnce(new Error('close failed'));
768
+ // Should not throw
769
+ await expect(BrowserManager.resetAll()).resolves.toBeUndefined();
770
+ });
771
+ it('should NOT log error when transport closes during resetAll()', async () => {
772
+ const instance = BrowserManager.getInstance(mockConfig);
773
+ await instance.ensureConnection();
774
+ const transportInstance = vi.mocked(StdioClientTransport).mock.results[0]?.value;
775
+ // Trigger onclose during close() which is called by resetAll()
776
+ vi.spyOn(transportInstance, 'close').mockImplementation(async () => {
777
+ transportInstance.onclose?.();
778
+ });
779
+ await BrowserManager.resetAll();
780
+ expect(debugLogger.error).not.toHaveBeenCalledWith(expect.stringContaining('transport closed unexpectedly'));
781
+ });
782
+ });
783
+ describe('isConnected', () => {
784
+ it('should return false before connection', () => {
785
+ const manager = new BrowserManager(mockConfig);
786
+ expect(manager.isConnected()).toBe(false);
787
+ });
788
+ it('should return true after successful connection', async () => {
789
+ const manager = new BrowserManager(mockConfig);
790
+ await manager.ensureConnection();
791
+ expect(manager.isConnected()).toBe(true);
792
+ });
793
+ it('should return false after close', async () => {
794
+ const manager = new BrowserManager(mockConfig);
795
+ await manager.ensureConnection();
478
796
  await manager.close();
479
- expect(client.close).toHaveBeenCalled();
797
+ expect(manager.isConnected()).toBe(false);
798
+ });
799
+ });
800
+ describe('reconnection', () => {
801
+ it('should reconnect after unexpected disconnect and log error', async () => {
802
+ const manager = new BrowserManager(mockConfig);
803
+ await manager.ensureConnection();
804
+ // Simulate transport closing unexpectedly via the onclose callback
805
+ const transportInstance = vi.mocked(StdioClientTransport).mock.results[0]?.value;
806
+ if (transportInstance?.onclose) {
807
+ transportInstance.onclose();
808
+ }
809
+ expect(debugLogger.error).toHaveBeenCalledWith(expect.stringContaining('transport closed unexpectedly'));
810
+ // Manager should recognize disconnection
811
+ expect(manager.isConnected()).toBe(false);
812
+ // ensureConnection should reconnect
813
+ await manager.ensureConnection();
814
+ expect(manager.isConnected()).toBe(true);
815
+ });
816
+ });
817
+ describe('concurrency', () => {
818
+ it('should not call connectMcp twice when ensureConnection is called concurrently', async () => {
819
+ const manager = new BrowserManager(mockConfig);
820
+ // Call ensureConnection twice simultaneously without awaiting the first
821
+ const [p1, p2] = [manager.ensureConnection(), manager.ensureConnection()];
822
+ await Promise.all([p1, p2]);
823
+ // connectMcp (via StdioClientTransport constructor) should only have been called once
824
+ // Each connection attempt creates a new StdioClientTransport
480
825
  });
481
826
  });
482
827
  describe('overlay re-injection in callTool', () => {
483
- it('should re-inject overlay after click in non-headless mode', async () => {
828
+ it('should re-inject overlay and input blocker after click in non-headless mode when input disabling is enabled', async () => {
829
+ // Enable input disabling in config
830
+ mockConfig = makeFakeConfig({
831
+ agents: {
832
+ overrides: {
833
+ browser_agent: {
834
+ enabled: true,
835
+ },
836
+ },
837
+ browser: {
838
+ headless: false,
839
+ disableUserInput: true,
840
+ },
841
+ },
842
+ });
484
843
  const manager = new BrowserManager(mockConfig);
485
844
  await manager.callTool('click', { uid: '1_2' });
486
845
  expect(injectAutomationOverlay).toHaveBeenCalledWith(manager, undefined);
846
+ expect(injectInputBlocker).toHaveBeenCalledWith(manager, undefined);
487
847
  });
488
- it('should re-inject overlay after navigate_page in non-headless mode', async () => {
848
+ it('should re-inject overlay and input blocker after navigate_page in non-headless mode when input disabling is enabled', async () => {
849
+ mockConfig = makeFakeConfig({
850
+ agents: {
851
+ overrides: {
852
+ browser_agent: {
853
+ enabled: true,
854
+ },
855
+ },
856
+ browser: {
857
+ headless: false,
858
+ disableUserInput: true,
859
+ },
860
+ },
861
+ });
489
862
  const manager = new BrowserManager(mockConfig);
490
863
  await manager.callTool('navigate_page', { url: 'https://example.com' });
491
864
  expect(injectAutomationOverlay).toHaveBeenCalledWith(manager, undefined);
865
+ expect(injectInputBlocker).toHaveBeenCalledWith(manager, undefined);
492
866
  });
493
- it('should re-inject overlay after click_at, new_page, press_key, handle_dialog', async () => {
867
+ it('should re-inject overlay and input blocker after click_at, new_page, press_key, handle_dialog when input disabling is enabled', async () => {
868
+ mockConfig = makeFakeConfig({
869
+ agents: {
870
+ overrides: {
871
+ browser_agent: {
872
+ enabled: true,
873
+ },
874
+ },
875
+ browser: {
876
+ headless: false,
877
+ disableUserInput: true,
878
+ },
879
+ },
880
+ });
494
881
  const manager = new BrowserManager(mockConfig);
495
882
  for (const tool of [
496
883
  'click_at',
@@ -499,11 +886,14 @@ describe('BrowserManager', () => {
499
886
  'handle_dialog',
500
887
  ]) {
501
888
  vi.mocked(injectAutomationOverlay).mockClear();
889
+ vi.mocked(injectInputBlocker).mockClear();
502
890
  await manager.callTool(tool, {});
503
891
  expect(injectAutomationOverlay).toHaveBeenCalledTimes(1);
892
+ expect(injectInputBlocker).toHaveBeenCalledTimes(1);
893
+ expect(injectInputBlocker).toHaveBeenCalledWith(manager, undefined);
504
894
  }
505
895
  });
506
- it('should NOT re-inject overlay after read-only tools', async () => {
896
+ it('should NOT re-inject overlay or input blocker after read-only tools', async () => {
507
897
  const manager = new BrowserManager(mockConfig);
508
898
  for (const tool of [
509
899
  'take_snapshot',
@@ -512,8 +902,10 @@ describe('BrowserManager', () => {
512
902
  'fill',
513
903
  ]) {
514
904
  vi.mocked(injectAutomationOverlay).mockClear();
905
+ vi.mocked(injectInputBlocker).mockClear();
515
906
  await manager.callTool(tool, {});
516
907
  expect(injectAutomationOverlay).not.toHaveBeenCalled();
908
+ expect(injectInputBlocker).not.toHaveBeenCalled();
517
909
  }
518
910
  });
519
911
  it('should NOT re-inject overlay when headless is true', async () => {
@@ -539,7 +931,136 @@ describe('BrowserManager', () => {
539
931
  }));
540
932
  const manager = new BrowserManager(mockConfig);
541
933
  await manager.callTool('click', { uid: 'bad' });
934
+ });
935
+ it('should NOT re-inject overlay if select_page is called with bringToFront: false', async () => {
936
+ mockConfig = makeFakeConfig({
937
+ agents: {
938
+ overrides: {
939
+ browser_agent: {
940
+ enabled: true,
941
+ },
942
+ },
943
+ browser: {
944
+ headless: false,
945
+ disableUserInput: true,
946
+ },
947
+ },
948
+ });
949
+ const manager = new BrowserManager(mockConfig);
950
+ await manager.callTool('select_page', { pageId: 1, bringToFront: false });
542
951
  expect(injectAutomationOverlay).not.toHaveBeenCalled();
952
+ expect(injectInputBlocker).not.toHaveBeenCalled();
953
+ });
954
+ });
955
+ describe('Rate limiting', () => {
956
+ it('should terminate task when maxActionsPerTask is reached', async () => {
957
+ const limitedConfig = makeFakeConfig({
958
+ agents: {
959
+ browser: {
960
+ maxActionsPerTask: 3,
961
+ },
962
+ },
963
+ });
964
+ const manager = new BrowserManager(limitedConfig);
965
+ // First 3 calls should succeed
966
+ await manager.callTool('take_snapshot', {});
967
+ await manager.callTool('take_snapshot', { some: 'args' });
968
+ await manager.callTool('take_snapshot', { other: 'args' });
969
+ await manager.callTool('take_snapshot', { other: 'new args' });
970
+ // 4th call should throw
971
+ await expect(manager.callTool('take_snapshot', {})).rejects.toThrow(/maximum action limit \(3\)/);
972
+ });
973
+ it('should NOT increment action counter when shouldCount is false', async () => {
974
+ const limitedConfig = makeFakeConfig({
975
+ agents: {
976
+ browser: {
977
+ maxActionsPerTask: 1,
978
+ },
979
+ },
980
+ });
981
+ const manager = new BrowserManager(limitedConfig);
982
+ // Multiple calls with isInternal: true should NOT exhaust the limit
983
+ await manager.callTool('evaluate_script', {}, undefined, true);
984
+ await manager.callTool('evaluate_script', {}, undefined, true);
985
+ await manager.callTool('evaluate_script', {}, undefined, true);
986
+ // This should still work
987
+ await manager.callTool('take_snapshot', {});
988
+ // Next one should throw (limit 1 allows exactly 1 call with >= check)
989
+ await expect(manager.callTool('take_snapshot', {})).rejects.toThrow(/maximum action limit \(1\)/);
990
+ });
991
+ });
992
+ describe('sandbox behavior', () => {
993
+ afterEach(() => {
994
+ vi.unstubAllEnvs();
995
+ });
996
+ it('should force --isolated and --headless when in seatbelt sandbox with persistent mode', async () => {
997
+ vi.stubEnv('SANDBOX', 'sandbox-exec');
998
+ const feedbackSpy = vi
999
+ .spyOn(coreEvents, 'emitFeedback')
1000
+ .mockImplementation(() => { });
1001
+ const manager = new BrowserManager(mockConfig); // default persistent mode
1002
+ await manager.ensureConnection();
1003
+ const args = vi.mocked(StdioClientTransport).mock.calls[0]?.[0]
1004
+ ?.args;
1005
+ expect(args).toContain('--isolated');
1006
+ expect(args).toContain('--headless');
1007
+ expect(args).not.toContain('--userDataDir');
1008
+ expect(args).not.toContain('--autoConnect');
1009
+ expect(feedbackSpy).toHaveBeenCalledWith('info', expect.stringContaining('isolated browser session'));
1010
+ });
1011
+ it('should preserve --autoConnect when in seatbelt sandbox with existing mode', async () => {
1012
+ vi.stubEnv('SANDBOX', 'sandbox-exec');
1013
+ const existingConfig = makeFakeConfig({
1014
+ agents: {
1015
+ overrides: { browser_agent: { enabled: true } },
1016
+ browser: { sessionMode: 'existing' },
1017
+ },
1018
+ });
1019
+ const manager = new BrowserManager(existingConfig);
1020
+ await manager.ensureConnection();
1021
+ const args = vi.mocked(StdioClientTransport).mock.calls[0]?.[0]
1022
+ ?.args;
1023
+ expect(args).toContain('--autoConnect');
1024
+ expect(args).not.toContain('--isolated');
1025
+ // Headless should NOT be forced for existing mode in seatbelt
1026
+ expect(args).not.toContain('--headless');
1027
+ });
1028
+ it('should use --browser-url with resolved IP for container sandbox with existing mode', async () => {
1029
+ vi.stubEnv('SANDBOX', 'docker-container-0');
1030
+ // Mock DNS resolution of host.docker.internal
1031
+ const dns = await import('node:dns');
1032
+ vi.spyOn(dns.promises, 'lookup').mockResolvedValue({
1033
+ address: '192.168.127.254',
1034
+ family: 4,
1035
+ });
1036
+ const feedbackSpy = vi
1037
+ .spyOn(coreEvents, 'emitFeedback')
1038
+ .mockImplementation(() => { });
1039
+ const existingConfig = makeFakeConfig({
1040
+ agents: {
1041
+ overrides: { browser_agent: { enabled: true } },
1042
+ browser: { sessionMode: 'existing' },
1043
+ },
1044
+ });
1045
+ const manager = new BrowserManager(existingConfig);
1046
+ await manager.ensureConnection();
1047
+ const args = vi.mocked(StdioClientTransport).mock.calls[0]?.[0]
1048
+ ?.args;
1049
+ expect(args).toContain('--browser-url');
1050
+ expect(args).toContain('http://192.168.127.254:9222');
1051
+ expect(args).not.toContain('--autoConnect');
1052
+ expect(feedbackSpy).toHaveBeenCalledWith('info', expect.stringContaining('192.168.127.254:9222'));
1053
+ });
1054
+ it('should not override session mode when not in sandbox', async () => {
1055
+ vi.stubEnv('SANDBOX', '');
1056
+ const manager = new BrowserManager(mockConfig);
1057
+ await manager.ensureConnection();
1058
+ const args = vi.mocked(StdioClientTransport).mock.calls[0]?.[0]
1059
+ ?.args;
1060
+ // Default persistent mode: no --isolated, no --autoConnect
1061
+ expect(args).not.toContain('--isolated');
1062
+ expect(args).not.toContain('--autoConnect');
1063
+ expect(args).toContain('--userDataDir');
543
1064
  });
544
1065
  });
545
1066
  });