@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,245 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ import { resolveClaudeCommand } from '../../engines/claude/claude-command.js';
4
+ import { getCurrentMinionryPort } from '../../services/runtime-info.js';
5
+ import { getBouncerSecret } from '../../services/websocket/ask-user-question-bridge.js';
6
+ import { executeClaudeCommand } from './claude-invoker.js';
7
+ import { estimateTokensFromOutput } from './output-utils.js';
8
+ import { enrichPromptWithContext } from './prompt-utils.js';
9
+ function readDefaultMinionryPort() {
10
+ return getCurrentMinionryPort();
11
+ }
12
+ function readDefaultBouncerSecret() {
13
+ return getBouncerSecret();
14
+ }
15
+ export function killProcessGroup(pid, signal) {
16
+ try {
17
+ process.kill(-pid, signal);
18
+ }
19
+ catch {
20
+ try {
21
+ process.kill(pid, signal);
22
+ }
23
+ catch { }
24
+ }
25
+ }
26
+ function sharedResultFields(result) {
27
+ return {
28
+ exitCode: result.exitCode,
29
+ signalName: result.signalName,
30
+ engineNotice: result.engineNotice,
31
+ resultSubtype: result.resultSubtype,
32
+ terminalReason: result.terminalReason,
33
+ resultIsError: result.resultIsError,
34
+ stderrTail: result.stderrTail,
35
+ firstEventLatencyMs: result.firstEventLatencyMs,
36
+ startupTimedOut: result.startupTimedOut,
37
+ pendingBackgroundTasks: result.pendingBackgroundTasks,
38
+ apiTokenUsage: result.apiTokenUsage,
39
+ outputTokens: result.apiTokenUsage?.outputTokens,
40
+ assistantResponse: result.assistantResponse,
41
+ thinkingOutput: result.thinkingOutput,
42
+ toolUseHistory: result.toolUseHistory,
43
+ claudeSessionId: result.claudeSessionId,
44
+ nativeTimeoutCount: result.nativeTimeoutCount,
45
+ postTimeoutOutput: result.postTimeoutOutput,
46
+ resumeBufferedOutput: result.resumeBufferedOutput,
47
+ stopReason: result.stopReason,
48
+ sessionNotFound: result.sessionNotFound,
49
+ failedMcpServers: result.failedMcpServers,
50
+ backgroundTasksPendingAtExit: result.backgroundTasksPendingAtExit,
51
+ pendingWakeup: result.pendingWakeup,
52
+ interrupted: result.interrupted,
53
+ };
54
+ }
55
+ function isSignalExitWithOutput(result) {
56
+ if (result.exitCode < 128 && !result.interrupted)
57
+ return false;
58
+ if (result.backgroundTasksPendingAtExit || result.pendingWakeup)
59
+ return false;
60
+ return !!(result.assistantResponse || (result.toolUseHistory && result.toolUseHistory.length > 0));
61
+ }
62
+ function plainStdoutLines(output) {
63
+ const plainLines = output.split('\n')
64
+ .filter(l => l.trim() && !l.trim().startsWith('{'))
65
+ .join('\n')
66
+ .trim();
67
+ return plainLines ? plainLines.slice(0, 500) : undefined;
68
+ }
69
+ function deriveErrorMessage(result) {
70
+ if (result.engineNotice)
71
+ return result.engineNotice.text;
72
+ if (result.startupTimedOut) {
73
+ return result.error || 'The engine produced no output after starting.';
74
+ }
75
+ if (result.signalName && result.backgroundTasksPendingAtExit) {
76
+ return `Process killed (${result.signalName}) while ${result.backgroundTasksPendingAtExit} background task(s) were still running — background work was lost and must be re-launched.`;
77
+ }
78
+ if (result.interrupted && !result.error) {
79
+ return 'Execution was interrupted before completion';
80
+ }
81
+ const exitLine = `Claude exited with code ${result.exitCode}${result.signalName ? ` (${result.signalName})` : ''}`;
82
+ if (result.error)
83
+ return `${exitLine}: ${result.error.slice(0, 500)}`;
84
+ return plainStdoutLines(result.output) ?? exitLine;
85
+ }
86
+ function buildSuccessResult(sessionId, result) {
87
+ return {
88
+ completed: true,
89
+ needsHandoff: false,
90
+ totalTokens: estimateTokensFromOutput(result.output),
91
+ sessionId,
92
+ ...sharedResultFields(result),
93
+ };
94
+ }
95
+ function buildErrorResult(sessionId, result) {
96
+ return {
97
+ completed: false,
98
+ needsHandoff: false,
99
+ totalTokens: 0,
100
+ sessionId,
101
+ error: deriveErrorMessage(result),
102
+ ...sharedResultFields(result),
103
+ };
104
+ }
105
+ function resolveSupervisionConfig(config) {
106
+ return {
107
+ stallWarningMs: config.stallWarningMs ?? 300_000,
108
+ stallKillMs: config.stallKillMs ?? 1_800_000,
109
+ stallAssessEnabled: config.stallAssessEnabled !== false,
110
+ stallMaxExtensions: config.stallMaxExtensions ?? 3,
111
+ stallHardCapMs: config.stallHardCapMs ?? 14_400_000,
112
+ backgroundWaitGraceMs: config.backgroundWaitGraceMs ?? 300_000,
113
+ backgroundWaitCapMs: config.backgroundWaitCapMs ?? 3_600_000,
114
+ backgroundWaitAbsoluteCapMs: config.backgroundWaitAbsoluteCapMs ?? 10_800_000,
115
+ firstEventDeadlineMs: config.firstEventDeadlineMs ?? 90_000,
116
+ };
117
+ }
118
+ export class HeadlessRunner {
119
+ config;
120
+ runningProcesses = new Map();
121
+ liveContext = null;
122
+ constructor(config) {
123
+ this.config = {
124
+ workingDir: config.workingDir || process.cwd(),
125
+ tokenBudgetThreshold: config.tokenBudgetThreshold || 170000,
126
+ maxSessions: config.maxSessions || 50,
127
+ maxRetries: config.maxRetries || 3,
128
+ claudeCommand: config.claudeCommand || resolveClaudeCommand(),
129
+ verbose: !!config.verbose,
130
+ noColor: !!config.noColor,
131
+ improvisationMode: !!config.improvisationMode,
132
+ movementNumber: config.movementNumber ?? 0,
133
+ outputCallback: config.outputCallback,
134
+ thinkingCallback: config.thinkingCallback,
135
+ toolUseCallback: config.toolUseCallback,
136
+ continueSession: config.continueSession,
137
+ claudeSessionId: config.claudeSessionId,
138
+ directPrompt: config.directPrompt || '',
139
+ promptContext: config.promptContext || { accumulatedKnowledge: '', filesModified: [] },
140
+ imageAttachments: config.imageAttachments,
141
+ ...resolveSupervisionConfig(config),
142
+ model: config.model,
143
+ effortLevel: config.effortLevel,
144
+ fastMode: !!config.fastMode,
145
+ ultracode: !!config.ultracode,
146
+ appendSystemPrompt: config.appendSystemPrompt,
147
+ toolTimeoutProfiles: config.toolTimeoutProfiles,
148
+ enableToolWatchdog: config.enableToolWatchdog !== false,
149
+ maxAutoRetries: config.maxAutoRetries ?? 2,
150
+ onToolTimeout: config.onToolTimeout,
151
+ onBackgroundActivity: config.onBackgroundActivity,
152
+ onExecutionTargetResolved: config.onExecutionTargetResolved,
153
+ extraEnv: config.extraEnv,
154
+ disallowedTools: config.disallowedTools,
155
+ inferenceOnly: !!config.inferenceOnly,
156
+ deployMode: config.deployMode,
157
+ tabId: config.tabId,
158
+ minionryPort: config.minionryPort ?? readDefaultMinionryPort(),
159
+ bouncerSecret: config.bouncerSecret ?? readDefaultBouncerSecret(),
160
+ agentId: config.agentId,
161
+ agentLabel: config.agentLabel,
162
+ planId: config.planId,
163
+ appRunProfile: config.appRunProfile,
164
+ appTools: config.appTools,
165
+ browserMcp: config.browserMcp,
166
+ };
167
+ }
168
+ async run() {
169
+ if (this.config.directPrompt) {
170
+ return await this.runDirectPrompt(this.config.directPrompt, this.config.promptContext);
171
+ }
172
+ return {
173
+ completed: false,
174
+ needsHandoff: false,
175
+ totalTokens: 0,
176
+ sessionId: '',
177
+ error: 'No prompt provided. Use directPrompt in improvise mode.'
178
+ };
179
+ }
180
+ async runDirectPrompt(userPrompt, context) {
181
+ const sessionId = `direct-${Date.now()}`;
182
+ const enrichedPrompt = context
183
+ ? await enrichPromptWithContext(userPrompt, context)
184
+ : userPrompt;
185
+ const result = await this.executePromptCommand(enrichedPrompt, 'main', 1);
186
+ if (result.exitCode === 0 && !result.interrupted) {
187
+ return buildSuccessResult(sessionId, result);
188
+ }
189
+ if (isSignalExitWithOutput(result)) {
190
+ return buildSuccessResult(sessionId, result);
191
+ }
192
+ return buildErrorResult(sessionId, result);
193
+ }
194
+ async executePromptCommand(prompt, promptId, sessionNumber) {
195
+ const invokerOptions = {
196
+ config: this.config,
197
+ runningProcesses: this.runningProcesses,
198
+ onLiveContext: (live) => { this.liveContext = live; },
199
+ };
200
+ return executeClaudeCommand(prompt, promptId, sessionNumber, invokerOptions);
201
+ }
202
+ snapshot() {
203
+ const live = this.liveContext;
204
+ if (!live)
205
+ return null;
206
+ const { ctx, sessionCapture } = live;
207
+ const u = ctx.apiTokenUsage;
208
+ const hasTokenUsage = u.inputTokens > 0 || u.outputTokens > 0 || u.cacheCreationTokens > 0 || u.cacheReadTokens > 0;
209
+ return {
210
+ assistantResponse: ctx.accumulatedAssistantResponse || undefined,
211
+ thinkingOutput: ctx.accumulatedThinking || undefined,
212
+ toolUseHistory: ctx.accumulatedToolUse.length > 0 ? ctx.accumulatedToolUse.map((t) => ({ ...t })) : undefined,
213
+ claudeSessionId: sessionCapture.claudeSessionId,
214
+ apiTokenUsage: hasTokenUsage ? { ...u } : undefined,
215
+ engineNotice: ctx.engineNotice,
216
+ };
217
+ }
218
+ cleanup() {
219
+ if (this.runningProcesses.size === 0)
220
+ return;
221
+ const pids = new Set();
222
+ for (const [pid] of this.runningProcesses) {
223
+ pids.add(pid);
224
+ killProcessGroup(pid, 'SIGTERM');
225
+ }
226
+ setTimeout(() => {
227
+ for (const [pid, proc] of this.runningProcesses) {
228
+ if (pids.has(pid) && !proc.killed) {
229
+ killProcessGroup(pid, 'SIGKILL');
230
+ }
231
+ }
232
+ this.runningProcesses.clear();
233
+ }, 5000);
234
+ }
235
+ sweepZombies() {
236
+ let swept = 0;
237
+ for (const [pid, proc] of this.runningProcesses) {
238
+ if (proc.exitCode !== null || proc.killed) {
239
+ this.runningProcesses.delete(pid);
240
+ swept++;
241
+ }
242
+ }
243
+ return swept;
244
+ }
245
+ }
@@ -0,0 +1,295 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ import { loadSkillPrompt } from '../../services/plan/agent-loader.js';
4
+ import { spawnHaikuRaw } from './haiku-assessments.js';
5
+ import { hlog } from './headless-logger.js';
6
+ export { assessApproval, assessBestResult, assessContextLoss, classifyError } from './haiku-assessments.js';
7
+ const STALL_MAX_MINUTES = 180;
8
+ const TOOL_TIMEOUT_MAX_MINUTES = 10;
9
+ export function createToolActivityState() {
10
+ return {
11
+ pendingToolIds: new Set(),
12
+ pendingToolNames: new Set(),
13
+ pendingToolNameById: new Map(),
14
+ totalToolCalls: 0,
15
+ };
16
+ }
17
+ export function applyEngineEventToActivity(state, event) {
18
+ if (event.kind === 'tool.start') {
19
+ state.pendingToolIds.add(event.toolCallId);
20
+ state.pendingToolNames.add(event.toolName);
21
+ state.pendingToolNameById.set(event.toolCallId, event.toolName);
22
+ state.lastToolName = event.toolName;
23
+ state.lastToolInputSummary = summarizeToolInput(event.input);
24
+ state.totalToolCalls++;
25
+ return;
26
+ }
27
+ if (event.kind === 'tool.end') {
28
+ state.pendingToolIds.delete(event.toolCallId);
29
+ state.pendingToolNameById.delete(event.toolCallId);
30
+ const stillPending = Array.from(state.pendingToolNameById.values()).includes(event.toolName);
31
+ if (!stillPending)
32
+ state.pendingToolNames.delete(event.toolName);
33
+ }
34
+ }
35
+ export function buildStallContext(activity, timing) {
36
+ return {
37
+ originalPrompt: timing.originalPrompt,
38
+ silenceMs: timing.silenceMs,
39
+ elapsedTotalMs: timing.elapsedTotalMs,
40
+ tokenSilenceMs: timing.tokenSilenceMs,
41
+ lastToolName: activity.lastToolName,
42
+ lastToolInputSummary: activity.lastToolInputSummary,
43
+ pendingToolCount: activity.pendingToolIds.size,
44
+ pendingToolNames: new Set(activity.pendingToolNames),
45
+ totalToolCalls: activity.totalToolCalls,
46
+ };
47
+ }
48
+ function summarizeToolInput(input) {
49
+ if (input.url)
50
+ return `URL: ${String(input.url).slice(0, 200)}`;
51
+ if (input.query)
52
+ return `Query: ${String(input.query).slice(0, 200)}`;
53
+ if (input.command)
54
+ return `Command: ${String(input.command).slice(0, 200)}`;
55
+ if (input.prompt)
56
+ return `Prompt: ${String(input.prompt).slice(0, 200)}`;
57
+ const serialized = JSON.stringify(input);
58
+ return serialized ? serialized.slice(0, 200) : undefined;
59
+ }
60
+ function hasSubagentPending(pendingNames, lastToolName, hasPendingTools) {
61
+ return pendingNames.has('Task') || pendingNames.has('Agent')
62
+ || ((lastToolName === 'Task' || lastToolName === 'Agent') && hasPendingTools);
63
+ }
64
+ function checkAgentTeamsWaiting(ctx, hasPendingTools) {
65
+ if (!hasPendingTools &&
66
+ ctx.totalToolCalls > 0 &&
67
+ ctx.originalPrompt.includes('team_name')) {
68
+ return {
69
+ action: 'extend',
70
+ extensionMs: 30 * 60_000,
71
+ reason: 'Agent Teams lead waiting for teammate idle notifications — extending 30 min',
72
+ };
73
+ }
74
+ return null;
75
+ }
76
+ function quickHeuristic(ctx, toolWatchdogActive = false) {
77
+ const pendingNames = ctx.pendingToolNames ?? new Set();
78
+ const hasPendingTools = ctx.pendingToolCount > 0;
79
+ if (ctx.tokenSilenceMs !== undefined && ctx.tokenSilenceMs < 60_000) {
80
+ return {
81
+ action: 'extend',
82
+ extensionMs: 10 * 60_000,
83
+ reason: `Tokens still flowing (last activity ${Math.round(ctx.tokenSilenceMs / 1000)}s ago) — process is alive`,
84
+ };
85
+ }
86
+ if (toolWatchdogActive && hasPendingTools) {
87
+ const toolList = pendingNames.size > 0
88
+ ? Array.from(pendingNames).join(', ')
89
+ : `${ctx.pendingToolCount} tool(s)`;
90
+ return {
91
+ action: 'extend',
92
+ extensionMs: 15 * 60_000,
93
+ reason: `Watchdog active, deferring — pending: ${toolList}`,
94
+ };
95
+ }
96
+ if (hasSubagentPending(pendingNames, ctx.lastToolName, hasPendingTools)) {
97
+ const extensionMin = Math.min(30, 10 + ctx.pendingToolCount * 5);
98
+ return {
99
+ action: 'extend',
100
+ extensionMs: extensionMin * 60_000,
101
+ reason: `${ctx.pendingToolCount} Task subagent(s) still executing — extending ${extensionMin} min`,
102
+ };
103
+ }
104
+ const agentTeamsVerdict = checkAgentTeamsWaiting(ctx, hasPendingTools);
105
+ if (agentTeamsVerdict)
106
+ return agentTeamsVerdict;
107
+ if (ctx.pendingToolCount >= 3) {
108
+ return {
109
+ action: 'extend',
110
+ extensionMs: 15 * 60_000,
111
+ reason: `${ctx.pendingToolCount} parallel tool calls in progress — extending 15 min`,
112
+ };
113
+ }
114
+ if (!toolWatchdogActive && (ctx.lastToolName === 'WebSearch' || ctx.lastToolName === 'WebFetch')) {
115
+ return {
116
+ action: 'extend',
117
+ extensionMs: 5 * 60_000,
118
+ reason: `${ctx.lastToolName} in progress — extending 5 min`,
119
+ };
120
+ }
121
+ return null;
122
+ }
123
+ function buildAssessmentPrompt(ctx) {
124
+ const silenceMin = String(Math.round(ctx.silenceMs / 60_000));
125
+ const totalMin = String(Math.round(ctx.elapsedTotalMs / 60_000));
126
+ const promptPreview = ctx.originalPrompt.length > 500
127
+ ? `${ctx.originalPrompt.slice(0, 500)}...`
128
+ : ctx.originalPrompt;
129
+ const tokenLine = ctx.tokenSilenceMs !== undefined
130
+ ? `Token activity: last token event ${Math.round(ctx.tokenSilenceMs / 1000)}s ago (tokens flowing = process alive)`
131
+ : 'Token activity: no token events observed';
132
+ const lastToolInputLine = ctx.lastToolInputSummary ? `Last tool input: ${ctx.lastToolInputSummary}` : '';
133
+ const backgroundLine = ctx.backgroundTasksPending
134
+ ? `Background orchestration: ${ctx.backgroundTasksPending} background subagent/workflow task(s) still pending (these do not show up as pending tool calls; long silence between their progress events is normal)`
135
+ : '';
136
+ const wakeupLine = ctx.wakeupOverdueMs && ctx.wakeupOverdueMs > 0
137
+ ? `Scheduled wakeup: the process armed a self-wakeup that is now ${Math.round(ctx.wakeupOverdueMs / 60_000)} min overdue with no output — a fired wakeup should have produced activity`
138
+ : '';
139
+ const fromSkill = loadSkillPrompt('assess-stall', {
140
+ silenceMin,
141
+ totalMin,
142
+ lastToolName: ctx.lastToolName || 'none',
143
+ lastToolInputLine,
144
+ pendingToolCount: String(ctx.pendingToolCount),
145
+ totalToolCalls: String(ctx.totalToolCalls),
146
+ tokenLine,
147
+ backgroundLine,
148
+ wakeupLine,
149
+ promptPreview,
150
+ });
151
+ if (fromSkill)
152
+ return fromSkill;
153
+ return [
154
+ 'You are a process health monitor. A Claude Code subprocess has gone silent (no stdout) and you must determine if it is working or stalled.',
155
+ '',
156
+ `Silent for: ${silenceMin} minutes`,
157
+ `Total runtime: ${totalMin} minutes`,
158
+ `Last tool before silence: ${ctx.lastToolName || 'none'}`,
159
+ lastToolInputLine,
160
+ `Pending tool calls: ${ctx.pendingToolCount}`,
161
+ `Total tool calls this session: ${ctx.totalToolCalls}`,
162
+ tokenLine,
163
+ backgroundLine,
164
+ wakeupLine,
165
+ `Task being executed: ${promptPreview}`,
166
+ '',
167
+ 'Weigh BOTH silence and total runtime against task complexity.',
168
+ '- Simple tasks (single Read/Write, one-liner edit, ls a directory) should finish in minutes. If total runtime has already far exceeded what the task should need, verdict STALLED even if silence is short.',
169
+ '- Complex tasks (agent teams, multi-step migrations, large refactors, dependency installs) can legitimately run hours. Extend generously when pending tool activity, subagents, or background orchestration tasks justify it.',
170
+ '- Recent token activity = process is alive; favor WORKING.',
171
+ '',
172
+ 'Respond in EXACTLY this format (3 lines, no extra text):',
173
+ 'VERDICT: WORKING or STALLED',
174
+ 'MINUTES: <integer 5-180, only if WORKING, how many more minutes to allow>',
175
+ 'REASON: <brief one-line explanation that references task complexity vs elapsed time>',
176
+ ].filter(Boolean).join('\n');
177
+ }
178
+ export function parseAssessmentResponse(output, maxMinutes = STALL_MAX_MINUTES) {
179
+ const lines = output.trim().split('\n');
180
+ let verdict = 'STALLED';
181
+ let minutes = Math.min(10, maxMinutes);
182
+ let reason = 'Assessment inconclusive';
183
+ for (const line of lines) {
184
+ const trimmed = line.trim();
185
+ if (trimmed.startsWith('VERDICT:')) {
186
+ verdict = trimmed.slice('VERDICT:'.length).trim().toUpperCase();
187
+ }
188
+ else if (trimmed.startsWith('MINUTES:')) {
189
+ const parsed = parseInt(trimmed.slice('MINUTES:'.length).trim(), 10);
190
+ if (!Number.isNaN(parsed) && parsed >= 1) {
191
+ minutes = Math.min(parsed, maxMinutes);
192
+ }
193
+ }
194
+ else if (trimmed.startsWith('REASON:')) {
195
+ reason = trimmed.slice('REASON:'.length).trim();
196
+ }
197
+ }
198
+ if (verdict.includes('WORKING')) {
199
+ return { action: 'extend', extensionMs: minutes * 60_000, reason, assessed: true };
200
+ }
201
+ return { action: 'kill', extensionMs: 0, reason, assessed: true };
202
+ }
203
+ async function spawnHaikuVerdict(prompt, claudeCommand, verbose, label = 'STALL-ASSESS', maxMinutes = STALL_MAX_MINUTES) {
204
+ const raw = await spawnHaikuRaw(prompt, claudeCommand, verbose, label);
205
+ return parseAssessmentResponse(raw, maxMinutes);
206
+ }
207
+ export async function assessStall(ctx, claudeCommand, verbose, toolWatchdogActive = false) {
208
+ const quick = quickHeuristic(ctx, toolWatchdogActive);
209
+ if (quick) {
210
+ if (verbose)
211
+ hlog(`[STALL-ASSESS] Heuristic verdict: ${quick.reason}`);
212
+ return quick;
213
+ }
214
+ try {
215
+ if (verbose)
216
+ hlog('[STALL-ASSESS] Running Haiku assessment...');
217
+ return await spawnHaikuVerdict(buildAssessmentPrompt(ctx), claudeCommand, verbose, 'STALL-ASSESS', STALL_MAX_MINUTES);
218
+ }
219
+ catch (err) {
220
+ if (verbose)
221
+ hlog(`[STALL-ASSESS] Haiku assessment failed: ${err}`);
222
+ return { action: 'extend', extensionMs: 10 * 60_000, reason: 'Stall assessment unavailable — extending 10 min as precaution', assessed: false };
223
+ }
224
+ }
225
+ export async function assessToolTimeout(toolName, toolInput, elapsedMs, claudeCommand, verbose, tokenSilenceMs, backgroundWorkPending = false, declaredTimeoutMs) {
226
+ const elapsedSec = Math.round(elapsedMs / 1000);
227
+ let inputSummary = '';
228
+ if (toolInput.url)
229
+ inputSummary = `URL: ${String(toolInput.url).slice(0, 200)}`;
230
+ else if (toolInput.query)
231
+ inputSummary = `Query: ${String(toolInput.query).slice(0, 200)}`;
232
+ else if (toolInput.command)
233
+ inputSummary = `Command: ${String(toolInput.command).slice(0, 200)}`;
234
+ else if (toolInput.prompt)
235
+ inputSummary = `Prompt: ${String(toolInput.prompt).slice(0, 200)}`;
236
+ else
237
+ inputSummary = JSON.stringify(toolInput).slice(0, 200);
238
+ const toolDescriptions = {
239
+ WebFetch: 'fetches a URL, converts HTML to markdown, and runs a Haiku summarization pass',
240
+ WebSearch: 'performs a web search and returns results',
241
+ Task: 'spawns a subagent that runs autonomously with its own tools',
242
+ Agent: 'spawns a subagent that runs autonomously with its own tools',
243
+ Workflow: 'orchestrates many subagents via a script; large runs take tens of minutes to hours',
244
+ Monitor: 'blocks waiting for a condition or background work to change state',
245
+ TaskOutput: 'blocks waiting for a background task to produce output',
246
+ Bash: 'executes a shell command',
247
+ Write: 'writes file content that may be very large; content streams token-by-token through stdio before disk write',
248
+ Edit: 'applies string replacements to a file; streams through stdio protocol',
249
+ Read: 'reads file contents that may be very large; result streams through stdio protocol',
250
+ Grep: 'searches file contents with regex; large codebases produce large result streams',
251
+ Glob: 'finds files by pattern; large directory trees take time to scan',
252
+ };
253
+ const toolDesc = toolDescriptions[toolName] || `executes the ${toolName} tool`;
254
+ const tokenLine = tokenSilenceMs !== undefined
255
+ ? `Token activity: last token event ${Math.round(tokenSilenceMs / 1000)}s ago (recent tokens = process is alive and processing)`
256
+ : 'Token activity: no token events observed';
257
+ const backgroundLine = backgroundWorkPending
258
+ ? 'Background orchestration tasks (subagents/workflows) are pending in this session — long coordination waits are normal; favor WORKING.'
259
+ : '';
260
+ const declaredLine = declaredTimeoutMs
261
+ ? `Declared timeout: the caller budgeted ${Math.round(declaredTimeoutMs / 1000)}s for this call${elapsedMs < declaredTimeoutMs ? ' — it is still within that budget; strongly favor WORKING' : ' — that budget is now exceeded'}.`
262
+ : '';
263
+ const prompt = [
264
+ `You are a process health monitor. A ${toolName} tool call has been running for ${elapsedSec}s.`,
265
+ `${toolName} ${toolDesc}.`,
266
+ `Tool input: ${inputSummary}`,
267
+ tokenLine,
268
+ backgroundLine,
269
+ declaredLine,
270
+ '',
271
+ `Is this tool call likely still working, or is it hung/frozen?`,
272
+ 'Consider: network latency, server response times, anti-bot protections, large page sizes, complex operations.',
273
+ 'IMPORTANT: If tokens were active recently (< 60s ago), the process is likely still alive and processing — strongly favor WORKING.',
274
+ '',
275
+ 'Respond in EXACTLY this format (3 lines, no extra text):',
276
+ 'VERDICT: WORKING or STALLED',
277
+ 'MINUTES: <number 1-10, only if WORKING, how many more minutes to allow>',
278
+ 'REASON: <brief one-line explanation>',
279
+ ].filter(Boolean).join('\n');
280
+ try {
281
+ if (verbose)
282
+ hlog(`[TOOL-ASSESS] Running Haiku assessment for ${toolName} (${elapsedSec}s elapsed)...`);
283
+ return await spawnHaikuVerdict(prompt, claudeCommand, verbose, 'TOOL-ASSESS', TOOL_TIMEOUT_MAX_MINUTES);
284
+ }
285
+ catch (err) {
286
+ if (verbose)
287
+ hlog(`[TOOL-ASSESS] Haiku assessment failed: ${err}`);
288
+ return {
289
+ action: 'extend',
290
+ extensionMs: 5 * 60_000,
291
+ reason: `Timeout assessment unavailable (${err instanceof Error ? err.message : String(err)})${backgroundWorkPending ? '; background tasks pending' : ''}`,
292
+ assessed: false,
293
+ };
294
+ }
295
+ }