@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,8 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+
4
+ export const PROD_PLATFORM_URL = 'https://api.minionry.com';
5
+
6
+ export function resolvePlatformUrl() {
7
+ return process.env.PLATFORM_URL || PROD_PLATFORM_URL;
8
+ }
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Copyright (c) 2025-present Minionry, Inc.
4
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
5
+
6
+
7
+ import { platform } from 'node:os';
8
+ import { CLI_ROOT, prebuiltPlatformDir } from './pty-locator.js';
9
+ import { nodePtyDirIn, normalizeNodePtyTree } from './pty-provision.js';
10
+
11
+ try {
12
+ normalizeNodePtyTree(prebuiltPlatformDir());
13
+ normalizeNodePtyTree(nodePtyDirIn(CLI_ROOT));
14
+ } catch (_) {
15
+ }
16
+
17
+ async function loadChromeSandbox() {
18
+ try {
19
+ return await import('../dist/server/services/browser/chrome-sandbox.js');
20
+ } catch {
21
+ const tsx = await import('tsx/esm/api').catch(() => null);
22
+ if (tsx?.tsImport) {
23
+ return tsx.tsImport('../server/services/browser/chrome-sandbox.ts', import.meta.url);
24
+ }
25
+ return import('../server/services/browser/chrome-sandbox.js');
26
+ }
27
+ }
28
+
29
+ async function fixChromeSandbox() {
30
+ if (platform() === 'win32') return;
31
+ if (process.env.MINIONRY_SKIP_SANDBOX_FIX === '1') return;
32
+
33
+ let mod;
34
+ try {
35
+ mod = await loadChromeSandbox();
36
+ } catch (_) {
37
+ return;
38
+ }
39
+
40
+ try {
41
+ const result = await mod.ensureChromeSandbox({ interactive: false });
42
+ if (result.state === 'fixed') {
43
+ console.log('Minionry: configured Electron chrome-sandbox (root:root, mode 4755).');
44
+ } else if (result.state === 'cannot-fix' && result.manualCommand) {
45
+ console.log('Minionry: the Electron browser sandbox needs a one-time root fix:');
46
+ console.log(` ${result.manualCommand}`);
47
+ }
48
+ } catch (_) {
49
+ }
50
+ }
51
+
52
+ fixChromeSandbox().catch(() => {});
@@ -0,0 +1,326 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+
4
+
5
+ import { execFileSync } from 'node:child_process';
6
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
7
+ import { join } from 'node:path';
8
+ import { machinePath } from './machine-layout.js';
9
+ import { NATIVE_ABI_KEY, nativeRoot } from './pty-locator.js';
10
+
11
+
12
+ const PYTHON_KNOWN_GOOD = { min: 6, max: 13 };
13
+
14
+ const PYTHON_CANDIDATES = ['python3.13', 'python3.12', 'python3.11', 'python3.10', 'python3.9', 'python3', 'python'];
15
+
16
+ function which(command) {
17
+ try {
18
+ const finder = process.platform === 'win32' ? 'where' : 'which';
19
+ const out = execFileSync(finder, [command], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
20
+ return out.split(/\r?\n/)[0].trim() || null;
21
+ } catch {
22
+ return null;
23
+ }
24
+ }
25
+
26
+ function pythonVersion(path) {
27
+ try {
28
+ const out = execFileSync(path, ['--version'], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });
29
+ const match = out.match(/(\d+)\.(\d+)\.(\d+)/);
30
+ if (!match) return null;
31
+ return { raw: out.trim(), major: Number(match[1]), minor: Number(match[2]) };
32
+ } catch {
33
+ return null;
34
+ }
35
+ }
36
+
37
+ function isKnownGood(version) {
38
+ return version.major === 3 && version.minor >= PYTHON_KNOWN_GOOD.min && version.minor <= PYTHON_KNOWN_GOOD.max;
39
+ }
40
+
41
+ function probePython() {
42
+ const path = which('python3') ?? which('python');
43
+ if (!path) return { path: null, version: null, supported: false, alternative: null };
44
+
45
+ const version = pythonVersion(path);
46
+ if (!version) return { path, version: null, supported: false, alternative: null };
47
+ if (isKnownGood(version)) return { path, version, supported: true, alternative: null };
48
+
49
+ for (const candidate of PYTHON_CANDIDATES) {
50
+ const candidatePath = which(candidate);
51
+ if (!candidatePath || candidatePath === path) continue;
52
+ const candidateVersion = pythonVersion(candidatePath);
53
+ if (candidateVersion && isKnownGood(candidateVersion)) {
54
+ return { path, version, supported: false, alternative: { path: candidatePath, version: candidateVersion } };
55
+ }
56
+ }
57
+ return { path, version, supported: false, alternative: null };
58
+ }
59
+
60
+ function probeCompiler() {
61
+ if (process.platform === 'win32') {
62
+ return { cc: which('cl') ?? which('clang'), make: which('nmake') ?? which('msbuild') };
63
+ }
64
+ return { cc: which('cc') ?? which('gcc') ?? which('clang'), make: which('make') ?? which('gmake') };
65
+ }
66
+
67
+ export function probeToolchain() {
68
+ return {
69
+ node: { version: process.version, abi: process.versions.modules },
70
+ abiKey: NATIVE_ABI_KEY,
71
+ prefix: nativeRoot(),
72
+ python: probePython(),
73
+ compiler: probeCompiler(),
74
+ };
75
+ }
76
+
77
+ export function toolchainReady(probe) {
78
+ const missing = [
79
+ probe.compiler.cc ? null : 'a C/C++ compiler (cc/gcc/clang)',
80
+ probe.compiler.make ? null : 'make',
81
+ probe.python.path ? null : 'python3',
82
+ ].filter(Boolean);
83
+ return { ready: missing.length === 0, missing };
84
+ }
85
+
86
+
87
+ function readOsRelease() {
88
+ try {
89
+ const fields = {};
90
+ for (const line of readFileSync('/etc/os-release', 'utf-8').split('\n')) {
91
+ const eq = line.indexOf('=');
92
+ if (eq === -1) continue;
93
+ fields[line.slice(0, eq).trim()] = line
94
+ .slice(eq + 1)
95
+ .trim()
96
+ .replace(/^"|"$/g, '');
97
+ }
98
+ return fields;
99
+ } catch {
100
+ return null;
101
+ }
102
+ }
103
+
104
+ const LINUX_INSTALLERS = [
105
+ { match: /\b(debian|ubuntu)\b/, command: 'sudo apt install build-essential python3' },
106
+ { match: /\b(fedora|rhel|centos|rocky|almalinux)\b/, command: 'sudo dnf install gcc-c++ make python3' },
107
+ { match: /\b(arch|manjaro)\b/, command: 'sudo pacman -S base-devel python' },
108
+ { match: /\balpine\b/, command: 'sudo apk add build-base python3' },
109
+ { match: /\b(opensuse|suse|sles)\b/, command: 'sudo zypper install -t pattern devel_basis && sudo zypper install python3' },
110
+ ];
111
+
112
+ const GENERIC_LINUX_ADVICE = [
113
+ 'Install a C/C++ toolchain and Python 3 with your package manager, e.g.:',
114
+ ' Debian/Ubuntu: sudo apt install build-essential python3',
115
+ ' Fedora/RHEL: sudo dnf install gcc-c++ make python3',
116
+ ' Arch: sudo pacman -S base-devel python',
117
+ ' Alpine: sudo apk add build-base python3',
118
+ ];
119
+
120
+ export function buildToolsAdvice(osRelease = readOsRelease()) {
121
+ if (process.platform === 'darwin') return ['Install the Xcode Command Line Tools: xcode-select --install'];
122
+ if (process.platform === 'win32') {
123
+ return ['Install the Visual Studio Build Tools with the "Desktop development with C++" workload, plus Python 3'];
124
+ }
125
+ const ids = `${osRelease?.ID ?? ''} ${osRelease?.ID_LIKE ?? ''}`.toLowerCase();
126
+ const installer = LINUX_INSTALLERS.find((i) => i.match.test(ids));
127
+ return installer ? [`Install a C/C++ toolchain and Python 3: ${installer.command}`] : GENERIC_LINUX_ADVICE;
128
+ }
129
+
130
+
131
+ function allOutput(ctx) {
132
+ return ctx.attempts.map((a) => a.output).join('\n');
133
+ }
134
+
135
+ function loadErrorText(ctx) {
136
+ return ctx.loadErrors.map((e) => `${e.code}: ${e.message}`).join('\n');
137
+ }
138
+
139
+ const RULES = [
140
+ {
141
+ code: 'PERMISSION',
142
+ title: 'npm could not write to the install directory.',
143
+ test: (ctx) => /\bEACCES\b|\bEPERM\b|permission denied/i.test(allOutput(ctx)),
144
+ remedies: (ctx) => [
145
+ `Check ownership of ${ctx.probe.prefix} and your npm cache:`,
146
+ ` sudo chown -R "$(id -u):$(id -g)" ${join(ctx.probe.prefix, '..')} ~/.npm`,
147
+ 'Then re-run: minion install terminal',
148
+ ],
149
+ },
150
+ {
151
+ code: 'REGISTRY',
152
+ title: 'The npm registry did not serve node-pty.',
153
+ test: (ctx) => /\bE404\b|\bETARGET\b|\bE401\b|\bE403\b|404 Not Found|401 Unauthorized/i.test(allOutput(ctx)),
154
+ remedies: () => [
155
+ 'Your default registry may be a private mirror that does not carry node-pty.',
156
+ 'Check it with: npm config get registry',
157
+ 'A public-registry retry was attempted automatically; if it also failed, the mirror may be proxying npmjs.org incorrectly.',
158
+ ],
159
+ },
160
+ {
161
+ code: 'NETWORK',
162
+ title: 'npm could not reach a registry.',
163
+ test: (ctx) => /\bENOTFOUND\b|\bEAI_AGAIN\b|\bECONNREFUSED\b|\bETIMEDOUT\b|network timeout/i.test(allOutput(ctx)),
164
+ remedies: () => [
165
+ 'Check connectivity and any proxy settings:',
166
+ ' npm config get proxy && npm config get https-proxy',
167
+ 'Then re-run: minion install terminal',
168
+ ],
169
+ },
170
+ {
171
+ code: 'MISSING_TOOLCHAIN',
172
+ title: 'A C/C++ toolchain is missing, so node-pty cannot be compiled on this machine.',
173
+ test: (ctx) =>
174
+ !toolchainReady(ctx.probe).ready ||
175
+ /(?:^|\s)(?:make|gcc|g\+\+|cc|clang):\s*(?:command\s+)?not found/im.test(allOutput(ctx)),
176
+ remedies: (ctx) => {
177
+ const { missing } = toolchainReady(ctx.probe);
178
+ return [
179
+ missing.length ? `Not found on PATH: ${missing.join(', ')}.` : 'The build reported a missing compiler.',
180
+ ...buildToolsAdvice(),
181
+ 'Then re-run: minion install terminal',
182
+ ];
183
+ },
184
+ },
185
+ {
186
+ code: 'PYTHON',
187
+ title: "node-gyp could not use this machine's Python.",
188
+ test: (ctx) =>
189
+ /gyp ERR!.*(?:Could not find any Python|find Python|Python is not set)/i.test(allOutput(ctx)) ||
190
+ /ModuleNotFoundError: No module named ['"]?(?:distutils|imp)/i.test(allOutput(ctx)),
191
+ remedies: (ctx) => {
192
+ const { python } = ctx.probe;
193
+ const lines = [];
194
+ if (python.version) {
195
+ lines.push(`Found ${python.path} (${python.version.raw}).`);
196
+ } else {
197
+ lines.push('No usable python3 was found on PATH.');
198
+ }
199
+ if (!python.supported && python.version) {
200
+ lines.push(
201
+ `node-gyp is known to work with Python 3.${PYTHON_KNOWN_GOOD.min}–3.${PYTHON_KNOWN_GOOD.max}; this is ${python.version.major}.${python.version.minor}.`,
202
+ );
203
+ }
204
+ if (python.alternative) {
205
+ lines.push(`A known-good interpreter is installed: ${python.alternative.path} (${python.alternative.version.raw}).`);
206
+ lines.push(`Point node-gyp at it: npm config set python ${python.alternative.path}`);
207
+ } else {
208
+ lines.push('Install a supported interpreter, e.g. Debian/Ubuntu: sudo apt install python3.12');
209
+ lines.push('Then: npm config set python "$(which python3.12)"');
210
+ }
211
+ lines.push('Then re-run: minion install terminal');
212
+ return lines;
213
+ },
214
+ },
215
+ {
216
+ code: 'ABI_MISMATCH',
217
+ title: 'node-pty is installed but was built for a different Node.js runtime.',
218
+ test: (ctx) =>
219
+ /NODE_MODULE_VERSION|was compiled against a different Node\.js version|invalid ELF header|undefined symbol|Module did not self-register/i.test(
220
+ `${loadErrorText(ctx)}\n${allOutput(ctx)}`,
221
+ ),
222
+ remedies: (ctx) => [
223
+ `This build is keyed to ${ctx.probe.abiKey}, so switching Node versions requires a fresh compile.`,
224
+ `Remove the cached build and re-provision: rm -rf ${ctx.probe.prefix}`,
225
+ 'Then re-run: minion install terminal',
226
+ ],
227
+ },
228
+ {
229
+ code: 'SPAWN_HELPER',
230
+ title: 'node-pty loaded but its spawn-helper is not executable.',
231
+ test: (ctx) => /posix_spawnp failed|spawn-helper/i.test(`${loadErrorText(ctx)}\n${allOutput(ctx)}`),
232
+ remedies: (ctx) => [
233
+ `chmod +x ${join(ctx.probe.prefix, 'node_modules/node-pty/build/Release/spawn-helper')}`,
234
+ 'Then re-run: minion install terminal',
235
+ ],
236
+ },
237
+ {
238
+ code: 'COMPILE_FAILED',
239
+ title: 'node-pty failed to compile.',
240
+ test: (ctx) => /gyp ERR!|gyp: |fatal error:|: error: |ld: cannot find/i.test(allOutput(ctx)),
241
+ remedies: (ctx) => {
242
+ const lines = [];
243
+ if (!ctx.probe.python.supported && ctx.probe.python.version) {
244
+ lines.push(
245
+ `Note: python3 is ${ctx.probe.python.version.raw}, outside node-gyp's known-good window (3.${PYTHON_KNOWN_GOOD.min}–3.${PYTHON_KNOWN_GOOD.max}). That is a likely cause.`,
246
+ );
247
+ if (ctx.probe.python.alternative) {
248
+ lines.push(`Try: npm config set python ${ctx.probe.python.alternative.path}`);
249
+ }
250
+ }
251
+ lines.push('The compiler output above (and in the log below) has the specific error.');
252
+ return lines;
253
+ },
254
+ },
255
+ {
256
+ code: 'NOT_INSTALLED',
257
+ title: 'npm reported success but wrote no node-pty.',
258
+ test: (ctx) => ctx.attempts.some((a) => a.code === 0),
259
+ remedies: (ctx) => [
260
+ `Nothing landed in ${join(ctx.probe.prefix, 'node_modules')}.`,
261
+ 'This usually means npm resolved the request against an existing dependency edge and omitted it.',
262
+ `Clear the prefix and retry: rm -rf ${ctx.probe.prefix} && minion install terminal`,
263
+ ],
264
+ },
265
+ ];
266
+
267
+ const UNKNOWN = {
268
+ code: 'UNKNOWN',
269
+ title: 'node-pty could not be installed, and the output did not identify why.',
270
+ remedies: () => ['Please report this with the log below.'],
271
+ };
272
+
273
+ export function classifyPtyFailure(input) {
274
+ const ctx = {
275
+ attempts: input.attempts ?? [],
276
+ loadErrors: input.loadErrors ?? [],
277
+ probe: input.probe ?? probeToolchain(),
278
+ };
279
+
280
+ const rule = RULES.find((r) => r.test(ctx)) ?? UNKNOWN;
281
+ return {
282
+ code: rule.code,
283
+ title: rule.title,
284
+ remedies: rule.remedies(ctx),
285
+ probe: ctx.probe,
286
+ };
287
+ }
288
+
289
+
290
+ function installLogDir() {
291
+ return machinePath('logs');
292
+ }
293
+
294
+ export function writeInstallLog(attempts, loadErrors = []) {
295
+ try {
296
+ const dir = installLogDir();
297
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
298
+ const path = join(dir, `terminal-install-${new Date().toISOString().replace(/[:.]/g, '-')}.log`);
299
+ const body = [
300
+ `node ${process.version} (abi ${process.versions.modules}) ${process.platform}-${process.arch}`,
301
+ `prefix ${nativeRoot()}`,
302
+ '',
303
+ ...attempts.map((a) => [`$ npm ${a.args?.join(' ') ?? ''}`, `# attempt: ${a.label} → exit ${a.code}`, a.output].join('\n')),
304
+ loadErrors.length ? `\n# load errors\n${loadErrors.map((e) => `${e.source}: ${e.code}: ${e.message}`).join('\n')}` : '',
305
+ ].join('\n');
306
+ writeFileSync(path, `${body}\n`);
307
+ return path;
308
+ } catch {
309
+ return null;
310
+ }
311
+ }
312
+
313
+ export function renderProbe(probe) {
314
+ const mark = (ok) => (ok ? '✓' : '✗');
315
+ const { python, compiler } = probe;
316
+ return [
317
+ `${mark(true)} node ${probe.node.version} (abi ${probe.node.abi})`,
318
+ `${mark(Boolean(compiler.cc))} C compiler ${compiler.cc ?? 'not found on PATH'}`,
319
+ `${mark(Boolean(compiler.make))} make ${compiler.make ?? 'not found on PATH'}`,
320
+ `${mark(python.supported)} python ${
321
+ python.version ? `${python.path} (${python.version.raw})` : (python.path ?? 'not found on PATH')
322
+ }${!python.supported && python.version ? ` — outside node-gyp's known-good 3.${PYTHON_KNOWN_GOOD.min}–3.${PYTHON_KNOWN_GOOD.max}` : ''}`,
323
+ ...(python.alternative ? [` alternative ${python.alternative.path} (${python.alternative.version.raw})`] : []),
324
+ ` prefix ${probe.prefix}`,
325
+ ];
326
+ }
@@ -0,0 +1,110 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+
4
+
5
+ import { createRequire } from 'node:module';
6
+ import { dirname, join, resolve } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { MACHINE_LAYOUT, machineRoot } from './machine-layout.js';
9
+
10
+ const __dirname = dirname(fileURLToPath(import.meta.url));
11
+
12
+ export const CLI_ROOT = resolve(__dirname, '..');
13
+
14
+ export const PREBUILT_PACKAGE = '@lydell/node-pty';
15
+
16
+ export const PREBUILT_PLATFORM_PACKAGE = `${PREBUILT_PACKAGE}-${process.platform}-${process.arch}`;
17
+
18
+ export const NATIVE_ABI_KEY = `node-${process.versions.modules}-${process.platform}-${process.arch}`;
19
+
20
+ export function nativeRoot() {
21
+ return join(machineRoot(), MACHINE_LAYOUT.native, 'node-pty', NATIVE_ABI_KEY);
22
+ }
23
+
24
+ export function nativeModulesDir() {
25
+ return join(nativeRoot(), 'node_modules');
26
+ }
27
+
28
+
29
+ const cliRequire = () => createRequire(join(CLI_ROOT, 'package.json'));
30
+
31
+ export function loadSources() {
32
+ return [
33
+ {
34
+ id: 'prebuilt',
35
+ describe: 'the prebuilt binary bundled with the CLI',
36
+ resolve: () => cliRequire().resolve(PREBUILT_PACKAGE),
37
+ },
38
+ {
39
+ id: 'bundled',
40
+ describe: "node-pty compiled in the CLI's own tree",
41
+ resolve: () => cliRequire().resolve('node-pty'),
42
+ },
43
+ {
44
+ id: 'prefix',
45
+ describe: 'node-pty compiled by "minion install terminal"',
46
+ resolve: () => createRequire(join(nativeRoot(), 'package.json')).resolve(join(nativeModulesDir(), 'node-pty')),
47
+ },
48
+ ];
49
+ }
50
+
51
+ export function describeSource(id) {
52
+ return loadSources().find((s) => s.id === id)?.describe ?? id;
53
+ }
54
+
55
+ function describeError(error) {
56
+ const own = typeof error?.code === 'string' ? error.code : null;
57
+ const cause = typeof error?.cause?.code === 'string' ? error.cause.code : null;
58
+ return {
59
+ code: own ?? cause ?? 'UNKNOWN',
60
+ message: error instanceof Error ? error.message : String(error),
61
+ };
62
+ }
63
+
64
+ function loadSource(source) {
65
+ try {
66
+ const resolved = source.resolve();
67
+ const req = createRequire(resolved);
68
+ delete req.cache[resolved];
69
+ const mod = req(resolved);
70
+ if (typeof mod?.spawn !== 'function') {
71
+ throw Object.assign(new Error('node-pty loaded but exports no spawn() — the native binding did not attach'), {
72
+ code: 'ERR_INVALID_MODULE',
73
+ });
74
+ }
75
+ return { ok: true, module: mod, source: source.id, path: resolved };
76
+ } catch (error) {
77
+ return { ok: false, error: { source: source.id, ...describeError(error) } };
78
+ }
79
+ }
80
+
81
+ export function loadNodePty() {
82
+ const errors = [];
83
+ for (const source of loadSources()) {
84
+ const result = loadSource(source);
85
+ if (result.ok) return result;
86
+ errors.push(result.error);
87
+ }
88
+ return { ok: false, errors };
89
+ }
90
+
91
+ export function loadNodePtySource(id) {
92
+ const source = loadSources().find((s) => s.id === id);
93
+ if (!source) {
94
+ return { ok: false, errors: [{ source: id, code: 'UNKNOWN_SOURCE', message: `no node-pty source "${id}"` }] };
95
+ }
96
+ const result = loadSource(source);
97
+ return result.ok ? result : { ok: false, errors: [result.error] };
98
+ }
99
+
100
+ export function isNodePtyLoadable() {
101
+ return loadNodePty().ok;
102
+ }
103
+
104
+ export function prebuiltPlatformDir() {
105
+ try {
106
+ return dirname(cliRequire().resolve(`${PREBUILT_PLATFORM_PACKAGE}/package.json`));
107
+ } catch {
108
+ return null;
109
+ }
110
+ }
@@ -0,0 +1,186 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+
4
+
5
+ import { spawn } from 'node:child_process';
6
+ import { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
7
+ import { join } from 'node:path';
8
+ import { CLI_ROOT, loadNodePtySource, NATIVE_ABI_KEY, nativeRoot } from './pty-locator.js';
9
+
10
+ const DEFAULT_PTY_SPEC = '^1.1.0';
11
+
12
+ export function nodePtySpec() {
13
+ try {
14
+ const pkg = JSON.parse(readFileSync(join(CLI_ROOT, 'package.json'), 'utf-8'));
15
+ return (
16
+ pkg.devDependencies?.['node-pty'] ||
17
+ pkg.dependencies?.['node-pty'] ||
18
+ pkg.optionalDependencies?.['node-pty'] ||
19
+ DEFAULT_PTY_SPEC
20
+ );
21
+ } catch {
22
+ return DEFAULT_PTY_SPEC;
23
+ }
24
+ }
25
+
26
+ export function ensureNativeRoot() {
27
+ const root = nativeRoot();
28
+ mkdirSync(root, { recursive: true });
29
+
30
+ const manifest = join(root, 'package.json');
31
+ if (!existsSync(manifest)) {
32
+ writeFileSync(
33
+ manifest,
34
+ `${JSON.stringify(
35
+ {
36
+ name: 'minionry-native-node-pty',
37
+ version: '1.0.0',
38
+ private: true,
39
+ description: `node-pty compiled for ${NATIVE_ABI_KEY}. Managed by "minion install terminal" — safe to delete.`,
40
+ },
41
+ null,
42
+ 2,
43
+ )}\n`,
44
+ );
45
+ }
46
+ return root;
47
+ }
48
+
49
+ export function nodePtyDirIn(root) {
50
+ return join(root, 'node_modules', 'node-pty');
51
+ }
52
+
53
+ export function normalizeNodePtyTree(dir) {
54
+ if (!dir || !existsSync(dir)) return;
55
+
56
+ const prebuilds = join(dir, 'prebuilds');
57
+ const keep = `${process.platform}-${process.arch}`;
58
+ pruneForeignPrebuilds(prebuilds, keep);
59
+
60
+ if (process.platform === 'win32') return;
61
+ for (const helper of [
62
+ join(prebuilds, keep, 'spawn-helper'),
63
+ join(dir, 'build', 'Release', 'spawn-helper'),
64
+ join(dir, 'spawn-helper'),
65
+ ]) {
66
+ restoreExecBit(helper);
67
+ }
68
+ }
69
+
70
+ function pruneForeignPrebuilds(prebuilds, keep) {
71
+ let entries = [];
72
+ try {
73
+ entries = readdirSync(prebuilds);
74
+ } catch {
75
+ return;
76
+ }
77
+ for (const entry of entries) {
78
+ if (entry === keep) continue;
79
+ try {
80
+ rmSync(join(prebuilds, entry), { recursive: true, force: true });
81
+ } catch {
82
+ }
83
+ }
84
+ }
85
+
86
+ function restoreExecBit(path) {
87
+ if (!existsSync(path)) return;
88
+ try {
89
+ chmodSync(path, 0o755);
90
+ } catch {
91
+ }
92
+ }
93
+
94
+ export function provisionEnv(env = process.env) {
95
+ const clean = {};
96
+ for (const [key, value] of Object.entries(env)) {
97
+ if (key.startsWith('npm_') || key === 'INIT_CWD' || key === 'NODE_ENV') continue;
98
+ clean[key] = value;
99
+ }
100
+ clean.npm_config_update_notifier = 'false';
101
+ return clean;
102
+ }
103
+
104
+ const PUBLIC_REGISTRY = 'https://registry.npmjs.org';
105
+
106
+ const REGISTRY_FAILURE = /E404|ETARGET|E401|E403|ENOTFOUND|EAI_AGAIN|ECONNREFUSED|ERR_INVALID_URL|404 Not Found/i;
107
+
108
+ export function planAttempts(spec, probe) {
109
+ const base = [
110
+ 'install',
111
+ `node-pty@${spec}`,
112
+ '--prefix',
113
+ nativeRoot(),
114
+ '--no-audit',
115
+ '--no-fund',
116
+ '--no-package-lock',
117
+ '--omit=dev',
118
+ '--foreground-scripts',
119
+ '--loglevel=error',
120
+ ];
121
+
122
+ const attempts = [];
123
+
124
+ if (probe?.python?.supported === false && probe?.python?.alternative) {
125
+ attempts.push({
126
+ label: `using ${probe.python.alternative.path}`,
127
+ args: [...base, `--python=${probe.python.alternative.path}`],
128
+ });
129
+ }
130
+
131
+ attempts.push({ label: 'default registry', args: base });
132
+ attempts.push({
133
+ label: 'public npm registry',
134
+ args: [...base, `--registry=${PUBLIC_REGISTRY}`],
135
+ onlyIf: (previous) => previous.some((a) => REGISTRY_FAILURE.test(a.output)),
136
+ });
137
+
138
+ return attempts;
139
+ }
140
+
141
+ function runNpm(args, cwd) {
142
+ return new Promise((resolveRun) => {
143
+ const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
144
+ let output = '';
145
+
146
+ const child = spawn(npmCmd, args, {
147
+ cwd,
148
+ stdio: ['ignore', 'pipe', 'pipe'],
149
+ env: provisionEnv(),
150
+ });
151
+
152
+ child.stdout?.on('data', (chunk) => {
153
+ output += chunk.toString();
154
+ });
155
+ child.stderr?.on('data', (chunk) => {
156
+ output += chunk.toString();
157
+ });
158
+ child.on('error', (err) => resolveRun({ code: -1, output: `${output}\n${err.message}` }));
159
+ child.on('exit', (code) => resolveRun({ code: code ?? -1, output }));
160
+ });
161
+ }
162
+
163
+ export async function provisionNodePty(options = {}) {
164
+ const spec = options.spec ?? nodePtySpec();
165
+ const root = ensureNativeRoot();
166
+ const attempts = [];
167
+
168
+ const stale = nodePtyDirIn(root);
169
+ if (existsSync(stale) && !loadNodePtySource('prefix').ok) {
170
+ rmSync(stale, { recursive: true, force: true });
171
+ }
172
+
173
+ for (const attempt of planAttempts(spec, options.probe)) {
174
+ if (attempt.onlyIf && !attempt.onlyIf(attempts)) continue;
175
+
176
+ options.onProgress?.(attempt.label);
177
+ const { code, output } = await runNpm(attempt.args, root);
178
+ attempts.push({ label: attempt.label, args: attempt.args, code, output });
179
+
180
+ normalizeNodePtyTree(nodePtyDirIn(root));
181
+ const loaded = loadNodePtySource('prefix');
182
+ if (loaded.ok) return { ok: true, source: loaded.source, path: loaded.path, attempts };
183
+ }
184
+
185
+ return { ok: false, attempts };
186
+ }