@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,78 @@
1
+ ---
2
+ name: triage-findings
3
+ description: "Relevance triage for programmatic code-quality findings — reads the actual code and decides which tool/heuristic findings are real issues vs. noise, so a cohesive long file or a justified complex function is not penalized. Use between programmatic detection and the AI deep review."
4
+ user-invocable: false
5
+ allowed-tools: Read, Grep, Glob, Bash
6
+ context: fork
7
+ variables: [dirPath, findingsJson]
8
+ ---
9
+
10
+ You are a pragmatic senior engineer triaging the output of automated code-quality tools. The tools (linters, formatters, complexity analyzers, file/function-length heuristics) optimize for RECALL — they flag everything that *might* matter. Your job is PRECISION: read the real code and decide which findings a thoughtful reviewer would actually act on, and which are technically-true-but-not-an-issue noise.
11
+
12
+ IMPORTANT: Your current working directory is "{{dirPath}}". Only read files within this directory. You do NOT fix anything and you do NOT invent new findings — you only classify the findings below.
13
+
14
+ ## Findings to triage
15
+
16
+ {{findingsJson}}
17
+
18
+ ## Process
19
+
20
+ For each finding:
21
+
22
+ 1. **Read the cited file** around the cited line (use Read; use Grep/Glob for surrounding context). Group findings by file so you read each file once.
23
+ 2. **Judge whether it is a real, worth-fixing issue in THIS codebase**, not in the abstract.
24
+ 3. Assign one status:
25
+ - **`confirmed`** — a real issue a good reviewer would want addressed. This is the default for findings from trusted tools (lint errors, build/compile errors, formatter violations, security/bug findings) unless you have strong evidence the tool is wrong.
26
+ - **`likely-fp`** — technically flagged, but not an actual problem here (a false positive or a non-issue). Use this for noise. The finding stays visible to the user but is excluded from the grade.
27
+ - **`uncertain`** — you genuinely cannot tell from the code whether it matters. Excluded from the grade.
28
+
29
+ ## Rubric for the noisy categories
30
+
31
+ These categories produce most of the false positives. Apply judgment, not the raw threshold:
32
+
33
+ ### `file-length` (long file)
34
+ - **`likely-fp`** when the file is *cohesive*: a single clear responsibility, a shared domain vocabulary, reads top-to-bottom, mostly one class/type plus its private helpers, or many small independent declarations of the same kind (e.g. a constants/registry/route table). Length alone is NOT a defect. A 1000-line file that does one thing well is fine.
35
+ - **`confirmed`** (low/medium) when the file *mixes unrelated concerns* — several independent export groups, multiple unrelated domains (e.g. config + parsing + rendering + IO in one file), or a clear seam where it should be split.
36
+ - **Always `confirmed`** when the file is extreme (> ~1500 lines) regardless of cohesion — that much in one file is hard to navigate even when focused.
37
+
38
+ ### `function-length` (long function)
39
+ - **`likely-fp`** when the function is long but *linear and readable* — a flat sequence (config builder, big switch/dispatch, sequential setup) with little nesting. Many short composable steps in one function are fine.
40
+ - **`confirmed`** when it is long AND *branchy/deeply nested* — high decision-point density, nested conditionals, does several distinct things. Severity scales with branchiness.
41
+
42
+ ### `complexity` (cyclomatic/cognitive)
43
+ - **`likely-fp`** when the complexity is *inherent and well-structured* — e.g. an unavoidable parser/state-machine/switch that is clearly written. High cyclomatic count from a flat switch is usually fine.
44
+ - **`confirmed`** when the complexity comes from *tangled nesting* a reader has to hold in their head.
45
+
46
+ ### `lint` / `linting`
47
+ - Trust the linter by default → **`confirmed`**. Only mark `likely-fp` if the rule is clearly misfiring on this specific code (e.g. an intentional, commented pattern).
48
+
49
+ ### `format`
50
+ - **`confirmed`** (these are deterministic and trivially auto-fixable). Keep low severity.
51
+
52
+ ### `build`
53
+ - Compile/build errors are **always `confirmed`**, critical. Never downgrade.
54
+
55
+ ### `security` / `bugs` / `logic` / `performance`
56
+ - Default **`confirmed`**. Only `likely-fp` with concrete counter-evidence in the code (a guard/sanitizer exists, the path is unreachable, etc.).
57
+
58
+ ## Severity
59
+
60
+ You may CORRECT a finding's severity when the tool over- or under-stated it (e.g. drop a cohesive-but-flagged complexity finding to `low`, or raise a genuinely dangerous one). Calibrate by likelihood × user impact. If you don't change it, omit the `severity` field.
61
+
62
+ ## Output
63
+
64
+ Output EXACTLY one JSON code block, then nothing else. Include one verdict per finding id.
65
+
66
+ ```json
67
+ {
68
+ "verdicts": [
69
+ {
70
+ "id": 1,
71
+ "status": "confirmed|likely-fp|uncertain",
72
+ "confidence": 0.9,
73
+ "rationale": "One concise sentence grounded in what you saw in the code.",
74
+ "severity": "critical|high|medium|low"
75
+ }
76
+ ]
77
+ }
78
+ ```
@@ -0,0 +1,57 @@
1
+ ---
2
+ name: verify-review
3
+ description: "Independent verification pass for code review findings — skeptically re-checks each finding against actual code to catch hallucinations and false positives. Use after an AI code review to validate findings."
4
+ user-invocable: false
5
+ allowed-tools: Read, Grep, Glob, Bash
6
+ context: fork
7
+ variables: [dirPath, findingsJson]
8
+ ---
9
+
10
+ You are an independent code review VERIFIER. A separate reviewer produced the findings below. Your job is to VERIFY each finding against the actual code. You are a skeptic — do NOT trust the original reviewer's claims.
11
+
12
+ IMPORTANT: Your current working directory is "{{dirPath}}". Only read files within this directory.
13
+
14
+ ## Findings to Verify
15
+
16
+ {{findingsJson}}
17
+
18
+ ## Verification Process
19
+
20
+ For EACH finding:
21
+
22
+ 1. **Read the cited file and line** using the Read tool. Read at least 20 lines around the cited line for context.
23
+ 2. **Check the specific claim** in the description. Does the code actually do what the finding claims?
24
+ 3. **Search for counter-evidence**:
25
+ - If the finding claims something is missing (no validation, no cleanup, no guard): search for it with Grep
26
+ - If the finding claims an API is used: verify the actual API call at that line
27
+ - If the finding claims a value is leaked/exposed: check if it's filtered/deleted elsewhere in the same function
28
+ 4. **Verdict**: Mark as "confirmed" or "rejected" with a brief explanation
29
+
30
+ ## Rules
31
+
32
+ - You MUST actually Read each cited file. Do not rely on memory or assumptions.
33
+ - Use Grep to search for patterns the finding claims exist (or don't exist).
34
+ - A finding is "rejected" if:
35
+ - The code does NOT match what the description claims
36
+ - There IS a guard/fix that the finding claims is missing
37
+ - The line number doesn't contain the relevant code
38
+ - The finding is about a different version of the code than what exists now
39
+ - A finding is "confirmed" if you can independently verify the issue exists in the current code.
40
+ - Be thorough but efficient — focus verification effort on high/critical severity findings.
41
+
42
+ ## Output
43
+
44
+ Output EXACTLY one JSON code block. No other text after the JSON block.
45
+
46
+ ```json
47
+ {
48
+ "verifications": [
49
+ {
50
+ "id": 1,
51
+ "verdict": "confirmed|rejected",
52
+ "confidence": 0.95,
53
+ "note": "Brief explanation of what you found when checking the code"
54
+ }
55
+ ]
56
+ }
57
+ ```
@@ -0,0 +1,143 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ export const DEFAULT_STRATEGY_THRESHOLDS = {
4
+ requireApprovalFor: ['pricing', 'positioning', 'direction', 'brand'],
5
+ minSeverity: 'medium',
6
+ };
7
+ export function getStrategyTriggers(template) {
8
+ return template?.board?.strategy_approval_triggers ?? [];
9
+ }
10
+ function collectTriggerEvidence(output, trigger, diagnostics) {
11
+ const evidence = [];
12
+ for (const keyword of trigger.keywords ?? []) {
13
+ const ev = findKeywordEvidence(output, keyword);
14
+ if (ev)
15
+ evidence.push(ev);
16
+ }
17
+ for (const patternSrc of trigger.patterns ?? []) {
18
+ let pattern;
19
+ try {
20
+ pattern = new RegExp(patternSrc, 'i');
21
+ }
22
+ catch (err) {
23
+ diagnostics.push(`Trigger "${trigger.id}" pattern "${patternSrc}" is invalid: ${err instanceof Error ? err.message : String(err)}`);
24
+ continue;
25
+ }
26
+ const ev = findPatternEvidence(output, patternSrc, pattern);
27
+ if (ev)
28
+ evidence.push(ev);
29
+ }
30
+ return evidence;
31
+ }
32
+ export function evaluateStrategyChange(output, triggers, ctx) {
33
+ const result = { hits: [], advisory: [], diagnostics: [] };
34
+ if (!output || triggers.length === 0)
35
+ return result;
36
+ const thresholds = ctx.thresholds ?? DEFAULT_STRATEGY_THRESHOLDS;
37
+ const minSeverityRank = severityRank(thresholds.minSeverity);
38
+ const requireSet = new Set(thresholds.requireApprovalFor);
39
+ for (const trigger of triggers) {
40
+ if (!triggerAppliesToIssue(trigger, ctx.issueId))
41
+ continue;
42
+ const evidence = collectTriggerEvidence(output, trigger, result.diagnostics);
43
+ const minHits = Math.max(1, trigger.min_hits ?? 1);
44
+ if (evidence.length < minHits)
45
+ continue;
46
+ const severity = trigger.severity ?? 'medium';
47
+ const hit = {
48
+ triggerId: trigger.id,
49
+ category: trigger.category,
50
+ severity,
51
+ description: trigger.description ?? defaultDescription(trigger.category, severity),
52
+ evidence,
53
+ requiresApproval: severityRank(severity) >= minSeverityRank && requireSet.has(trigger.category),
54
+ };
55
+ if (hit.requiresApproval)
56
+ result.hits.push(hit);
57
+ else
58
+ result.advisory.push(hit);
59
+ }
60
+ return result;
61
+ }
62
+ export function buildApprovalRequest(hit, args) {
63
+ const evidenceSummary = hit.evidence
64
+ .slice(0, 5)
65
+ .map((e) => `• [${e.kind}] ${e.source}: "${truncate(e.snippet, 160)}"`)
66
+ .join('\n');
67
+ const description = [
68
+ hit.description,
69
+ '',
70
+ `Category: ${hit.category} (severity: ${hit.severity})`,
71
+ `Issue: ${args.issueId}`,
72
+ `Trigger: ${hit.triggerId}`,
73
+ '',
74
+ 'Evidence:',
75
+ evidenceSummary || '(no detailed evidence — keyword match only)',
76
+ ].join('\n');
77
+ return {
78
+ type: 'strategy',
79
+ title: truncate(args.titleOverride ?? hit.description, 500),
80
+ description: truncate(description, 8000),
81
+ requestedBy: args.requestedBy,
82
+ departmentId: args.departmentId ?? null,
83
+ executionId: args.executionId ?? null,
84
+ estimatedCostCents: null,
85
+ };
86
+ }
87
+ const SEVERITY_ORDER = {
88
+ low: 0,
89
+ medium: 1,
90
+ high: 2,
91
+ };
92
+ function severityRank(s) {
93
+ return SEVERITY_ORDER[s] ?? 1;
94
+ }
95
+ function triggerAppliesToIssue(trigger, issueId) {
96
+ if (!trigger.applies_to || trigger.applies_to.length === 0)
97
+ return true;
98
+ return trigger.applies_to.includes(issueId);
99
+ }
100
+ function findKeywordEvidence(haystack, keyword) {
101
+ if (!keyword)
102
+ return null;
103
+ const escaped = escapeRegex(keyword);
104
+ const re = new RegExp(`(^|\\W)(${escaped})(\\W|$)`, 'i');
105
+ const match = re.exec(haystack);
106
+ if (!match)
107
+ return null;
108
+ const matchIdx = match.index + match[1].length;
109
+ return {
110
+ kind: 'keyword',
111
+ source: keyword,
112
+ snippet: extractSnippet(haystack, matchIdx, keyword.length),
113
+ };
114
+ }
115
+ function findPatternEvidence(haystack, source, pattern) {
116
+ const match = pattern.exec(haystack);
117
+ if (!match)
118
+ return null;
119
+ return {
120
+ kind: 'pattern',
121
+ source,
122
+ snippet: extractSnippet(haystack, match.index, match[0].length),
123
+ };
124
+ }
125
+ function extractSnippet(text, idx, len) {
126
+ const radius = 60;
127
+ const start = Math.max(0, idx - radius);
128
+ const end = Math.min(text.length, idx + len + radius);
129
+ const prefix = start > 0 ? '…' : '';
130
+ const suffix = end < text.length ? '…' : '';
131
+ return `${prefix}${text.slice(start, end).replace(/\s+/g, ' ').trim()}${suffix}`;
132
+ }
133
+ function escapeRegex(s) {
134
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
135
+ }
136
+ function truncate(s, max) {
137
+ if (s.length <= max)
138
+ return s;
139
+ return `${s.slice(0, max - 1)}…`;
140
+ }
141
+ function defaultDescription(category, severity) {
142
+ return `Proposed ${severity}-severity ${category} change requires owner approval before publishing.`;
143
+ }
@@ -0,0 +1,102 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ import { readdirSync, readFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { unzipSync, zipSync } from 'fflate';
6
+ import { parseBoardDirectory } from './parser.js';
7
+ import { parseFrontMatter } from './parser-core.js';
8
+ export const TEMPLATE_MANIFEST_NAME = 'minionry-template.json';
9
+ export const TEMPLATE_FORMAT = 'minionry-board-template';
10
+ const MAX_ENTRIES = 2000;
11
+ const MAX_TOTAL_UNCOMPRESSED = 200 * 1024 * 1024;
12
+ function collectFiles(dir, base, out) {
13
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
14
+ if (entry.isSymbolicLink())
15
+ continue;
16
+ const abs = join(dir, entry.name);
17
+ const rel = base ? `${base}/${entry.name}` : entry.name;
18
+ if (entry.isDirectory()) {
19
+ collectFiles(abs, rel, out);
20
+ }
21
+ else if (entry.isFile()) {
22
+ out[rel] = readFileSync(abs);
23
+ }
24
+ }
25
+ }
26
+ export function packBoardArchive(pmDir, boardId) {
27
+ const boardState = parseBoardDirectory(pmDir, boardId);
28
+ if (!boardState)
29
+ throw new Error(`Board not found: ${boardId}`);
30
+ const files = {};
31
+ collectFiles(join(pmDir, 'boards', boardId), '', files);
32
+ const manifest = {
33
+ format: TEMPLATE_FORMAT,
34
+ version: 1,
35
+ boardId,
36
+ title: boardState.board.title,
37
+ exportedAt: new Date().toISOString(),
38
+ };
39
+ files[TEMPLATE_MANIFEST_NAME] = Buffer.from(JSON.stringify(manifest, null, 2), 'utf-8');
40
+ return { data: Buffer.from(zipSync(files, { level: 6 })), board: boardState.board };
41
+ }
42
+ function isHostileEntryName(name) {
43
+ if (name.includes('\0'))
44
+ return true;
45
+ if (name.startsWith('/') || /^[a-zA-Z]:/.test(name))
46
+ return true;
47
+ return name.split('/').some(segment => segment === '..');
48
+ }
49
+ function collectSafeEntries(unzipped) {
50
+ const files = new Map();
51
+ for (const [rawName, bytes] of Object.entries(unzipped)) {
52
+ const name = rawName.replace(/\\/g, '/');
53
+ if (name.endsWith('/'))
54
+ continue;
55
+ if (isHostileEntryName(name))
56
+ throw new Error(`Unsafe entry in archive: ${rawName}`);
57
+ files.set(name, bytes);
58
+ }
59
+ return files;
60
+ }
61
+ function unwrapSingleRootFolder(files) {
62
+ if (files.has('board.md'))
63
+ return files;
64
+ const roots = new Set([...files.keys()].map(name => name.split('/')[0]));
65
+ const root = roots.size === 1 ? [...roots][0] : null;
66
+ if (!root || !files.has(`${root}/board.md`))
67
+ return files;
68
+ const unwrapped = new Map();
69
+ for (const [name, bytes] of files)
70
+ unwrapped.set(name.slice(root.length + 1), bytes);
71
+ return unwrapped;
72
+ }
73
+ export function extractBoardArchive(data) {
74
+ let entryCount = 0;
75
+ let totalSize = 0;
76
+ const unzipped = unzipSync(data, {
77
+ filter: file => {
78
+ entryCount++;
79
+ if (entryCount > MAX_ENTRIES)
80
+ throw new Error(`Archive has too many entries (max ${MAX_ENTRIES})`);
81
+ totalSize += file.originalSize;
82
+ if (totalSize > MAX_TOTAL_UNCOMPRESSED)
83
+ throw new Error('Archive is too large when uncompressed');
84
+ return true;
85
+ },
86
+ });
87
+ const files = unwrapSingleRootFolder(collectSafeEntries(unzipped));
88
+ const boardMd = files.get('board.md');
89
+ if (!boardMd)
90
+ throw new Error('Not a board template archive (missing board.md)');
91
+ const { frontMatter } = parseFrontMatter(Buffer.from(boardMd).toString('utf-8'));
92
+ const sourceBoardId = typeof frontMatter.id === 'string' && frontMatter.id ? frontMatter.id : null;
93
+ files.delete(TEMPLATE_MANIFEST_NAME);
94
+ return { files, sourceBoardId };
95
+ }
96
+ export function slugifyBoardTitle(title) {
97
+ return title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
98
+ }
99
+ export function defaultArchiveFileName(board) {
100
+ const slug = slugifyBoardTitle(board.title) || board.id.toLowerCase();
101
+ return `${slug}-template.zip`;
102
+ }
@@ -0,0 +1,108 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ import { existsSync, readFileSync } from 'node:fs';
4
+ import { readFile, writeFile } from 'node:fs/promises';
5
+ import { join } from 'node:path';
6
+ import { replaceFrontMatterField } from './front-matter.js';
7
+ import { DEFAULT_QUALITY_GATE, parseQualityGate, parseWorkspace } from './parser-core.js';
8
+ export const DEFAULT_MAX_PARALLEL_AGENTS = 3;
9
+ export async function getBoardMaxParallelAgents(pmDir, boardId, warn) {
10
+ if (!pmDir || !boardId)
11
+ return DEFAULT_MAX_PARALLEL_AGENTS;
12
+ const boardMdPath = join(pmDir, 'boards', boardId, 'board.md');
13
+ if (!existsSync(boardMdPath))
14
+ return DEFAULT_MAX_PARALLEL_AGENTS;
15
+ try {
16
+ const content = await readFile(boardMdPath, 'utf-8');
17
+ const match = content.match(/^max_parallel_agents:\s*(\d+)/m);
18
+ return match ? Math.max(1, Math.min(Number(match[1]), 10)) : DEFAULT_MAX_PARALLEL_AGENTS;
19
+ }
20
+ catch (err) {
21
+ warn(`Warning: failed to read board max_parallel_agents: ${errMsg(err)}`);
22
+ return DEFAULT_MAX_PARALLEL_AGENTS;
23
+ }
24
+ }
25
+ export async function getBoardQualityGate(pmDir, boardId, warn) {
26
+ if (!pmDir || !boardId)
27
+ return DEFAULT_QUALITY_GATE;
28
+ const boardMdPath = join(pmDir, 'boards', boardId, 'board.md');
29
+ if (!existsSync(boardMdPath))
30
+ return DEFAULT_QUALITY_GATE;
31
+ try {
32
+ const content = await readFile(boardMdPath, 'utf-8');
33
+ const match = content.match(/^quality_gate:\s*["']?(\w+)["']?\s*$/m);
34
+ return parseQualityGate(match?.[1]);
35
+ }
36
+ catch (err) {
37
+ warn(`Warning: failed to read board quality_gate: ${errMsg(err)}`);
38
+ return DEFAULT_QUALITY_GATE;
39
+ }
40
+ }
41
+ export function resolveActiveBoardId(pmDir) {
42
+ if (!pmDir)
43
+ return null;
44
+ try {
45
+ const workspacePath = join(pmDir, 'workspace.json');
46
+ if (!existsSync(workspacePath))
47
+ return null;
48
+ const workspace = JSON.parse(readFileSync(workspacePath, 'utf-8'));
49
+ return workspace.activeBoardId ?? null;
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
55
+ export function resolveBoardWorktreePath(pmDir, boardId) {
56
+ if (!pmDir || !boardId)
57
+ return null;
58
+ try {
59
+ const workspacePath = join(pmDir, 'workspace.json');
60
+ if (!existsSync(workspacePath))
61
+ return null;
62
+ return parseWorkspace(readFileSync(workspacePath, 'utf-8')).boardWorktrees?.[boardId]?.path ?? null;
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
68
+ export function resolveBoardDir(pmDir, boardId) {
69
+ if (!pmDir)
70
+ return null;
71
+ const effective = boardId ?? resolveActiveBoardId(pmDir);
72
+ if (!effective)
73
+ return null;
74
+ const boardDir = join(pmDir, 'boards', effective);
75
+ return existsSync(boardDir) ? boardDir : null;
76
+ }
77
+ export async function activateBoard(pmDir, boardId, warn) {
78
+ const boardMdPath = join(pmDir, 'boards', boardId, 'board.md');
79
+ if (!existsSync(boardMdPath))
80
+ return;
81
+ try {
82
+ const content = await readFile(boardMdPath, 'utf-8');
83
+ await writeFile(boardMdPath, replaceFrontMatterField(content, 'status', 'active'), 'utf-8');
84
+ }
85
+ catch (err) {
86
+ warn(`Warning: failed to activate board ${boardId}: ${errMsg(err)}`);
87
+ }
88
+ }
89
+ export async function tryCompleteBoardIfDone(pmDir, boardId, issues, warn) {
90
+ const allDone = issues.length > 0 && issues.every(i => i.status === 'done' || i.status === 'cancelled');
91
+ if (!allDone)
92
+ return;
93
+ const boardMdPath = join(pmDir, 'boards', boardId, 'board.md');
94
+ if (!existsSync(boardMdPath))
95
+ return;
96
+ try {
97
+ let content = await readFile(boardMdPath, 'utf-8');
98
+ content = replaceFrontMatterField(content, 'status', 'completed');
99
+ content = replaceFrontMatterField(content, 'completed_at', `"${new Date().toISOString()}"`);
100
+ await writeFile(boardMdPath, content, 'utf-8');
101
+ }
102
+ catch (err) {
103
+ warn(`Warning: failed to mark board ${boardId} as completed: ${errMsg(err)}`);
104
+ }
105
+ }
106
+ function errMsg(err) {
107
+ return err instanceof Error ? err.message : String(err);
108
+ }