@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,634 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { getNextId, parseBoardDirectory, parsePlanDirectory, parseSingleIssue, resolvePmDir } from '../plan/parser.js';
6
+ import { tryCompleteParentEpic } from '../plan/state-reconciler.js';
7
+ import { renderIssueMarkdown } from '../plan/template-instantiator.js';
8
+ import { applyBoardFieldUpdates } from '../websocket/plan-board-handlers.js';
9
+ import { resolvePlanPath } from '../websocket/plan-helpers.js';
10
+ import { applyIssueFieldUpdates, deleteIssueFile } from '../websocket/plan-issue-handlers.js';
11
+ import { logAppAudit } from './audit.js';
12
+ import { getGrant } from './grant-store.js';
13
+ import { listLiveSubscriptions, registerLiveSubscription } from './live-registry.js';
14
+ import { SdkMethodError } from './registry.js';
15
+ let pmHost = null;
16
+ export function setSdkPmHost(host) {
17
+ pmHost = host;
18
+ }
19
+ export function resetSdkPmHost() {
20
+ pmHost = null;
21
+ }
22
+ function requirePmHost(method) {
23
+ if (!pmHost) {
24
+ throw new SdkMethodError('INTERNAL', `'${method}' host is not wired — the WebSocket handler installs it at startup`);
25
+ }
26
+ return pmHost;
27
+ }
28
+ function idFromPlanPath(planPath) {
29
+ const file = planPath.split('/').pop() ?? planPath;
30
+ return file.replace(/\.md$/, '');
31
+ }
32
+ function toIssueRef(summary) {
33
+ return { id: summary.id, title: summary.title, priority: summary.priority };
34
+ }
35
+ function toSnapshotIssue(issue, idByPath) {
36
+ const resolveRef = (planPath) => idByPath.get(planPath) ?? idFromPlanPath(planPath);
37
+ return {
38
+ id: issue.id,
39
+ title: issue.title,
40
+ type: issue.type,
41
+ status: issue.status,
42
+ priority: issue.priority,
43
+ estimate: issue.estimate,
44
+ labels: [...issue.labels],
45
+ epicId: issue.epic ? resolveRef(issue.epic) : null,
46
+ blockedBy: issue.blockedBy.map(resolveRef),
47
+ blocks: issue.blocks.map(resolveRef),
48
+ description: issue.description,
49
+ acceptanceCriteria: issue.acceptanceCriteria.map(({ text, checked }) => ({ text, checked })),
50
+ created: issue.created,
51
+ updated: issue.updated,
52
+ };
53
+ }
54
+ export function toBoardSnapshot(full) {
55
+ const idByPath = new Map(full.issues.map((issue) => [issue.path, issue.id]));
56
+ return {
57
+ board: {
58
+ id: full.board.id,
59
+ title: full.board.title,
60
+ status: full.board.status,
61
+ goal: full.board.goal,
62
+ created: full.board.created,
63
+ completedAt: full.board.completedAt,
64
+ },
65
+ state: {
66
+ paused: full.state.paused,
67
+ readyToWork: full.state.readyToWork.map(toIssueRef),
68
+ inProgress: full.state.inProgress.map(toIssueRef),
69
+ blocked: full.state.blocked.map(toIssueRef),
70
+ recentlyCompleted: full.state.recentlyCompleted.map(toIssueRef),
71
+ warnings: [...full.state.warnings],
72
+ },
73
+ issues: full.issues.map((issue) => toSnapshotIssue(issue, idByPath)),
74
+ };
75
+ }
76
+ export function readBoardSnapshot(workingDir, boardId) {
77
+ const pmDir = resolvePmDir(workingDir);
78
+ if (!pmDir)
79
+ return null;
80
+ const full = parseBoardDirectory(pmDir, boardId);
81
+ if (!full)
82
+ return null;
83
+ return toBoardSnapshot(full);
84
+ }
85
+ function toBoardSummary(board) {
86
+ return {
87
+ id: board.id,
88
+ title: board.title,
89
+ status: board.status,
90
+ goal: board.goal,
91
+ created: board.created,
92
+ completedAt: board.completedAt,
93
+ };
94
+ }
95
+ export function listBoardSummaries(workingDir) {
96
+ const full = parsePlanDirectory(workingDir);
97
+ if (!full)
98
+ return [];
99
+ return full.boards.map(toBoardSummary);
100
+ }
101
+ function paramsObject(params) {
102
+ return typeof params === 'object' && params !== null && !Array.isArray(params)
103
+ ? params
104
+ : {};
105
+ }
106
+ function parseBoardIdParams(params, method) {
107
+ const raw = paramsObject(params);
108
+ if (typeof raw.boardId !== 'string' || raw.boardId.trim() === '') {
109
+ throw new SdkMethodError('BAD_REQUEST', `${method} requires params { boardId }`);
110
+ }
111
+ return raw.boardId;
112
+ }
113
+ const MAX_RUN_INPUT_DATA_BYTES = 1024 * 1024;
114
+ const MAX_GATHER_PROMPT_CHARS = 4000;
115
+ const VARIABLE_NAME_PATTERN = /^\w+$/;
116
+ function parseRunInputVariables(raw, method) {
117
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
118
+ throw new SdkMethodError('BAD_REQUEST', `${method} input.variables must be a plain object`);
119
+ }
120
+ const variables = {};
121
+ for (const [name, value] of Object.entries(raw)) {
122
+ if (!VARIABLE_NAME_PATTERN.test(name)) {
123
+ throw new SdkMethodError('BAD_REQUEST', `${method} input.variables key '${name}' must match /^\\w+$/`);
124
+ }
125
+ if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {
126
+ throw new SdkMethodError('BAD_REQUEST', `${method} input.variables.${name} must be a string, number, or boolean`);
127
+ }
128
+ variables[name] = value;
129
+ }
130
+ return variables;
131
+ }
132
+ function parseRunInputData(raw, method) {
133
+ let serialized;
134
+ try {
135
+ serialized = JSON.stringify(raw);
136
+ }
137
+ catch {
138
+ throw new SdkMethodError('BAD_REQUEST', `${method} input.data must be JSON-serializable`);
139
+ }
140
+ if (serialized === undefined) {
141
+ throw new SdkMethodError('BAD_REQUEST', `${method} input.data must be JSON-serializable`);
142
+ }
143
+ if (Buffer.byteLength(serialized, 'utf-8') > MAX_RUN_INPUT_DATA_BYTES) {
144
+ throw new SdkMethodError('BAD_REQUEST', `${method} input.data must serialize to 1 MiB or less`);
145
+ }
146
+ return raw;
147
+ }
148
+ function parseRunInputGatherPrompt(raw, method) {
149
+ if (typeof raw !== 'string' || raw.trim() === '') {
150
+ throw new SdkMethodError('BAD_REQUEST', `${method} input.gatherPrompt must be a non-empty string`);
151
+ }
152
+ if (raw.trim().length > MAX_GATHER_PROMPT_CHARS) {
153
+ throw new SdkMethodError('BAD_REQUEST', `${method} input.gatherPrompt must be ${MAX_GATHER_PROMPT_CHARS} characters or fewer after trim`);
154
+ }
155
+ return raw;
156
+ }
157
+ export function parseBoardRunInput(raw, method = 'pm.createBoard') {
158
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
159
+ throw new SdkMethodError('BAD_REQUEST', `${method} input must be an object`);
160
+ }
161
+ const obj = raw;
162
+ const input = {};
163
+ if (obj.variables !== undefined)
164
+ input.variables = parseRunInputVariables(obj.variables, method);
165
+ if (obj.data !== undefined)
166
+ input.data = parseRunInputData(obj.data, method);
167
+ if (obj.gatherPrompt !== undefined)
168
+ input.gatherPrompt = parseRunInputGatherPrompt(obj.gatherPrompt, method);
169
+ return input;
170
+ }
171
+ function parseCreateBoardParams(params) {
172
+ const raw = paramsObject(params);
173
+ if (typeof raw.prompt !== 'string' || raw.prompt.trim() === '') {
174
+ throw new SdkMethodError('BAD_REQUEST', 'pm.createBoard requires params { prompt, autoImplement? } with a non-empty prompt');
175
+ }
176
+ if (raw.autoImplement !== undefined && typeof raw.autoImplement !== 'boolean') {
177
+ throw new SdkMethodError('BAD_REQUEST', 'pm.createBoard autoImplement must be a boolean when present');
178
+ }
179
+ const input = raw.input !== undefined ? parseBoardRunInput(raw.input) : undefined;
180
+ return { prompt: raw.prompt, autoImplement: raw.autoImplement === true, ...(input ? { input } : {}) };
181
+ }
182
+ function boardNotFound(boardId) {
183
+ return new SdkMethodError('BAD_REQUEST', `board '${boardId}' not found in this Space`);
184
+ }
185
+ export async function pmCreateBoardHandler(args) {
186
+ const host = requirePmHost(args.method);
187
+ const { prompt, autoImplement, input } = parseCreateBoardParams(args.params);
188
+ let created;
189
+ try {
190
+ created = await host.createBoard({ workingDir: args.workingDir, prompt, autoImplement, ...(input ? { input } : {}) });
191
+ }
192
+ catch (error) {
193
+ throw new SdkMethodError('INTERNAL', `board creation failed: ${error instanceof Error ? error.message : String(error)}`);
194
+ }
195
+ logAppAudit({
196
+ appId: args.appId,
197
+ origin: args.origin,
198
+ method: 'pm.createBoard.created',
199
+ decision: 'allow',
200
+ requestId: args.requestId,
201
+ spaceKey: args.spaceKey,
202
+ reason: `board ${created.boardId} created via chatToBoard (autoImplement=${autoImplement})`,
203
+ });
204
+ return created;
205
+ }
206
+ export function pmGetBoardHandler(args) {
207
+ const boardId = parseBoardIdParams(args.params, args.method);
208
+ const snapshot = readBoardSnapshot(args.workingDir, boardId);
209
+ if (!snapshot)
210
+ throw boardNotFound(boardId);
211
+ return snapshot;
212
+ }
213
+ export function pmListBoardsHandler(args) {
214
+ return listBoardSummaries(args.workingDir);
215
+ }
216
+ export function pmOnBoardUpdateHandler(args) {
217
+ const host = requirePmHost(args.method);
218
+ const boardId = parseBoardIdParams(args.params, args.method);
219
+ const initial = readBoardSnapshot(args.workingDir, boardId);
220
+ if (!initial)
221
+ throw boardNotFound(boardId);
222
+ if (listLiveSubscriptions().some((sub) => sub.requestId === args.requestId)) {
223
+ throw new SdkMethodError('BAD_REQUEST', `requestId '${args.requestId}' already holds a live subscription`);
224
+ }
225
+ let lastSerialized = JSON.stringify(initial);
226
+ let active = true;
227
+ const unsubscribe = host.subscribeBoardUpdates(args.workingDir, () => {
228
+ if (!active)
229
+ return;
230
+ const snapshot = readBoardSnapshot(args.workingDir, boardId);
231
+ if (!snapshot)
232
+ return;
233
+ const serialized = JSON.stringify(snapshot);
234
+ if (serialized === lastSerialized)
235
+ return;
236
+ lastSerialized = serialized;
237
+ args.emit('boardUpdate', snapshot);
238
+ });
239
+ registerLiveSubscription({
240
+ requestId: args.requestId,
241
+ appId: args.appId,
242
+ origin: args.origin,
243
+ spaceKey: args.spaceKey,
244
+ kind: 'pm.subscribeBoard',
245
+ viewerId: getGrant(args.appId, args.spaceKey) ? undefined : args.viewerId,
246
+ teardown: () => {
247
+ active = false;
248
+ unsubscribe();
249
+ },
250
+ });
251
+ return { subscribed: true, boardId };
252
+ }
253
+ const DEFAULT_ID_PREFIXES = {
254
+ issue: 'IS',
255
+ epic: 'EP',
256
+ bug: 'BG',
257
+ task: 'TASK',
258
+ };
259
+ const ISSUE_TYPES = ['issue', 'epic', 'bug', 'task'];
260
+ const PRIORITIES = ['P0', 'P1', 'P2', 'P3'];
261
+ const ISSUE_ID_ALLOCATION_ATTEMPTS = 25;
262
+ function issueNotFound(boardId, issueId) {
263
+ return new SdkMethodError('BAD_REQUEST', `issue '${issueId}' not found on board '${boardId}'`);
264
+ }
265
+ function badRequest(message) {
266
+ return new SdkMethodError('BAD_REQUEST', message);
267
+ }
268
+ function assertYamlSafe(value, field, method, listItem = false) {
269
+ if (/[\r\n]/.test(value))
270
+ throw badRequest(`${method} ${field} must not contain line breaks`);
271
+ if (listItem && value.includes(','))
272
+ throw badRequest(`${method} ${field} must not contain commas`);
273
+ return value;
274
+ }
275
+ function requiredStringParam(raw, name, method) {
276
+ const value = raw[name];
277
+ if (typeof value !== 'string' || value.trim() === '') {
278
+ throw badRequest(`${method} requires a non-empty ${name}`);
279
+ }
280
+ return value;
281
+ }
282
+ function optionalStringParam(raw, name, method) {
283
+ if (raw[name] === undefined)
284
+ return undefined;
285
+ if (typeof raw[name] !== 'string')
286
+ throw badRequest(`${method} ${name} must be a string`);
287
+ return raw[name];
288
+ }
289
+ function optionalStringListParam(raw, name, method) {
290
+ if (raw[name] === undefined)
291
+ return undefined;
292
+ const value = raw[name];
293
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string' || entry.trim() === '')) {
294
+ throw badRequest(`${method} ${name} must be an array of non-empty strings`);
295
+ }
296
+ return value;
297
+ }
298
+ function optionalEnumParam(raw, name, method, allowed) {
299
+ if (raw[name] === undefined)
300
+ return undefined;
301
+ const value = raw[name];
302
+ if (typeof value !== 'string' || !allowed.includes(value)) {
303
+ throw badRequest(`${method} ${name} must be one of ${allowed.join(', ')}`);
304
+ }
305
+ return value;
306
+ }
307
+ function optionalEstimateParam(raw, method) {
308
+ if (!('estimate' in raw))
309
+ return undefined;
310
+ const value = raw.estimate;
311
+ if (value === null)
312
+ return null;
313
+ if (typeof value === 'number' && Number.isFinite(value))
314
+ return value;
315
+ if (typeof value === 'string' && value.trim() !== '')
316
+ return assertYamlSafe(value, 'estimate', method);
317
+ throw badRequest(`${method} estimate must be a number, a non-empty string, or null`);
318
+ }
319
+ function optionalTextParam(raw, name, method) {
320
+ const value = optionalStringParam(raw, name, method);
321
+ if (value === undefined)
322
+ return undefined;
323
+ if (value.trim() === '')
324
+ throw badRequest(`${method} ${name} must be a non-empty string`);
325
+ return assertYamlSafe(value, name, method);
326
+ }
327
+ function parseIssueRefFields(raw, method, patch) {
328
+ if ('epicId' in raw) {
329
+ if (raw.epicId !== null && (typeof raw.epicId !== 'string' || raw.epicId.trim() === '')) {
330
+ throw badRequest(`${method} epicId must be an issue id or null`);
331
+ }
332
+ patch.epicId = raw.epicId;
333
+ }
334
+ const blockedBy = optionalStringListParam(raw, 'blockedBy', method);
335
+ if (blockedBy !== undefined)
336
+ patch.blockedBy = blockedBy;
337
+ const blocks = optionalStringListParam(raw, 'blocks', method);
338
+ if (blocks !== undefined)
339
+ patch.blocks = blocks;
340
+ }
341
+ function parseIssueFieldPatch(raw, method) {
342
+ const patch = {};
343
+ const title = optionalTextParam(raw, 'title', method);
344
+ if (title !== undefined)
345
+ patch.title = title;
346
+ const status = optionalTextParam(raw, 'status', method);
347
+ if (status !== undefined)
348
+ patch.status = status;
349
+ const priority = optionalEnumParam(raw, 'priority', method, PRIORITIES);
350
+ if (priority !== undefined)
351
+ patch.priority = priority;
352
+ const estimate = optionalEstimateParam(raw, method);
353
+ if (estimate !== undefined)
354
+ patch.estimate = estimate;
355
+ const labels = optionalStringListParam(raw, 'labels', method);
356
+ if (labels !== undefined)
357
+ patch.labels = labels.map((label) => assertYamlSafe(label, 'labels', method, true));
358
+ parseIssueRefFields(raw, method, patch);
359
+ return patch;
360
+ }
361
+ function parseCreateIssueParams(params) {
362
+ const method = 'pm.createIssue';
363
+ const raw = paramsObject(params);
364
+ const boardId = requiredStringParam(raw, 'boardId', method);
365
+ const title = assertYamlSafe(requiredStringParam(raw, 'title', method), 'title', method);
366
+ const patch = parseIssueFieldPatch({ ...raw, title }, method);
367
+ const description = optionalStringParam(raw, 'description', method);
368
+ const acceptanceCriteria = optionalStringListParam(raw, 'acceptanceCriteria', method);
369
+ return {
370
+ ...patch,
371
+ boardId,
372
+ title,
373
+ type: optionalEnumParam(raw, 'type', method, ISSUE_TYPES) ?? 'issue',
374
+ ...(description !== undefined ? { description } : {}),
375
+ ...(acceptanceCriteria !== undefined ? { acceptanceCriteria } : {}),
376
+ };
377
+ }
378
+ function parseIssueTargetParams(params, method) {
379
+ const raw = paramsObject(params);
380
+ return {
381
+ boardId: requiredStringParam(raw, 'boardId', method),
382
+ issueId: requiredStringParam(raw, 'issueId', method),
383
+ };
384
+ }
385
+ function parseUpdateIssueParams(params) {
386
+ const method = 'pm.updateIssue';
387
+ const raw = paramsObject(params);
388
+ const { boardId, issueId } = parseIssueTargetParams(params, method);
389
+ if (typeof raw.fields !== 'object' || raw.fields === null || Array.isArray(raw.fields)) {
390
+ throw badRequest(`${method} requires params { boardId, issueId, fields }`);
391
+ }
392
+ const fields = parseIssueFieldPatch(raw.fields, method);
393
+ if (Object.keys(fields).length === 0) {
394
+ throw badRequest(`${method} fields must name at least one of title, status, priority, estimate, labels, epicId, blockedBy, blocks`);
395
+ }
396
+ return { boardId, issueId, fields };
397
+ }
398
+ function parseBoardExecutionFields(rawFields, method, fields) {
399
+ if (rawFields.maxParallelAgents !== undefined) {
400
+ const value = rawFields.maxParallelAgents;
401
+ if (typeof value !== 'number' || !Number.isInteger(value) || value < 1 || value > 10) {
402
+ throw badRequest(`${method} maxParallelAgents must be an integer between 1 and 10`);
403
+ }
404
+ fields.maxParallelAgents = value;
405
+ }
406
+ if (rawFields.autoImplement !== undefined) {
407
+ if (typeof rawFields.autoImplement !== 'boolean')
408
+ throw badRequest(`${method} autoImplement must be a boolean`);
409
+ fields.autoImplement = rawFields.autoImplement;
410
+ }
411
+ }
412
+ function parseBoardFieldPatch(rawFields, method) {
413
+ const fields = {};
414
+ const title = optionalTextParam(rawFields, 'title', method);
415
+ if (title !== undefined)
416
+ fields.title = title;
417
+ const status = optionalEnumParam(rawFields, 'status', method, ['draft', 'active', 'completed']);
418
+ if (status !== undefined)
419
+ fields.status = status;
420
+ const goal = optionalStringParam(rawFields, 'goal', method);
421
+ if (goal !== undefined)
422
+ fields.goal = assertYamlSafe(goal, 'goal', method);
423
+ parseBoardExecutionFields(rawFields, method, fields);
424
+ return fields;
425
+ }
426
+ function parseUpdateBoardParams(params) {
427
+ const method = 'pm.updateBoard';
428
+ const raw = paramsObject(params);
429
+ const boardId = requiredStringParam(raw, 'boardId', method);
430
+ if (typeof raw.fields !== 'object' || raw.fields === null || Array.isArray(raw.fields)) {
431
+ throw badRequest(`${method} requires params { boardId, fields }`);
432
+ }
433
+ const fields = parseBoardFieldPatch(raw.fields, method);
434
+ if (Object.keys(fields).length === 0) {
435
+ throw badRequest(`${method} fields must name at least one of title, status, goal, maxParallelAgents, autoImplement`);
436
+ }
437
+ return { boardId, fields };
438
+ }
439
+ function requireBoard(workingDir, boardId) {
440
+ const pmDir = resolvePmDir(workingDir);
441
+ if (!pmDir)
442
+ throw boardNotFound(boardId);
443
+ const full = parseBoardDirectory(pmDir, boardId);
444
+ if (!full)
445
+ throw boardNotFound(boardId);
446
+ return { pmDir, full };
447
+ }
448
+ function boardRelativePath(issuePath, boardId) {
449
+ const prefix = `boards/${boardId}/`;
450
+ return issuePath.startsWith(prefix) ? issuePath.slice(prefix.length) : issuePath;
451
+ }
452
+ function boardIssuePaths(full, boardId) {
453
+ const paths = {};
454
+ for (const issue of full.issues)
455
+ paths[issue.id] = boardRelativePath(issue.path, boardId);
456
+ return paths;
457
+ }
458
+ function refPath(full, boardId, issueId, field) {
459
+ const issue = full.issues.find((candidate) => candidate.id === issueId);
460
+ if (!issue)
461
+ throw badRequest(`${field} names unknown issue '${issueId}' on board '${boardId}'`);
462
+ return boardRelativePath(issue.path, boardId);
463
+ }
464
+ function toIssueFrontMatterFields(full, boardId, fields) {
465
+ const writable = {};
466
+ if (fields.title !== undefined)
467
+ writable.title = fields.title;
468
+ if (fields.status !== undefined)
469
+ writable.status = fields.status;
470
+ if (fields.priority !== undefined)
471
+ writable.priority = fields.priority;
472
+ if (fields.estimate !== undefined)
473
+ writable.estimate = fields.estimate;
474
+ if (fields.labels !== undefined)
475
+ writable.labels = fields.labels;
476
+ if (fields.epicId !== undefined) {
477
+ writable.epic = fields.epicId === null ? null : refPath(full, boardId, fields.epicId, 'epicId');
478
+ }
479
+ if (fields.blockedBy !== undefined) {
480
+ writable.blockedBy = fields.blockedBy.map((id) => refPath(full, boardId, id, 'blockedBy'));
481
+ }
482
+ if (fields.blocks !== undefined) {
483
+ writable.blocks = fields.blocks.map((id) => refPath(full, boardId, id, 'blocks'));
484
+ }
485
+ return writable;
486
+ }
487
+ function toTemplateIssue(id, params) {
488
+ return {
489
+ id,
490
+ type: params.type,
491
+ title: params.title,
492
+ priority: params.priority ?? 'P2',
493
+ estimate: params.estimate ?? null,
494
+ labels: params.labels ?? [],
495
+ epic: params.epicId ?? null,
496
+ blocked_by: params.blockedBy ?? [],
497
+ blocks: params.blocks ?? [],
498
+ description: params.description ?? '',
499
+ acceptance_criteria: params.acceptanceCriteria ?? [],
500
+ };
501
+ }
502
+ function resolveIdPrefix(workingDir, type) {
503
+ const configured = parsePlanDirectory(workingDir)?.project.idPrefixes?.[type];
504
+ return typeof configured === 'string' && configured.trim() !== '' ? configured : DEFAULT_ID_PREFIXES[type];
505
+ }
506
+ function nextFreeIssueId(backlogDir, issues, prefix) {
507
+ let candidate = getNextId(issues, prefix);
508
+ while (existsSync(join(backlogDir, `${candidate}.md`))) {
509
+ const current = Number.parseInt(candidate.slice(prefix.length + 1), 10);
510
+ candidate = `${prefix}-${String(current + 1).padStart(3, '0')}`;
511
+ }
512
+ return candidate;
513
+ }
514
+ function readIssueSnapshot(pmDir, boardId, issueId) {
515
+ const full = parseBoardDirectory(pmDir, boardId);
516
+ if (!full)
517
+ return null;
518
+ const idByPath = new Map(full.issues.map((issue) => [issue.path, issue.id]));
519
+ const issue = full.issues.find((candidate) => candidate.id === issueId);
520
+ return issue ? toSnapshotIssue(issue, idByPath) : null;
521
+ }
522
+ function notifyPlanUpdate(workingDir) {
523
+ pmHost?.broadcastPlanUpdate(workingDir);
524
+ }
525
+ function auditMutation(args, method, reason) {
526
+ logAppAudit({
527
+ appId: args.appId,
528
+ origin: args.origin,
529
+ method,
530
+ decision: 'allow',
531
+ requestId: args.requestId,
532
+ spaceKey: args.spaceKey,
533
+ reason,
534
+ });
535
+ }
536
+ function assertIssueRefsResolve(full, params) {
537
+ if (params.epicId != null)
538
+ refPath(full, params.boardId, params.epicId, 'epicId');
539
+ for (const id of params.blockedBy ?? [])
540
+ refPath(full, params.boardId, id, 'blockedBy');
541
+ for (const id of params.blocks ?? [])
542
+ refPath(full, params.boardId, id, 'blocks');
543
+ }
544
+ function writeNewIssueFile(pmDir, backlogDir, params, prefix) {
545
+ const created = new Date().toISOString().split('T')[0];
546
+ for (let attempt = 0; attempt < ISSUE_ID_ALLOCATION_ATTEMPTS; attempt++) {
547
+ const full = parseBoardDirectory(pmDir, params.boardId);
548
+ if (!full)
549
+ throw boardNotFound(params.boardId);
550
+ assertIssueRefsResolve(full, params);
551
+ const candidate = nextFreeIssueId(backlogDir, full.issues, prefix);
552
+ const issuePaths = boardIssuePaths(full, params.boardId);
553
+ issuePaths[candidate] = `backlog/${candidate}.md`;
554
+ const markdown = renderIssueMarkdown(toTemplateIssue(candidate, params), {}, issuePaths, created);
555
+ try {
556
+ writeFileSync(join(backlogDir, `${candidate}.md`), markdown, { encoding: 'utf-8', flag: 'wx' });
557
+ return candidate;
558
+ }
559
+ catch (error) {
560
+ if (error?.code !== 'EEXIST') {
561
+ throw new SdkMethodError('INTERNAL', `failed to write issue on board '${params.boardId}': ${error instanceof Error ? error.message : String(error)}`);
562
+ }
563
+ }
564
+ }
565
+ throw new SdkMethodError('INTERNAL', `could not allocate a free issue id on board '${params.boardId}'`);
566
+ }
567
+ export function pmCreateIssueHandler(args) {
568
+ const params = parseCreateIssueParams(args.params);
569
+ const { pmDir } = requireBoard(args.workingDir, params.boardId);
570
+ const backlogDir = join(pmDir, 'boards', params.boardId, 'backlog');
571
+ mkdirSync(backlogDir, { recursive: true });
572
+ const issueId = writeNewIssueFile(pmDir, backlogDir, params, resolveIdPrefix(args.workingDir, params.type));
573
+ if (params.status !== undefined && params.status !== 'todo') {
574
+ const issuePath = `boards/${params.boardId}/backlog/${issueId}.md`;
575
+ const fullPath = resolvePlanPath(args.workingDir, issuePath);
576
+ if (fullPath)
577
+ applyIssueFieldUpdates(fullPath, { status: params.status });
578
+ }
579
+ const snapshot = readIssueSnapshot(pmDir, params.boardId, issueId);
580
+ if (!snapshot)
581
+ throw issueNotFound(params.boardId, issueId);
582
+ auditMutation(args, 'pm.createIssue.created', `issue ${issueId} created on board ${params.boardId}`);
583
+ notifyPlanUpdate(args.workingDir);
584
+ return snapshot;
585
+ }
586
+ export function pmUpdateIssueHandler(args) {
587
+ const { boardId, issueId, fields } = parseUpdateIssueParams(args.params);
588
+ const { pmDir, full } = requireBoard(args.workingDir, boardId);
589
+ const issue = full.issues.find((candidate) => candidate.id === issueId);
590
+ if (!issue)
591
+ throw issueNotFound(boardId, issueId);
592
+ const fullPath = resolvePlanPath(args.workingDir, issue.path);
593
+ if (!fullPath || !existsSync(fullPath))
594
+ throw issueNotFound(boardId, issueId);
595
+ if (!applyIssueFieldUpdates(fullPath, toIssueFrontMatterFields(full, boardId, fields))) {
596
+ throw new SdkMethodError('INTERNAL', `issue '${issueId}' is not front-matter shaped`);
597
+ }
598
+ const updated = parseSingleIssue(args.workingDir, issue.path);
599
+ if (updated)
600
+ tryCompleteParentEpic(args.workingDir, updated);
601
+ const snapshot = readIssueSnapshot(pmDir, boardId, issueId);
602
+ if (!snapshot)
603
+ throw issueNotFound(boardId, issueId);
604
+ auditMutation(args, 'pm.updateIssue.updated', `issue ${issueId} on board ${boardId} updated (${Object.keys(fields).join(', ')})`);
605
+ notifyPlanUpdate(args.workingDir);
606
+ return snapshot;
607
+ }
608
+ export function pmDeleteIssueHandler(args) {
609
+ const { boardId, issueId } = parseIssueTargetParams(args.params, 'pm.deleteIssue');
610
+ const { full } = requireBoard(args.workingDir, boardId);
611
+ const issue = full.issues.find((candidate) => candidate.id === issueId);
612
+ if (!issue)
613
+ throw issueNotFound(boardId, issueId);
614
+ const fullPath = resolvePlanPath(args.workingDir, issue.path);
615
+ if (!fullPath || !deleteIssueFile(fullPath))
616
+ throw issueNotFound(boardId, issueId);
617
+ auditMutation(args, 'pm.deleteIssue.deleted', `issue ${issueId} deleted from board ${boardId}`);
618
+ notifyPlanUpdate(args.workingDir);
619
+ return { deleted: true, issueId };
620
+ }
621
+ export function pmUpdateBoardHandler(args) {
622
+ const { boardId, fields } = parseUpdateBoardParams(args.params);
623
+ const { pmDir } = requireBoard(args.workingDir, boardId);
624
+ const boardMdPath = join(pmDir, 'boards', boardId, 'board.md');
625
+ if (!existsSync(boardMdPath))
626
+ throw boardNotFound(boardId);
627
+ applyBoardFieldUpdates(boardMdPath, fields);
628
+ const updated = parseBoardDirectory(pmDir, boardId);
629
+ if (!updated)
630
+ throw boardNotFound(boardId);
631
+ auditMutation(args, 'pm.updateBoard.updated', `board ${boardId} updated (${Object.keys(fields).join(', ')})`);
632
+ notifyPlanUpdate(args.workingDir);
633
+ return toBoardSummary(updated.board);
634
+ }
@@ -0,0 +1,20 @@
1
+ // Copyright (c) 2025-present Minionry, Inc.
2
+ // SPDX-License-Identifier: LicenseRef-Minionry-Software
3
+ const listeners = new Set();
4
+ export function registerQualityChangeListener(spaceKey, cb) {
5
+ const listener = { spaceKey, cb };
6
+ listeners.add(listener);
7
+ return () => {
8
+ listeners.delete(listener);
9
+ };
10
+ }
11
+ export function notifyQualityChanged(spaceKey, change) {
12
+ for (const listener of listeners) {
13
+ if (listener.spaceKey !== spaceKey)
14
+ continue;
15
+ listener.cb(change);
16
+ }
17
+ }
18
+ export function resetQualityChangeListeners() {
19
+ listeners.clear();
20
+ }