@evalops/maestro 0.10.49 → 0.10.51

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 (422) hide show
  1. package/dist/agent/agent-outcome.d.ts +54 -0
  2. package/dist/agent/agent-outcome.d.ts.map +1 -0
  3. package/dist/agent/agent-outcome.js +142 -0
  4. package/dist/agent/agent-outcome.js.map +1 -0
  5. package/dist/agent/agent-resume.d.ts.map +1 -1
  6. package/dist/agent/agent-resume.js +3 -3
  7. package/dist/agent/agent-resume.js.map +1 -1
  8. package/dist/agent/agent-run-summary.d.ts +37 -0
  9. package/dist/agent/agent-run-summary.d.ts.map +1 -0
  10. package/dist/agent/agent-run-summary.js +15 -0
  11. package/dist/agent/agent-run-summary.js.map +1 -0
  12. package/dist/agent/agent-work-board.d.ts +82 -0
  13. package/dist/agent/agent-work-board.d.ts.map +1 -0
  14. package/dist/agent/agent-work-board.js +312 -0
  15. package/dist/agent/agent-work-board.js.map +1 -0
  16. package/dist/agent/auto-compaction.d.ts +7 -2
  17. package/dist/agent/auto-compaction.d.ts.map +1 -1
  18. package/dist/agent/auto-compaction.js +23 -10
  19. package/dist/agent/auto-compaction.js.map +1 -1
  20. package/dist/agent/mission-artifacts.d.ts +62 -0
  21. package/dist/agent/mission-artifacts.d.ts.map +1 -0
  22. package/dist/agent/mission-artifacts.js +438 -0
  23. package/dist/agent/mission-artifacts.js.map +1 -0
  24. package/dist/agent/mission-manifest.d.ts +139 -3
  25. package/dist/agent/mission-manifest.d.ts.map +1 -1
  26. package/dist/agent/mission-manifest.js +549 -3
  27. package/dist/agent/mission-manifest.js.map +1 -1
  28. package/dist/agent/mission-store.d.ts +80 -0
  29. package/dist/agent/mission-store.d.ts.map +1 -0
  30. package/dist/agent/mission-store.js +603 -0
  31. package/dist/agent/mission-store.js.map +1 -0
  32. package/dist/agent/modes.d.ts +2 -2
  33. package/dist/agent/modes.d.ts.map +1 -1
  34. package/dist/agent/modes.js +10 -3
  35. package/dist/agent/modes.js.map +1 -1
  36. package/dist/agent/providers/codex-app-server.d.ts.map +1 -1
  37. package/dist/agent/providers/codex-app-server.js +1 -3
  38. package/dist/agent/providers/codex-app-server.js.map +1 -1
  39. package/dist/agent/providers/google-gemini-cli.js +203 -107
  40. package/dist/agent/providers/google.js +100 -41
  41. package/dist/agent/providers/scripted.d.ts.map +1 -1
  42. package/dist/agent/providers/scripted.js +1 -3
  43. package/dist/agent/providers/scripted.js.map +1 -1
  44. package/dist/agent/providers/validation.d.ts.map +1 -1
  45. package/dist/agent/providers/validation.js +1 -3
  46. package/dist/agent/providers/validation.js.map +1 -1
  47. package/dist/agent/providers/vertex.js +203 -107
  48. package/dist/agent/snapshot-store.d.ts +32 -0
  49. package/dist/agent/snapshot-store.d.ts.map +1 -0
  50. package/dist/agent/snapshot-store.js +195 -0
  51. package/dist/agent/snapshot-store.js.map +1 -0
  52. package/dist/agent/specialist-profiles.d.ts +36 -0
  53. package/dist/agent/specialist-profiles.d.ts.map +1 -0
  54. package/dist/agent/specialist-profiles.js +159 -0
  55. package/dist/agent/specialist-profiles.js.map +1 -0
  56. package/dist/agent/subagent-specs.d.ts +4 -1
  57. package/dist/agent/subagent-specs.d.ts.map +1 -1
  58. package/dist/agent/subagent-specs.js +81 -8
  59. package/dist/agent/subagent-specs.js.map +1 -1
  60. package/dist/agent/swarm/coverage-gate.d.ts +37 -0
  61. package/dist/agent/swarm/coverage-gate.d.ts.map +1 -0
  62. package/dist/agent/swarm/coverage-gate.js +48 -0
  63. package/dist/agent/swarm/coverage-gate.js.map +1 -0
  64. package/dist/agent/swarm/executor.d.ts +1 -0
  65. package/dist/agent/swarm/executor.d.ts.map +1 -1
  66. package/dist/agent/swarm/executor.js +151 -15
  67. package/dist/agent/swarm/executor.js.map +1 -1
  68. package/dist/agent/swarm/orchestrator-prompt.d.ts +25 -0
  69. package/dist/agent/swarm/orchestrator-prompt.d.ts.map +1 -0
  70. package/dist/agent/swarm/orchestrator-prompt.js +48 -0
  71. package/dist/agent/swarm/orchestrator-prompt.js.map +1 -0
  72. package/dist/agent/swarm/plan-parser.d.ts.map +1 -1
  73. package/dist/agent/swarm/plan-parser.js +27 -2
  74. package/dist/agent/swarm/plan-parser.js.map +1 -1
  75. package/dist/agent/swarm/types.d.ts +17 -0
  76. package/dist/agent/swarm/types.d.ts.map +1 -1
  77. package/dist/agent/swarm/types.js.map +1 -1
  78. package/dist/agent/swarm/validation-directive.d.ts +21 -0
  79. package/dist/agent/swarm/validation-directive.d.ts.map +1 -0
  80. package/dist/agent/swarm/validation-directive.js +25 -0
  81. package/dist/agent/swarm/validation-directive.js.map +1 -0
  82. package/dist/agent/transport/tool-execution-bridge.d.ts.map +1 -1
  83. package/dist/agent/transport/tool-execution-bridge.js +4 -1
  84. package/dist/agent/transport/tool-execution-bridge.js.map +1 -1
  85. package/dist/api/enterprise-routes.d.ts.map +1 -1
  86. package/dist/api/enterprise-routes.js +87 -10
  87. package/dist/api/enterprise-routes.js.map +1 -1
  88. package/dist/api/org-settings-merge.d.ts +12 -0
  89. package/dist/api/org-settings-merge.d.ts.map +1 -0
  90. package/dist/api/org-settings-merge.js +38 -0
  91. package/dist/api/org-settings-merge.js.map +1 -0
  92. package/dist/api/user-settings-merge.d.ts +16 -0
  93. package/dist/api/user-settings-merge.d.ts.map +1 -0
  94. package/dist/api/user-settings-merge.js +37 -0
  95. package/dist/api/user-settings-merge.js.map +1 -0
  96. package/dist/app-server/daemon-lifecycle-api.d.ts.map +1 -1
  97. package/dist/app-server/daemon-lifecycle-api.js +1 -3
  98. package/dist/app-server/daemon-lifecycle-api.js.map +1 -1
  99. package/dist/app-server/external-agent-import-api.d.ts.map +1 -1
  100. package/dist/app-server/external-agent-import-api.js +1 -3
  101. package/dist/app-server/external-agent-import-api.js.map +1 -1
  102. package/dist/app-server/network-governance-api.d.ts.map +1 -1
  103. package/dist/app-server/network-governance-api.js +1 -3
  104. package/dist/app-server/network-governance-api.js.map +1 -1
  105. package/dist/app-server/plugin-bundle-api.d.ts.map +1 -1
  106. package/dist/app-server/plugin-bundle-api.js +1 -3
  107. package/dist/app-server/plugin-bundle-api.js.map +1 -1
  108. package/dist/app-server/policy-control-api.d.ts.map +1 -1
  109. package/dist/app-server/policy-control-api.js +1 -3
  110. package/dist/app-server/policy-control-api.js.map +1 -1
  111. package/dist/app-server/protocol-modes-api.d.ts.map +1 -1
  112. package/dist/app-server/protocol-modes-api.js +1 -3
  113. package/dist/app-server/protocol-modes-api.js.map +1 -1
  114. package/dist/cli/args.d.ts +2 -0
  115. package/dist/cli/args.d.ts.map +1 -1
  116. package/dist/cli/args.js +15 -0
  117. package/dist/cli/args.js.map +1 -1
  118. package/dist/cli/commands/a2a.d.ts.map +1 -1
  119. package/dist/cli/commands/a2a.js +1 -3
  120. package/dist/cli/commands/a2a.js.map +1 -1
  121. package/dist/cli/commands/agents.d.ts +4 -0
  122. package/dist/cli/commands/agents.d.ts.map +1 -1
  123. package/dist/cli/commands/agents.js +149 -0
  124. package/dist/cli/commands/agents.js.map +1 -1
  125. package/dist/cli/commands/mission.d.ts +4 -0
  126. package/dist/cli/commands/mission.d.ts.map +1 -0
  127. package/dist/cli/commands/mission.js +196 -0
  128. package/dist/cli/commands/mission.js.map +1 -0
  129. package/dist/cli/commands/value.d.ts +10 -0
  130. package/dist/cli/commands/value.d.ts.map +1 -0
  131. package/dist/cli/commands/value.js +33 -0
  132. package/dist/cli/commands/value.js.map +1 -0
  133. package/dist/cli/headless-protocol.d.ts.map +1 -1
  134. package/dist/cli/headless-protocol.js +1 -3
  135. package/dist/cli/headless-protocol.js.map +1 -1
  136. package/dist/cli/help.d.ts.map +1 -1
  137. package/dist/cli/help.js +10 -0
  138. package/dist/cli/help.js.map +1 -1
  139. package/dist/cli/system-prompt.d.ts.map +1 -1
  140. package/dist/cli/system-prompt.js +38 -7
  141. package/dist/cli/system-prompt.js.map +1 -1
  142. package/dist/cli-command-runtime.js +2 -2
  143. package/dist/cli-command-runtime.js.map +1 -1
  144. package/dist/cli-runtime.js +7798 -2805
  145. package/dist/cli-tui/client-tools/client-tool-controller.d.ts.map +1 -1
  146. package/dist/cli-tui/client-tools/client-tool-controller.js +1 -3
  147. package/dist/cli-tui/client-tools/client-tool-controller.js.map +1 -1
  148. package/dist/cli-tui/commands/undo-handlers.d.ts.map +1 -1
  149. package/dist/cli-tui/commands/undo-handlers.js +7 -2
  150. package/dist/cli-tui/commands/undo-handlers.js.map +1 -1
  151. package/dist/cli-tui/tui-renderer/skills-controller.d.ts +3 -0
  152. package/dist/cli-tui/tui-renderer/skills-controller.d.ts.map +1 -1
  153. package/dist/cli-tui/tui-renderer/skills-controller.js +77 -33
  154. package/dist/cli-tui/tui-renderer/skills-controller.js.map +1 -1
  155. package/dist/cli.js +4 -6
  156. package/dist/cli.js.map +1 -1
  157. package/dist/codex/app-server-client.d.ts.map +1 -1
  158. package/dist/codex/app-server-client.js +1 -3
  159. package/dist/codex/app-server-client.js.map +1 -1
  160. package/dist/codex/compatibility.d.ts.map +1 -1
  161. package/dist/codex/compatibility.js +1 -3
  162. package/dist/codex/compatibility.js.map +1 -1
  163. package/dist/codex/subagent-dispatch-table.d.ts +8 -0
  164. package/dist/codex/subagent-dispatch-table.d.ts.map +1 -1
  165. package/dist/codex/subagent-dispatch-table.js +23 -0
  166. package/dist/codex/subagent-dispatch-table.js.map +1 -1
  167. package/dist/context/manifest.d.ts.map +1 -1
  168. package/dist/context/manifest.js +1 -3
  169. package/dist/context/manifest.js.map +1 -1
  170. package/dist/conversation/render-model.d.ts +0 -36
  171. package/dist/conversation/render-model.d.ts.map +1 -1
  172. package/dist/conversation/render-model.js +1 -3
  173. package/dist/conversation/render-model.js.map +1 -1
  174. package/dist/customer-value/ambient-learning.d.ts +75 -0
  175. package/dist/customer-value/ambient-learning.d.ts.map +1 -0
  176. package/dist/customer-value/ambient-learning.js +472 -0
  177. package/dist/customer-value/ambient-learning.js.map +1 -0
  178. package/dist/customer-value/internal-helpers.d.ts +13 -0
  179. package/dist/customer-value/internal-helpers.d.ts.map +1 -0
  180. package/dist/customer-value/internal-helpers.js +70 -0
  181. package/dist/customer-value/internal-helpers.js.map +1 -0
  182. package/dist/customer-value/report.d.ts +282 -0
  183. package/dist/customer-value/report.d.ts.map +1 -0
  184. package/dist/customer-value/report.js +2085 -0
  185. package/dist/customer-value/report.js.map +1 -0
  186. package/dist/db/health.d.ts +1 -1
  187. package/dist/db/health.d.ts.map +1 -1
  188. package/dist/db/health.js +10 -0
  189. package/dist/db/health.js.map +1 -1
  190. package/dist/db/migrations/0009_operating_layer_evidence.sql +30 -0
  191. package/dist/db/migrations/meta/_journal.json +7 -0
  192. package/dist/db/schema.d.ts +268 -1
  193. package/dist/db/schema.d.ts.map +1 -1
  194. package/dist/db/schema.js +28 -0
  195. package/dist/db/schema.js.map +1 -1
  196. package/dist/evalops/agent-bootstrap.d.ts.map +1 -1
  197. package/dist/evalops/agent-bootstrap.js +1 -3
  198. package/dist/evalops/agent-bootstrap.js.map +1 -1
  199. package/dist/evalops/agent-mcp-metadata.d.ts.map +1 -1
  200. package/dist/evalops/agent-mcp-metadata.js +1 -3
  201. package/dist/evalops/agent-mcp-metadata.js.map +1 -1
  202. package/dist/index.d.ts +1 -0
  203. package/dist/index.d.ts.map +1 -1
  204. package/dist/index.js +1 -0
  205. package/dist/index.js.map +1 -1
  206. package/dist/installers/maestro-review-workflow.d.ts +38 -0
  207. package/dist/installers/maestro-review-workflow.d.ts.map +1 -0
  208. package/dist/installers/maestro-review-workflow.js +163 -0
  209. package/dist/installers/maestro-review-workflow.js.map +1 -0
  210. package/dist/load-env.d.ts +13 -0
  211. package/dist/load-env.d.ts.map +1 -1
  212. package/dist/load-env.js +17 -0
  213. package/dist/load-env.js.map +1 -1
  214. package/dist/main.d.ts.map +1 -1
  215. package/dist/main.js +96 -7
  216. package/dist/main.js.map +1 -1
  217. package/dist/mcp/config.d.ts.map +1 -1
  218. package/dist/mcp/config.js +1 -3
  219. package/dist/mcp/config.js.map +1 -1
  220. package/dist/mcp/elicitation.d.ts.map +1 -1
  221. package/dist/mcp/elicitation.js +1 -3
  222. package/dist/mcp/elicitation.js.map +1 -1
  223. package/dist/mcp/official-registry.d.ts.map +1 -1
  224. package/dist/mcp/official-registry.js +1 -3
  225. package/dist/mcp/official-registry.js.map +1 -1
  226. package/dist/mcp/workspace-trust.d.ts.map +1 -1
  227. package/dist/mcp/workspace-trust.js +1 -3
  228. package/dist/mcp/workspace-trust.js.map +1 -1
  229. package/dist/memory/service-client.d.ts.map +1 -1
  230. package/dist/memory/service-client.js +1 -3
  231. package/dist/memory/service-client.js.map +1 -1
  232. package/dist/models/config-loader.d.ts.map +1 -1
  233. package/dist/models/config-loader.js +1 -3
  234. package/dist/models/config-loader.js.map +1 -1
  235. package/dist/node_modules/@evalops/contracts/dist/index.d.ts +1 -0
  236. package/dist/node_modules/@evalops/contracts/dist/index.d.ts.map +1 -1
  237. package/dist/node_modules/@evalops/contracts/dist/index.js +1 -0
  238. package/dist/node_modules/@evalops/contracts/dist/index.js.map +1 -1
  239. package/dist/node_modules/@evalops/contracts/dist/maestro-settings.d.ts +61 -0
  240. package/dist/node_modules/@evalops/contracts/dist/maestro-settings.d.ts.map +1 -0
  241. package/dist/node_modules/@evalops/contracts/dist/maestro-settings.js +183 -0
  242. package/dist/node_modules/@evalops/contracts/dist/maestro-settings.js.map +1 -0
  243. package/dist/node_modules/@evalops/contracts/package.json +1 -1
  244. package/dist/node_modules/@evalops/tui/package.json +1 -1
  245. package/dist/oauth/connectors.d.ts.map +1 -1
  246. package/dist/oauth/connectors.js +1 -3
  247. package/dist/oauth/connectors.js.map +1 -1
  248. package/dist/oauth/evalops.d.ts.map +1 -1
  249. package/dist/oauth/evalops.js +1 -3
  250. package/dist/oauth/evalops.js.map +1 -1
  251. package/dist/platform/a2a-client.d.ts.map +1 -1
  252. package/dist/platform/a2a-client.js +1 -3
  253. package/dist/platform/a2a-client.js.map +1 -1
  254. package/dist/platform/a2a-cockpit.d.ts +1 -0
  255. package/dist/platform/a2a-cockpit.d.ts.map +1 -1
  256. package/dist/platform/a2a-cockpit.js +42 -11
  257. package/dist/platform/a2a-cockpit.js.map +1 -1
  258. package/dist/platform/a2a-completion-audit.d.ts +1 -1
  259. package/dist/platform/a2a-completion-audit.d.ts.map +1 -1
  260. package/dist/platform/a2a-completion-audit.js +7 -11
  261. package/dist/platform/a2a-completion-audit.js.map +1 -1
  262. package/dist/platform/a2a-maestro-peer.js +16 -0
  263. package/dist/platform/a2a-maestro-peer.js.map +1 -1
  264. package/dist/platform/a2a-peer-pairing.d.ts.map +1 -1
  265. package/dist/platform/a2a-peer-pairing.js +1 -3
  266. package/dist/platform/a2a-peer-pairing.js.map +1 -1
  267. package/dist/platform/a2a-peer-registry.d.ts.map +1 -1
  268. package/dist/platform/a2a-peer-registry.js +1 -3
  269. package/dist/platform/a2a-peer-registry.js.map +1 -1
  270. package/dist/platform/a2a-task-ledger.d.ts +20 -0
  271. package/dist/platform/a2a-task-ledger.d.ts.map +1 -1
  272. package/dist/platform/a2a-task-ledger.js +207 -11
  273. package/dist/platform/a2a-task-ledger.js.map +1 -1
  274. package/dist/platform/a2a-work-graph.d.ts.map +1 -1
  275. package/dist/platform/a2a-work-graph.js +1 -3
  276. package/dist/platform/a2a-work-graph.js.map +1 -1
  277. package/dist/platform/operating-layer.d.ts +127 -0
  278. package/dist/platform/operating-layer.d.ts.map +1 -0
  279. package/dist/platform/operating-layer.js +360 -0
  280. package/dist/platform/operating-layer.js.map +1 -0
  281. package/dist/platform/tool-execution-client.d.ts.map +1 -1
  282. package/dist/platform/tool-execution-client.js +19 -2
  283. package/dist/platform/tool-execution-client.js.map +1 -1
  284. package/dist/providers/auth.d.ts.map +1 -1
  285. package/dist/providers/auth.js +1 -3
  286. package/dist/providers/auth.js.map +1 -1
  287. package/dist/runtime/env.d.ts +9 -1
  288. package/dist/runtime/env.d.ts.map +1 -1
  289. package/dist/runtime/env.js +63 -1
  290. package/dist/runtime/env.js.map +1 -1
  291. package/dist/safety/policy.d.ts.map +1 -1
  292. package/dist/safety/policy.js +1 -4
  293. package/dist/safety/policy.js.map +1 -1
  294. package/dist/sandbox/docker-sandbox.d.ts.map +1 -1
  295. package/dist/sandbox/docker-sandbox.js +6 -1
  296. package/dist/sandbox/docker-sandbox.js.map +1 -1
  297. package/dist/server/handlers/hosted-runner-drain.d.ts.map +1 -1
  298. package/dist/server/handlers/hosted-runner-drain.js +1 -3
  299. package/dist/server/handlers/hosted-runner-drain.js.map +1 -1
  300. package/dist/server/handlers/platform-a2a-push.d.ts.map +1 -1
  301. package/dist/server/handlers/platform-a2a-push.js +53 -2
  302. package/dist/server/handlers/platform-a2a-push.js.map +1 -1
  303. package/dist/server/handlers/runtime-app-server-ws.d.ts.map +1 -1
  304. package/dist/server/handlers/runtime-app-server-ws.js +1 -3
  305. package/dist/server/handlers/runtime-app-server-ws.js.map +1 -1
  306. package/dist/server/headless-runtime-service.d.ts +16 -0
  307. package/dist/server/headless-runtime-service.d.ts.map +1 -1
  308. package/dist/server/headless-runtime-service.js +232 -206
  309. package/dist/server/headless-runtime-service.js.map +1 -1
  310. package/dist/server/hosted-agent-runtime-progress.d.ts.map +1 -1
  311. package/dist/server/hosted-agent-runtime-progress.js +12 -3
  312. package/dist/server/hosted-agent-runtime-progress.js.map +1 -1
  313. package/dist/server/pending-request-payload.d.ts.map +1 -1
  314. package/dist/server/pending-request-payload.js +1 -3
  315. package/dist/server/pending-request-payload.js.map +1 -1
  316. package/dist/server/route-auth.d.ts.map +1 -1
  317. package/dist/server/route-auth.js +2 -0
  318. package/dist/server/route-auth.js.map +1 -1
  319. package/dist/server/session-serialization.d.ts.map +1 -1
  320. package/dist/server/session-serialization.js +1 -3
  321. package/dist/server/session-serialization.js.map +1 -1
  322. package/dist/services/compliance/normalize.d.ts.map +1 -1
  323. package/dist/services/compliance/normalize.js +1 -3
  324. package/dist/services/compliance/normalize.js.map +1 -1
  325. package/dist/services/intelligent-router/normalize.d.ts.map +1 -1
  326. package/dist/services/intelligent-router/normalize.js +1 -3
  327. package/dist/services/intelligent-router/normalize.js.map +1 -1
  328. package/dist/services/revenue-attribution/normalize.d.ts.map +1 -1
  329. package/dist/services/revenue-attribution/normalize.js +1 -3
  330. package/dist/services/revenue-attribution/normalize.js.map +1 -1
  331. package/dist/services/traces/normalize.d.ts.map +1 -1
  332. package/dist/services/traces/normalize.js +1 -3
  333. package/dist/services/traces/normalize.js.map +1 -1
  334. package/dist/services/workspace-config/normalize.d.ts.map +1 -1
  335. package/dist/services/workspace-config/normalize.js +1 -3
  336. package/dist/services/workspace-config/normalize.js.map +1 -1
  337. package/dist/skills/composer.d.ts.map +1 -1
  338. package/dist/skills/composer.js +13 -1
  339. package/dist/skills/composer.js.map +1 -1
  340. package/dist/skills/index.d.ts +1 -0
  341. package/dist/skills/index.d.ts.map +1 -1
  342. package/dist/skills/index.js +1 -0
  343. package/dist/skills/index.js.map +1 -1
  344. package/dist/skills/learned-guidelines.d.ts +33 -0
  345. package/dist/skills/learned-guidelines.d.ts.map +1 -0
  346. package/dist/skills/learned-guidelines.js +291 -0
  347. package/dist/skills/learned-guidelines.js.map +1 -0
  348. package/dist/skills/linter.d.ts.map +1 -1
  349. package/dist/skills/linter.js +1 -3
  350. package/dist/skills/linter.js.map +1 -1
  351. package/dist/skills/runtime-activation.d.ts +1 -0
  352. package/dist/skills/runtime-activation.d.ts.map +1 -1
  353. package/dist/skills/runtime-activation.js +2 -3
  354. package/dist/skills/runtime-activation.js.map +1 -1
  355. package/dist/skills/tool.d.ts.map +1 -1
  356. package/dist/skills/tool.js +26 -21
  357. package/dist/skills/tool.js.map +1 -1
  358. package/dist/skills/trust-cache.d.ts +7 -0
  359. package/dist/skills/trust-cache.d.ts.map +1 -1
  360. package/dist/skills/trust-cache.js +16 -0
  361. package/dist/skills/trust-cache.js.map +1 -1
  362. package/dist/telemetry/agent-workforce-native-event.d.ts.map +1 -1
  363. package/dist/telemetry/agent-workforce-native-event.js +1 -3
  364. package/dist/telemetry/agent-workforce-native-event.js.map +1 -1
  365. package/dist/telemetry/maestro-event-bus.d.ts.map +1 -1
  366. package/dist/telemetry/maestro-event-bus.js +42 -81
  367. package/dist/telemetry/maestro-event-bus.js.map +1 -1
  368. package/dist/telemetry/maestro-platform-replay-fixture.d.ts.map +1 -1
  369. package/dist/telemetry/maestro-platform-replay-fixture.js +1 -3
  370. package/dist/telemetry/maestro-platform-replay-fixture.js.map +1 -1
  371. package/dist/telemetry.d.ts.map +1 -1
  372. package/dist/telemetry.js +54 -43
  373. package/dist/telemetry.js.map +1 -1
  374. package/dist/theme/theme-loader.d.ts.map +1 -1
  375. package/dist/theme/theme-loader.js +1 -3
  376. package/dist/theme/theme-loader.js.map +1 -1
  377. package/dist/tools/apply-patch.d.ts.map +1 -1
  378. package/dist/tools/apply-patch.js +76 -8
  379. package/dist/tools/apply-patch.js.map +1 -1
  380. package/dist/tools/diff-preview.d.ts.map +1 -1
  381. package/dist/tools/diff-preview.js +10 -1
  382. package/dist/tools/diff-preview.js.map +1 -1
  383. package/dist/tools/edit.d.ts.map +1 -1
  384. package/dist/tools/edit.js +17 -0
  385. package/dist/tools/edit.js.map +1 -1
  386. package/dist/tools/write.d.ts.map +1 -1
  387. package/dist/tools/write.js +9 -0
  388. package/dist/tools/write.js.map +1 -1
  389. package/dist/undo/tracker.d.ts +5 -0
  390. package/dist/undo/tracker.d.ts.map +1 -1
  391. package/dist/undo/tracker.js +13 -0
  392. package/dist/undo/tracker.js.map +1 -1
  393. package/dist/utils/fs.d.ts +1 -1
  394. package/dist/utils/fs.d.ts.map +1 -1
  395. package/dist/utils/fs.js +29 -2
  396. package/dist/utils/fs.js.map +1 -1
  397. package/dist/utils/git-stash.d.ts.map +1 -1
  398. package/dist/utils/git-stash.js +15 -8
  399. package/dist/utils/git-stash.js.map +1 -1
  400. package/dist/utils/json.d.ts +11 -0
  401. package/dist/utils/json.d.ts.map +1 -1
  402. package/dist/utils/json.js +9 -0
  403. package/dist/utils/json.js.map +1 -1
  404. package/dist/utils/shell-env.d.ts.map +1 -1
  405. package/dist/utils/shell-env.js +2 -0
  406. package/dist/utils/shell-env.js.map +1 -1
  407. package/dist/utils/url-extractor-git.d.ts +26 -0
  408. package/dist/utils/url-extractor-git.d.ts.map +1 -0
  409. package/dist/utils/url-extractor-git.js +259 -0
  410. package/dist/utils/url-extractor-git.js.map +1 -0
  411. package/dist/utils/url-extractor.d.ts.map +1 -1
  412. package/dist/utils/url-extractor.js +23 -251
  413. package/dist/utils/url-extractor.js.map +1 -1
  414. package/dist/version.json +2 -2
  415. package/dist/web-server.d.ts.map +1 -1
  416. package/dist/web-server.js +2 -5
  417. package/dist/web-server.js.map +1 -1
  418. package/package.json +310 -306
  419. package/skills/incident-triage/SKILL.md +19 -1
  420. package/skills/install-code-review/SKILL.md +69 -0
  421. package/skills/security-review/SKILL.md +68 -0
  422. package/skills/security-review/reference/rubric.md +85 -0
@@ -0,0 +1,603 @@
1
+ import { existsSync, mkdirSync, readdirSync, rmSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { PATHS } from "../config/constants.js";
4
+ import { defaultRuntimeEnv } from "../runtime/env.js";
5
+ import { readJsonFile, writeJsonFile } from "../utils/fs.js";
6
+ import { MISSION_MANIFEST_VERSION, isMissionFeature, } from "./mission-manifest.js";
7
+ export const MISSION_STORE_SCHEMA = "evalops.maestro.mission-store.v1";
8
+ const MISSION_STATE_LOCK_STALE_MS = 60_000;
9
+ export function getMissionStoreRoot(rootDir) {
10
+ return (rootDir ??
11
+ defaultRuntimeEnv().missionStoreDir ??
12
+ join(PATHS.MAESTRO_HOME, "missions"));
13
+ }
14
+ export function sanitizeMissionId(missionId) {
15
+ const trimmed = normalizeMissionIdInput(missionId);
16
+ if (!trimmed) {
17
+ throw new Error("missionId is required");
18
+ }
19
+ const safe = trimmed
20
+ .replace(/[^A-Za-z0-9._-]+/g, "-")
21
+ .replace(/^-+|-+$/g, "");
22
+ if (!safe || !/[A-Za-z0-9]/u.test(safe)) {
23
+ throw new Error("missionId must include at least one alphanumeric character");
24
+ }
25
+ return safe;
26
+ }
27
+ function normalizeMissionIdInput(missionId) {
28
+ const trimmed = missionId.trim();
29
+ if (!trimmed) {
30
+ throw new Error("missionId is required");
31
+ }
32
+ return trimmed;
33
+ }
34
+ export function getMissionDir(missionId, rootDir) {
35
+ return join(getMissionStoreRoot(rootDir), sanitizeMissionId(missionId));
36
+ }
37
+ export function getMissionStatePath(missionId, rootDir) {
38
+ return join(getMissionDir(missionId, rootDir), "state.json");
39
+ }
40
+ export function createMissionStoreSnapshot(options) {
41
+ const now = options.now ?? new Date().toISOString();
42
+ return {
43
+ schemaVersion: MISSION_STORE_SCHEMA,
44
+ missionId: sanitizeMissionId(options.missionId),
45
+ sourceMissionId: normalizeMissionIdInput(options.missionId),
46
+ title: options.title,
47
+ state: "awaiting-input",
48
+ features: options.manifest?.features ? [...options.manifest.features] : [],
49
+ progressLog: [
50
+ {
51
+ type: "mission_created",
52
+ timestamp: now,
53
+ message: options.title,
54
+ },
55
+ ],
56
+ workerSessionIds: [],
57
+ workerStates: {},
58
+ tokenUsageBySessionId: {},
59
+ createdAt: now,
60
+ updatedAt: now,
61
+ };
62
+ }
63
+ export function sumMissionTokenUsage(usages) {
64
+ const values = Object.values(usages);
65
+ if (values.length === 0)
66
+ return undefined;
67
+ return values.reduce((total, usage) => ({
68
+ inputTokens: total.inputTokens + usage.inputTokens,
69
+ outputTokens: total.outputTokens + usage.outputTokens,
70
+ cacheCreationTokens: (total.cacheCreationTokens ?? 0) + (usage.cacheCreationTokens ?? 0),
71
+ cacheReadTokens: (total.cacheReadTokens ?? 0) + (usage.cacheReadTokens ?? 0),
72
+ thinkingTokens: (total.thinkingTokens ?? 0) + (usage.thinkingTokens ?? 0),
73
+ credits: (total.credits ?? 0) + (usage.credits ?? 0),
74
+ }), { inputTokens: 0, outputTokens: 0 });
75
+ }
76
+ function deriveWorkerState(progressLog, previous) {
77
+ const next = { ...previous };
78
+ for (const entry of progressLog) {
79
+ if (!entry.workerSessionId)
80
+ continue;
81
+ const existing = next[entry.workerSessionId];
82
+ if (!existing) {
83
+ next[entry.workerSessionId] = { startedAt: entry.timestamp };
84
+ }
85
+ if (entry.type === "worker_completed" || entry.type === "worker_failed") {
86
+ next[entry.workerSessionId] = {
87
+ startedAt: next[entry.workerSessionId]?.startedAt ?? entry.timestamp,
88
+ completedAt: entry.timestamp,
89
+ exitCode: entry.exitCode,
90
+ };
91
+ }
92
+ }
93
+ return next;
94
+ }
95
+ function normalizeSnapshot(snapshot) {
96
+ const workerStates = deriveWorkerState(snapshot.progressLog ?? [], snapshot.workerStates ?? {});
97
+ const workerSessionIds = Array.from(new Set([
98
+ ...(snapshot.workerSessionIds ?? []),
99
+ ...Object.keys(workerStates),
100
+ ...(snapshot.features ?? []).flatMap((feature) => feature.handoff?.workerId ? [feature.handoff.workerId] : []),
101
+ ])).sort();
102
+ const tokenUsageBySessionId = snapshot.tokenUsageBySessionId ?? {};
103
+ return {
104
+ ...snapshot,
105
+ schemaVersion: MISSION_STORE_SCHEMA,
106
+ missionId: sanitizeMissionId(snapshot.missionId),
107
+ sourceMissionId: typeof snapshot.sourceMissionId === "string"
108
+ ? snapshot.sourceMissionId
109
+ : undefined,
110
+ features: snapshot.features ?? [],
111
+ progressLog: snapshot.progressLog ?? [],
112
+ workerSessionIds,
113
+ workerStates,
114
+ tokenUsageBySessionId,
115
+ tokenUsage: sumMissionTokenUsage(tokenUsageBySessionId),
116
+ };
117
+ }
118
+ export class MissionStore {
119
+ constructor(snapshot, config = {}) {
120
+ this.stateTouched = false;
121
+ this.snapshot = normalizeSnapshot(snapshot);
122
+ this.lastSavedSnapshot = this.snapshot;
123
+ this.rootDir = config.rootDir;
124
+ this.now = config.now ?? (() => new Date().toISOString());
125
+ }
126
+ static create(options) {
127
+ assertMissionCreateTargetAvailable(options.missionId, options.config?.rootDir);
128
+ return new MissionStore(createMissionStoreSnapshot({
129
+ missionId: options.missionId,
130
+ title: options.title,
131
+ manifest: options.manifest,
132
+ now: options.config?.now?.(),
133
+ }), options.config);
134
+ }
135
+ static load(missionId, config = {}) {
136
+ const path = getMissionStatePath(missionId, config.rootDir);
137
+ if (!existsSync(path)) {
138
+ throw new Error(`mission not found: ${sanitizeMissionId(missionId)}`);
139
+ }
140
+ const requestedId = normalizeMissionIdInput(missionId);
141
+ const snapshot = readJsonFile(path, {
142
+ rotateOnParseFail: true,
143
+ });
144
+ if (snapshot.sourceMissionId?.trim() &&
145
+ snapshot.sourceMissionId.trim() !== requestedId &&
146
+ snapshot.missionId !== requestedId) {
147
+ throw new Error(`missionId "${requestedId}" collides with existing mission "${snapshot.sourceMissionId.trim()}"`);
148
+ }
149
+ return new MissionStore(applyArtifactFeaturesToSnapshot(snapshot, config.rootDir), config);
150
+ }
151
+ getSnapshot() {
152
+ return normalizeSnapshot(this.snapshot);
153
+ }
154
+ save() {
155
+ const snapshot = this.getSnapshot();
156
+ const path = getMissionStatePath(snapshot.missionId, this.rootDir);
157
+ mkdirSync(getMissionDir(snapshot.missionId, this.rootDir), {
158
+ recursive: true,
159
+ });
160
+ return withMissionStateLock(path, () => {
161
+ assertNoMissionIdCollision(path, snapshot);
162
+ const existing = existsSync(path)
163
+ ? normalizeSnapshot(readJsonFile(path))
164
+ : null;
165
+ const merged = existing
166
+ ? mergeSnapshots(this.lastSavedSnapshot, snapshot, applyArtifactFeaturesToSnapshot(existing, this.rootDir), { stateTouched: this.stateTouched })
167
+ : snapshot;
168
+ try {
169
+ writeJsonFile(path, merged);
170
+ writeMissionManifest(merged, this.rootDir);
171
+ }
172
+ catch (error) {
173
+ restoreMissionStateFile(path, existing);
174
+ throw error;
175
+ }
176
+ this.snapshot = merged;
177
+ this.lastSavedSnapshot = merged;
178
+ this.stateTouched = false;
179
+ return merged;
180
+ });
181
+ }
182
+ setState(state, message) {
183
+ if (isTerminalMissionState(this.snapshot.state)) {
184
+ if (this.snapshot.state !== state) {
185
+ throw new Error(`mission ${this.snapshot.missionId} is already ${this.snapshot.state}`);
186
+ }
187
+ return this.getSnapshot();
188
+ }
189
+ const timestamp = this.now();
190
+ const progressType = stateToProgressType(state);
191
+ const previousSnapshot = this.snapshot;
192
+ const previousStateTouched = this.stateTouched;
193
+ this.stateTouched = true;
194
+ this.snapshot = {
195
+ ...this.snapshot,
196
+ state,
197
+ progressLog: progressType === "note" && !message?.trim()
198
+ ? this.snapshot.progressLog
199
+ : [
200
+ ...this.snapshot.progressLog,
201
+ {
202
+ type: progressType,
203
+ timestamp,
204
+ message: message?.trim() || defaultStateProgressMessage(state),
205
+ },
206
+ ],
207
+ updatedAt: timestamp,
208
+ };
209
+ return this.saveOrRestore(previousSnapshot, previousStateTouched);
210
+ }
211
+ setFeatures(features) {
212
+ const previousSnapshot = this.snapshot;
213
+ const previousStateTouched = this.stateTouched;
214
+ this.snapshot = {
215
+ ...this.snapshot,
216
+ features: [...features],
217
+ updatedAt: this.now(),
218
+ };
219
+ return this.saveOrRestore(previousSnapshot, previousStateTouched);
220
+ }
221
+ appendProgress(entry) {
222
+ const timestamp = entry.timestamp ?? this.now();
223
+ const previousSnapshot = this.snapshot;
224
+ const previousStateTouched = this.stateTouched;
225
+ this.snapshot = {
226
+ ...this.snapshot,
227
+ progressLog: [...this.snapshot.progressLog, { ...entry, timestamp }],
228
+ updatedAt: timestamp,
229
+ };
230
+ return this.saveOrRestore(previousSnapshot, previousStateTouched);
231
+ }
232
+ setSessionTokenUsage(sessionId, tokenUsage) {
233
+ const previousSnapshot = this.snapshot;
234
+ const previousStateTouched = this.stateTouched;
235
+ this.snapshot = {
236
+ ...this.snapshot,
237
+ tokenUsageBySessionId: {
238
+ ...this.snapshot.tokenUsageBySessionId,
239
+ [sessionId]: tokenUsage,
240
+ },
241
+ updatedAt: this.now(),
242
+ };
243
+ return this.saveOrRestore(previousSnapshot, previousStateTouched);
244
+ }
245
+ saveOrRestore(previousSnapshot, previousStateTouched) {
246
+ try {
247
+ return this.save();
248
+ }
249
+ catch (error) {
250
+ this.snapshot = previousSnapshot;
251
+ this.stateTouched = previousStateTouched;
252
+ throw error;
253
+ }
254
+ }
255
+ }
256
+ function restoreMissionStateFile(path, previous) {
257
+ if (previous) {
258
+ writeJsonFile(path, previous);
259
+ return;
260
+ }
261
+ rmSync(path, { force: true });
262
+ }
263
+ function defaultStateProgressMessage(state) {
264
+ switch (state) {
265
+ case "running":
266
+ return "Mission started";
267
+ case "blocked":
268
+ return "Mission is blocked";
269
+ case "completed":
270
+ return "Mission completed";
271
+ default:
272
+ return undefined;
273
+ }
274
+ }
275
+ function withMissionStateLock(path, operation) {
276
+ const lockPath = `${path}.lock`;
277
+ const startedAt = Date.now();
278
+ while (true) {
279
+ try {
280
+ mkdirSync(lockPath);
281
+ writeMissionLockOwner(lockPath);
282
+ break;
283
+ }
284
+ catch (error) {
285
+ const code = error.code;
286
+ if (code !== "EEXIST")
287
+ throw error;
288
+ if (recoverStaleMissionStateLock(lockPath))
289
+ continue;
290
+ if (Date.now() - startedAt > 5000) {
291
+ throw new Error(`timed out waiting for mission state lock: ${path}`);
292
+ }
293
+ sleepSync(25);
294
+ }
295
+ }
296
+ try {
297
+ return operation();
298
+ }
299
+ finally {
300
+ rmSync(lockPath, { recursive: true, force: true });
301
+ }
302
+ }
303
+ function writeMissionLockOwner(lockPath) {
304
+ try {
305
+ writeJsonFile(join(lockPath, "owner.json"), {
306
+ pid: process.pid,
307
+ createdAt: new Date().toISOString(),
308
+ });
309
+ }
310
+ catch {
311
+ // Best-effort metadata: lock ownership should not make acquisition fail.
312
+ }
313
+ }
314
+ function recoverStaleMissionStateLock(lockPath) {
315
+ try {
316
+ const stats = statSync(lockPath);
317
+ if (Date.now() - stats.mtimeMs <= MISSION_STATE_LOCK_STALE_MS) {
318
+ return false;
319
+ }
320
+ const owner = readJsonFile(join(lockPath, "owner.json"), { fallback: null });
321
+ if (typeof owner?.pid === "number" && isProcessAlive(owner.pid)) {
322
+ return false;
323
+ }
324
+ rmSync(lockPath, { recursive: true, force: true });
325
+ return true;
326
+ }
327
+ catch {
328
+ return false;
329
+ }
330
+ }
331
+ function isProcessAlive(pid) {
332
+ if (!Number.isInteger(pid) || pid <= 0)
333
+ return false;
334
+ try {
335
+ process.kill(pid, 0);
336
+ return true;
337
+ }
338
+ catch (error) {
339
+ return error.code === "EPERM";
340
+ }
341
+ }
342
+ function sleepSync(ms) {
343
+ const buffer = new SharedArrayBuffer(4);
344
+ Atomics.wait(new Int32Array(buffer), 0, 0, ms);
345
+ }
346
+ function mergeSnapshots(base, intended, existing, options = {}) {
347
+ const state = mergeMissionState(base, intended, existing, options.stateTouched);
348
+ const progressLog = mergeProgressLog(existing.progressLog, base.progressLog, withoutRejectedStateTransitionProgress(base, intended, state, options.stateTouched));
349
+ const tokenUsageBySessionId = { ...existing.tokenUsageBySessionId };
350
+ for (const [sessionId, usage] of Object.entries(intended.tokenUsageBySessionId)) {
351
+ if (!jsonEqual(usage, base.tokenUsageBySessionId[sessionId])) {
352
+ tokenUsageBySessionId[sessionId] = usage;
353
+ }
354
+ }
355
+ return normalizeSnapshot({
356
+ ...existing,
357
+ title: fieldChanged(intended.title, base.title)
358
+ ? intended.title
359
+ : existing.title,
360
+ state,
361
+ features: mergeFeatures(base.features, intended.features, existing.features),
362
+ progressLog,
363
+ tokenUsageBySessionId,
364
+ updatedAt: maxIsoTimestamp(existing.updatedAt, intended.updatedAt),
365
+ });
366
+ }
367
+ function withoutRejectedStateTransitionProgress(base, intended, mergedState, stateTouched = false) {
368
+ const intendedChanged = stateTouched || fieldChanged(intended.state, base.state);
369
+ if (!intendedChanged || mergedState === intended.state) {
370
+ return intended.progressLog;
371
+ }
372
+ const lastEntry = intended.progressLog.at(-1);
373
+ if (!lastEntry)
374
+ return intended.progressLog;
375
+ const baseKeys = new Set(base.progressLog.map(progressEntryKey));
376
+ if (baseKeys.has(progressEntryKey(lastEntry)) ||
377
+ lastEntry.timestamp !== intended.updatedAt ||
378
+ lastEntry.type !== stateToProgressType(intended.state)) {
379
+ return intended.progressLog;
380
+ }
381
+ return intended.progressLog.slice(0, -1);
382
+ }
383
+ function mergeMissionState(base, intended, existing, stateTouched = false) {
384
+ const intendedChanged = stateTouched || fieldChanged(intended.state, base.state);
385
+ if (!intendedChanged) {
386
+ return existing.state;
387
+ }
388
+ if (isTerminalMissionState(existing.state) &&
389
+ existing.state !== intended.state) {
390
+ return existing.state;
391
+ }
392
+ if (!fieldChanged(existing.state, base.state) ||
393
+ jsonEqual(intended.state, existing.state)) {
394
+ return intended.state;
395
+ }
396
+ return existing.state;
397
+ }
398
+ function isTerminalMissionState(state) {
399
+ return state === "completed" || state === "failed";
400
+ }
401
+ function mergeFeatures(base, intended, existing) {
402
+ const baseById = new Map(base.map((feature) => [feature.id, feature]));
403
+ const intendedById = new Map(intended.map((feature) => [feature.id, feature]));
404
+ const existingById = new Map(existing.map((feature) => [feature.id, feature]));
405
+ const orderedIds = Array.from(new Set([
406
+ ...existing.map((feature) => feature.id),
407
+ ...intended.map((feature) => feature.id),
408
+ ]));
409
+ const merged = [];
410
+ for (const featureId of orderedIds) {
411
+ const baseFeature = baseById.get(featureId);
412
+ const intendedFeature = intendedById.get(featureId);
413
+ const existingFeature = existingById.get(featureId);
414
+ const intendedChanged = !jsonEqual(intendedFeature, baseFeature);
415
+ const existingChanged = !jsonEqual(existingFeature, baseFeature);
416
+ if (!intendedChanged) {
417
+ if (existingFeature)
418
+ merged.push(existingFeature);
419
+ continue;
420
+ }
421
+ if (!existingChanged || jsonEqual(intendedFeature, existingFeature)) {
422
+ if (intendedFeature)
423
+ merged.push(intendedFeature);
424
+ continue;
425
+ }
426
+ throw new Error(`mission feature ${featureId} changed concurrently; reload before saving`);
427
+ }
428
+ return merged;
429
+ }
430
+ function mergeProgressLog(existing, base, intended) {
431
+ const baseKeys = new Set(base.map(progressEntryKey));
432
+ const existingKeys = new Set(existing.map(progressEntryKey));
433
+ const next = [...existing];
434
+ for (const entry of intended) {
435
+ const key = progressEntryKey(entry);
436
+ if (baseKeys.has(key) || existingKeys.has(key))
437
+ continue;
438
+ next.push(entry);
439
+ existingKeys.add(key);
440
+ }
441
+ return next.sort((left, right) => left.timestamp.localeCompare(right.timestamp));
442
+ }
443
+ function progressEntryKey(entry) {
444
+ return JSON.stringify(entry);
445
+ }
446
+ function fieldChanged(intended, base) {
447
+ return !jsonEqual(intended, base);
448
+ }
449
+ function jsonEqual(left, right) {
450
+ return JSON.stringify(left) === JSON.stringify(right);
451
+ }
452
+ function maxIsoTimestamp(left, right) {
453
+ return left.localeCompare(right) >= 0 ? left : right;
454
+ }
455
+ function stateToProgressType(state) {
456
+ switch (state) {
457
+ case "running":
458
+ return "mission_started";
459
+ case "blocked":
460
+ return "mission_blocked";
461
+ case "completed":
462
+ return "mission_completed";
463
+ default:
464
+ return "note";
465
+ }
466
+ }
467
+ export function listMissionStoreSnapshots(rootDir) {
468
+ const root = getMissionStoreRoot(rootDir);
469
+ if (!existsSync(root))
470
+ return [];
471
+ return readdirSync(root, { withFileTypes: true })
472
+ .filter((entry) => entry.isDirectory())
473
+ .flatMap((entry) => {
474
+ try {
475
+ const path = join(root, entry.name, "state.json");
476
+ if (!existsSync(path))
477
+ return [];
478
+ const snapshot = readJsonFile(path, {
479
+ fallback: null,
480
+ rotateOnParseFail: true,
481
+ });
482
+ return snapshot
483
+ ? [normalizeSnapshot(applyArtifactFeaturesToSnapshot(snapshot, root))]
484
+ : [];
485
+ }
486
+ catch {
487
+ return [];
488
+ }
489
+ })
490
+ .sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
491
+ }
492
+ function applyArtifactFeaturesToSnapshot(snapshot, rootDir) {
493
+ const featuresPath = join(getMissionDir(snapshot.missionId, rootDir), "features.json");
494
+ if (!existsSync(featuresPath))
495
+ return snapshot;
496
+ const manifest = readJsonFile(featuresPath, {
497
+ fallback: null,
498
+ rotateOnParseFail: true,
499
+ });
500
+ const features = getValidArtifactFeatures(manifest, snapshot);
501
+ return features
502
+ ? {
503
+ ...snapshot,
504
+ features,
505
+ updatedAt: typeof manifest.updatedAt === "string"
506
+ ? manifest.updatedAt
507
+ : snapshot.updatedAt,
508
+ }
509
+ : snapshot;
510
+ }
511
+ function getValidArtifactFeatures(value, snapshot) {
512
+ if (!value || typeof value !== "object")
513
+ return null;
514
+ const record = value;
515
+ if (typeof record.version !== "number")
516
+ return null;
517
+ if (typeof record.missionId !== "string")
518
+ return null;
519
+ let missionId;
520
+ try {
521
+ missionId = sanitizeMissionId(record.missionId);
522
+ }
523
+ catch {
524
+ return null;
525
+ }
526
+ if (missionId !== snapshot.missionId)
527
+ return null;
528
+ if (typeof record.updatedAt !== "string" ||
529
+ Number.isNaN(Date.parse(record.updatedAt)) ||
530
+ Date.parse(record.updatedAt) < Date.parse(snapshot.updatedAt)) {
531
+ return null;
532
+ }
533
+ if (!Array.isArray(record.features))
534
+ return null;
535
+ if (record.features.length === 0 && snapshot.features.length > 0)
536
+ return null;
537
+ const featureIds = new Set();
538
+ for (const feature of record.features) {
539
+ if (!isMissionFeature(feature))
540
+ return null;
541
+ if (featureIds.has(feature.id))
542
+ return null;
543
+ featureIds.add(feature.id);
544
+ }
545
+ return record.features;
546
+ }
547
+ function assertNoMissionIdCollision(path, snapshot) {
548
+ if (!existsSync(path))
549
+ return;
550
+ const existing = readJsonFile(path, {
551
+ fallback: null,
552
+ });
553
+ if (!existing?.sourceMissionId || !snapshot.sourceMissionId)
554
+ return;
555
+ if (existing.sourceMissionId !== snapshot.sourceMissionId) {
556
+ throw new Error(`missionId collision: ${snapshot.sourceMissionId} maps to existing mission ${existing.sourceMissionId}`);
557
+ }
558
+ }
559
+ function assertMissionCreateTargetAvailable(missionId, rootDir) {
560
+ const statePath = getMissionStatePath(missionId, rootDir);
561
+ if (existsSync(statePath)) {
562
+ const snapshot = readJsonFile(statePath, {
563
+ rotateOnParseFail: true,
564
+ });
565
+ const requestedId = normalizeMissionIdInput(missionId);
566
+ if (snapshot.sourceMissionId?.trim() &&
567
+ snapshot.sourceMissionId.trim() !== requestedId) {
568
+ throw new Error(`missionId "${requestedId}" collides with existing mission "${snapshot.sourceMissionId.trim()}"`);
569
+ }
570
+ throw new Error(`mission already exists: ${sanitizeMissionId(missionId)}`);
571
+ }
572
+ const missionDir = getMissionDir(missionId, rootDir);
573
+ if (existsSync(missionDir) && readdirSync(missionDir).length > 0) {
574
+ throw new Error(`mission already exists without durable state: ${sanitizeMissionId(missionId)}`);
575
+ }
576
+ }
577
+ function writeMissionManifest(snapshot, rootDir) {
578
+ const path = join(getMissionDir(snapshot.missionId, rootDir), "features.json");
579
+ const existing = readJsonFile(path, {
580
+ fallback: null,
581
+ rotateOnParseFail: true,
582
+ });
583
+ if (isNewerMissionManifest(existing, snapshot))
584
+ return;
585
+ writeJsonFile(path, {
586
+ version: typeof existing?.version === "number"
587
+ ? existing.version
588
+ : MISSION_MANIFEST_VERSION,
589
+ missionId: snapshot.missionId,
590
+ milestones: Array.isArray(existing?.milestones) ? existing.milestones : [],
591
+ features: snapshot.features,
592
+ createdAt: typeof existing?.createdAt === "string"
593
+ ? existing.createdAt
594
+ : snapshot.createdAt,
595
+ updatedAt: snapshot.updatedAt,
596
+ });
597
+ }
598
+ function isNewerMissionManifest(manifest, snapshot) {
599
+ return Boolean(getValidArtifactFeatures(manifest, snapshot) &&
600
+ typeof manifest?.updatedAt === "string" &&
601
+ Date.parse(manifest.updatedAt) > Date.parse(snapshot.updatedAt));
602
+ }
603
+ //# sourceMappingURL=mission-store.js.map