@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,526 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { basename, isAbsolute, join } from 'node:path';
5
+ import { loadSkillPrompt } from '../plan/agent-loader.js';
6
+ import { estimateCodebaseSize, estimateReviewMs } from './quality-eta.js';
7
+ import { diskContentReader, stampFingerprints } from './quality-fingerprint.js';
8
+ import { getQualityModels, indexDismissals, recomputeGrade, stampDismissals, stampIntroduced } from './quality-service.js';
9
+ import { runTriagePass } from './quality-triage-agent.js';
10
+ import { jsonCandidates, } from './quality-types.js';
11
+ let reviewHost = null;
12
+ export function setQualityReviewHost(host) {
13
+ reviewHost = host;
14
+ }
15
+ const DISMISSED_PROMPT_CAP = 100;
16
+ export function buildCodeReviewPrompt(dirPath, cliFindings, dismissed) {
17
+ const cliFindingsList = cliFindings && cliFindings.length > 0
18
+ ? `\n## CLI Tool Findings (already detected)\n\nThe following issues were found by automated CLI tools (linters, formatters, complexity analyzers). Review these for context — they are already included in the final report. Focus your analysis on DEEPER issues these tools cannot detect.\n\n${cliFindings.slice(0, 50).map((f, i) => `${i + 1}. [${f.severity.toUpperCase()}] ${f.category} — ${f.file}${f.line ? `:${f.line}` : ''} — ${f.title}: ${f.description}`).join('\n')}\n${cliFindings.length > 50 ? `\n...and ${cliFindings.length - 50} more issues from CLI tools.\n` : ''}`
19
+ : '';
20
+ const dismissedList = dismissed && dismissed.length > 0
21
+ ? `\n## Dismissed by the user — do not report again\n\nThe user reviewed and dismissed the following findings from earlier reviews of this directory. Do NOT report them again, in any wording, and do not report a variant of the same issue at the same place.\n\n${dismissed.slice(0, DISMISSED_PROMPT_CAP).map((d, i) => `${i + 1}. ${d.file} — ${d.title} (dismissed by the user: ${d.reason})`).join('\n')}\n${dismissed.length > DISMISSED_PROMPT_CAP ? `\n...and ${dismissed.length - DISMISSED_PROMPT_CAP} more dismissed findings.\n` : ''}`
22
+ : '';
23
+ const cliFindingsSection = `${cliFindingsList}${dismissedList}`;
24
+ const fromSkill = loadSkillPrompt('code-review', { dirPath, cliFindingsSection });
25
+ if (fromSkill)
26
+ return fromSkill;
27
+ return `You are a senior staff engineer performing a rigorous code review.\n\nIMPORTANT: Your current working directory is "${dirPath}". Only review files within this directory.\n${cliFindingsSection}\nDiscover source files with Glob, read important files, analyze for architecture, SOLID, security, bugs, and performance issues. Each finding needs file, line, evidence. Output one JSON code block with score, grade, findings array, and summary.`;
28
+ }
29
+ const VALID_SEVERITIES = new Set(['critical', 'high', 'medium', 'low']);
30
+ const VALID_CATEGORIES = new Set(['architecture', 'oop', 'security', 'bugs', 'performance', 'logic', 'maintainability']);
31
+ function normalizeFinding(f) {
32
+ if (typeof f.file !== 'string' || typeof f.title !== 'string')
33
+ return null;
34
+ return {
35
+ severity: VALID_SEVERITIES.has(f.severity) ? f.severity : 'medium',
36
+ category: VALID_CATEGORIES.has(f.category) ? f.category : 'maintainability',
37
+ file: f.file,
38
+ line: typeof f.line === 'number' ? f.line : null,
39
+ title: f.title,
40
+ description: typeof f.description === 'string' ? f.description : '',
41
+ suggestion: typeof f.suggestion === 'string' ? f.suggestion : undefined,
42
+ evidence: typeof f.evidence === 'string' ? f.evidence : undefined,
43
+ };
44
+ }
45
+ export function parseCodeReviewResponse(response) {
46
+ for (const candidate of jsonCandidates(response)) {
47
+ try {
48
+ const parsed = JSON.parse(candidate);
49
+ if (!Array.isArray(parsed.findings))
50
+ continue;
51
+ const rawFindings = parsed.findings;
52
+ const findings = rawFindings.map(normalizeFinding).filter((f) => f !== null);
53
+ const summary = typeof parsed.summary === 'string' ? parsed.summary : `Found ${findings.length} issue(s).`;
54
+ const score = typeof parsed.score === 'number' ? Math.max(0, Math.min(100, Math.round(parsed.score))) : null;
55
+ const grade = typeof parsed.grade === 'string' ? parsed.grade : null;
56
+ const scoreRationale = typeof parsed.scoreRationale === 'string' ? parsed.scoreRationale : null;
57
+ return { findings, summary, score, grade, scoreRationale };
58
+ }
59
+ catch {
60
+ }
61
+ }
62
+ throw new Error("The AI review's reply had no readable findings, so nothing from it was recorded. Open its Agent tab to see what it said, then retry.");
63
+ }
64
+ function resolveFilePath(dirPath, filePath) {
65
+ if (isAbsolute(filePath))
66
+ return filePath;
67
+ return join(dirPath, filePath);
68
+ }
69
+ function extractClaimedIdentifiers(description, title) {
70
+ const identifiers = [];
71
+ const combined = `${title} ${description}`;
72
+ const callPatterns = combined.matchAll(/\b([a-zA-Z_$][\w.$]*)\s*\(/g);
73
+ for (const m of callPatterns) {
74
+ const name = m[1];
75
+ if (!['If', 'When', 'While', 'For', 'This', 'That', 'The', 'Each', 'Uses', 'Has', 'Does', 'Returns', 'Takes', 'Calls'].includes(name)) {
76
+ identifiers.push(name);
77
+ }
78
+ }
79
+ const backtickPatterns = combined.matchAll(/`([^`]+)`/g);
80
+ for (const m of backtickPatterns) {
81
+ const inner = m[1].replace(/[()[\]{};,]/g, ' ').trim();
82
+ if (inner && inner.length < 60) {
83
+ identifiers.push(inner);
84
+ }
85
+ }
86
+ return identifiers;
87
+ }
88
+ export function validateFindings(findings, dirPath) {
89
+ const validated = [];
90
+ const rejected = [];
91
+ for (const finding of findings) {
92
+ const result = validateSingleFinding(finding, dirPath);
93
+ if (result.valid) {
94
+ validated.push({ ...finding, verified: undefined });
95
+ }
96
+ else {
97
+ rejected.push({ ...finding, verified: false, verificationNote: result.reason });
98
+ }
99
+ }
100
+ return {
101
+ validated,
102
+ rejected,
103
+ stats: { total: findings.length, passed: validated.length, failed: rejected.length },
104
+ };
105
+ }
106
+ function readFileContent(filePath) {
107
+ try {
108
+ return readFileSync(filePath, 'utf-8');
109
+ }
110
+ catch {
111
+ return null;
112
+ }
113
+ }
114
+ const COMMON_KEYWORDS = /^(const|let|var|function|return|import|export|from|this|true|false|null|undefined|new|if|else|for|while|try|catch)$/;
115
+ function checkLineInRange(content, line) {
116
+ if (line === null || line <= 0)
117
+ return null;
118
+ const lineCount = content.split('\n').length;
119
+ if (line > lineCount)
120
+ return `Line ${line} exceeds file length (${lineCount} lines)`;
121
+ return null;
122
+ }
123
+ function checkEvidenceTokens(content, evidence) {
124
+ if (!evidence)
125
+ return null;
126
+ const evidenceTokens = evidence
127
+ .replace(/['"`;{}[\]()]/g, ' ')
128
+ .split(/\s+/)
129
+ .filter(t => t.length > 3 && !COMMON_KEYWORDS.test(t));
130
+ if (evidenceTokens.length === 0)
131
+ return null;
132
+ const matchCount = evidenceTokens.filter(token => content.includes(token)).length;
133
+ if (matchCount === 0)
134
+ return `Evidence tokens not found in file: ${evidenceTokens.slice(0, 3).join(', ')}`;
135
+ return null;
136
+ }
137
+ function checkClaimedIdentifiers(content, finding) {
138
+ const claimedIds = extractClaimedIdentifiers(finding.description, finding.title);
139
+ if (claimedIds.length < 2)
140
+ return null;
141
+ const foundAny = claimedIds.some(id => {
142
+ if (id.includes('.'))
143
+ return content.includes(id);
144
+ return new RegExp(`\\b${id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(content);
145
+ });
146
+ if (!foundAny)
147
+ return `Claimed identifiers not found in file: ${claimedIds.slice(0, 3).join(', ')}`;
148
+ return null;
149
+ }
150
+ function validateSingleFinding(finding, dirPath) {
151
+ const filePath = resolveFilePath(dirPath, finding.file);
152
+ if (!existsSync(filePath)) {
153
+ return { finding, valid: false, reason: `File does not exist: ${finding.file}` };
154
+ }
155
+ const content = readFileContent(filePath);
156
+ if (!content)
157
+ return { finding, valid: true };
158
+ const lineErr = checkLineInRange(content, finding.line);
159
+ if (lineErr)
160
+ return { finding, valid: false, reason: lineErr };
161
+ const evidenceErr = checkEvidenceTokens(content, finding.evidence);
162
+ if (evidenceErr)
163
+ return { finding, valid: false, reason: evidenceErr };
164
+ const idErr = checkClaimedIdentifiers(content, finding);
165
+ if (idErr)
166
+ return { finding, valid: false, reason: idErr };
167
+ return { finding, valid: true };
168
+ }
169
+ export function buildVerificationPrompt(dirPath, findings) {
170
+ const findingsJson = JSON.stringify(findings.map((f, i) => ({
171
+ id: i + 1,
172
+ severity: f.severity,
173
+ category: f.category,
174
+ file: f.file,
175
+ line: f.line,
176
+ title: f.title,
177
+ description: f.description,
178
+ evidence: f.evidence || '(none provided)',
179
+ })), null, 2);
180
+ const fromSkill = loadSkillPrompt('verify-review', { dirPath, findingsJson });
181
+ if (fromSkill)
182
+ return fromSkill;
183
+ return `You are an independent code review VERIFIER. Verify each finding below against actual code in "${dirPath}".\n\n## Findings to Verify\n\n${findingsJson}\n\nFor each finding: Read the cited file, check the claim, search for counter-evidence. Output one JSON code block with verifications array containing id, verdict (confirmed|rejected), confidence, and note.`;
184
+ }
185
+ export function parseVerificationResponse(response) {
186
+ for (const candidate of jsonCandidates(response)) {
187
+ try {
188
+ const parsed = JSON.parse(candidate);
189
+ if (!Array.isArray(parsed.verifications))
190
+ continue;
191
+ const raw = parsed.verifications;
192
+ return raw
193
+ .filter((v) => typeof v.id === 'number' && typeof v.verdict === 'string')
194
+ .map(v => ({
195
+ id: v.id,
196
+ verdict: v.verdict === 'rejected' ? 'rejected' : 'confirmed',
197
+ confidence: typeof v.confidence === 'number' ? v.confidence : 0.5,
198
+ note: typeof v.note === 'string' ? v.note : '',
199
+ }));
200
+ }
201
+ catch {
202
+ }
203
+ }
204
+ return [];
205
+ }
206
+ export function applyVerification(findings, verdicts) {
207
+ const verdictMap = new Map(verdicts.map(v => [v.id, v]));
208
+ const verified = [];
209
+ const rejected = [];
210
+ for (let i = 0; i < findings.length; i++) {
211
+ const verdict = verdictMap.get(i + 1);
212
+ if (!verdict) {
213
+ verified.push({ ...findings[i], verified: undefined });
214
+ continue;
215
+ }
216
+ if (verdict.verdict === 'confirmed' && verdict.confidence >= 0.6) {
217
+ verified.push({
218
+ ...findings[i],
219
+ verified: true,
220
+ verificationNote: verdict.note || undefined,
221
+ });
222
+ }
223
+ else {
224
+ rejected.push({
225
+ ...findings[i],
226
+ verified: false,
227
+ verificationNote: verdict.note || undefined,
228
+ });
229
+ }
230
+ }
231
+ return { verified, rejected };
232
+ }
233
+ const TOOL_START_MESSAGES = {
234
+ Glob: 'Discovering project files...',
235
+ Read: 'Reading source files...',
236
+ Grep: 'Searching codebase...',
237
+ Bash: 'Running analysis command...',
238
+ };
239
+ function getToolCompleteMessage(event) {
240
+ const input = event.completeInput;
241
+ if (!input)
242
+ return null;
243
+ if (event.toolName === 'Read' && input.file_path) {
244
+ return `Reviewed ${String(input.file_path).split('/').slice(-2).join('/')}`;
245
+ }
246
+ if (event.toolName === 'Grep' && input.pattern) {
247
+ return `Searched for "${String(input.pattern).slice(0, 40)}"`;
248
+ }
249
+ return null;
250
+ }
251
+ function createCodeReviewProgressTracker() {
252
+ const seenToolStarts = new Set();
253
+ return (event) => {
254
+ if (event.type === 'tool_start' && event.toolName) {
255
+ if (seenToolStarts.has(event.toolName))
256
+ return null;
257
+ seenToolStarts.add(event.toolName);
258
+ return TOOL_START_MESSAGES[event.toolName] ?? null;
259
+ }
260
+ if (event.type === 'tool_complete')
261
+ return getToolCompleteMessage(event);
262
+ return null;
263
+ };
264
+ }
265
+ function makeToolCallback(send, prefix) {
266
+ const getProgressMessage = createCodeReviewProgressTracker();
267
+ return (event) => {
268
+ const message = getProgressMessage(event);
269
+ if (message)
270
+ send(prefix ? `${prefix}${message}` : message);
271
+ };
272
+ }
273
+ function startHeartbeat(send, phase, intervalMs = 30_000) {
274
+ let elapsed = 0;
275
+ const timer = setInterval(() => {
276
+ elapsed += intervalMs;
277
+ const mins = Math.floor(elapsed / 60_000);
278
+ const secs = Math.floor((elapsed % 60_000) / 1000);
279
+ const timeStr = mins > 0 ? `${mins}m ${secs}s` : `${secs}s`;
280
+ send(`${phase} (${timeStr} elapsed, still working...)`);
281
+ }, intervalMs);
282
+ return () => clearInterval(timer);
283
+ }
284
+ function loadCliFindings(persistence, reportPath) {
285
+ try {
286
+ return persistence.loadReport(reportPath)?.findings;
287
+ }
288
+ catch {
289
+ return undefined;
290
+ }
291
+ }
292
+ function dismissedReviewFindings(suppressions, persistence, reportPath) {
293
+ if (suppressions.length === 0)
294
+ return [];
295
+ let scanFingerprints = new Set();
296
+ try {
297
+ scanFingerprints = new Set(persistence.loadReport(reportPath)?.fingerprints ?? []);
298
+ }
299
+ catch {
300
+ }
301
+ return suppressions.filter((s) => !scanFingerprints.has(s.fingerprint)).map(({ file, title, reason }) => ({ file, title, reason }));
302
+ }
303
+ async function runVerificationPass(dirPath, findings, ctx) {
304
+ const { send, signal, session } = ctx;
305
+ send(`Verifying ${findings.length} findings against actual code...`);
306
+ const stopHeartbeat = startHeartbeat(send, 'Verification');
307
+ ctx.toolProgress.current = makeToolCallback(send, 'Verifying: ');
308
+ try {
309
+ const verified = await session.prompt(buildVerificationPrompt(dirPath, findings));
310
+ if (verified.cancelled || signal.aborted)
311
+ return findings;
312
+ const verdicts = parseVerificationResponse(verified.text);
313
+ if (verdicts.length === 0)
314
+ return findings;
315
+ const applied = applyVerification(findings, verdicts);
316
+ if (applied.rejected.length > 0) {
317
+ send(`Verification rejected ${applied.rejected.length} inaccurate finding(s)`);
318
+ }
319
+ return applied.verified;
320
+ }
321
+ finally {
322
+ stopHeartbeat();
323
+ }
324
+ }
325
+ export function identifyReviewFindings(findings, dirPath) {
326
+ return stampFingerprints(findings.map((f) => ({ ...f })), { dirPath, contentOf: diskContentReader(dirPath) });
327
+ }
328
+ function persistReviewResults(reviewResult, reportPath, persistence, reviewDurationMs, reviewSessionId, dismissals) {
329
+ const existingReport = persistence.loadReport(reportPath);
330
+ const findings = reviewResult.findings.map((f) => ({ ...f, status: 'confirmed' }));
331
+ stampDismissals(findings, dismissals);
332
+ const findingsRecord = findings;
333
+ if (!existingReport) {
334
+ persistence.saveCodeReview(reportPath, findingsRecord, reviewResult.summary);
335
+ return null;
336
+ }
337
+ stampDismissals(existingReport.findings ?? [], dismissals);
338
+ const updatedResults = recomputeGrade({
339
+ ...existingReport,
340
+ codeReview: findings,
341
+ reviewDurationMs,
342
+ ...(reviewSessionId === undefined ? {} : { reviewSessionId }),
343
+ });
344
+ persistence.saveReport(reportPath, updatedResults);
345
+ persistence.updateHistoryEntry(updatedResults, reportPath);
346
+ persistence.saveCodeReview(reportPath, findingsRecord, reviewResult.summary, updatedResults.timestamp);
347
+ return updatedResults;
348
+ }
349
+ const REVIEWER_NAMES = {
350
+ 'claude-code': 'Claude',
351
+ codex: 'Codex',
352
+ hermes: 'Hermes',
353
+ };
354
+ async function runInitialReview(dirPath, cliFindings, dismissed, ctx) {
355
+ const { send, session, models } = ctx;
356
+ const stopReviewHeartbeat = startHeartbeat(send, 'AI code review');
357
+ try {
358
+ send(`${REVIEWER_NAMES[models.engine] ?? 'The reviewer'} is analyzing your codebase...`);
359
+ const result = await session.prompt(buildCodeReviewPrompt(dirPath, cliFindings, dismissed));
360
+ if (result.cancelled)
361
+ return null;
362
+ try {
363
+ return parseCodeReviewResponse(result.text);
364
+ }
365
+ catch (error) {
366
+ if (result.notice)
367
+ throw new Error(`[[MINIONRY_ERROR:${result.notice.code}]] ${result.notice.text}`);
368
+ throw error;
369
+ }
370
+ }
371
+ finally {
372
+ stopReviewHeartbeat();
373
+ }
374
+ }
375
+ async function refineFindings(reviewResult, dirPath, ctx) {
376
+ const { send, signal } = ctx;
377
+ send(`Validating ${reviewResult.findings.length} findings against codebase...`);
378
+ const validation = validateFindings(reviewResult.findings, dirPath);
379
+ if (validation.stats.failed > 0) {
380
+ send(`Filtered ${validation.stats.failed} finding(s) with invalid references`);
381
+ }
382
+ let finalFindings = validation.validated;
383
+ if (finalFindings.length > 0 && !signal.aborted) {
384
+ try {
385
+ finalFindings = await runVerificationPass(dirPath, finalFindings, ctx);
386
+ }
387
+ catch {
388
+ send('Verification pass skipped (timeout or error)');
389
+ }
390
+ }
391
+ return finalFindings;
392
+ }
393
+ async function computeReviewEta(dirPath, persistence, reportPath) {
394
+ try {
395
+ const size = await estimateCodebaseSize(dirPath);
396
+ return estimateReviewMs(size, persistence.loadHistory(), reportPath);
397
+ }
398
+ catch {
399
+ return undefined;
400
+ }
401
+ }
402
+ async function runTriageStep(reportPath, dirPath, persistence, ctx, dismissals) {
403
+ const { send, signal, models } = ctx;
404
+ const report = persistence.loadReport(reportPath);
405
+ if (!report || !Array.isArray(report.findings) || report.findings.length === 0)
406
+ return;
407
+ const findings = stampDismissals(report.findings, dismissals);
408
+ const candidates = findings.filter((f) => f.dismissal === undefined);
409
+ const hasUncertain = candidates.some((f) => f.status === 'uncertain');
410
+ if (!hasUncertain)
411
+ return;
412
+ const stopHeartbeat = startHeartbeat(send, 'Triage');
413
+ let triaged;
414
+ try {
415
+ triaged = await runTriagePass(dirPath, candidates, send, signal, models.triageModel, models.engine, models.effortLevel, models.fastMode);
416
+ }
417
+ catch {
418
+ send('Triage pass skipped (timeout or error)');
419
+ return;
420
+ }
421
+ finally {
422
+ stopHeartbeat();
423
+ }
424
+ if (signal.aborted || !triaged.ran)
425
+ return;
426
+ const verdictByCandidate = new Map();
427
+ for (let i = 0; i < candidates.length; i++)
428
+ verdictByCandidate.set(candidates[i], triaged.findings[i]);
429
+ const updated = recomputeGrade({ ...report, findings: findings.map((f) => verdictByCandidate.get(f) ?? f) });
430
+ try {
431
+ persistence.saveReport(reportPath, updated);
432
+ }
433
+ catch {
434
+ }
435
+ }
436
+ function reviewTabLabel(reportPath, dirPath, persistence) {
437
+ try {
438
+ const configured = persistence.loadConfig().find((dir) => dir.path === reportPath)?.label;
439
+ if (configured)
440
+ return configured;
441
+ }
442
+ catch {
443
+ }
444
+ return reportPath === '.' ? basename(dirPath) || '.' : reportPath;
445
+ }
446
+ function openReviewSession(options, models, toolProgress) {
447
+ if (!reviewHost) {
448
+ throw new Error('the quality review host is not installed — the review leg has no Agent tab to run in');
449
+ }
450
+ return reviewHost.open({
451
+ workingDir: options.workingDir,
452
+ reportPath: options.reportPath,
453
+ dirPath: options.dirPath,
454
+ tabName: `Quality review · ${reviewTabLabel(options.reportPath, options.dirPath, options.persistence)}`,
455
+ ...(options.initiator ? { initiator: options.initiator } : {}),
456
+ engine: models.engine,
457
+ model: models.reviewModel,
458
+ effortLevel: models.effortLevel,
459
+ fastMode: models.fastMode,
460
+ onToolUse: (event) => toolProgress.current(event),
461
+ });
462
+ }
463
+ export async function runCodeReviewPipeline(options) {
464
+ const { signal } = options;
465
+ if (signal.aborted)
466
+ return null;
467
+ const startedAt = Date.now();
468
+ const metaRef = { current: { startedAt } };
469
+ const send = (message) => {
470
+ options.onProgress({ message, etaMs: metaRef.current.etaMs, startedAt });
471
+ };
472
+ const models = options.models ?? getQualityModels();
473
+ const toolProgress = { current: makeToolCallback(send) };
474
+ const session = openReviewSession(options, models, toolProgress);
475
+ const runCtx = { models, send, signal, session, toolProgress };
476
+ options.onSession?.(session.sessionId);
477
+ const cancelSession = () => {
478
+ try {
479
+ session.cancel();
480
+ }
481
+ catch (error) {
482
+ console.error('[QualityReview] cancelling the review session failed:', error);
483
+ }
484
+ };
485
+ signal.addEventListener('abort', cancelSession, { once: true });
486
+ try {
487
+ return await runReviewPasses(options, runCtx, startedAt, metaRef);
488
+ }
489
+ finally {
490
+ signal.removeEventListener('abort', cancelSession);
491
+ }
492
+ }
493
+ async function runReviewPasses(options, runCtx, startedAt, metaRef) {
494
+ const { reportPath, dirPath, persistence, signal } = options;
495
+ const { send } = runCtx;
496
+ computeReviewEta(dirPath, persistence, reportPath)
497
+ .then((etaMs) => { if (etaMs !== undefined)
498
+ metaRef.current = { ...metaRef.current, etaMs }; })
499
+ .catch(() => { });
500
+ send('Starting AI code review...');
501
+ const suppressions = (options.suppressions ?? []).filter((s) => s.path === reportPath);
502
+ const dismissals = indexDismissals(reportPath, suppressions);
503
+ await runTriageStep(reportPath, dirPath, persistence, runCtx, dismissals);
504
+ if (signal.aborted)
505
+ return null;
506
+ const cliFindings = loadCliFindings(persistence, reportPath);
507
+ const dismissed = dismissedReviewFindings(suppressions, persistence, reportPath);
508
+ const reviewResult = await runInitialReview(dirPath, cliFindings, dismissed, runCtx);
509
+ if (!reviewResult || signal.aborted)
510
+ return null;
511
+ const refined = await refineFindings(reviewResult, dirPath, runCtx);
512
+ if (signal.aborted)
513
+ return null;
514
+ send('Generating review report...');
515
+ const finalFindings = identifyReviewFindings(refined, dirPath);
516
+ if (options.baseline)
517
+ stampIntroduced(finalFindings, options.baseline);
518
+ const reviewDurationMs = Date.now() - startedAt;
519
+ let results = null;
520
+ try {
521
+ results = persistReviewResults({ ...reviewResult, findings: finalFindings }, reportPath, persistence, reviewDurationMs, runCtx.session.sessionId, dismissals);
522
+ }
523
+ catch {
524
+ }
525
+ return { findings: finalFindings, summary: reviewResult.summary, results, reviewDurationMs };
526
+ }