@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,383 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ import { spawn } from 'node:child_process';
4
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
5
+ import { basename, dirname, extname, isAbsolute, join, relative, resolve } from 'node:path';
6
+ import { ADDITIONAL_EXCLUDES, ECOSYSTEM_TOOLS, SOURCE_EXTENSIONS } from './quality-types.js';
7
+ export const FALLBACK_IGNORE_DIRS = new Set([
8
+ 'node_modules', '.git', 'dist', 'build', '.next', '__pycache__',
9
+ 'target', 'vendor', '.venv', 'venv', '.tox', 'coverage',
10
+ '.minionry', '.cache', '.turbo', '.output',
11
+ ]);
12
+ export function detectEcosystem(dirPath) {
13
+ const ecosystems = [];
14
+ try {
15
+ const files = readdirSync(dirPath);
16
+ if (files.includes('package.json'))
17
+ ecosystems.push('node');
18
+ if (files.includes('pyproject.toml') || files.includes('setup.py') || files.includes('requirements.txt'))
19
+ ecosystems.push('python');
20
+ if (files.includes('Cargo.toml'))
21
+ ecosystems.push('rust');
22
+ if (files.includes('go.mod'))
23
+ ecosystems.push('go');
24
+ if (files.includes('Package.swift') || files.some(f => f.endsWith('.xcodeproj') || f.endsWith('.xcworkspace')))
25
+ ecosystems.push('swift');
26
+ if (files.includes('build.gradle') || files.includes('build.gradle.kts'))
27
+ ecosystems.push('kotlin');
28
+ }
29
+ catch {
30
+ }
31
+ if (ecosystems.length === 0)
32
+ ecosystems.push('unknown');
33
+ return ecosystems;
34
+ }
35
+ function detectNodePackageManager(dirPath) {
36
+ try {
37
+ const files = readdirSync(dirPath);
38
+ if (files.includes('bun.lockb') || files.includes('bun.lock'))
39
+ return 'bun';
40
+ if (files.includes('pnpm-lock.yaml'))
41
+ return 'pnpm';
42
+ if (files.includes('yarn.lock'))
43
+ return 'yarn';
44
+ }
45
+ catch {
46
+ }
47
+ return 'npm';
48
+ }
49
+ function nodeInstallCmd(pm, pkg) {
50
+ switch (pm) {
51
+ case 'yarn': return `yarn add -D ${pkg}`;
52
+ case 'pnpm': return `pnpm add -D ${pkg}`;
53
+ case 'bun': return `bun add -d ${pkg}`;
54
+ default: return `npm install -D ${pkg}`;
55
+ }
56
+ }
57
+ async function checkToolInstalled(check, cwd) {
58
+ return new Promise((resolve) => {
59
+ const proc = spawn(check[0], check.slice(1), {
60
+ cwd,
61
+ stdio: ['ignore', 'pipe', 'pipe'],
62
+ timeout: 10000,
63
+ });
64
+ proc.on('close', (code) => resolve(code === 0));
65
+ proc.on('error', () => resolve(false));
66
+ });
67
+ }
68
+ export async function detectTools(dirPath) {
69
+ const ecosystems = detectEcosystem(dirPath);
70
+ const tools = [];
71
+ const nodePm = ecosystems.includes('node') ? detectNodePackageManager(dirPath) : 'npm';
72
+ for (const eco of ecosystems) {
73
+ const specs = ECOSYSTEM_TOOLS[eco] || [];
74
+ for (const spec of specs) {
75
+ const installed = await checkToolInstalled(spec.check, dirPath);
76
+ const installCommand = eco === 'node'
77
+ ? nodeInstallCmd(nodePm, spec.installCmd.replace(/^npm install -D /, ''))
78
+ : spec.installCmd;
79
+ tools.push({
80
+ name: spec.name,
81
+ installed,
82
+ installCommand,
83
+ category: spec.category,
84
+ });
85
+ }
86
+ }
87
+ return { tools, ecosystem: ecosystems };
88
+ }
89
+ async function tryInstallCommands(tool, dirPath) {
90
+ if (tool.installCommand.startsWith('('))
91
+ return null;
92
+ const commands = tool.installCommand.split(' || ');
93
+ let lastStderr = '';
94
+ for (const cmd of commands) {
95
+ const parts = cmd.trim().split(' ');
96
+ const result = await runCommand(parts[0], parts.slice(1), dirPath, { NODE_ENV: 'development' });
97
+ if (result.exitCode === 0)
98
+ return null;
99
+ lastStderr = result.stderr;
100
+ }
101
+ const detail = lastStderr ? ` (${lastStderr.trim().split('\n').pop()})` : '';
102
+ return `${tool.name}: install failed${detail}`;
103
+ }
104
+ export async function installTools(dirPath, toolNames) {
105
+ const { tools } = await detectTools(dirPath);
106
+ const toInstall = tools.filter((t) => !t.installed && (!toolNames || toolNames.includes(t.name)));
107
+ const failures = [];
108
+ for (const tool of toInstall) {
109
+ const failure = await tryInstallCommands(tool, dirPath);
110
+ if (failure)
111
+ failures.push(failure);
112
+ }
113
+ const detected = await detectTools(dirPath);
114
+ const requestedNames = new Set(toolNames ?? toInstall.map((t) => t.name));
115
+ const stillMissing = detected.tools.filter((t) => !t.installed && requestedNames.has(t.name)).map((t) => t.name);
116
+ if (stillMissing.length > 0) {
117
+ const detail = failures.length > 0 ? ` ${failures.join('; ')}` : '';
118
+ throw new Error(`Failed to install: ${stillMissing.join(', ')}.${detail}`);
119
+ }
120
+ return detected;
121
+ }
122
+ function tryStatSync(path) {
123
+ try {
124
+ return statSync(path);
125
+ }
126
+ catch {
127
+ return null;
128
+ }
129
+ }
130
+ function tryReadFile(path) {
131
+ try {
132
+ return readFileSync(path, 'utf-8');
133
+ }
134
+ catch {
135
+ return null;
136
+ }
137
+ }
138
+ function tryReaddirSync(dir) {
139
+ try {
140
+ return readdirSync(dir);
141
+ }
142
+ catch {
143
+ return null;
144
+ }
145
+ }
146
+ function tryReadSourceFile(fullPath, rootPath) {
147
+ const content = tryReadFile(fullPath);
148
+ if (!content)
149
+ return null;
150
+ return {
151
+ path: fullPath,
152
+ relativePath: relative(rootPath, fullPath),
153
+ lines: content.split('\n').length,
154
+ content,
155
+ };
156
+ }
157
+ function processEntry(entry, dir, rootPath, stack, files) {
158
+ if (FALLBACK_IGNORE_DIRS.has(entry))
159
+ return;
160
+ const fullPath = join(dir, entry);
161
+ const stat = tryStatSync(fullPath);
162
+ if (!stat)
163
+ return;
164
+ if (stat.isDirectory()) {
165
+ stack.push(fullPath);
166
+ return;
167
+ }
168
+ if (!stat.isFile() || !SOURCE_EXTENSIONS.has(extname(entry).toLowerCase()))
169
+ return;
170
+ const sourceFile = tryReadSourceFile(fullPath, rootPath);
171
+ if (sourceFile)
172
+ files.push(sourceFile);
173
+ }
174
+ function collectSourceFilesFallback(dirPath, rootPath) {
175
+ const files = [];
176
+ const stack = [dirPath];
177
+ while (stack.length > 0) {
178
+ const dir = stack.pop();
179
+ const entries = tryReaddirSync(dir);
180
+ if (!entries)
181
+ continue;
182
+ for (const entry of entries) {
183
+ processEntry(entry, dir, rootPath, stack, files);
184
+ }
185
+ }
186
+ return files;
187
+ }
188
+ export async function collectSourceFiles(dirPath, rootPath) {
189
+ const gitCheck = await runCommand('git', ['rev-parse', '--is-inside-work-tree'], dirPath);
190
+ if (gitCheck.exitCode !== 0) {
191
+ return collectSourceFilesFallback(dirPath, rootPath);
192
+ }
193
+ const result = await runCommand('git', ['ls-files', '--cached', '--others', '--exclude-standard'], dirPath);
194
+ if (result.exitCode !== 0) {
195
+ return collectSourceFilesFallback(dirPath, rootPath);
196
+ }
197
+ const files = [];
198
+ const relativePaths = result.stdout.split('\n').filter(Boolean);
199
+ for (const relPath of relativePaths) {
200
+ const ext = extname(relPath).toLowerCase();
201
+ if (!SOURCE_EXTENSIONS.has(ext))
202
+ continue;
203
+ const fileName = relPath.split('/').pop() || '';
204
+ if (ADDITIONAL_EXCLUDES.has(fileName))
205
+ continue;
206
+ const fullPath = join(dirPath, relPath);
207
+ const sourceFile = tryReadSourceFile(fullPath, rootPath);
208
+ if (sourceFile)
209
+ files.push(sourceFile);
210
+ }
211
+ return files;
212
+ }
213
+ export function readSourceFiles(dirPath, paths) {
214
+ const files = [];
215
+ for (const path of paths) {
216
+ const fullPath = isAbsolute(path) ? path : join(dirPath, path);
217
+ const sourceFile = tryReadSourceFile(fullPath, dirPath);
218
+ if (sourceFile)
219
+ files.push(sourceFile);
220
+ }
221
+ return files;
222
+ }
223
+ export async function ignoredByGit(absolutePaths) {
224
+ const ignored = new Set();
225
+ for (const [dir, names] of groupByDirectory(absolutePaths)) {
226
+ for (const chunk of chunkFileList(names)) {
227
+ const result = await runCommand('git', ['check-ignore', '--', ...chunk], dir);
228
+ if (result.exitCode !== 0)
229
+ continue;
230
+ for (const line of result.stdout.split('\n')) {
231
+ if (line)
232
+ ignored.add(join(dir, line));
233
+ }
234
+ }
235
+ }
236
+ return ignored;
237
+ }
238
+ function groupByDirectory(absolutePaths) {
239
+ const byDir = new Map();
240
+ for (const path of absolutePaths) {
241
+ const dir = dirname(path);
242
+ const group = byDir.get(dir);
243
+ if (group)
244
+ group.push(basename(path));
245
+ else
246
+ byDir.set(dir, [basename(path)]);
247
+ }
248
+ return byDir;
249
+ }
250
+ export async function filterSourceFiles(paths) {
251
+ const candidates = paths.filter((path) => isAbsolute(path) && SOURCE_EXTENSIONS.has(extname(path).toLowerCase()));
252
+ if (candidates.length === 0)
253
+ return [];
254
+ const ignored = await ignoredByGit(candidates);
255
+ return candidates.filter((path) => !ignored.has(path));
256
+ }
257
+ export function attributeToTrackedDirectories(spaceRoot, directories, files) {
258
+ const root = resolve(spaceRoot);
259
+ const candidates = new Map([['.', root]]);
260
+ for (const dir of directories) {
261
+ if (!candidates.has(dir.path))
262
+ candidates.set(dir.path, resolve(root, dir.path));
263
+ }
264
+ const attributed = new Map();
265
+ for (const file of files) {
266
+ const absolute = resolve(file);
267
+ if (!isInside(root, absolute))
268
+ continue;
269
+ const [path, dir] = deepestContaining(candidates, absolute);
270
+ const entry = attributed.get(path);
271
+ if (entry)
272
+ entry.files.push(relative(dir, absolute));
273
+ else
274
+ attributed.set(path, { path, files: [relative(dir, absolute)] });
275
+ }
276
+ return [...attributed.values()];
277
+ }
278
+ function isInside(dir, path) {
279
+ return path === dir || path.startsWith(`${dir}/`);
280
+ }
281
+ function deepestContaining(candidates, absolute) {
282
+ let deepest;
283
+ for (const candidate of candidates) {
284
+ if (!isInside(candidate[1], absolute))
285
+ continue;
286
+ if (!deepest || candidate[1].length > deepest[1].length)
287
+ deepest = candidate;
288
+ }
289
+ if (!deepest)
290
+ throw new Error(`${absolute} is inside no candidate directory`);
291
+ return deepest;
292
+ }
293
+ export function filesByExt(files, exts) {
294
+ const set = new Set(exts.map((e) => e.toLowerCase()));
295
+ const out = [];
296
+ for (const f of files) {
297
+ if (set.has(extname(f.path).toLowerCase()))
298
+ out.push(f.relativePath);
299
+ }
300
+ return out;
301
+ }
302
+ const TEST_FOLDER_SEGMENTS = ['__tests__', '__mocks__', 'tests', 'test', 'e2e', 'spec'];
303
+ const TEST_FILE_PATTERNS = [
304
+ /\.(test|spec)\.(ts|tsx|js|jsx|mjs|cjs|mts|cts)$/,
305
+ /_test\.(go|py)$/,
306
+ /^test_.+\.py$/,
307
+ ];
308
+ function pathHasTestFolder(path) {
309
+ for (const segment of TEST_FOLDER_SEGMENTS) {
310
+ if (path.includes(`/${segment}/`) || path.startsWith(`${segment}/`))
311
+ return true;
312
+ }
313
+ return false;
314
+ }
315
+ function fileNameLooksLikeTest(name) {
316
+ for (const pattern of TEST_FILE_PATTERNS) {
317
+ if (pattern.test(name))
318
+ return true;
319
+ }
320
+ return false;
321
+ }
322
+ export function isTestFile(relativePath) {
323
+ const path = relativePath.replace(/\\/g, '/').toLowerCase();
324
+ if (pathHasTestFolder(path))
325
+ return true;
326
+ const name = path.split('/').pop() ?? path;
327
+ return fileNameLooksLikeTest(name);
328
+ }
329
+ const GENERATED_PATH_SEGMENTS = [
330
+ '/dist/', '/build/', '/.next/', '/out/', '/.output/',
331
+ '/generated/', '/__generated__/', '/coverage/', '/.turbo/',
332
+ ];
333
+ const CONFIG_BASENAMES = new Set([
334
+ 'package.json', 'tsconfig.json', 'biome.json', 'biome.jsonc',
335
+ '.eslintrc', '.eslintrc.js', '.eslintrc.cjs', '.eslintrc.json',
336
+ '.prettierrc', '.prettierrc.json', '.prettierrc.js',
337
+ 'babel.config.js', '.babelrc', 'jest.config.js', 'vitest.config.ts',
338
+ ]);
339
+ const CONFIG_FILENAME_PATTERNS = [
340
+ /\.config\.(ts|tsx|js|jsx|mjs|cjs|cts|mts|json)$/,
341
+ /^tsconfig\..+\.json$/,
342
+ ];
343
+ export function classifyFileRole(relativePath) {
344
+ const path = relativePath.replace(/\\/g, '/').toLowerCase();
345
+ if (isTestFile(path))
346
+ return 'test';
347
+ const withSlash = path.startsWith('/') ? path : `/${path}`;
348
+ if (GENERATED_PATH_SEGMENTS.some((seg) => withSlash.includes(seg)))
349
+ return 'generated';
350
+ const name = path.split('/').pop() ?? path;
351
+ if (CONFIG_BASENAMES.has(name) || CONFIG_FILENAME_PATTERNS.some((re) => re.test(name)))
352
+ return 'config';
353
+ return 'production';
354
+ }
355
+ export function chunkFileList(paths, size = 400) {
356
+ if (paths.length === 0)
357
+ return [];
358
+ const chunks = [];
359
+ for (let i = 0; i < paths.length; i += size) {
360
+ chunks.push(paths.slice(i, i + size));
361
+ }
362
+ return chunks;
363
+ }
364
+ export const DEFAULT_COMMAND_TIMEOUT_MS = 120_000;
365
+ export function runCommand(cmd, args, cwd, envOverrides, timeoutMs = DEFAULT_COMMAND_TIMEOUT_MS) {
366
+ return new Promise((resolve) => {
367
+ const proc = spawn(cmd, args, {
368
+ cwd,
369
+ stdio: ['ignore', 'pipe', 'pipe'],
370
+ timeout: timeoutMs,
371
+ env: envOverrides ? { ...process.env, ...envOverrides } : undefined,
372
+ });
373
+ let stdout = '';
374
+ let stderr = '';
375
+ proc.stdout?.on('data', (d) => { stdout += d.toString(); });
376
+ proc.stderr?.on('data', (d) => { stderr += d.toString(); });
377
+ proc.on('close', (code) => {
378
+ const timedOut = proc.killed && code === null;
379
+ resolve({ stdout, stderr, exitCode: code ?? 1, ...(timedOut ? { timedOut: true } : {}) });
380
+ });
381
+ proc.on('error', (err) => resolve({ stdout: '', stderr: err.message, exitCode: 1 }));
382
+ });
383
+ }
@@ -0,0 +1,101 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ import { ResilientRunner } from '../../cli/headless/resilient-runner.js';
4
+ import { readOnlyDisallowedTools, readOnlyRefusal } from '../../engines/read-only.js';
5
+ import { loadSkillPrompt } from '../plan/agent-loader.js';
6
+ import { jsonCandidates } from './quality-types.js';
7
+ const VALID_STATUSES = new Set(['confirmed', 'likely-fp', 'uncertain']);
8
+ const VALID_SEVERITIES = new Set(['critical', 'high', 'medium', 'low']);
9
+ export function buildTriagePrompt(dirPath, findings) {
10
+ const findingsJson = JSON.stringify(findings.map((f, i) => ({
11
+ id: i + 1,
12
+ severity: f.severity,
13
+ category: f.category,
14
+ file: f.file,
15
+ line: f.line,
16
+ title: f.title,
17
+ description: f.description,
18
+ })), null, 2);
19
+ const fromSkill = loadSkillPrompt('triage-findings', { dirPath, findingsJson });
20
+ if (fromSkill)
21
+ return fromSkill;
22
+ return `You are triaging automated code-quality findings for precision. Working directory: "${dirPath}". Read the cited files and classify each finding below as "confirmed" (a real issue worth fixing), "likely-fp" (technically flagged but not an actual problem here — e.g. a long but cohesive file), or "uncertain". Trust linters/build/format/security findings by default; apply judgment to file-length, function-length, and complexity. Do NOT invent new findings or fix anything.\n\n## Findings to triage\n\n${findingsJson}\n\nOutput EXACTLY one JSON code block: {"verdicts":[{"id":1,"status":"confirmed|likely-fp|uncertain","confidence":0.9,"rationale":"...","severity":"critical|high|medium|low"}]}`;
23
+ }
24
+ function toTriageVerdict(v) {
25
+ if (typeof v.id !== 'number')
26
+ return null;
27
+ const status = v.status;
28
+ if (!VALID_STATUSES.has(status))
29
+ return null;
30
+ return {
31
+ id: v.id,
32
+ status: status,
33
+ confidence: typeof v.confidence === 'number' ? Math.max(0, Math.min(1, v.confidence)) : 0.5,
34
+ rationale: typeof v.rationale === 'string' ? v.rationale : '',
35
+ severity: VALID_SEVERITIES.has(v.severity) ? v.severity : undefined,
36
+ };
37
+ }
38
+ export function parseTriageResponse(response) {
39
+ for (const candidate of jsonCandidates(response)) {
40
+ try {
41
+ const parsed = JSON.parse(candidate);
42
+ if (!Array.isArray(parsed.verdicts))
43
+ continue;
44
+ return parsed.verdicts.map(toTriageVerdict).filter((v) => v !== null);
45
+ }
46
+ catch {
47
+ }
48
+ }
49
+ return [];
50
+ }
51
+ export function applyTriage(findings, verdicts) {
52
+ const byId = new Map(verdicts.map((v) => [v.id, v]));
53
+ return findings.map((f, i) => {
54
+ const v = byId.get(i + 1);
55
+ if (!v)
56
+ return f;
57
+ return {
58
+ ...f,
59
+ status: v.status,
60
+ confidence: v.confidence,
61
+ triageRationale: v.rationale || undefined,
62
+ severity: v.severity ?? f.severity,
63
+ };
64
+ });
65
+ }
66
+ export async function runTriagePass(dirPath, findings, send, signal,
67
+ model, engineId, effortLevel, fastMode) {
68
+ if (findings.length === 0)
69
+ return { findings, ran: false };
70
+ if (engineId && readOnlyRefusal(engineId))
71
+ return { findings, ran: false };
72
+ send(`Triaging ${findings.length} programmatic ${findings.length === 1 ? 'finding' : 'findings'} for relevance...`);
73
+ const runner = new ResilientRunner({
74
+ workingDir: dirPath,
75
+ prompt: buildTriagePrompt(dirPath, findings),
76
+ policy: 'STANDARD',
77
+ model,
78
+ engineId,
79
+ effortLevel,
80
+ fastMode,
81
+ disallowedTools: readOnlyDisallowedTools(),
82
+ stallWarningMs: 180_000,
83
+ stallKillMs: 600_000,
84
+ stallHardCapMs: 1_800_000,
85
+ logLabel: 'quality-triage',
86
+ abortSignal: signal,
87
+ });
88
+ const result = await runner.run();
89
+ if (signal?.aborted)
90
+ return { findings, ran: false };
91
+ const verdicts = parseTriageResponse(result.assistantResponse || '');
92
+ if (verdicts.length === 0) {
93
+ return { findings, ran: false };
94
+ }
95
+ const triaged = applyTriage(findings, verdicts);
96
+ const hidden = triaged.filter((f) => f.status === 'likely-fp').length;
97
+ if (hidden > 0) {
98
+ send(`Triage filtered ${hidden} likely false ${hidden === 1 ? 'positive' : 'positives'}`);
99
+ }
100
+ return { findings: triaged, ran: true };
101
+ }
@@ -0,0 +1,149 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ export const STRUCTURAL_CATEGORIES = new Set([
4
+ 'file-length',
5
+ 'function-length',
6
+ 'parameters',
7
+ 'nesting',
8
+ 'returns',
9
+ 'tech-debt',
10
+ 'duplication',
11
+ ]);
12
+ export function findingCountsTowardGrade(f) {
13
+ return f.status !== 'uncertain' && f.status !== 'likely-fp' && f.dismissal === undefined;
14
+ }
15
+ export const ECOSYSTEM_TOOLS = {
16
+ node: [
17
+ { name: 'eslint', check: ['npx', 'eslint', '--version'], category: 'linter', installCmd: 'npm install -D eslint' },
18
+ { name: 'biome', check: ['npx', '@biomejs/biome', '--version'], category: 'linter', installCmd: 'npm install -D @biomejs/biome' },
19
+ { name: 'prettier', check: ['npx', 'prettier', '--version'], category: 'formatter', installCmd: 'npm install -D prettier' },
20
+ { name: 'typescript', check: ['npx', 'tsc', '--version'], category: 'general', installCmd: 'npm install -D typescript' },
21
+ { name: 'jscpd', check: ['npx', '--no-install', 'jscpd', '--version'], category: 'general', installCmd: 'npm install -D jscpd' },
22
+ ],
23
+ python: [
24
+ { name: 'ruff', check: ['ruff', '--version'], category: 'linter', installCmd: 'uv tool install ruff || pip install ruff' },
25
+ { name: 'black', check: ['black', '--version'], category: 'formatter', installCmd: 'uv tool install black || pip install black' },
26
+ { name: 'radon', check: ['radon', '--version'], category: 'complexity', installCmd: 'uv tool install radon || pip install radon' },
27
+ { name: 'pip-audit', check: ['pip-audit', '--version'], category: 'security', installCmd: 'pip install pip-audit' },
28
+ ],
29
+ rust: [
30
+ { name: 'clippy', check: ['cargo', 'clippy', '--version'], category: 'linter', installCmd: 'rustup component add clippy' },
31
+ { name: 'rustfmt', check: ['rustfmt', '--version'], category: 'formatter', installCmd: 'rustup component add rustfmt' },
32
+ { name: 'cargo-audit', check: ['cargo', 'audit', '--version'], category: 'security', installCmd: 'cargo install cargo-audit' },
33
+ ],
34
+ go: [],
35
+ swift: [],
36
+ kotlin: [],
37
+ unknown: [],
38
+ };
39
+ export const SOURCE_EXTENSIONS = new Set([
40
+ '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
41
+ '.py', '.pyi',
42
+ '.rs',
43
+ '.go',
44
+ '.java', '.kt',
45
+ '.cs',
46
+ '.rb',
47
+ '.php',
48
+ '.swift',
49
+ '.c', '.cpp', '.h', '.hpp',
50
+ ]);
51
+ export const ADDITIONAL_EXCLUDES = new Set([
52
+ 'package-lock.json',
53
+ 'pnpm-lock.yaml',
54
+ 'yarn.lock',
55
+ 'bun.lockb',
56
+ 'bun.lock',
57
+ 'composer.lock',
58
+ 'Gemfile.lock',
59
+ 'Cargo.lock',
60
+ 'poetry.lock',
61
+ 'go.sum',
62
+ ]);
63
+ export const FILE_LENGTH_THRESHOLD = 300;
64
+ export const FUNCTION_LENGTH_THRESHOLD = 50;
65
+ export const PARAM_COUNT_THRESHOLD = 4;
66
+ export const NESTING_DEPTH_THRESHOLD = 4;
67
+ export const RETURN_COUNT_THRESHOLD = 5;
68
+ export const TOTAL_STEPS = 12;
69
+ export const ANALYZER_FINDING_BOUND = 5000;
70
+ export function hasInstalledToolInCategory(installedSet, ecosystems, category) {
71
+ for (const eco of ecosystems) {
72
+ const specs = ECOSYSTEM_TOOLS[eco] || [];
73
+ for (const spec of specs) {
74
+ if (spec.category === category && installedSet.has(spec.name))
75
+ return true;
76
+ }
77
+ }
78
+ return false;
79
+ }
80
+ export function biomeSeverity(severity) {
81
+ if (severity === 'error')
82
+ return 'high';
83
+ if (severity === 'warning')
84
+ return 'medium';
85
+ return 'low';
86
+ }
87
+ const BIOME_COGNITIVE_COMPLEXITY_RULE = 'noExcessiveCognitiveComplexity';
88
+ function biomeRuleGroup(category) {
89
+ const parts = (category || '').split('/');
90
+ return { group: parts.length >= 2 ? parts[parts.length - 2] : '', rule: parts[parts.length - 1] || '' };
91
+ }
92
+ export function biomeGroupSeverity(category, emitted) {
93
+ const { group, rule } = biomeRuleGroup(category);
94
+ if (group === 'security')
95
+ return 'high';
96
+ if (group === 'correctness')
97
+ return emitted === 'error' ? 'high' : 'medium';
98
+ if (group === 'suspicious')
99
+ return 'medium';
100
+ if (group === 'complexity')
101
+ return rule === BIOME_COGNITIVE_COMPLEXITY_RULE ? biomeSeverity(emitted) : 'low';
102
+ if (group === 'style' || group === 'a11y' || group === 'performance' || group === 'nursery') {
103
+ return 'low';
104
+ }
105
+ return biomeSeverity(emitted);
106
+ }
107
+ export function isBiomeComplexityDiagnostic(d) {
108
+ return (d.category || '').includes('/complexity/');
109
+ }
110
+ export function isEslintComplexityRule(ruleId) {
111
+ if (!ruleId)
112
+ return false;
113
+ return ruleId === 'complexity' || ruleId.endsWith('-complexity') || ruleId.endsWith('/complexity');
114
+ }
115
+ function biomeDiagLine(location, content) {
116
+ const start = location?.start;
117
+ if (typeof start?.line === 'number')
118
+ return start.line;
119
+ const span = location?.span;
120
+ if (!Array.isArray(span) || typeof span[0] !== 'number' || content === undefined)
121
+ return null;
122
+ const offset = Math.max(0, Math.min(span[0], Buffer.byteLength(content, 'utf8')));
123
+ const before = Buffer.from(content, 'utf8').subarray(0, offset).toString('utf8');
124
+ return before.split('\n').length;
125
+ }
126
+ export function biomeDiagToFinding(d, category, contentOf) {
127
+ const rawCategory = d.category || '';
128
+ const sev = biomeGroupSeverity(rawCategory, d.severity);
129
+ const location = d.location;
130
+ const file = location?.path || '';
131
+ const message = d.message;
132
+ const desc = (typeof message === 'object' ? message?.text : message) || '';
133
+ const ruleName = rawCategory.split('/').pop() || 'Issue';
134
+ return {
135
+ severity: sev,
136
+ category: biomeRuleGroup(rawCategory).group === 'security' ? 'security' : category,
137
+ file,
138
+ line: biomeDiagLine(location, contentOf?.(file)),
139
+ title: ruleName,
140
+ description: desc,
141
+ };
142
+ }
143
+ export function jsonCandidates(reply) {
144
+ const fenced = [/```json\s*([\s\S]*)```/, /```json\s*([\s\S]*?)```/, /```\s*([\s\S]*)```/, /```\s*([\s\S]*?)```/]
145
+ .map((pattern) => reply.match(pattern)?.[1]?.trim())
146
+ .filter((candidate) => !!candidate);
147
+ const braces = reply.match(/\{[\s\S]*\}/)?.[0];
148
+ return [...fenced, ...(braces ? [braces] : []), reply.trim()];
149
+ }
@@ -0,0 +1,28 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ const RECOMMENDED_MARKER = '(recommended)';
4
+ export function selectRecommendedAnswers(questions) {
5
+ const answers = {};
6
+ for (const q of questions) {
7
+ if (q.options.length === 0)
8
+ continue;
9
+ const recommended = q.options.filter((o) => o.label.toLowerCase().includes(RECOMMENDED_MARKER));
10
+ if (q.multiSelect) {
11
+ answers[q.question] =
12
+ recommended.length > 0
13
+ ? recommended.map((o) => o.label).join(', ')
14
+ : q.options[0].label;
15
+ }
16
+ else {
17
+ answers[q.question] =
18
+ recommended.length > 0 ? recommended[0].label : q.options[0].label;
19
+ }
20
+ }
21
+ return answers;
22
+ }
23
+ export function buildLateAnswerPrompt(answers) {
24
+ const bullets = Object.entries(answers)
25
+ .map(([question, answer]) => `- ${question}: ${answer}`)
26
+ .join('\n');
27
+ return `Following up on the question(s) you asked me earlier — here are my answers:\n${bullets}\nPlease incorporate these and continue.`;
28
+ }