@minionry/minion 0.7.36

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 (476) hide show
  1. package/LICENSE +14 -0
  2. package/PRIVACY.md +357 -0
  3. package/README.md +57 -0
  4. package/THIRD_PARTY_NOTICES.md +245 -0
  5. package/bin/branding.js +4 -0
  6. package/bin/commands/browser-install.js +483 -0
  7. package/bin/commands/create-sandbox.js +542 -0
  8. package/bin/commands/fingerprint.js +101 -0
  9. package/bin/commands/login.js +400 -0
  10. package/bin/commands/logout.js +93 -0
  11. package/bin/commands/minions.js +211 -0
  12. package/bin/commands/sandboxes.js +309 -0
  13. package/bin/commands/status.js +298 -0
  14. package/bin/commands/whoami.js +153 -0
  15. package/bin/launch-env.js +35 -0
  16. package/bin/machine-identity.js +221 -0
  17. package/bin/machine-layout.js +200 -0
  18. package/bin/minion.js +839 -0
  19. package/bin/platform-endpoints.js +8 -0
  20. package/bin/postinstall.js +52 -0
  21. package/bin/pty-doctor.js +326 -0
  22. package/bin/pty-locator.js +110 -0
  23. package/bin/pty-provision.js +186 -0
  24. package/bin/sandbox/Dockerfile +78 -0
  25. package/bin/sandbox/entrypoint.sh +14 -0
  26. package/bin/sandbox/install-repo.sh +53 -0
  27. package/bin/sandbox/seccomp-userns.json +883 -0
  28. package/bin/sandbox-config.js +306 -0
  29. package/dist/bin/machine-identity.js +221 -0
  30. package/dist/bin/machine-layout.js +200 -0
  31. package/dist/electron-host/agent-lease.js +141 -0
  32. package/dist/electron-host/dom-driver.js +642 -0
  33. package/dist/electron-host/ipc-protocol.js +89 -0
  34. package/dist/electron-host/js-driver.js +216 -0
  35. package/dist/electron-host/view-manager.js +254 -0
  36. package/dist/server/cli/engine-resume.js +49 -0
  37. package/dist/server/cli/eta-estimator.js +278 -0
  38. package/dist/server/cli/headless/background-activity.js +109 -0
  39. package/dist/server/cli/headless/claude-invoker-process.js +614 -0
  40. package/dist/server/cli/headless/claude-invoker-stall.js +150 -0
  41. package/dist/server/cli/headless/claude-invoker-stream.js +555 -0
  42. package/dist/server/cli/headless/claude-invoker-tools.js +148 -0
  43. package/dist/server/cli/headless/claude-invoker.js +151 -0
  44. package/dist/server/cli/headless/engine-availability.js +92 -0
  45. package/dist/server/cli/headless/engine-notice.js +185 -0
  46. package/dist/server/cli/headless/haiku-assessments.js +293 -0
  47. package/dist/server/cli/headless/headless-logger.js +75 -0
  48. package/dist/server/cli/headless/index.js +9 -0
  49. package/dist/server/cli/headless/mcp-config.js +314 -0
  50. package/dist/server/cli/headless/native-timeout-detector.js +72 -0
  51. package/dist/server/cli/headless/output-utils.js +71 -0
  52. package/dist/server/cli/headless/prompt-utils.js +82 -0
  53. package/dist/server/cli/headless/resilient-runner.js +326 -0
  54. package/dist/server/cli/headless/retry-strategies.js +292 -0
  55. package/dist/server/cli/headless/runner.js +245 -0
  56. package/dist/server/cli/headless/stall-assessor.js +295 -0
  57. package/dist/server/cli/headless/tool-watchdog.js +447 -0
  58. package/dist/server/cli/headless/types.js +18 -0
  59. package/dist/server/cli/history-portability.js +85 -0
  60. package/dist/server/cli/improvisation-attachments.js +99 -0
  61. package/dist/server/cli/improvisation-history-store.js +121 -0
  62. package/dist/server/cli/improvisation-movements.js +137 -0
  63. package/dist/server/cli/improvisation-output-queue.js +34 -0
  64. package/dist/server/cli/improvisation-retry.js +8 -0
  65. package/dist/server/cli/improvisation-session-manager.js +1016 -0
  66. package/dist/server/cli/improvisation-types.js +31 -0
  67. package/dist/server/cli/plan-lifecycle.js +72 -0
  68. package/dist/server/cli/prompt-builders.js +371 -0
  69. package/dist/server/cli/retry/retry-best-result.js +28 -0
  70. package/dist/server/cli/retry/retry-context-loss.js +75 -0
  71. package/dist/server/cli/retry/retry-recovery-strategies.js +213 -0
  72. package/dist/server/cli/retry/retry-resume-strategy.js +20 -0
  73. package/dist/server/cli/retry/retry-runner-factory.js +92 -0
  74. package/dist/server/cli/retry/retry-tool-results.js +22 -0
  75. package/dist/server/cli/retry/retry-types.js +3 -0
  76. package/dist/server/engines/EngineEvent.js +57 -0
  77. package/dist/server/engines/claude/ClaudeCodeEngine.js +316 -0
  78. package/dist/server/engines/claude/claude-command.js +32 -0
  79. package/dist/server/engines/codex/CodexEngine.js +469 -0
  80. package/dist/server/engines/codex/codex-auth.js +203 -0
  81. package/dist/server/engines/codex/codex-invoker.js +205 -0
  82. package/dist/server/engines/codex/codex-provision.js +215 -0
  83. package/dist/server/engines/credentials/credential-probe.js +88 -0
  84. package/dist/server/engines/credentials/model-profiles.js +249 -0
  85. package/dist/server/engines/credentials/provider-credentials.js +146 -0
  86. package/dist/server/engines/engine-event-stream.js +52 -0
  87. package/dist/server/engines/execution/engine-session.js +380 -0
  88. package/dist/server/engines/factory.js +42 -0
  89. package/dist/server/engines/hermes/HermesEngine.js +628 -0
  90. package/dist/server/engines/hermes/hermes-auth.js +159 -0
  91. package/dist/server/engines/hermes/hermes-gateway-home.js +271 -0
  92. package/dist/server/engines/hermes/hermes-invoker.js +350 -0
  93. package/dist/server/engines/hermes/hermes-provision.js +318 -0
  94. package/dist/server/engines/read-only.js +20 -0
  95. package/dist/server/engines/types.js +27 -0
  96. package/dist/server/handlers/company-execution-registry.js +67 -0
  97. package/dist/server/handlers/company-handlers.js +514 -0
  98. package/dist/server/handlers/company-triggers.js +189 -0
  99. package/dist/server/handlers/company-types.js +3 -0
  100. package/dist/server/index.js +244 -0
  101. package/dist/server/mcp/app-tools-bridge.js +110 -0
  102. package/dist/server/mcp/app-tools-mcp-server.js +99 -0
  103. package/dist/server/mcp/bouncer-integration.js +744 -0
  104. package/dist/server/mcp/browser-mcp-server.js +915 -0
  105. package/dist/server/mcp/browser-redaction.js +103 -0
  106. package/dist/server/mcp/classifier/BouncerClassifier.js +3 -0
  107. package/dist/server/mcp/classifier/ClaudeBouncerClassifier.js +212 -0
  108. package/dist/server/mcp/classifier/factory.js +124 -0
  109. package/dist/server/mcp/classifier/health.js +54 -0
  110. package/dist/server/mcp/classifier/telemetry.js +0 -0
  111. package/dist/server/mcp/company-patterns.js +104 -0
  112. package/dist/server/mcp/department-profiles.js +133 -0
  113. package/dist/server/mcp/quality-bridge.js +153 -0
  114. package/dist/server/mcp/quality-mcp-server.js +105 -0
  115. package/dist/server/mcp/security-analysis.js +384 -0
  116. package/dist/server/mcp/security-audit.js +152 -0
  117. package/dist/server/mcp/security-patterns.js +314 -0
  118. package/dist/server/mcp/server.js +194 -0
  119. package/dist/server/mcp/test-utils/agent-simulator.js +301 -0
  120. package/dist/server/mcp/test-utils/e2e-agent.js +103 -0
  121. package/dist/server/mcp/test-utils/e2e-capture.js +92 -0
  122. package/dist/server/mcp/test-utils/e2e-client.js +116 -0
  123. package/dist/server/mcp/test-utils/e2e-fixtures.js +87 -0
  124. package/dist/server/mcp/test-utils/e2e-gating.js +8 -0
  125. package/dist/server/mcp/test-utils/e2e-harness.js +8 -0
  126. package/dist/server/mcp/test-utils/e2e-scenarios.js +105 -0
  127. package/dist/server/routes/files.js +18 -0
  128. package/dist/server/routes/improvise.js +64 -0
  129. package/dist/server/routes/index.js +7 -0
  130. package/dist/server/routes/instances.js +41 -0
  131. package/dist/server/routes/internal.js +900 -0
  132. package/dist/server/routes/notifications.js +110 -0
  133. package/dist/server/server-setup.js +282 -0
  134. package/dist/server/services/agent-push.js +148 -0
  135. package/dist/server/services/analytics.js +197 -0
  136. package/dist/server/services/apps/build.js +249 -0
  137. package/dist/server/services/apps/greenlight.js +199 -0
  138. package/dist/server/services/apps/install.js +101 -0
  139. package/dist/server/services/apps/layout.js +35 -0
  140. package/dist/server/services/apps/serve.js +665 -0
  141. package/dist/server/services/apps/space-apps.js +248 -0
  142. package/dist/server/services/auth.js +48 -0
  143. package/dist/server/services/browser/chrome-sandbox.js +245 -0
  144. package/dist/server/services/browser/chromium-launch-spec.js +51 -0
  145. package/dist/server/services/browser/claude-reasoner.js +669 -0
  146. package/dist/server/services/browser/debug-log.js +3 -0
  147. package/dist/server/services/browser/driver-state.js +546 -0
  148. package/dist/server/services/browser/electron-provision.js +256 -0
  149. package/dist/server/services/browser/host-internal.js +245 -0
  150. package/dist/server/services/browser/host-mock.js +334 -0
  151. package/dist/server/services/browser/host-types.js +3 -0
  152. package/dist/server/services/browser/host.js +1067 -0
  153. package/dist/server/services/browser/index.js +4 -0
  154. package/dist/server/services/browser/ipc-client.js +354 -0
  155. package/dist/server/services/browser/pipewire-sink.js +199 -0
  156. package/dist/server/services/browser/preflight.js +590 -0
  157. package/dist/server/services/browser/reasoning-agent.js +659 -0
  158. package/dist/server/services/browser/sandbox-policy.js +169 -0
  159. package/dist/server/services/browser/stderr-noise-filter.js +26 -0
  160. package/dist/server/services/browser/telemetry.js +107 -0
  161. package/dist/server/services/browser/xvfb-supervisor.js +139 -0
  162. package/dist/server/services/browser-frame-policy.js +56 -0
  163. package/dist/server/services/client-id.js +32 -0
  164. package/dist/server/services/collab/registry.js +408 -0
  165. package/dist/server/services/collab/session.js +489 -0
  166. package/dist/server/services/collab/text-diff.js +28 -0
  167. package/dist/server/services/collab/types.js +19 -0
  168. package/dist/server/services/e2ee-group-key.js +197 -0
  169. package/dist/server/services/e2ee-identity.js +203 -0
  170. package/dist/server/services/file-explorer-ops.js +328 -0
  171. package/dist/server/services/file-transfer-zip.js +188 -0
  172. package/dist/server/services/files.js +111 -0
  173. package/dist/server/services/git/branch-ops.js +62 -0
  174. package/dist/server/services/git/command.js +68 -0
  175. package/dist/server/services/git/commit-message.js +74 -0
  176. package/dist/server/services/git/diff-ops.js +56 -0
  177. package/dist/server/services/git/haiku.js +76 -0
  178. package/dist/server/services/git/head-watcher.js +226 -0
  179. package/dist/server/services/git/index.js +17 -0
  180. package/dist/server/services/git/log-ops.js +98 -0
  181. package/dist/server/services/git/merge-ops.js +314 -0
  182. package/dist/server/services/git/parsers.js +401 -0
  183. package/dist/server/services/git/remote-ops.js +192 -0
  184. package/dist/server/services/git/status-ops.js +105 -0
  185. package/dist/server/services/git/suggestion-ops.js +80 -0
  186. package/dist/server/services/git/tag-ops.js +36 -0
  187. package/dist/server/services/git/types.js +4 -0
  188. package/dist/server/services/git/worktree-ops.js +114 -0
  189. package/dist/server/services/instances.js +337 -0
  190. package/dist/server/services/model-catalog.js +247 -0
  191. package/dist/server/services/observability/posthog.js +153 -0
  192. package/dist/server/services/pathUtils.js +114 -0
  193. package/dist/server/services/plan/agent-loader.js +97 -0
  194. package/dist/server/services/plan/agent-manager.js +363 -0
  195. package/dist/server/services/plan/agent-resolver.js +74 -0
  196. package/dist/server/services/plan/agents/assess-stall.md +33 -0
  197. package/dist/server/services/plan/agents/browser-planner.md +53 -0
  198. package/dist/server/services/plan/agents/browser-reasoner.md +114 -0
  199. package/dist/server/services/plan/agents/check-injection.md +95 -0
  200. package/dist/server/services/plan/agents/classify-error.md +30 -0
  201. package/dist/server/services/plan/agents/code-review.md +142 -0
  202. package/dist/server/services/plan/agents/commit-message.md +28 -0
  203. package/dist/server/services/plan/agents/detect-context-loss.md +30 -0
  204. package/dist/server/services/plan/agents/execute-issue.md +58 -0
  205. package/dist/server/services/plan/agents/fix-quality.md +25 -0
  206. package/dist/server/services/plan/agents/plan-coordinator.md +72 -0
  207. package/dist/server/services/plan/agents/pr-description.md +29 -0
  208. package/dist/server/services/plan/agents/retry-task.md +27 -0
  209. package/dist/server/services/plan/agents/review-code.md +38 -0
  210. package/dist/server/services/plan/agents/review-quality.md +45 -0
  211. package/dist/server/services/plan/agents/triage-findings.md +78 -0
  212. package/dist/server/services/plan/agents/verify-review.md +57 -0
  213. package/dist/server/services/plan/approval-evaluator.js +143 -0
  214. package/dist/server/services/plan/board-archive.js +102 -0
  215. package/dist/server/services/plan/board-config.js +108 -0
  216. package/dist/server/services/plan/board-export.js +214 -0
  217. package/dist/server/services/plan/composer-prompt.js +115 -0
  218. package/dist/server/services/plan/composer.js +664 -0
  219. package/dist/server/services/plan/config-installer.js +103 -0
  220. package/dist/server/services/plan/dependency-resolver.js +137 -0
  221. package/dist/server/services/plan/executor.js +696 -0
  222. package/dist/server/services/plan/front-matter.js +43 -0
  223. package/dist/server/services/plan/issue-classification.js +10 -0
  224. package/dist/server/services/plan/issue-effort.js +182 -0
  225. package/dist/server/services/plan/issue-loader.js +35 -0
  226. package/dist/server/services/plan/issue-prompt-builder.js +152 -0
  227. package/dist/server/services/plan/issue-retry.js +42 -0
  228. package/dist/server/services/plan/issue-writer.js +102 -0
  229. package/dist/server/services/plan/metrics-collector.js +272 -0
  230. package/dist/server/services/plan/output-manager.js +77 -0
  231. package/dist/server/services/plan/parser-core.js +435 -0
  232. package/dist/server/services/plan/parser-migration.js +108 -0
  233. package/dist/server/services/plan/parser.js +258 -0
  234. package/dist/server/services/plan/plan-runner-factory.js +68 -0
  235. package/dist/server/services/plan/pm-timeline.js +320 -0
  236. package/dist/server/services/plan/progress-log.js +101 -0
  237. package/dist/server/services/plan/prompt-builder.js +142 -0
  238. package/dist/server/services/plan/quality-delta.js +274 -0
  239. package/dist/server/services/plan/readiness-planner.js +34 -0
  240. package/dist/server/services/plan/review-gate.js +409 -0
  241. package/dist/server/services/plan/review-report.js +134 -0
  242. package/dist/server/services/plan/review-verdict-stream.js +161 -0
  243. package/dist/server/services/plan/state-reconciler.js +238 -0
  244. package/dist/server/services/plan/template-diff.js +175 -0
  245. package/dist/server/services/plan/template-instantiator.js +516 -0
  246. package/dist/server/services/plan/template-manifest.js +56 -0
  247. package/dist/server/services/plan/template-types.js +3 -0
  248. package/dist/server/services/plan/trigger-evaluator.js +211 -0
  249. package/dist/server/services/plan/types.js +3 -0
  250. package/dist/server/services/plan/watcher.js +73 -0
  251. package/dist/server/services/platform-credentials.js +56 -0
  252. package/dist/server/services/platform-e2ee.js +421 -0
  253. package/dist/server/services/platform-envelope.js +102 -0
  254. package/dist/server/services/platform-heartbeat.js +88 -0
  255. package/dist/server/services/platform-reconnect.js +60 -0
  256. package/dist/server/services/platform-token-lifecycle.js +95 -0
  257. package/dist/server/services/platform-url.js +17 -0
  258. package/dist/server/services/platform.js +656 -0
  259. package/dist/server/services/runtime-info.js +9 -0
  260. package/dist/server/services/schedule/agent-schedule-store.js +232 -0
  261. package/dist/server/services/schedule/agent-scheduler.js +323 -0
  262. package/dist/server/services/schedule/daily-timing.js +105 -0
  263. package/dist/server/services/schedule/quality-schedule-launch.js +11 -0
  264. package/dist/server/services/schedule/quality-schedule-store.js +211 -0
  265. package/dist/server/services/schedule/quality-scheduler.js +215 -0
  266. package/dist/server/services/schedule/run-bootstrap.js +329 -0
  267. package/dist/server/services/schedule/schedule-store.js +238 -0
  268. package/dist/server/services/schedule/schedule-wire.js +77 -0
  269. package/dist/server/services/schedule/scheduler.js +310 -0
  270. package/dist/server/services/schedule/template-source.js +97 -0
  271. package/dist/server/services/sdk/agent-sessions.js +264 -0
  272. package/dist/server/services/sdk/agents.js +557 -0
  273. package/dist/server/services/sdk/app-endpoints.js +48 -0
  274. package/dist/server/services/sdk/app-tools.js +303 -0
  275. package/dist/server/services/sdk/audit.js +48 -0
  276. package/dist/server/services/sdk/browser-transport.js +188 -0
  277. package/dist/server/services/sdk/browser.js +605 -0
  278. package/dist/server/services/sdk/composer.js +129 -0
  279. package/dist/server/services/sdk/connect.js +273 -0
  280. package/dist/server/services/sdk/consent-cooldown.js +31 -0
  281. package/dist/server/services/sdk/endpoint-url.js +141 -0
  282. package/dist/server/services/sdk/endpoints.js +314 -0
  283. package/dist/server/services/sdk/file-change-notify.js +36 -0
  284. package/dist/server/services/sdk/files-app.js +163 -0
  285. package/dist/server/services/sdk/files-search.js +131 -0
  286. package/dist/server/services/sdk/files-transfer.js +279 -0
  287. package/dist/server/services/sdk/files-workspace.js +233 -0
  288. package/dist/server/services/sdk/git.js +520 -0
  289. package/dist/server/services/sdk/grant-store.js +318 -0
  290. package/dist/server/services/sdk/host-ops.js +84 -0
  291. package/dist/server/services/sdk/inference-claude.js +214 -0
  292. package/dist/server/services/sdk/inference.js +247 -0
  293. package/dist/server/services/sdk/live-registry.js +42 -0
  294. package/dist/server/services/sdk/local-app-bindings.js +71 -0
  295. package/dist/server/services/sdk/pipeline.js +190 -0
  296. package/dist/server/services/sdk/pm-execute.js +228 -0
  297. package/dist/server/services/sdk/pm-planning-tap.js +29 -0
  298. package/dist/server/services/sdk/pm-schedule.js +165 -0
  299. package/dist/server/services/sdk/pm.js +634 -0
  300. package/dist/server/services/sdk/quality-change-notify.js +20 -0
  301. package/dist/server/services/sdk/quality-schedule.js +165 -0
  302. package/dist/server/services/sdk/quality.js +602 -0
  303. package/dist/server/services/sdk/rate-limits.js +198 -0
  304. package/dist/server/services/sdk/registry.js +597 -0
  305. package/dist/server/services/sdk/revoke.js +86 -0
  306. package/dist/server/services/sdk/run-profile.js +41 -0
  307. package/dist/server/services/sdk/sandbox.js +89 -0
  308. package/dist/server/services/sdk/storage.js +110 -0
  309. package/dist/server/services/sdk/streams.js +147 -0
  310. package/dist/server/services/sdk/terminal.js +201 -0
  311. package/dist/server/services/sdk/test-utils/workshop-browser-app.js +466 -0
  312. package/dist/server/services/sentry.js +99 -0
  313. package/dist/server/services/settings.js +374 -0
  314. package/dist/server/services/snippets/expander.js +87 -0
  315. package/dist/server/services/snippets/index.js +6 -0
  316. package/dist/server/services/snippets/loader.js +119 -0
  317. package/dist/server/services/snippets/parser.js +52 -0
  318. package/dist/server/services/snippets/types.js +3 -0
  319. package/dist/server/services/snippets/watcher.js +60 -0
  320. package/dist/server/services/space-layout.js +80 -0
  321. package/dist/server/services/system-prompts.js +219 -0
  322. package/dist/server/services/terminal/pty-manager.js +206 -0
  323. package/dist/server/services/terminal/pty-utils.js +150 -0
  324. package/dist/server/services/timeline/assembler.js +890 -0
  325. package/dist/server/services/timeline/contract.js +196 -0
  326. package/dist/server/services/timeline/index.js +4 -0
  327. package/dist/server/services/websocket/agent-schedule-handlers.js +217 -0
  328. package/dist/server/services/websocket/apps-handlers.js +399 -0
  329. package/dist/server/services/websocket/ask-user-question-bridge.js +112 -0
  330. package/dist/server/services/websocket/autocomplete-index.js +415 -0
  331. package/dist/server/services/websocket/autocomplete-match.js +243 -0
  332. package/dist/server/services/websocket/autocomplete.js +407 -0
  333. package/dist/server/services/websocket/browser-agent-runtime.js +208 -0
  334. package/dist/server/services/websocket/browser-device-profile.js +46 -0
  335. package/dist/server/services/websocket/browser-handlers.js +377 -0
  336. package/dist/server/services/websocket/browser-host-broadcast.js +179 -0
  337. package/dist/server/services/websocket/browser-ice-config.js +121 -0
  338. package/dist/server/services/websocket/browser-payloads.js +222 -0
  339. package/dist/server/services/websocket/browser-viewer-lifecycle.js +84 -0
  340. package/dist/server/services/websocket/browser-viewer-registry.js +118 -0
  341. package/dist/server/services/websocket/collab-broadcast.js +11 -0
  342. package/dist/server/services/websocket/collab-handlers.js +116 -0
  343. package/dist/server/services/websocket/commit-suggestion-service.js +132 -0
  344. package/dist/server/services/websocket/debug-log.js +38 -0
  345. package/dist/server/services/websocket/dispatch-util.js +10 -0
  346. package/dist/server/services/websocket/engine-auth-handlers.js +323 -0
  347. package/dist/server/services/websocket/engine-credential-watcher.js +83 -0
  348. package/dist/server/services/websocket/engine-profile-handlers.js +92 -0
  349. package/dist/server/services/websocket/file-definition-handlers.js +180 -0
  350. package/dist/server/services/websocket/file-download-handler.js +291 -0
  351. package/dist/server/services/websocket/file-explorer-handlers.js +291 -0
  352. package/dist/server/services/websocket/file-search-handlers.js +267 -0
  353. package/dist/server/services/websocket/file-share-handlers.js +328 -0
  354. package/dist/server/services/websocket/file-transfer-http.js +361 -0
  355. package/dist/server/services/websocket/file-upload-handler.js +267 -0
  356. package/dist/server/services/websocket/file-utils.js +346 -0
  357. package/dist/server/services/websocket/git-branch-handlers.js +90 -0
  358. package/dist/server/services/websocket/git-diff-handlers.js +59 -0
  359. package/dist/server/services/websocket/git-handlers.js +212 -0
  360. package/dist/server/services/websocket/git-head-watcher.js +85 -0
  361. package/dist/server/services/websocket/git-log-handlers.js +104 -0
  362. package/dist/server/services/websocket/git-pr-handlers.js +56 -0
  363. package/dist/server/services/websocket/git-tag-handlers.js +53 -0
  364. package/dist/server/services/websocket/git-utils.js +11 -0
  365. package/dist/server/services/websocket/git-worktree-handlers.js +521 -0
  366. package/dist/server/services/websocket/handler-context.js +113 -0
  367. package/dist/server/services/websocket/handler.js +1197 -0
  368. package/dist/server/services/websocket/index.js +5 -0
  369. package/dist/server/services/websocket/movement-written-files.js +26 -0
  370. package/dist/server/services/websocket/msg-id-tracker.js +48 -0
  371. package/dist/server/services/websocket/plan-board-handlers.js +410 -0
  372. package/dist/server/services/websocket/plan-execution-handlers.js +244 -0
  373. package/dist/server/services/websocket/plan-handlers.js +67 -0
  374. package/dist/server/services/websocket/plan-helpers.js +161 -0
  375. package/dist/server/services/websocket/plan-issue-handlers.js +168 -0
  376. package/dist/server/services/websocket/plan-sprint-handlers.js +190 -0
  377. package/dist/server/services/websocket/plan-transfer-handlers.js +310 -0
  378. package/dist/server/services/websocket/pm-timeline-broadcast.js +28 -0
  379. package/dist/server/services/websocket/post-session-scan.js +132 -0
  380. package/dist/server/services/websocket/prompt-queue-handlers.js +96 -0
  381. package/dist/server/services/websocket/quality-agent-cost.js +229 -0
  382. package/dist/server/services/websocket/quality-agent-notes.js +113 -0
  383. package/dist/server/services/websocket/quality-change-activity.js +187 -0
  384. package/dist/server/services/websocket/quality-complexity.js +345 -0
  385. package/dist/server/services/websocket/quality-dependencies.js +445 -0
  386. package/dist/server/services/websocket/quality-duplication.js +162 -0
  387. package/dist/server/services/websocket/quality-eta.js +65 -0
  388. package/dist/server/services/websocket/quality-fingerprint.js +104 -0
  389. package/dist/server/services/websocket/quality-grading.js +575 -0
  390. package/dist/server/services/websocket/quality-handlers.js +48 -0
  391. package/dist/server/services/websocket/quality-linting.js +270 -0
  392. package/dist/server/services/websocket/quality-operations.js +54 -0
  393. package/dist/server/services/websocket/quality-persistence.js +410 -0
  394. package/dist/server/services/websocket/quality-review-agent.js +526 -0
  395. package/dist/server/services/websocket/quality-run.js +220 -0
  396. package/dist/server/services/websocket/quality-secrets.js +0 -0
  397. package/dist/server/services/websocket/quality-service.js +775 -0
  398. package/dist/server/services/websocket/quality-tools.js +383 -0
  399. package/dist/server/services/websocket/quality-triage-agent.js +101 -0
  400. package/dist/server/services/websocket/quality-types.js +149 -0
  401. package/dist/server/services/websocket/recommended-answers.js +28 -0
  402. package/dist/server/services/websocket/schedule-handlers.js +197 -0
  403. package/dist/server/services/websocket/sdk-agent-host.js +569 -0
  404. package/dist/server/services/websocket/sdk-browser-host.js +459 -0
  405. package/dist/server/services/websocket/sdk-composer-host.js +10 -0
  406. package/dist/server/services/websocket/sdk-git-host.js +115 -0
  407. package/dist/server/services/websocket/sdk-handlers.js +242 -0
  408. package/dist/server/services/websocket/sdk-pm-execution-host.js +63 -0
  409. package/dist/server/services/websocket/sdk-pm-schedule-host.js +21 -0
  410. package/dist/server/services/websocket/sdk-quality-schedule-host.js +34 -0
  411. package/dist/server/services/websocket/sdk-terminal-host.js +140 -0
  412. package/dist/server/services/websocket/session-handlers.js +565 -0
  413. package/dist/server/services/websocket/session-history.js +335 -0
  414. package/dist/server/services/websocket/session-initialization.js +315 -0
  415. package/dist/server/services/websocket/session-registry.js +340 -0
  416. package/dist/server/services/websocket/session-role-directory.js +39 -0
  417. package/dist/server/services/websocket/settings-handlers.js +276 -0
  418. package/dist/server/services/websocket/skill-handlers.js +324 -0
  419. package/dist/server/services/websocket/skill-watcher.js +83 -0
  420. package/dist/server/services/websocket/snippet-handlers.js +261 -0
  421. package/dist/server/services/websocket/tab-broadcast.js +35 -0
  422. package/dist/server/services/websocket/tab-event-buffer.js +110 -0
  423. package/dist/server/services/websocket/tab-event-replay.js +47 -0
  424. package/dist/server/services/websocket/tab-handlers.js +211 -0
  425. package/dist/server/services/websocket/terminal-handlers.js +268 -0
  426. package/dist/server/services/websocket/types.js +96 -0
  427. package/dist/server/types/company-messages.js +102 -0
  428. package/dist/server/utils/agent-manager.js +202 -0
  429. package/dist/server/utils/console-timestamps.js +24 -0
  430. package/dist/server/utils/file-store.js +112 -0
  431. package/dist/server/utils/paths.js +28 -0
  432. package/dist/server/utils/port-manager.js +43 -0
  433. package/dist/server/utils/port.js +204 -0
  434. package/electron-host/dist/agent-lease.js +141 -0
  435. package/electron-host/dist/capture-recovery.js +77 -0
  436. package/electron-host/dist/codec-policy.js +37 -0
  437. package/electron-host/dist/controller-channel.js +60 -0
  438. package/electron-host/dist/controller-handlers.js +153 -0
  439. package/electron-host/dist/device-emulator.js +106 -0
  440. package/electron-host/dist/dom-driver.js +642 -0
  441. package/electron-host/dist/domain-registry.js +159 -0
  442. package/electron-host/dist/domain-validators.js +308 -0
  443. package/electron-host/dist/editable-focus-reporter.js +143 -0
  444. package/electron-host/dist/fake-peer.test-util.js +105 -0
  445. package/electron-host/dist/host-log.js +31 -0
  446. package/electron-host/dist/host-wire.js +11 -0
  447. package/electron-host/dist/input-router.js +421 -0
  448. package/electron-host/dist/ipc-protocol.js +89 -0
  449. package/electron-host/dist/ipc-server.js +193 -0
  450. package/electron-host/dist/js-driver.js +216 -0
  451. package/electron-host/dist/main-guards.js +70 -0
  452. package/electron-host/dist/main.js +716 -0
  453. package/electron-host/dist/roster-sync.js +87 -0
  454. package/electron-host/dist/rpc-context.js +1 -0
  455. package/electron-host/dist/rpc-tab-methods.js +138 -0
  456. package/electron-host/dist/rpc-webrtc-methods.js +121 -0
  457. package/electron-host/dist/screen-capture-cache.js +147 -0
  458. package/electron-host/dist/sdk-injector.js +166 -0
  459. package/electron-host/dist/sdp.js +102 -0
  460. package/electron-host/dist/session-surface.js +78 -0
  461. package/electron-host/dist/surface-sizing.js +59 -0
  462. package/electron-host/dist/view-manager.js +254 -0
  463. package/electron-host/dist/viewer-registry.js +46 -0
  464. package/electron-host/dist/viewer-session.js +288 -0
  465. package/electron-host/dist/webrtc-channels.js +14 -0
  466. package/electron-host/dist/webrtc-controller.js +57 -0
  467. package/electron-host/dist/webrtc-ice-filter.js +13 -0
  468. package/electron-host/dist/webrtc-peer.js +45 -0
  469. package/electron-host/package.json +12 -0
  470. package/electron-host/tsconfig.json +23 -0
  471. package/electron-host/webrtc-controller-preload.cjs +3 -0
  472. package/electron-host/webrtc-controller.html +14 -0
  473. package/package.json +85 -0
  474. package/vendor/e2ee/LICENSE +14 -0
  475. package/vendor/e2ee/package.json +14 -0
  476. package/vendor/e2ee/src/index.js +310 -0
@@ -0,0 +1,659 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ import { randomUUID } from 'node:crypto';
4
+ import { formatOperationForReview, mapBouncerDecisionToOutcome, reviewOperation, } from '../../mcp/bouncer-integration.js';
5
+ import { browserLog } from './debug-log.js';
6
+ import { getBrowserDriverState } from './driver-state.js';
7
+ const agentLog = browserLog('agent');
8
+ export const AGENT_HEARTBEAT_INTERVAL_MS = 10_000;
9
+ export const DEFAULT_MAX_STEPS = 24;
10
+ export const MAX_CONSECUTIVE_NONMUTATING_STEPS = 3;
11
+ export const MAX_TURNS_PER_GOAL = 6;
12
+ export const MAX_STEP_RETRIES = 2;
13
+ export const MAX_REPLANS = 2;
14
+ export const ARBITRATION_WAIT_MS = 30_000;
15
+ export const ARBITRATION_POLL_MS = 500;
16
+ export const FAILSAFE_RESULT_PREFIX = 'browser-reasoner:';
17
+ function isFailsafeResult(result) {
18
+ return result?.startsWith(FAILSAFE_RESULT_PREFIX) ?? false;
19
+ }
20
+ function formatPlan(goals) {
21
+ return `Plan:\n${goals.map((g, i) => `${i + 1}. ${g}`).join('\n')}`;
22
+ }
23
+ export const EXTRACT_CONTENT_CHAR_BUDGET = 8_000;
24
+ export function serializeExtractContent(root, charBudget = EXTRACT_CONTENT_CHAR_BUDGET) {
25
+ const lines = [];
26
+ let chars = 0;
27
+ let truncated = false;
28
+ const walk = (node) => {
29
+ if (truncated)
30
+ return;
31
+ const name = node.name?.trim();
32
+ if (name) {
33
+ let line = `${node.role} "${name}"`;
34
+ if (node.value !== undefined)
35
+ line += ` value="${node.value}"`;
36
+ if (chars + line.length + 1 > charBudget) {
37
+ truncated = true;
38
+ return;
39
+ }
40
+ lines.push(line);
41
+ chars += line.length + 1;
42
+ }
43
+ for (const child of node.children) {
44
+ if (truncated)
45
+ break;
46
+ walk(child);
47
+ }
48
+ };
49
+ walk(root);
50
+ if (truncated)
51
+ lines.push('... [content truncated]');
52
+ return lines.join('\n');
53
+ }
54
+ function validateDone(input) {
55
+ if (!input.isFailsafe)
56
+ return input.isLastGoal ? 'finish' : 'advance';
57
+ if (input.failsafeStreak < MAX_STEP_RETRIES)
58
+ return 'retry';
59
+ if (input.replans < MAX_REPLANS)
60
+ return 'replan';
61
+ return 'finish';
62
+ }
63
+ function validateProgress(input) {
64
+ if (input.planLength <= 1 || input.turnsOnGoal + 1 < MAX_TURNS_PER_GOAL)
65
+ return 'continue';
66
+ if (input.replans < MAX_REPLANS)
67
+ return 'replan';
68
+ return input.isLastGoal ? 'finish' : 'advance';
69
+ }
70
+ export const defaultStepValidator = (input) => input.directive.kind === 'done' ? validateDone(input) : validateProgress(input);
71
+ export function parseNavigationIntent(task) {
72
+ const trimmed = task.trim();
73
+ if (!trimmed)
74
+ return null;
75
+ const verb = /^(?:open|go\s+to|goto|navigate\s+to|nav\s+to|visit|load|browse\s+to)\s+(.+)$/i;
76
+ const match = trimmed.match(verb);
77
+ const candidate = (match ? match[1] : trimmed).trim();
78
+ if (/\s/.test(candidate))
79
+ return null;
80
+ return normalizeUrlCandidate(candidate);
81
+ }
82
+ function normalizeUrlCandidate(raw) {
83
+ let s = raw.replace(/^['"]+|['"]+$/g, '').replace(/[.,!?;:]+$/g, '');
84
+ if (!s)
85
+ return null;
86
+ const scheme = s.match(/^([a-z][a-z0-9+.-]*):\/\//i);
87
+ if (scheme) {
88
+ const proto = scheme[1].toLowerCase();
89
+ if (proto !== 'http' && proto !== 'https')
90
+ return null;
91
+ }
92
+ else {
93
+ const host = s.split(/[/?#]/, 1)[0];
94
+ const isLocalhost = host === 'localhost' || host.startsWith('localhost:');
95
+ if (!isLocalhost && !/^[^\s.]+(?:\.[^\s.]+)+$/.test(host))
96
+ return null;
97
+ s = `https://${s}`;
98
+ }
99
+ try {
100
+ const url = new URL(s);
101
+ if (url.protocol !== 'http:' && url.protocol !== 'https:')
102
+ return null;
103
+ return url.toString();
104
+ }
105
+ catch {
106
+ return null;
107
+ }
108
+ }
109
+ export function shouldCaptureScreenshot(input) {
110
+ if (input.failsafeStreak > 0)
111
+ return true;
112
+ return input.interactiveNodeCount === 0 && input.totalNodeCount > 1;
113
+ }
114
+ export function countInteractiveNodes(node) {
115
+ let total = INTERACTIVE_SNAPSHOT_ROLES.has(node.role.toLowerCase()) ? 1 : 0;
116
+ for (const child of node.children)
117
+ total += countInteractiveNodes(child);
118
+ return total;
119
+ }
120
+ const INTERACTIVE_SNAPSHOT_ROLES = new Set([
121
+ 'button', 'link', 'textbox', 'searchbox', 'checkbox', 'radio', 'combobox',
122
+ 'listbox', 'option', 'menuitem', 'menuitemcheckbox', 'menuitemradio',
123
+ 'menulistoption', 'tab', 'switch', 'slider', 'spinbutton', 'treeitem',
124
+ 'gridcell', 'columnheader', 'rowheader',
125
+ ]);
126
+ export function withNavigationFastPath(inner) {
127
+ return (input) => {
128
+ const navUrl = parseNavigationIntent(input.task);
129
+ if (navUrl) {
130
+ const navigated = input.history.some((h) => h.phase === 'act');
131
+ return navigated
132
+ ? { kind: 'done', result: `Navigated to ${navUrl}` }
133
+ : { kind: 'navigate', url: navUrl, summary: `Navigate to ${navUrl}` };
134
+ }
135
+ return inner(input);
136
+ };
137
+ }
138
+ export const REASONING_UNAVAILABLE_RESULT = 'Autonomous browser reasoning is unavailable, so this task was not attempted. ' +
139
+ 'Direct navigation still works — try "go to <site>". To enable multi-step browser tasks, ' +
140
+ 'make sure the selected reasoning engine (e.g. the Claude CLI) is installed and authenticated.';
141
+ export function defaultAgentReasoner({ task, history, }) {
142
+ const navUrl = parseNavigationIntent(task);
143
+ const navigated = history.some((h) => h.phase === 'act');
144
+ if (navUrl && !navigated) {
145
+ agentLog('reasoner.navigate', `url=${navUrl}`);
146
+ return { kind: 'navigate', url: navUrl, summary: `Navigate to ${navUrl}` };
147
+ }
148
+ if (navUrl && navigated) {
149
+ return { kind: 'done', result: `Navigated to ${navUrl}` };
150
+ }
151
+ agentLog('reasoner.unavailable', `non-navigation task with no model-backed reasoner: "${task}"`);
152
+ return { kind: 'done', result: REASONING_UNAVAILABLE_RESULT };
153
+ }
154
+ const AGENT_ACTION_TOOL_NAMES = {
155
+ click: 'browser_click',
156
+ type: 'browser_type',
157
+ hover: 'browser_hover',
158
+ pressKey: 'browser_press_key',
159
+ selectOption: 'browser_select_option',
160
+ fillForm: 'browser_fill_form',
161
+ };
162
+ function agentActionOperation(action) {
163
+ const { method, ...args } = action;
164
+ return formatOperationForReview(AGENT_ACTION_TOOL_NAMES[method], args);
165
+ }
166
+ export const defaultAgentActionReviewer = (action, tabId) => reviewOperation({ operation: agentActionOperation(action), context: { browserTabId: tabId } });
167
+ export class ReasoningAgent {
168
+ host;
169
+ sink;
170
+ reasoner;
171
+ planner;
172
+ validator;
173
+ reviewer;
174
+ task;
175
+ agentId;
176
+ agentLabel;
177
+ initialUrl;
178
+ maxSteps;
179
+ heartbeatIntervalMs;
180
+ settleDelayMs;
181
+ setIntervalFn;
182
+ clearIntervalFn;
183
+ sleepFn;
184
+ tabId;
185
+ leased = false;
186
+ heartbeatHandle = null;
187
+ pending = null;
188
+ finished = false;
189
+ cancelled = false;
190
+ history = [];
191
+ cachedSnapshot = null;
192
+ nonMutatingStreak = 0;
193
+ plan = [];
194
+ stepIndex = 0;
195
+ turnsOnGoal = 0;
196
+ failsafeStreak = 0;
197
+ replans = 0;
198
+ constructor(opts) {
199
+ this.host = opts.host;
200
+ this.sink = opts.sink;
201
+ this.reasoner = opts.reasoner;
202
+ this.planner = opts.planner;
203
+ this.validator = opts.validator ?? defaultStepValidator;
204
+ this.reviewer = opts.reviewer ?? defaultAgentActionReviewer;
205
+ this.task = opts.task;
206
+ this.agentId = opts.agentId ?? `browser-agent-${randomUUID()}`;
207
+ this.agentLabel = opts.agentLabel ?? 'Browser Agent';
208
+ this.tabId = opts.tabId;
209
+ this.initialUrl = opts.initialUrl ?? 'about:blank';
210
+ this.maxSteps = opts.maxSteps ?? DEFAULT_MAX_STEPS;
211
+ this.heartbeatIntervalMs = opts.heartbeatIntervalMs ?? AGENT_HEARTBEAT_INTERVAL_MS;
212
+ this.settleDelayMs = opts.settleDelayMs ?? 200;
213
+ this.setIntervalFn = opts.setIntervalFn ?? ((handler, ms) => setInterval(handler, ms));
214
+ this.clearIntervalFn = opts.clearIntervalFn ?? clearInterval;
215
+ this.sleepFn = opts.sleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
216
+ }
217
+ get pendingProposalId() {
218
+ return this.pending?.proposalId ?? null;
219
+ }
220
+ get id() {
221
+ return this.agentId;
222
+ }
223
+ async run() {
224
+ try {
225
+ if (!this.tabId) {
226
+ const tab = await this.host.openTab(this.initialUrl);
227
+ this.tabId = tab.id;
228
+ }
229
+ await this.host.leaseTab({ tabId: this.tabId, agentId: this.agentId });
230
+ this.leased = true;
231
+ this.startHeartbeat();
232
+ await this.sink.badgeTab();
233
+ this.recordTarget();
234
+ await this.planTask();
235
+ for (let i = 0; i < this.maxSteps && !this.cancelled; i++) {
236
+ const snapshot = await this.observe();
237
+ const currentGoal = this.currentGoalText();
238
+ const screenshot = await this.maybeCaptureScreenshot(snapshot);
239
+ const directive = await this.reasoner({
240
+ task: this.task.task,
241
+ snapshot,
242
+ history: this.history,
243
+ ...(currentGoal !== undefined ? { currentGoal } : {}),
244
+ ...(screenshot ? { screenshot } : {}),
245
+ });
246
+ agentLog('directive', `step=${i} goal=${this.stepIndex + 1}/${this.plan.length} kind=${directive.kind}`);
247
+ if (this.cancelled)
248
+ break;
249
+ if (await this.advanceStateMachine(directive))
250
+ return;
251
+ }
252
+ this.finish(this.cancelled ? 'cancelled' : 'success');
253
+ }
254
+ catch (err) {
255
+ this.finish('error', undefined, err);
256
+ }
257
+ finally {
258
+ this.cleanup();
259
+ }
260
+ }
261
+ async planTask() {
262
+ this.plan = [this.task.task];
263
+ if (!this.planner)
264
+ return;
265
+ if (parseNavigationIntent(this.task.task) !== null)
266
+ return;
267
+ let goals = [];
268
+ try {
269
+ goals = await this.planner({ task: this.task.task });
270
+ }
271
+ catch {
272
+ goals = [];
273
+ }
274
+ if (goals.length > 1) {
275
+ this.plan = goals;
276
+ this.recordStep('plan', formatPlan(goals));
277
+ }
278
+ }
279
+ currentGoalText() {
280
+ if (this.plan.length <= 1)
281
+ return undefined;
282
+ return this.plan[Math.min(this.stepIndex, this.plan.length - 1)];
283
+ }
284
+ advanceGoal() {
285
+ this.stepIndex += 1;
286
+ this.turnsOnGoal = 0;
287
+ this.failsafeStreak = 0;
288
+ this.nonMutatingStreak = 0;
289
+ }
290
+ async advanceStateMachine(directive) {
291
+ const isFailsafe = directive.kind === 'done' && isFailsafeResult(directive.result);
292
+ if (directive.kind !== 'done') {
293
+ if (await this.executeDirective(directive))
294
+ return true;
295
+ }
296
+ const verdict = this.validator({
297
+ directive,
298
+ isFailsafe,
299
+ isLastGoal: this.stepIndex >= this.plan.length - 1,
300
+ planLength: this.plan.length,
301
+ turnsOnGoal: this.turnsOnGoal,
302
+ failsafeStreak: this.failsafeStreak,
303
+ replans: this.replans,
304
+ });
305
+ return this.applyVerdict(verdict, directive);
306
+ }
307
+ async applyVerdict(verdict, directive) {
308
+ switch (verdict) {
309
+ case 'finish':
310
+ this.finish('success', directive.kind === 'done' ? directive.result : undefined);
311
+ return true;
312
+ case 'advance':
313
+ this.advanceGoal();
314
+ return false;
315
+ case 'retry':
316
+ this.failsafeStreak += 1;
317
+ this.cachedSnapshot = null;
318
+ return false;
319
+ case 'replan':
320
+ return this.replan(directive);
321
+ case 'continue': {
322
+ this.failsafeStreak = 0;
323
+ this.turnsOnGoal += 1;
324
+ if (directive.kind === 'extract') {
325
+ if (++this.nonMutatingStreak >= MAX_CONSECUTIVE_NONMUTATING_STEPS) {
326
+ this.finish('success', `Stopped after ${this.nonMutatingStreak} read-only steps without making progress on the task.`);
327
+ return true;
328
+ }
329
+ }
330
+ else {
331
+ this.nonMutatingStreak = 0;
332
+ }
333
+ return false;
334
+ }
335
+ }
336
+ }
337
+ async replan(trigger) {
338
+ if (!this.planner) {
339
+ this.finish('success', trigger.kind === 'done' ? trigger.result : undefined);
340
+ return true;
341
+ }
342
+ this.replans += 1;
343
+ let goals = [];
344
+ try {
345
+ const tabId = this.requireTabId();
346
+ const snapshot = this.cachedSnapshot ?? (await this.host.dom.snapshot({ tabId }));
347
+ goals = await this.planner({ task: this.task.task, snapshot });
348
+ }
349
+ catch {
350
+ goals = [];
351
+ }
352
+ this.plan = goals.length >= 1 ? goals : [this.task.task];
353
+ this.stepIndex = 0;
354
+ this.turnsOnGoal = 0;
355
+ this.failsafeStreak = 0;
356
+ this.nonMutatingStreak = 0;
357
+ this.recordStep('plan', `Re-planning from the current page.\n${formatPlan(this.plan)}`);
358
+ return false;
359
+ }
360
+ async executeDirective(directive) {
361
+ switch (directive.kind) {
362
+ case 'done':
363
+ return false;
364
+ case 'navigate':
365
+ await this.navigate(directive.url, directive.summary);
366
+ return false;
367
+ case 'extract':
368
+ await this.extract(directive.summary);
369
+ return false;
370
+ case 'act': {
371
+ const decision = await this.greenlight(directive.action, directive.summary);
372
+ if (decision.outcome === 'deny') {
373
+ if (decision.reason !== undefined) {
374
+ this.recordStep('act', `Skipped — Bouncer denied: ${decision.reason}`);
375
+ }
376
+ this.finish('cancelled', decision.reason);
377
+ return true;
378
+ }
379
+ await this.act(decision.action, directive.summary, decision.proposalId);
380
+ return false;
381
+ }
382
+ }
383
+ }
384
+ approve(payload) {
385
+ if (!this.pending || this.pending.proposalId !== payload.proposalId)
386
+ return false;
387
+ const { resolve } = this.pending;
388
+ this.pending = null;
389
+ resolve(payload);
390
+ return true;
391
+ }
392
+ cancel() {
393
+ this.cancelled = true;
394
+ this.stopHeartbeat();
395
+ if (this.pending) {
396
+ const { resolve, proposalId } = this.pending;
397
+ this.pending = null;
398
+ resolve({ proposalId, verdict: 'deny' });
399
+ }
400
+ }
401
+ async reviewAction(action) {
402
+ const tabId = this.requireTabId();
403
+ const gate = await this.waitForPerson(tabId, AGENT_ACTION_TOOL_NAMES[action.method]);
404
+ if (!gate.allow) {
405
+ return { outcome: 'autoDeny', reason: `Driver arbitration: ${gate.hint}` };
406
+ }
407
+ const decision = await this.reviewer(action, tabId);
408
+ return { outcome: mapBouncerDecisionToOutcome(decision), reason: decision.reasoning };
409
+ }
410
+ async waitForPerson(tabId, tool) {
411
+ const driverState = getBrowserDriverState();
412
+ let gate = driverState.gateSync(tabId, tool);
413
+ if (gate.allow)
414
+ return gate;
415
+ agentLog('arbitration.wait', `tab=${tabId.slice(0, 8)} tool=${tool} state=${gate.state}`);
416
+ this.emitStep('observe', 'Waiting for you to finish on this tab…');
417
+ for (let waited = 0; waited < ARBITRATION_WAIT_MS && !this.cancelled; waited += ARBITRATION_POLL_MS) {
418
+ await this.sleepFn(ARBITRATION_POLL_MS);
419
+ gate = driverState.gateSync(tabId, tool);
420
+ if (gate.allow)
421
+ return gate;
422
+ }
423
+ return gate;
424
+ }
425
+ async greenlight(action, summary) {
426
+ const review = await this.reviewAction(action);
427
+ if (this.cancelled)
428
+ return { outcome: 'deny' };
429
+ if (review.outcome === 'autoDeny') {
430
+ return { outcome: 'deny', reason: review.reason };
431
+ }
432
+ if (review.outcome === 'autoAllow') {
433
+ return { outcome: 'proceed', action };
434
+ }
435
+ const proposalId = randomUUID();
436
+ const proposed = {
437
+ proposalId,
438
+ summary,
439
+ ...(this.task.boardId ? { boardId: this.task.boardId } : {}),
440
+ };
441
+ this.sink.emit({ type: 'browser_agent_proposed', data: proposed });
442
+ const verdict = await new Promise((resolve) => {
443
+ this.pending = { proposalId, resolve };
444
+ });
445
+ if (verdict.verdict === 'deny')
446
+ return { outcome: 'deny' };
447
+ const effective = verdict.verdict === 'edit'
448
+ ? this.applyEdit(action, verdict.editedText)
449
+ : action;
450
+ return { outcome: 'proceed', action: effective, proposalId };
451
+ }
452
+ applyEdit(action, editedText) {
453
+ if (editedText === undefined)
454
+ return action;
455
+ if (action.method === 'type')
456
+ return { ...action, text: editedText };
457
+ return action;
458
+ }
459
+ async settle(kind) {
460
+ if (kind === 'act' && this.settleDelayMs > 0) {
461
+ await this.sleepFn(this.settleDelayMs);
462
+ }
463
+ try {
464
+ await this.host.dom.waitFor({
465
+ tabId: this.requireTabId(),
466
+ timeoutMs: kind === 'navigate' ? 10_000 : 5_000,
467
+ pollIntervalMs: 150,
468
+ condition: { type: 'navigation' },
469
+ agentId: this.agentId,
470
+ });
471
+ }
472
+ catch {
473
+ }
474
+ }
475
+ async observe() {
476
+ const tabId = this.requireTabId();
477
+ const snapshot = this.cachedSnapshot ?? (await this.host.dom.snapshot({ tabId }));
478
+ this.cachedSnapshot = snapshot;
479
+ this.recordStep('observe', `Observed ${countNodes(snapshot.root)} accessibility nodes`);
480
+ return snapshot;
481
+ }
482
+ async maybeCaptureScreenshot(snapshot) {
483
+ const capture = shouldCaptureScreenshot({
484
+ failsafeStreak: this.failsafeStreak,
485
+ interactiveNodeCount: countInteractiveNodes(snapshot.root),
486
+ totalNodeCount: countNodes(snapshot.root),
487
+ });
488
+ if (!capture)
489
+ return null;
490
+ try {
491
+ const shot = await this.host.dom.screenshot({
492
+ tabId: this.requireTabId(),
493
+ format: 'jpeg',
494
+ quality: 60,
495
+ });
496
+ if (!shot?.data)
497
+ return null;
498
+ this.recordStep('observe', 'Captured a screenshot to visually ground the next step');
499
+ return { data: shot.data, format: shot.format === 'jpeg' ? 'jpeg' : 'png' };
500
+ }
501
+ catch {
502
+ return null;
503
+ }
504
+ }
505
+ async navigate(url, summary) {
506
+ const tabId = this.requireTabId();
507
+ agentLog('navigate', `tab=${tabId.slice(0, 8)} url=${url}`);
508
+ this.markDriving(tabId);
509
+ await this.host.navigate(url, tabId);
510
+ await this.settle('navigate');
511
+ this.cachedSnapshot = null;
512
+ this.recordStep('act', summary ?? `Navigated to ${url}`);
513
+ }
514
+ async act(action, summary, proposalId) {
515
+ const tabId = this.requireTabId();
516
+ const agentId = this.agentId;
517
+ const { dom } = this.host;
518
+ this.markDriving(tabId);
519
+ switch (action.method) {
520
+ case 'click':
521
+ await dom.click({ tabId, ref: action.ref, agentId });
522
+ break;
523
+ case 'type':
524
+ await dom.type({
525
+ tabId,
526
+ ref: action.ref,
527
+ text: action.text,
528
+ agentId,
529
+ ...(action.submit !== undefined ? { submit: action.submit } : {}),
530
+ });
531
+ break;
532
+ case 'hover':
533
+ await dom.hover({ tabId, ref: action.ref, agentId });
534
+ break;
535
+ case 'pressKey':
536
+ await dom.pressKey({ tabId, key: action.key, agentId });
537
+ break;
538
+ case 'selectOption':
539
+ await dom.selectOption({ tabId, ref: action.ref, values: action.values, agentId });
540
+ break;
541
+ case 'fillForm':
542
+ await dom.fillForm({ tabId, fields: action.fields, agentId });
543
+ break;
544
+ }
545
+ await this.settle('act');
546
+ this.cachedSnapshot = null;
547
+ this.recordStep('act', summary, proposalId);
548
+ }
549
+ async extract(summary) {
550
+ const tabId = this.requireTabId();
551
+ const snapshot = this.cachedSnapshot ?? (await this.host.dom.snapshot({ tabId }));
552
+ this.cachedSnapshot = snapshot;
553
+ const [consoleEntries, networkEntries] = await Promise.all([
554
+ this.host.dom.console({ tabId }),
555
+ this.host.dom.network({ tabId }),
556
+ ]);
557
+ const detail = summary ??
558
+ `Extracted ${countNodes(snapshot.root)} nodes, ${consoleEntries.length} console, ${networkEntries.length} network entries`;
559
+ const content = serializeExtractContent(snapshot.root);
560
+ this.recordStep('extract', detail, undefined, content ? `${detail}\nPage content:\n${content}` : detail);
561
+ }
562
+ recordTarget() {
563
+ const { engine, model } = this.task;
564
+ if (!engine && !model)
565
+ return;
566
+ const target = [engine ?? 'default engine', model && model !== 'default' ? model : null]
567
+ .filter(Boolean)
568
+ .join(' · ');
569
+ this.emitStep('plan', `Running on ${target}`);
570
+ }
571
+ recordStep(phase, detail, proposalId, historyDetail) {
572
+ this.history.push({ phase, detail: historyDetail ?? detail });
573
+ this.emitStep(phase, detail, proposalId);
574
+ }
575
+ emitStep(phase, detail, proposalId) {
576
+ const payload = {
577
+ phase,
578
+ detail,
579
+ ...(this.task.taskId ? { taskId: this.task.taskId } : {}),
580
+ ...(proposalId ? { proposalId } : {}),
581
+ ...(this.task.engine ? { engine: this.task.engine } : {}),
582
+ ...(this.task.model ? { model: this.task.model } : {}),
583
+ };
584
+ agentLog('step', `phase=${phase} task=${this.task.taskId ?? '-'} detail=${detail}`);
585
+ this.sink.emit({ type: 'browser_agent_step', data: payload });
586
+ }
587
+ finish(status, result, err) {
588
+ if (this.finished)
589
+ return;
590
+ this.finished = true;
591
+ const userResult = toUserFacingResult(result);
592
+ const payload = {
593
+ status,
594
+ ...(this.task.taskId ? { taskId: this.task.taskId } : {}),
595
+ ...(this.task.boardId ? { boardId: this.task.boardId } : {}),
596
+ ...(userResult !== undefined ? { result: userResult } : {}),
597
+ ...(status === 'error'
598
+ ? { error: err instanceof Error ? err.message : String(err ?? 'unknown error') }
599
+ : {}),
600
+ };
601
+ const rawNote = userResult !== result ? ` rawResult="${result}"` : '';
602
+ agentLog('done', `status=${status} task=${this.task.taskId ?? '-'}${rawNote}`);
603
+ this.sink.emit({ type: 'browser_agent_done', data: payload });
604
+ }
605
+ startHeartbeat() {
606
+ if (this.heartbeatHandle)
607
+ return;
608
+ this.heartbeatHandle = this.setIntervalFn(() => {
609
+ void this.heartbeatTick();
610
+ }, this.heartbeatIntervalMs);
611
+ }
612
+ async heartbeatTick() {
613
+ if (!this.tabId)
614
+ return;
615
+ try {
616
+ await this.host.heartbeat({ agentId: this.agentId, tabIds: [this.tabId] });
617
+ }
618
+ catch {
619
+ }
620
+ }
621
+ stopHeartbeat() {
622
+ if (this.heartbeatHandle) {
623
+ this.clearIntervalFn(this.heartbeatHandle);
624
+ this.heartbeatHandle = null;
625
+ }
626
+ }
627
+ cleanup() {
628
+ this.stopHeartbeat();
629
+ if (this.tabId && this.leased) {
630
+ this.leased = false;
631
+ void this.host
632
+ .releaseTab({ tabId: this.tabId, agentId: this.agentId })
633
+ .then(() => this.sink.badgeTab())
634
+ .catch(() => {
635
+ });
636
+ }
637
+ }
638
+ requireTabId() {
639
+ if (!this.tabId)
640
+ throw new Error('reasoning-agent: no tab acquired');
641
+ return this.tabId;
642
+ }
643
+ markDriving(tabId) {
644
+ getBrowserDriverState().recordInput(tabId, 'agent');
645
+ }
646
+ }
647
+ function toUserFacingResult(result) {
648
+ if (result === undefined)
649
+ return undefined;
650
+ if (!isFailsafeResult(result))
651
+ return result;
652
+ return "I couldn't complete this browser task — I had trouble understanding the page. Please try rephrasing the task, or take the action manually.";
653
+ }
654
+ function countNodes(node) {
655
+ let total = 1;
656
+ for (const child of node.children)
657
+ total += countNodes(child);
658
+ return total;
659
+ }