smol-symphony 0.2.0 → 0.3.0

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 (716) hide show
  1. package/AGENTS.md +41 -22
  2. package/DESIGN.md +494 -273
  3. package/README.md +109 -57
  4. package/SPEC.md +33 -24
  5. package/WORKFLOW.minimal.yaml +34 -0
  6. package/{WORKFLOW.template.md → WORKFLOW.template.yaml} +409 -256
  7. package/WORKFLOW.yaml +487 -0
  8. package/assets/skills/symphony-issues/SKILL.md +136 -0
  9. package/assets/symphony-mise.system.toml +68 -0
  10. package/dist/src/bin/symphony.js +30 -0
  11. package/dist/src/bin/symphony.js.map +1 -0
  12. package/dist/src/core/actions/context.js +109 -0
  13. package/dist/src/core/actions/context.js.map +1 -0
  14. package/dist/{actions/parsing.js → src/core/actions/parse.js} +33 -114
  15. package/dist/src/core/actions/parse.js.map +1 -0
  16. package/dist/src/core/actions/plan.js +197 -0
  17. package/dist/src/core/actions/plan.js.map +1 -0
  18. package/dist/src/core/actions/predicates.js +111 -0
  19. package/dist/src/core/actions/predicates.js.map +1 -0
  20. package/dist/src/core/actions/run-fold.js +248 -0
  21. package/dist/src/core/actions/run-fold.js.map +1 -0
  22. package/dist/src/core/actions/template.js +118 -0
  23. package/dist/src/core/actions/template.js.map +1 -0
  24. package/dist/src/core/cli/args.js +116 -0
  25. package/dist/src/core/cli/args.js.map +1 -0
  26. package/dist/src/core/coerce.js +75 -0
  27. package/dist/src/core/coerce.js.map +1 -0
  28. package/dist/src/core/credential/account-id.js +20 -0
  29. package/dist/src/core/credential/account-id.js.map +1 -0
  30. package/dist/src/core/credential/adapter-config.js +136 -0
  31. package/dist/src/core/credential/adapter-config.js.map +1 -0
  32. package/dist/src/core/credential/availability.js +98 -0
  33. package/dist/src/core/credential/availability.js.map +1 -0
  34. package/dist/src/core/credential/extract.js +228 -0
  35. package/dist/src/core/credential/extract.js.map +1 -0
  36. package/dist/src/core/credential/fake-creds.js +171 -0
  37. package/dist/src/core/credential/fake-creds.js.map +1 -0
  38. package/dist/src/core/credential/identity.js +125 -0
  39. package/dist/src/core/credential/identity.js.map +1 -0
  40. package/dist/src/core/credential/shape.js +230 -0
  41. package/dist/src/core/credential/shape.js.map +1 -0
  42. package/dist/src/core/credential/strings.js +15 -0
  43. package/dist/src/core/credential/strings.js.map +1 -0
  44. package/dist/src/core/doctor/checks.js +303 -0
  45. package/dist/src/core/doctor/checks.js.map +1 -0
  46. package/dist/src/core/git/result.js +107 -0
  47. package/dist/src/core/git/result.js.map +1 -0
  48. package/dist/src/core/http/decisions.js +225 -0
  49. package/dist/src/core/http/decisions.js.map +1 -0
  50. package/dist/{http.js → src/core/http/render.js} +472 -738
  51. package/dist/src/core/http/render.js.map +1 -0
  52. package/dist/{http-handlers.js → src/core/http/routes.js} +52 -87
  53. package/dist/src/core/http/routes.js.map +1 -0
  54. package/dist/src/core/http/views.js +181 -0
  55. package/dist/src/core/http/views.js.map +1 -0
  56. package/dist/src/core/image/managed-image.js +95 -0
  57. package/dist/src/core/image/managed-image.js.map +1 -0
  58. package/dist/src/core/issue/file.js +149 -0
  59. package/dist/src/core/issue/file.js.map +1 -0
  60. package/dist/src/core/issue/parse.js +210 -0
  61. package/dist/src/core/issue/parse.js.map +1 -0
  62. package/dist/src/core/mcp/dispatch.js +239 -0
  63. package/dist/src/core/mcp/dispatch.js.map +1 -0
  64. package/dist/src/core/mcp/post-move.js +92 -0
  65. package/dist/src/core/mcp/post-move.js.map +1 -0
  66. package/dist/src/core/mcp/protocol.js +293 -0
  67. package/dist/src/core/mcp/protocol.js.map +1 -0
  68. package/dist/src/core/mcp/url.js +162 -0
  69. package/dist/src/core/mcp/url.js.map +1 -0
  70. package/dist/src/core/path.js +63 -0
  71. package/dist/src/core/path.js.map +1 -0
  72. package/dist/src/core/reconcile/image-decide.js +48 -0
  73. package/dist/src/core/reconcile/image-decide.js.map +1 -0
  74. package/dist/src/core/reconcile/ledger.js +142 -0
  75. package/dist/src/core/reconcile/ledger.js.map +1 -0
  76. package/dist/src/core/reconcile/pr-classify.js +62 -0
  77. package/dist/src/core/reconcile/pr-classify.js.map +1 -0
  78. package/dist/{reconciler → src/core/reconcile}/pr-decide.js +25 -12
  79. package/dist/src/core/reconcile/pr-decide.js.map +1 -0
  80. package/dist/src/core/reconcile/pr-loop.js +161 -0
  81. package/dist/src/core/reconcile/pr-loop.js.map +1 -0
  82. package/dist/src/core/reconcile/pr-notes.js +35 -0
  83. package/dist/src/core/reconcile/pr-notes.js.map +1 -0
  84. package/dist/src/core/reconcile/vm-decide.js +70 -0
  85. package/dist/src/core/reconcile/vm-decide.js.map +1 -0
  86. package/dist/src/core/reconcile/vm-reap.js +207 -0
  87. package/dist/src/core/reconcile/vm-reap.js.map +1 -0
  88. package/dist/src/core/reconcile/workspace-decide.js +162 -0
  89. package/dist/src/core/reconcile/workspace-decide.js.map +1 -0
  90. package/dist/src/core/runlog/summary.js +231 -0
  91. package/dist/src/core/runlog/summary.js.map +1 -0
  92. package/dist/src/core/runner/dispatch-config.js +95 -0
  93. package/dist/src/core/runner/dispatch-config.js.map +1 -0
  94. package/dist/src/core/runner/injection.js +61 -0
  95. package/dist/src/core/runner/injection.js.map +1 -0
  96. package/dist/src/core/runner/mise.js +210 -0
  97. package/dist/src/core/runner/mise.js.map +1 -0
  98. package/dist/src/core/runner/prompt.js +720 -0
  99. package/dist/src/core/runner/prompt.js.map +1 -0
  100. package/dist/src/core/runner/turn.js +242 -0
  101. package/dist/src/core/runner/turn.js.map +1 -0
  102. package/dist/src/core/runner/vm-plan.js +390 -0
  103. package/dist/src/core/runner/vm-plan.js.map +1 -0
  104. package/dist/src/core/schedule/admission.js +123 -0
  105. package/dist/src/core/schedule/admission.js.map +1 -0
  106. package/dist/src/core/schedule/circuit-breaker.js +111 -0
  107. package/dist/src/core/schedule/circuit-breaker.js.map +1 -0
  108. package/dist/src/core/schedule/eligibility.js +83 -0
  109. package/dist/src/core/schedule/eligibility.js.map +1 -0
  110. package/dist/src/core/schedule/reconcile-issue.js +82 -0
  111. package/dist/src/core/schedule/reconcile-issue.js.map +1 -0
  112. package/dist/src/core/schedule/retry.js +96 -0
  113. package/dist/src/core/schedule/retry.js.map +1 -0
  114. package/dist/src/core/schedule/sleep-cycle.js +133 -0
  115. package/dist/src/core/schedule/sleep-cycle.js.map +1 -0
  116. package/dist/src/core/schedule/slots.js +124 -0
  117. package/dist/src/core/schedule/slots.js.map +1 -0
  118. package/dist/src/core/schedule/tick.js +553 -0
  119. package/dist/src/core/schedule/tick.js.map +1 -0
  120. package/dist/src/core/schedule/token-fold.js +181 -0
  121. package/dist/src/core/schedule/token-fold.js.map +1 -0
  122. package/dist/src/core/state-resolve.js +86 -0
  123. package/dist/src/core/state-resolve.js.map +1 -0
  124. package/dist/src/core/vm-guards.js +278 -0
  125. package/dist/src/core/vm-guards.js.map +1 -0
  126. package/dist/src/core/workflow/derive.js +107 -0
  127. package/dist/src/core/workflow/derive.js.map +1 -0
  128. package/dist/src/core/workflow/parse.js +687 -0
  129. package/dist/src/core/workflow/parse.js.map +1 -0
  130. package/dist/src/core/workflow/prompt-probe.js +78 -0
  131. package/dist/src/core/workflow/prompt-probe.js.map +1 -0
  132. package/dist/src/core/workflow/validate.js +189 -0
  133. package/dist/src/core/workflow/validate.js.map +1 -0
  134. package/dist/src/core/workspace-key.js +19 -0
  135. package/dist/src/core/workspace-key.js.map +1 -0
  136. package/dist/src/shell/actions-runner.js +356 -0
  137. package/dist/src/shell/actions-runner.js.map +1 -0
  138. package/dist/src/shell/adapter/adapter-registry.js +45 -0
  139. package/dist/src/shell/adapter/adapter-registry.js.map +1 -0
  140. package/dist/src/shell/adapter/clock-random.js +96 -0
  141. package/dist/src/shell/adapter/clock-random.js.map +1 -0
  142. package/dist/src/shell/adapter/gondolin-dispatch-helpers.js +158 -0
  143. package/dist/src/shell/adapter/gondolin-dispatch-helpers.js.map +1 -0
  144. package/dist/src/shell/adapter/gondolin-dispatch.js +385 -0
  145. package/dist/src/shell/adapter/gondolin-dispatch.js.map +1 -0
  146. package/dist/src/shell/adapter/gondolin-image-converter.js +233 -0
  147. package/dist/src/shell/adapter/gondolin-image-converter.js.map +1 -0
  148. package/dist/src/shell/adapter/gondolin-image-fetch.js +180 -0
  149. package/dist/src/shell/adapter/gondolin-image-fetch.js.map +1 -0
  150. package/dist/src/shell/adapter/launcher-asset.js +57 -0
  151. package/dist/src/shell/adapter/launcher-asset.js.map +1 -0
  152. package/dist/src/shell/adapter/mise-config-asset.js +65 -0
  153. package/dist/src/shell/adapter/mise-config-asset.js.map +1 -0
  154. package/dist/src/shell/adapter/workflow-loader.js +304 -0
  155. package/dist/src/shell/adapter/workflow-loader.js.map +1 -0
  156. package/dist/src/shell/cli/doctor.js +268 -0
  157. package/dist/src/shell/cli/doctor.js.map +1 -0
  158. package/dist/src/shell/effect-interpreter-families.js +314 -0
  159. package/dist/src/shell/effect-interpreter-families.js.map +1 -0
  160. package/dist/src/shell/effect-interpreter.js +29 -0
  161. package/dist/src/shell/effect-interpreter.js.map +1 -0
  162. package/dist/src/shell/interp/acp-frame.js +137 -0
  163. package/dist/src/shell/interp/acp-frame.js.map +1 -0
  164. package/dist/src/shell/interp/acp-ws-conn.js +320 -0
  165. package/dist/src/shell/interp/acp-ws-conn.js.map +1 -0
  166. package/dist/src/shell/interp/acp-ws-frames.js +159 -0
  167. package/dist/src/shell/interp/acp-ws-frames.js.map +1 -0
  168. package/dist/src/shell/interp/acp-ws.js +197 -0
  169. package/dist/src/shell/interp/acp-ws.js.map +1 -0
  170. package/dist/src/shell/interp/acp.js +319 -0
  171. package/dist/src/shell/interp/acp.js.map +1 -0
  172. package/dist/src/shell/interp/credential-defaults.js +128 -0
  173. package/dist/src/shell/interp/credential-defaults.js.map +1 -0
  174. package/dist/src/shell/interp/credential-hooks.js +149 -0
  175. package/dist/src/shell/interp/credential-hooks.js.map +1 -0
  176. package/dist/src/shell/interp/credential-registry.js +226 -0
  177. package/dist/src/shell/interp/credential-registry.js.map +1 -0
  178. package/dist/src/shell/interp/credential.js +103 -0
  179. package/dist/src/shell/interp/credential.js.map +1 -0
  180. package/dist/src/shell/interp/gh.js +163 -0
  181. package/dist/src/shell/interp/gh.js.map +1 -0
  182. package/dist/src/shell/interp/git.js +28 -0
  183. package/dist/src/shell/interp/git.js.map +1 -0
  184. package/dist/src/shell/interp/log.js +213 -0
  185. package/dist/src/shell/interp/log.js.map +1 -0
  186. package/dist/src/shell/interp/process.js +178 -0
  187. package/dist/src/shell/interp/process.js.map +1 -0
  188. package/dist/src/shell/interp/runlog.js +193 -0
  189. package/dist/src/shell/interp/runlog.js.map +1 -0
  190. package/dist/src/shell/interp/timer.js +64 -0
  191. package/dist/src/shell/interp/timer.js.map +1 -0
  192. package/dist/src/shell/interp/tracker-disk.js +99 -0
  193. package/dist/src/shell/interp/tracker-disk.js.map +1 -0
  194. package/dist/src/shell/interp/tracker-parse.js +71 -0
  195. package/dist/src/shell/interp/tracker-parse.js.map +1 -0
  196. package/dist/src/shell/interp/tracker-scan.js +238 -0
  197. package/dist/src/shell/interp/tracker-scan.js.map +1 -0
  198. package/dist/src/shell/interp/tracker-write.js +91 -0
  199. package/dist/src/shell/interp/tracker-write.js.map +1 -0
  200. package/dist/src/shell/interp/tracker.js +41 -0
  201. package/dist/src/shell/interp/tracker.js.map +1 -0
  202. package/dist/src/shell/interp/tty.js +48 -0
  203. package/dist/src/shell/interp/tty.js.map +1 -0
  204. package/dist/src/shell/interp/vm.js +199 -0
  205. package/dist/src/shell/interp/vm.js.map +1 -0
  206. package/dist/src/shell/interp/workspace.js +310 -0
  207. package/dist/src/shell/interp/workspace.js.map +1 -0
  208. package/dist/src/shell/main-acp.js +78 -0
  209. package/dist/src/shell/main-acp.js.map +1 -0
  210. package/dist/src/shell/main-adapters.js +222 -0
  211. package/dist/src/shell/main-adapters.js.map +1 -0
  212. package/dist/src/shell/main-credential.js +122 -0
  213. package/dist/src/shell/main-credential.js.map +1 -0
  214. package/dist/src/shell/main-doctor.js +22 -0
  215. package/dist/src/shell/main-doctor.js.map +1 -0
  216. package/dist/src/shell/main-entry.js +46 -0
  217. package/dist/src/shell/main-entry.js.map +1 -0
  218. package/dist/src/shell/main-http-csrf.js +45 -0
  219. package/dist/src/shell/main-http-csrf.js.map +1 -0
  220. package/dist/src/shell/main-http-handler.js +389 -0
  221. package/dist/src/shell/main-http-handler.js.map +1 -0
  222. package/dist/src/shell/main-http-mcp.js +122 -0
  223. package/dist/src/shell/main-http-mcp.js.map +1 -0
  224. package/dist/src/shell/main-http-views.js +253 -0
  225. package/dist/src/shell/main-http-views.js.map +1 -0
  226. package/dist/src/shell/main-http.js +76 -0
  227. package/dist/src/shell/main-http.js.map +1 -0
  228. package/dist/src/shell/main-loops.js +130 -0
  229. package/dist/src/shell/main-loops.js.map +1 -0
  230. package/dist/src/shell/main-mcp.js +129 -0
  231. package/dist/src/shell/main-mcp.js.map +1 -0
  232. package/dist/src/shell/main-orchestrator.js +120 -0
  233. package/dist/src/shell/main-orchestrator.js.map +1 -0
  234. package/dist/src/shell/main-preflight.js +43 -0
  235. package/dist/src/shell/main-preflight.js.map +1 -0
  236. package/dist/src/shell/main-reconcilers-helpers.js +244 -0
  237. package/dist/src/shell/main-reconcilers-helpers.js.map +1 -0
  238. package/dist/src/shell/main-reconcilers-pr.js +148 -0
  239. package/dist/src/shell/main-reconcilers-pr.js.map +1 -0
  240. package/dist/src/shell/main-reconcilers.js +225 -0
  241. package/dist/src/shell/main-reconcilers.js.map +1 -0
  242. package/dist/src/shell/main-runner.js +355 -0
  243. package/dist/src/shell/main-runner.js.map +1 -0
  244. package/dist/src/shell/main-scaffold.js +116 -0
  245. package/dist/src/shell/main-scaffold.js.map +1 -0
  246. package/dist/src/shell/main-shutdown.js +115 -0
  247. package/dist/src/shell/main-shutdown.js.map +1 -0
  248. package/dist/src/shell/main-startup.js +48 -0
  249. package/dist/src/shell/main-startup.js.map +1 -0
  250. package/dist/src/shell/main-substrates.js +43 -0
  251. package/dist/src/shell/main-substrates.js.map +1 -0
  252. package/dist/src/shell/main.js +385 -0
  253. package/dist/src/shell/main.js.map +1 -0
  254. package/dist/src/shell/orchestrator-feedback.js +69 -0
  255. package/dist/src/shell/orchestrator-feedback.js.map +1 -0
  256. package/dist/src/shell/orchestrator-image.js +167 -0
  257. package/dist/src/shell/orchestrator-image.js.map +1 -0
  258. package/dist/src/shell/orchestrator-loop.js +468 -0
  259. package/dist/src/shell/orchestrator-loop.js.map +1 -0
  260. package/dist/src/shell/orchestrator-reconcile.js +36 -0
  261. package/dist/src/shell/orchestrator-reconcile.js.map +1 -0
  262. package/dist/src/shell/reconciler-loop.js +228 -0
  263. package/dist/src/shell/reconciler-loop.js.map +1 -0
  264. package/dist/src/shell/runner-loop-turn.js +301 -0
  265. package/dist/src/shell/runner-loop-turn.js.map +1 -0
  266. package/dist/src/shell/runner-loop.js +338 -0
  267. package/dist/src/shell/runner-loop.js.map +1 -0
  268. package/dist/src/shell/server/http.js +208 -0
  269. package/dist/src/shell/server/http.js.map +1 -0
  270. package/dist/src/shell/server/mcp-runtime-effects.js +237 -0
  271. package/dist/src/shell/server/mcp-runtime-effects.js.map +1 -0
  272. package/dist/src/shell/server/mcp-runtime.js +99 -0
  273. package/dist/src/shell/server/mcp-runtime.js.map +1 -0
  274. package/dist/src/shell/workspace-key.js +14 -0
  275. package/dist/src/shell/workspace-key.js.map +1 -0
  276. package/dist/src/types/acp.js +8 -0
  277. package/dist/src/types/acp.js.map +1 -0
  278. package/dist/src/types/actions/plan.js +6 -0
  279. package/dist/src/types/actions/plan.js.map +1 -0
  280. package/dist/src/types/actions/predicates.js +6 -0
  281. package/dist/src/types/actions/predicates.js.map +1 -0
  282. package/dist/src/types/actions/run-fold.js +8 -0
  283. package/dist/src/types/actions/run-fold.js.map +1 -0
  284. package/dist/src/types/actions.js +7 -0
  285. package/dist/src/types/actions.js.map +1 -0
  286. package/dist/src/types/adapter/clock-random.js +4 -0
  287. package/dist/src/types/adapter/clock-random.js.map +1 -0
  288. package/dist/src/types/adapter/gondolin-image-converter.js +5 -0
  289. package/dist/src/types/adapter/gondolin-image-converter.js.map +1 -0
  290. package/dist/src/types/adapter/gondolin-image-fetch.js +5 -0
  291. package/dist/src/types/adapter/gondolin-image-fetch.js.map +1 -0
  292. package/dist/src/types/adapter/workflow-loader.js +4 -0
  293. package/dist/src/types/adapter/workflow-loader.js.map +1 -0
  294. package/dist/src/types/cli/args.js +8 -0
  295. package/dist/src/types/cli/args.js.map +1 -0
  296. package/dist/src/types/config.js +8 -0
  297. package/dist/src/types/config.js.map +1 -0
  298. package/dist/src/types/credential-interp.js +6 -0
  299. package/dist/src/types/credential-interp.js.map +1 -0
  300. package/dist/src/types/credentials.js +10 -0
  301. package/dist/src/types/credentials.js.map +1 -0
  302. package/dist/src/types/doctor.js +7 -0
  303. package/dist/src/types/doctor.js.map +1 -0
  304. package/dist/src/types/domain.js +7 -0
  305. package/dist/src/types/domain.js.map +1 -0
  306. package/dist/src/types/effect.js +15 -0
  307. package/dist/src/types/effect.js.map +1 -0
  308. package/dist/src/types/errors.js +39 -0
  309. package/dist/src/types/errors.js.map +1 -0
  310. package/dist/src/types/http/decisions.js +6 -0
  311. package/dist/src/types/http/decisions.js.map +1 -0
  312. package/dist/src/types/http/render.js +10 -0
  313. package/dist/src/types/http/render.js.map +1 -0
  314. package/dist/src/types/http/views.js +6 -0
  315. package/dist/src/types/http/views.js.map +1 -0
  316. package/dist/src/types/http.js +9 -0
  317. package/dist/src/types/http.js.map +1 -0
  318. package/dist/src/types/image/managed-image.js +7 -0
  319. package/dist/src/types/image/managed-image.js.map +1 -0
  320. package/dist/src/types/interp/effect-interpreter.js +8 -0
  321. package/dist/src/types/interp/effect-interpreter.js.map +1 -0
  322. package/dist/src/types/interp/tracker.js +7 -0
  323. package/dist/src/types/interp/tracker.js.map +1 -0
  324. package/dist/src/types/issue/file.js +6 -0
  325. package/dist/src/types/issue/file.js.map +1 -0
  326. package/dist/src/types/issue/parse.js +8 -0
  327. package/dist/src/types/issue/parse.js.map +1 -0
  328. package/dist/src/types/main-acp.js +13 -0
  329. package/dist/src/types/main-acp.js.map +1 -0
  330. package/dist/src/types/main-adapters.js +5 -0
  331. package/dist/src/types/main-adapters.js.map +1 -0
  332. package/dist/src/types/main-credential.js +21 -0
  333. package/dist/src/types/main-credential.js.map +1 -0
  334. package/dist/src/types/main-doctor.js +6 -0
  335. package/dist/src/types/main-doctor.js.map +1 -0
  336. package/dist/src/types/main-http-handler.js +12 -0
  337. package/dist/src/types/main-http-handler.js.map +1 -0
  338. package/dist/src/types/main-http.js +5 -0
  339. package/dist/src/types/main-http.js.map +1 -0
  340. package/dist/src/types/main-loops.js +5 -0
  341. package/dist/src/types/main-loops.js.map +1 -0
  342. package/dist/src/types/main-mcp.js +12 -0
  343. package/dist/src/types/main-mcp.js.map +1 -0
  344. package/dist/src/types/main-orchestrator.js +5 -0
  345. package/dist/src/types/main-orchestrator.js.map +1 -0
  346. package/dist/src/types/main-reconcilers.js +11 -0
  347. package/dist/src/types/main-reconcilers.js.map +1 -0
  348. package/dist/src/types/main-runner.js +13 -0
  349. package/dist/src/types/main-runner.js.map +1 -0
  350. package/dist/src/types/main-startup.js +5 -0
  351. package/dist/src/types/main-startup.js.map +1 -0
  352. package/dist/src/types/main-substrates.js +5 -0
  353. package/dist/src/types/main-substrates.js.map +1 -0
  354. package/dist/src/types/mcp/dispatch.js +4 -0
  355. package/dist/src/types/mcp/dispatch.js.map +1 -0
  356. package/dist/src/types/mcp/post-move.js +7 -0
  357. package/dist/src/types/mcp/post-move.js.map +1 -0
  358. package/dist/src/types/mcp.js +9 -0
  359. package/dist/src/types/mcp.js.map +1 -0
  360. package/dist/src/types/ports.js +12 -0
  361. package/dist/src/types/ports.js.map +1 -0
  362. package/dist/src/types/reconcile/image-decide.js +5 -0
  363. package/dist/src/types/reconcile/image-decide.js.map +1 -0
  364. package/dist/src/types/reconcile/ledger.js +7 -0
  365. package/dist/src/types/reconcile/ledger.js.map +1 -0
  366. package/dist/src/types/reconcile/pr-loop.js +8 -0
  367. package/dist/src/types/reconcile/pr-loop.js.map +1 -0
  368. package/dist/src/types/reconcile/vm-reap.js +8 -0
  369. package/dist/src/types/reconcile/vm-reap.js.map +1 -0
  370. package/dist/src/types/reconcile/workspace-decide.js +7 -0
  371. package/dist/src/types/reconcile/workspace-decide.js.map +1 -0
  372. package/dist/src/types/reconcile.js +9 -0
  373. package/dist/src/types/reconcile.js.map +1 -0
  374. package/dist/src/types/runlog.js +7 -0
  375. package/dist/src/types/runlog.js.map +1 -0
  376. package/dist/src/types/runner/actions-runner.js +12 -0
  377. package/dist/src/types/runner/actions-runner.js.map +1 -0
  378. package/dist/src/types/runner/gondolin-dispatch.js +5 -0
  379. package/dist/src/types/runner/gondolin-dispatch.js.map +1 -0
  380. package/dist/src/types/runner/injection.js +6 -0
  381. package/dist/src/types/runner/injection.js.map +1 -0
  382. package/dist/src/types/runner/runner-loop.js +5 -0
  383. package/dist/src/types/runner/runner-loop.js.map +1 -0
  384. package/dist/src/types/runner/turn.js +4 -0
  385. package/dist/src/types/runner/turn.js.map +1 -0
  386. package/dist/src/types/runner/vm-plan.js +4 -0
  387. package/dist/src/types/runner/vm-plan.js.map +1 -0
  388. package/dist/src/types/runtime.js +9 -0
  389. package/dist/src/types/runtime.js.map +1 -0
  390. package/dist/src/types/schedule/admission.js +7 -0
  391. package/dist/src/types/schedule/admission.js.map +1 -0
  392. package/dist/src/types/schedule/circuit-breaker.js +2 -0
  393. package/dist/src/types/schedule/circuit-breaker.js.map +1 -0
  394. package/dist/src/types/schedule/eligibility.js +9 -0
  395. package/dist/src/types/schedule/eligibility.js.map +1 -0
  396. package/dist/src/types/schedule/orchestrator-loop.js +10 -0
  397. package/dist/src/types/schedule/orchestrator-loop.js.map +1 -0
  398. package/dist/src/types/schedule/sleep-cycle.js +4 -0
  399. package/dist/src/types/schedule/sleep-cycle.js.map +1 -0
  400. package/dist/src/types/schedule/slots.js +8 -0
  401. package/dist/src/types/schedule/slots.js.map +1 -0
  402. package/dist/src/types/schedule/tick.js +9 -0
  403. package/dist/src/types/schedule/tick.js.map +1 -0
  404. package/dist/src/types/server/mcp-runtime.js +8 -0
  405. package/dist/src/types/server/mcp-runtime.js.map +1 -0
  406. package/dist/src/types/workflow/parse.js +4 -0
  407. package/dist/src/types/workflow/parse.js.map +1 -0
  408. package/dist/tests/core/account-id.test.js +35 -0
  409. package/dist/tests/core/account-id.test.js.map +1 -0
  410. package/dist/tests/core/actions-parse.test.js +176 -0
  411. package/dist/tests/core/actions-parse.test.js.map +1 -0
  412. package/dist/tests/core/adapter-config.test.js +133 -0
  413. package/dist/tests/core/adapter-config.test.js.map +1 -0
  414. package/dist/tests/core/admission.test.js +215 -0
  415. package/dist/tests/core/admission.test.js.map +1 -0
  416. package/dist/tests/core/args.test.js +132 -0
  417. package/dist/tests/core/args.test.js.map +1 -0
  418. package/dist/tests/core/availability.test.js +62 -0
  419. package/dist/tests/core/availability.test.js.map +1 -0
  420. package/dist/tests/core/checks.test.js +395 -0
  421. package/dist/tests/core/checks.test.js.map +1 -0
  422. package/dist/tests/core/circuit-breaker.test.js +172 -0
  423. package/dist/tests/core/circuit-breaker.test.js.map +1 -0
  424. package/dist/tests/core/coerce.test.js +87 -0
  425. package/dist/tests/core/coerce.test.js.map +1 -0
  426. package/dist/tests/core/context.test.js +228 -0
  427. package/dist/tests/core/context.test.js.map +1 -0
  428. package/dist/tests/core/decisions.test.js +310 -0
  429. package/dist/tests/core/decisions.test.js.map +1 -0
  430. package/dist/tests/core/derive.test.js +205 -0
  431. package/dist/tests/core/derive.test.js.map +1 -0
  432. package/dist/tests/core/dispatch-config.test.js +164 -0
  433. package/dist/tests/core/dispatch-config.test.js.map +1 -0
  434. package/dist/tests/core/dispatch.test.js +302 -0
  435. package/dist/tests/core/dispatch.test.js.map +1 -0
  436. package/dist/tests/core/eligibility.test.js +163 -0
  437. package/dist/tests/core/eligibility.test.js.map +1 -0
  438. package/dist/tests/core/extract.test.js +139 -0
  439. package/dist/tests/core/extract.test.js.map +1 -0
  440. package/dist/tests/core/fake-creds.test.js +134 -0
  441. package/dist/tests/core/fake-creds.test.js.map +1 -0
  442. package/dist/tests/core/file.test.js +197 -0
  443. package/dist/tests/core/file.test.js.map +1 -0
  444. package/dist/tests/core/git-result.test.js +113 -0
  445. package/dist/tests/core/git-result.test.js.map +1 -0
  446. package/dist/tests/core/identity.test.js +180 -0
  447. package/dist/tests/core/identity.test.js.map +1 -0
  448. package/dist/tests/core/image-decide.test.js +59 -0
  449. package/dist/tests/core/image-decide.test.js.map +1 -0
  450. package/dist/tests/core/injection.test.js +163 -0
  451. package/dist/tests/core/injection.test.js.map +1 -0
  452. package/dist/tests/core/ledger.test.js +218 -0
  453. package/dist/tests/core/ledger.test.js.map +1 -0
  454. package/dist/tests/core/managed-image.test.js +68 -0
  455. package/dist/tests/core/managed-image.test.js.map +1 -0
  456. package/dist/tests/core/mise.test.js +138 -0
  457. package/dist/tests/core/mise.test.js.map +1 -0
  458. package/dist/tests/core/parse.test.js +174 -0
  459. package/dist/tests/core/parse.test.js.map +1 -0
  460. package/dist/tests/core/path.test.js +50 -0
  461. package/dist/tests/core/path.test.js.map +1 -0
  462. package/dist/tests/core/plan.test.js +218 -0
  463. package/dist/tests/core/plan.test.js.map +1 -0
  464. package/dist/tests/core/post-move.test.js +162 -0
  465. package/dist/tests/core/post-move.test.js.map +1 -0
  466. package/dist/tests/core/pr-classify.test.js +117 -0
  467. package/dist/tests/core/pr-classify.test.js.map +1 -0
  468. package/dist/tests/core/pr-decide.test.js +298 -0
  469. package/dist/tests/core/pr-decide.test.js.map +1 -0
  470. package/dist/tests/core/pr-loop.test.js +301 -0
  471. package/dist/tests/core/pr-loop.test.js.map +1 -0
  472. package/dist/tests/core/pr-notes.test.js +165 -0
  473. package/dist/tests/core/pr-notes.test.js.map +1 -0
  474. package/dist/tests/core/predicates.test.js +154 -0
  475. package/dist/tests/core/predicates.test.js.map +1 -0
  476. package/dist/tests/core/prompt.test.js +189 -0
  477. package/dist/tests/core/prompt.test.js.map +1 -0
  478. package/dist/tests/core/protocol.test.js +195 -0
  479. package/dist/tests/core/protocol.test.js.map +1 -0
  480. package/dist/tests/core/reconcile-issue.test.js +116 -0
  481. package/dist/tests/core/reconcile-issue.test.js.map +1 -0
  482. package/dist/tests/core/render.test.js +549 -0
  483. package/dist/tests/core/render.test.js.map +1 -0
  484. package/dist/tests/core/retry.test.js +186 -0
  485. package/dist/tests/core/retry.test.js.map +1 -0
  486. package/dist/tests/core/routes.test.js +247 -0
  487. package/dist/tests/core/routes.test.js.map +1 -0
  488. package/dist/tests/core/run-fold.test.js +299 -0
  489. package/dist/tests/core/run-fold.test.js.map +1 -0
  490. package/dist/tests/core/shape.test.js +185 -0
  491. package/dist/tests/core/shape.test.js.map +1 -0
  492. package/dist/tests/core/sleep-cycle.test.js +150 -0
  493. package/dist/tests/core/sleep-cycle.test.js.map +1 -0
  494. package/dist/tests/core/slots.test.js +201 -0
  495. package/dist/tests/core/slots.test.js.map +1 -0
  496. package/dist/tests/core/state-resolve.test.js +80 -0
  497. package/dist/tests/core/state-resolve.test.js.map +1 -0
  498. package/dist/tests/core/summary.test.js +200 -0
  499. package/dist/tests/core/summary.test.js.map +1 -0
  500. package/dist/tests/core/template.test.js +116 -0
  501. package/dist/tests/core/template.test.js.map +1 -0
  502. package/dist/tests/core/tick.test.js +558 -0
  503. package/dist/tests/core/tick.test.js.map +1 -0
  504. package/dist/tests/core/token-fold.test.js +176 -0
  505. package/dist/tests/core/token-fold.test.js.map +1 -0
  506. package/dist/tests/core/turn.test.js +388 -0
  507. package/dist/tests/core/turn.test.js.map +1 -0
  508. package/dist/tests/core/url.test.js +118 -0
  509. package/dist/tests/core/url.test.js.map +1 -0
  510. package/dist/tests/core/validate.test.js +247 -0
  511. package/dist/tests/core/validate.test.js.map +1 -0
  512. package/dist/tests/core/views.test.js +252 -0
  513. package/dist/tests/core/views.test.js.map +1 -0
  514. package/dist/tests/core/vm-decide.test.js +110 -0
  515. package/dist/tests/core/vm-decide.test.js.map +1 -0
  516. package/dist/tests/core/vm-guards.test.js +153 -0
  517. package/dist/tests/core/vm-guards.test.js.map +1 -0
  518. package/dist/tests/core/vm-plan.test.js +332 -0
  519. package/dist/tests/core/vm-plan.test.js.map +1 -0
  520. package/dist/tests/core/vm-reap.test.js +196 -0
  521. package/dist/tests/core/vm-reap.test.js.map +1 -0
  522. package/dist/tests/core/workflow-parse.test.js +493 -0
  523. package/dist/tests/core/workflow-parse.test.js.map +1 -0
  524. package/dist/tests/core/workspace-decide.test.js +236 -0
  525. package/dist/tests/core/workspace-decide.test.js.map +1 -0
  526. package/dist/tests/helpers/fixtures.js +167 -0
  527. package/dist/tests/helpers/fixtures.js.map +1 -0
  528. package/dist/tests/shell/acp-substrate.test.js +101 -0
  529. package/dist/tests/shell/acp-substrate.test.js.map +1 -0
  530. package/dist/tests/shell/actions-runner-push.test.js +203 -0
  531. package/dist/tests/shell/actions-runner-push.test.js.map +1 -0
  532. package/dist/tests/shell/credential-hooks.test.js +36 -0
  533. package/dist/tests/shell/credential-hooks.test.js.map +1 -0
  534. package/dist/tests/shell/credential-registry.test.js +165 -0
  535. package/dist/tests/shell/credential-registry.test.js.map +1 -0
  536. package/dist/tests/shell/credential-substrate.test.js +179 -0
  537. package/dist/tests/shell/credential-substrate.test.js.map +1 -0
  538. package/dist/tests/shell/dockerfile-mise-pin.test.js +51 -0
  539. package/dist/tests/shell/dockerfile-mise-pin.test.js.map +1 -0
  540. package/dist/tests/shell/doctor.test.js +101 -0
  541. package/dist/tests/shell/doctor.test.js.map +1 -0
  542. package/dist/tests/shell/effect-vm-create.test.js +52 -0
  543. package/dist/tests/shell/effect-vm-create.test.js.map +1 -0
  544. package/dist/tests/shell/gh-port.test.js +63 -0
  545. package/dist/tests/shell/gh-port.test.js.map +1 -0
  546. package/dist/tests/shell/gondolin-dispatch-guard.test.js +144 -0
  547. package/dist/tests/shell/gondolin-dispatch-guard.test.js.map +1 -0
  548. package/dist/tests/shell/gondolin-dispatch-shquote.test.js +168 -0
  549. package/dist/tests/shell/gondolin-dispatch-shquote.test.js.map +1 -0
  550. package/dist/tests/shell/gondolin-image-converter.test.js +208 -0
  551. package/dist/tests/shell/gondolin-image-converter.test.js.map +1 -0
  552. package/dist/tests/shell/gondolin-image-fetch.test.js +93 -0
  553. package/dist/tests/shell/gondolin-image-fetch.test.js.map +1 -0
  554. package/dist/tests/shell/http-handler.test.js +608 -0
  555. package/dist/tests/shell/http-handler.test.js.map +1 -0
  556. package/dist/tests/shell/http-server.test.js +53 -0
  557. package/dist/tests/shell/http-server.test.js.map +1 -0
  558. package/dist/tests/shell/mcp-runtime.test.js +366 -0
  559. package/dist/tests/shell/mcp-runtime.test.js.map +1 -0
  560. package/dist/tests/shell/mise-config-asset.test.js +87 -0
  561. package/dist/tests/shell/mise-config-asset.test.js.map +1 -0
  562. package/dist/tests/shell/orchestrator-loop.test.js +583 -0
  563. package/dist/tests/shell/orchestrator-loop.test.js.map +1 -0
  564. package/dist/tests/shell/reconciler-passes.test.js +314 -0
  565. package/dist/tests/shell/reconciler-passes.test.js.map +1 -0
  566. package/dist/tests/shell/runner-loop-turn.test.js +97 -0
  567. package/dist/tests/shell/runner-loop-turn.test.js.map +1 -0
  568. package/dist/tests/shell/runner-slice.test.js +536 -0
  569. package/dist/tests/shell/runner-slice.test.js.map +1 -0
  570. package/dist/tests/shell/scaffold.test.js +65 -0
  571. package/dist/tests/shell/scaffold.test.js.map +1 -0
  572. package/dist/tests/shell/tick-config.test.js +83 -0
  573. package/dist/tests/shell/tick-config.test.js.map +1 -0
  574. package/dist/tests/shell/tracker-parse-dates.test.js +44 -0
  575. package/dist/tests/shell/tracker-parse-dates.test.js.map +1 -0
  576. package/dist/tests/shell/tracker-write-issue.test.js +154 -0
  577. package/dist/tests/shell/tracker-write-issue.test.js.map +1 -0
  578. package/dist/tests/shell/workflow-prompt-split.test.js +208 -0
  579. package/dist/tests/shell/workflow-prompt-split.test.js.map +1 -0
  580. package/dist/tests/shell/workspace-live-config.test.js +140 -0
  581. package/dist/tests/shell/workspace-live-config.test.js.map +1 -0
  582. package/package.json +21 -9
  583. package/patches/@earendil-works+gondolin+0.12.0.patch +173 -0
  584. package/prompts/Reflect.md +91 -0
  585. package/prompts/Review.md +97 -0
  586. package/prompts/Todo.md +96 -0
  587. package/prompts/_footer.md +41 -0
  588. package/prompts/_preamble.md +42 -0
  589. package/prompts-minimal/Todo.md +26 -0
  590. package/scripts/postinstall.mjs +63 -0
  591. package/scripts/vm-agent.mjs +312 -90
  592. package/WORKFLOW.md +0 -744
  593. package/dist/acp-bridge.js +0 -324
  594. package/dist/acp-bridge.js.map +0 -1
  595. package/dist/actions/cache.js +0 -191
  596. package/dist/actions/cache.js.map +0 -1
  597. package/dist/actions/effects.js +0 -41
  598. package/dist/actions/effects.js.map +0 -1
  599. package/dist/actions/executor.js +0 -570
  600. package/dist/actions/executor.js.map +0 -1
  601. package/dist/actions/index.js +0 -13
  602. package/dist/actions/index.js.map +0 -1
  603. package/dist/actions/parsing.js.map +0 -1
  604. package/dist/actions/predicate-env.js +0 -27
  605. package/dist/actions/predicate-env.js.map +0 -1
  606. package/dist/actions/predicates.js +0 -49
  607. package/dist/actions/predicates.js.map +0 -1
  608. package/dist/actions/templating.js +0 -66
  609. package/dist/actions/templating.js.map +0 -1
  610. package/dist/actions/types.js +0 -15
  611. package/dist/actions/types.js.map +0 -1
  612. package/dist/agent/acp.js +0 -473
  613. package/dist/agent/acp.js.map +0 -1
  614. package/dist/agent/adapter-names.js +0 -159
  615. package/dist/agent/adapter-names.js.map +0 -1
  616. package/dist/agent/adapters.js +0 -511
  617. package/dist/agent/adapters.js.map +0 -1
  618. package/dist/agent/credential-extractors.js +0 -342
  619. package/dist/agent/credential-extractors.js.map +0 -1
  620. package/dist/agent/credential-secrets.js +0 -628
  621. package/dist/agent/credential-secrets.js.map +0 -1
  622. package/dist/agent/credential-ticker.js +0 -57
  623. package/dist/agent/credential-ticker.js.map +0 -1
  624. package/dist/agent/gondolin-creds-staging.js +0 -356
  625. package/dist/agent/gondolin-creds-staging.js.map +0 -1
  626. package/dist/agent/gondolin-dispatch.js +0 -375
  627. package/dist/agent/gondolin-dispatch.js.map +0 -1
  628. package/dist/agent/gondolin.js +0 -124
  629. package/dist/agent/gondolin.js.map +0 -1
  630. package/dist/agent/runner-decisions.js +0 -134
  631. package/dist/agent/runner-decisions.js.map +0 -1
  632. package/dist/agent/runner.js +0 -1456
  633. package/dist/agent/runner.js.map +0 -1
  634. package/dist/agent/tool-call-summary.js +0 -102
  635. package/dist/agent/tool-call-summary.js.map +0 -1
  636. package/dist/agent/vm-acp-mapping.js +0 -73
  637. package/dist/agent/vm-acp-mapping.js.map +0 -1
  638. package/dist/agent/vm-guards.js +0 -262
  639. package/dist/agent/vm-guards.js.map +0 -1
  640. package/dist/agent/vm-port.js +0 -22
  641. package/dist/agent/vm-port.js.map +0 -1
  642. package/dist/agent/vm-process-registry.js +0 -79
  643. package/dist/agent/vm-process-registry.js.map +0 -1
  644. package/dist/bin/cli-args.js +0 -105
  645. package/dist/bin/cli-args.js.map +0 -1
  646. package/dist/bin/symphony.js +0 -794
  647. package/dist/bin/symphony.js.map +0 -1
  648. package/dist/errors.js +0 -15
  649. package/dist/errors.js.map +0 -1
  650. package/dist/http-disk.js +0 -135
  651. package/dist/http-disk.js.map +0 -1
  652. package/dist/http-handlers.js.map +0 -1
  653. package/dist/http.js.map +0 -1
  654. package/dist/issues.js +0 -178
  655. package/dist/issues.js.map +0 -1
  656. package/dist/logging.js +0 -203
  657. package/dist/logging.js.map +0 -1
  658. package/dist/mcp.js +0 -706
  659. package/dist/mcp.js.map +0 -1
  660. package/dist/memory.js +0 -85
  661. package/dist/memory.js.map +0 -1
  662. package/dist/orchestrator-decisions.js +0 -331
  663. package/dist/orchestrator-decisions.js.map +0 -1
  664. package/dist/orchestrator.js +0 -1569
  665. package/dist/orchestrator.js.map +0 -1
  666. package/dist/prompt.js +0 -65
  667. package/dist/prompt.js.map +0 -1
  668. package/dist/reconciler/cache.js +0 -65
  669. package/dist/reconciler/cache.js.map +0 -1
  670. package/dist/reconciler/index.js +0 -448
  671. package/dist/reconciler/index.js.map +0 -1
  672. package/dist/reconciler/ledger.js +0 -131
  673. package/dist/reconciler/ledger.js.map +0 -1
  674. package/dist/reconciler/pr-adapters.js +0 -174
  675. package/dist/reconciler/pr-adapters.js.map +0 -1
  676. package/dist/reconciler/pr-decide.js.map +0 -1
  677. package/dist/reconciler/pr.js +0 -422
  678. package/dist/reconciler/pr.js.map +0 -1
  679. package/dist/reconciler/types.js +0 -12
  680. package/dist/reconciler/types.js.map +0 -1
  681. package/dist/reconciler/vm.js +0 -243
  682. package/dist/reconciler/vm.js.map +0 -1
  683. package/dist/reconciler/workspace-defaults.js +0 -83
  684. package/dist/reconciler/workspace-defaults.js.map +0 -1
  685. package/dist/reconciler/workspace.js +0 -272
  686. package/dist/reconciler/workspace.js.map +0 -1
  687. package/dist/runlog.js +0 -403
  688. package/dist/runlog.js.map +0 -1
  689. package/dist/scaffold.js +0 -165
  690. package/dist/scaffold.js.map +0 -1
  691. package/dist/trackers/local.js +0 -445
  692. package/dist/trackers/local.js.map +0 -1
  693. package/dist/trackers/types.js +0 -10
  694. package/dist/trackers/types.js.map +0 -1
  695. package/dist/types.js +0 -3
  696. package/dist/types.js.map +0 -1
  697. package/dist/util/clock.js +0 -12
  698. package/dist/util/clock.js.map +0 -1
  699. package/dist/util/crypto.js +0 -25
  700. package/dist/util/crypto.js.map +0 -1
  701. package/dist/util/frontmatter.js +0 -70
  702. package/dist/util/frontmatter.js.map +0 -1
  703. package/dist/util/fs-issues.js +0 -22
  704. package/dist/util/fs-issues.js.map +0 -1
  705. package/dist/util/process.js +0 -152
  706. package/dist/util/process.js.map +0 -1
  707. package/dist/util/workspace-key.js +0 -10
  708. package/dist/util/workspace-key.js.map +0 -1
  709. package/dist/workflow-loader.js +0 -147
  710. package/dist/workflow-loader.js.map +0 -1
  711. package/dist/workflow.js +0 -822
  712. package/dist/workflow.js.map +0 -1
  713. package/dist/workspace-types.js +0 -8
  714. package/dist/workspace-types.js.map +0 -1
  715. package/dist/workspace.js +0 -443
  716. package/dist/workspace.js.map +0 -1
@@ -0,0 +1,95 @@
1
+ // FCIS rewrite — pure per-dispatch config resolution + eval-mode mount list.
2
+ //
3
+ // Functional core: every export here is a pure, synchronous (data) -> data
4
+ // function. No IO, no clock, no randomness, no node: imports. Imports ONLY from
5
+ // src/types. Ports the runner-facing half of the original
6
+ // src/agent/runner.ts:resolveDispatchConfig / buildEvalModeMounts.
7
+ //
8
+ // WHY this slice exists separate from the per-knob resolvers in core/states.ts:
9
+ // the runner pins ONE struct (adapter + model + effort + max_turns + eval_mode)
10
+ // ONCE at the top of an attempt and reads everything downstream from it
11
+ // (mustFix: config pinning). A workflow reload mid-attempt must NOT be able to
12
+ // redirect the adapter / model / loop budget / mount set on the live VM. This
13
+ // module produces that pinned struct + the derived eval-mode mounts.
14
+ //
15
+ // Override precedence (ported faithfully from the original resolveDispatchConfig):
16
+ // - adapter: state.adapter ?? acp.adapter
17
+ // - model: state.model === undefined ? acp.model : state.model
18
+ // - effort: state.effort === undefined ? acp.effort : state.effort
19
+ // (an explicit `null` on the state means "use the adapter's own
20
+ // default", which is DISTINCT from "not declared" → inherit the
21
+ // workflow-level default)
22
+ // - max_turns: state.max_turns ?? agent.max_turns
23
+ // - eval_mode: state.eval_mode === true (any non-true value ⇒ off)
24
+ import { resolveStateKey } from '../state-resolve.js';
25
+ /**
26
+ * Fixed guest paths for the eval/debug read-only mounts. Hardcoded (not
27
+ * configurable) so the prompt body can reference them by literal path. Kept as
28
+ * exports for tests and any operator-facing surface that needs to mention them.
29
+ */
30
+ export const EVAL_MODE_ISSUES_GUEST_PATH = '/symphony/issues';
31
+ export const EVAL_MODE_LOGS_GUEST_PATH = '/symphony/logs';
32
+ /**
33
+ * Resolve effective adapter/model/effort/max_turns/eval_mode for an issue's
34
+ * current state — the runner's dispatch-config pin. Per-state overrides declared
35
+ * under `states.<name>` win; otherwise the workflow-level `acp.adapter` /
36
+ * `acp.model` / `acp.effort` / `agent.max_turns` defaults apply.
37
+ *
38
+ * Takes the whole `ServiceConfig` because that is the runner's call shape (it
39
+ * pins this struct once and reads only from it thereafter, never from
40
+ * `cfg.acp.*` / `cfg.agent.max_turns` directly).
41
+ *
42
+ * Returns `Error` AS DATA when `state` is not declared (after case-insensitive
43
+ * canonicalization). The orchestrator should never dispatch an issue whose state
44
+ * is not declared (validateDispatch + reconciliation both gate on that), but
45
+ * defense in depth: a silent fallback here would mask a tracker/workflow drift
46
+ * bug as a confusing default-adapter run, so the caller gets an explicit error
47
+ * value to surface or throw at the IO boundary (functional core: no throwing for
48
+ * control flow).
49
+ */
50
+ export function resolveDispatchConfig(cfg, state) {
51
+ const states = cfg.states;
52
+ const key = resolveStateKey(states, state);
53
+ if (key === null) {
54
+ const declared = Object.keys(states).join(', ');
55
+ return new Error(`resolveDispatchConfig: state "${state}" is not declared in workflow states (declared: ${declared.length > 0 ? declared : '<none>'})`);
56
+ }
57
+ const s = states[key];
58
+ const adapter = s.adapter ?? cfg.acp.adapter;
59
+ // Distinguish "not overridden" (undefined) from "explicitly null" (means: use
60
+ // the adapter default). Only fall back to the workflow-level value when the
61
+ // state did not declare the key at all.
62
+ const model = s.model === undefined ? cfg.acp.model : s.model;
63
+ const effort = s.effort === undefined ? cfg.acp.effort : s.effort;
64
+ const maxTurns = s.max_turns ?? cfg.agent.max_turns;
65
+ const evalMode = s.eval_mode === true;
66
+ return { adapter, model, effort, maxTurns, evalMode };
67
+ }
68
+ /**
69
+ * Derive the extra read-only bind mounts the eval/debug mode (issue 40)
70
+ * contributes for a single dispatch. Returns an empty list when the state did
71
+ * not opt in (`resolved.evalMode === false`) or when neither symphony state root
72
+ * is configured (defense in depth — the local tracker always sets `tracker.root`
73
+ * and the loader always sets `logs.root`, but a hand-built ServiceConfig in
74
+ * tests might not).
75
+ *
76
+ * The host paths come straight from config (the loader normalizes both roots to
77
+ * absolute); the guest paths are the fixed `EVAL_MODE_*` constants so the prompt
78
+ * body can reference them by literal path. `readonly: true` always — an in-VM
79
+ * eval/debug agent inspects symphony's own state but must never mutate it.
80
+ */
81
+ export function buildEvalModeMounts(cfg, resolved) {
82
+ if (!resolved.evalMode)
83
+ return [];
84
+ const mounts = [];
85
+ const trackerRoot = cfg.tracker.root;
86
+ if (trackerRoot && trackerRoot.length > 0) {
87
+ mounts.push({ host: trackerRoot, guest: EVAL_MODE_ISSUES_GUEST_PATH, readonly: true });
88
+ }
89
+ const logsRoot = cfg.logs.root;
90
+ if (logsRoot && logsRoot.length > 0) {
91
+ mounts.push({ host: logsRoot, guest: EVAL_MODE_LOGS_GUEST_PATH, readonly: true });
92
+ }
93
+ return mounts;
94
+ }
95
+ //# sourceMappingURL=dispatch-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch-config.js","sourceRoot":"","sources":["../../../../src/core/runner/dispatch-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ // FCIS rewrite — pure runtime-injection fold for adapter dispatch.
2
+ //
3
+ // Ported faithfully from the reference `src/agent/runner.ts`
4
+ // (`applyRuntimeInjections` + `applyModelInjection`) and the per-adapter
5
+ // `ModelInjection`/`EffortInjection` channels declared by `src/agent/adapters.ts`.
6
+ // The reference ran inside the async dispatch pipeline, but the composition was
7
+ // already pure: a `(data) -> data` fold of the model + effort injections a
8
+ // profile declares into one runtime descriptor across three orthogonal channels
9
+ // (env vars, extra argv, staged guest files), with NO IO.
10
+ //
11
+ // Faithful semantics preserved from the reference:
12
+ // • model is folded BEFORE effort, so effort wins on env-key collisions; staged
13
+ // files from both are kept in order (`runtimeExtraFiles.push`).
14
+ // • model injection applies only when `model` is a non-empty string
15
+ // (reference: `if (resolved.model)`); effort applies only when `effort` is
16
+ // non-empty AND the profile declares an `effortInjection`.
17
+ // • staged files become guest files with mode 0o600.
18
+ // • adapter binary is `binary[0]`; effective argv is `binary.slice(1)` ++ folded args.
19
+ /** Mode every staged guest file is written with (reference: `mode: 0o600`). */
20
+ export const STAGED_FILE_MODE = 0o600;
21
+ /**
22
+ * Fold one `ModelInjection` into the accumulator across the three channels,
23
+ * returning a NEW accumulator (no input mutation):
24
+ * • env — merged key-by-key, later value wins on collision.
25
+ * • extraArgs — appended in order.
26
+ * • stagedFiles → guest files at mode 0o600, appended in order.
27
+ */
28
+ export function foldInjection(acc, inj) {
29
+ const runtimeEnv = { ...acc.runtimeEnv, ...inj.env };
30
+ const runtimeArgs = inj.extraArgs ? [...acc.runtimeArgs, ...inj.extraArgs] : [...acc.runtimeArgs];
31
+ const runtimeExtraFiles = [...acc.runtimeExtraFiles];
32
+ for (const f of inj.stagedFiles ?? []) {
33
+ runtimeExtraFiles.push({ guestPath: f.guestPath, content: f.content, mode: STAGED_FILE_MODE });
34
+ }
35
+ return { runtimeEnv, runtimeArgs, runtimeExtraFiles };
36
+ }
37
+ /**
38
+ * Compose a profile's model + effort injections into one runtime descriptor.
39
+ * The single decision-bearing function for this slice.
40
+ */
41
+ export function applyRuntimeInjections(profile, choices) {
42
+ let acc = { runtimeEnv: {}, runtimeArgs: [], runtimeExtraFiles: [] };
43
+ if (isNonEmpty(choices.model))
44
+ acc = foldInjection(acc, profile.modelInjection(choices.model));
45
+ if (isNonEmpty(choices.effort) && profile.effortInjection) {
46
+ acc = foldInjection(acc, profile.effortInjection(choices.effort));
47
+ }
48
+ return {
49
+ adapterBin: profile.binary[0] ?? '',
50
+ effectiveAdapterArgs: [...profile.binary.slice(1), ...acc.runtimeArgs],
51
+ ...acc,
52
+ };
53
+ }
54
+ /**
55
+ * The reference applied an injection only on a truthy, non-empty string knob
56
+ * (`if (resolved.model)`); `null` and `''` both skip. Kept exactly.
57
+ */
58
+ function isNonEmpty(value) {
59
+ return value !== null && value.length > 0;
60
+ }
61
+ //# sourceMappingURL=injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injection.js","sourceRoot":"","sources":["../../../../src/core/runner/injection.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,EAAE;AACF,6DAA6D;AAC7D,yEAAyE;AACzE,mFAAmF;AACnF,gFAAgF;AAChF,2EAA2E;AAC3E,gFAAgF;AAChF,0DAA0D;AAC1D,EAAE;AACF,mDAAmD;AACnD,kFAAkF;AAClF,oEAAoE;AACpE,sEAAsE;AACtE,+EAA+E;AAC/E,+DAA+D;AAC/D,uDAAuD;AACvD,yFAAyF;AAWzF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAItC;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,GAAgB,EAAE,GAAmB;IACjE,MAAM,UAAU,GAA2B,EAAE,GAAG,GAAG,CAAC,UAAU,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAC7E,MAAM,WAAW,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC;IAClG,MAAM,iBAAiB,GAAoB,CAAC,GAAG,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACtE,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;QACtC,iBAAiB,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAuB,EACvB,OAAuB;IAEvB,IAAI,GAAG,GAAgB,EAAE,UAAU,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC;IAElF,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/F,IAAI,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC1D,GAAG,GAAG,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,OAAO;QACL,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE;QACnC,oBAAoB,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,WAAW,CAAC;QACtE,GAAG,GAAG;KACP,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,KAAoB;IACtC,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,210 @@
1
+ // FCIS rewrite — pure mise (jdx/mise) toolchain-provisioning deciders (issue 209).
2
+ //
3
+ // Functional core: every export is a pure, synchronous (data) -> data function or
4
+ // a constant. No IO, no async, no clock, no randomness, no node: imports. Imports
5
+ // ONLY type-only from src/types.
6
+ //
7
+ // The contract: the agent image ships ONLY the `mise` binary (+ glibc essentials).
8
+ // node + the agent CLIs come from a STAGED mise SYSTEM config (/etc/mise/config.toml);
9
+ // project toolchains come from the consuming repo's own mise.toml. Everything installs
10
+ // into MISE_DATA_GUEST_DIR, which lives on the guest ROOTFS (ext4, ephemeral per VM) —
11
+ // NOT a bind mount. The gondolin sandboxfs bind mount has no chmod opcode (chmod is a
12
+ // silent no-op there), so mise's create-then-chmod extractor + npm postinstall produce
13
+ // NON-executable binaries on it; the rootfs honors chmod, so installs land executable
14
+ // (issue 222). The pure downloads — node tarballs + npm packages, no exec bit needed —
15
+ // DO persist on a sandboxfs bind mount (MISE_CACHE_GUEST_DIR) so a cold install isn't
16
+ // re-downloaded every dispatch.
17
+ //
18
+ // These deciders assemble the data the shell EXECUTES: the download-cache mount, the boot
19
+ // env (MISE_DATA_DIR + MISE_YES + npm_config_cache), the staged system-config guest file,
20
+ // the pre-install prep argv (point mise's downloads at the cache), and the
21
+ // `mise trust … && mise install` argv. The actual execs (mount, stage, prep, install,
22
+ // probe) live in the shell dispatcher.
23
+ // ─── fixed guest-side constants ────────────────────────────────────────────────
24
+ /**
25
+ * Guest path mise installs the toolchain into. Lives on the guest ROOTFS (ext4,
26
+ * unmounted, ephemeral per VM) — NOT a bind mount — so mise's create-then-chmod installs
27
+ * land executable (the sandboxfs bind mount silently drops chmod; issue 222).
28
+ */
29
+ export const MISE_DATA_GUEST_DIR = '/opt/symphony/mise-data';
30
+ /**
31
+ * Guest shims dir mise populates under the data dir. Prepended to the probe/launch
32
+ * PATH so the agent's CHILD processes (project build/test) resolve the project's
33
+ * tools; the AGENT runtime node is resolved separately via `mise which node` so a
34
+ * project mise.toml can't downgrade it (see {@link miseNodeResolveExpr}).
35
+ */
36
+ export const MISE_SHIMS_GUEST_DIR = `${MISE_DATA_GUEST_DIR}/shims`;
37
+ /**
38
+ * Guest mount point for the persistent mise DOWNLOAD CACHE — the host
39
+ * `gondolin.mise.data_dir` bind-mounted RW here (issue 222). Downloads are pure data
40
+ * (node tarballs + npm packages; no exec bit), so they live safely on the sandboxfs bind
41
+ * mount the install dir can't use. mise's tool-download dir + npm's package cache point
42
+ * here (see {@link buildMisePrepCommand} + {@link buildMiseEnv}) so a cold install isn't
43
+ * re-fetched every dispatch.
44
+ */
45
+ export const MISE_CACHE_GUEST_DIR = '/opt/symphony/mise-cache';
46
+ /** Guest path the symphony-bundled mise SYSTEM config is staged at (lowest precedence). */
47
+ export const MISE_SYSTEM_CONFIG_GUEST_PATH = '/etc/mise/config.toml';
48
+ /**
49
+ * The egress hosts the staged SYSTEM config's tools need so `mise install` can fetch
50
+ * node (mise's node backend → nodejs.org) + the agent CLIs (the `npm:` backend →
51
+ * registry.npmjs.org), mise's own registry metadata (mise.jdx.dev), and mise's
52
+ * precompiled tool-version lists (mise-versions.jdx.dev — `GET /tools/node.toml`, the
53
+ * version index `node@<N>` resolves against on a cold mise cache; issues 223 + 231).
54
+ * Always seeded into the egress allowlist DEFAULT (parse.ts; mise provisioning is
55
+ * unconditional, issue 233) so the firewall doesn't silently block provisioning.
56
+ * PROJECT toolchains may need MORE
57
+ * per-tool hosts (rustup → static.rust-lang.org, gradle → services.gradle.org, JDK →
58
+ * api.adoptium.net); the consuming repo adds those to `egress.allowed_hosts` (which
59
+ * REPLACES this default). SECURITY: firewall hosts only — no credential is ever
60
+ * substituted for these.
61
+ */
62
+ export const MISE_EGRESS_HOSTS = [
63
+ 'nodejs.org',
64
+ 'registry.npmjs.org',
65
+ 'mise.jdx.dev',
66
+ 'mise-versions.jdx.dev',
67
+ ];
68
+ /** Non-secret mode for the staged system config — it is config, not a credential. */
69
+ export const MISE_SYSTEM_CONFIG_MODE = 0o644;
70
+ /**
71
+ * Project-config filenames mise recognises in a workspace. Used by
72
+ * {@link hasProjectMiseConfig} to detect whether the consuming repo contributes its
73
+ * own toolchains on top of the staged system config (purely informational — the
74
+ * `mise install` cwd=workspace picks them up regardless).
75
+ */
76
+ export const MISE_PROJECT_CONFIG_FILENAMES = [
77
+ 'mise.toml',
78
+ '.mise.toml',
79
+ 'mise.local.toml',
80
+ '.mise.local.toml',
81
+ '.tool-versions',
82
+ ];
83
+ // ─── POSIX single-quote-safe shell quoting (pure) ──────────────────────────────
84
+ /**
85
+ * Wrap a value in single quotes, escaping any embedded single quote via the
86
+ * canonical `'\''` close-escape-reopen trick. Used for EVERY host-controlled value
87
+ * interpolated into a `/bin/sh -c '…'` guest script (the workspace path, the system
88
+ * config path, the adapter name) so a `'` cannot break out and inject commands.
89
+ */
90
+ export function shQuote(value) {
91
+ return `'${value.replace(/'/g, `'\\''`)}'`;
92
+ }
93
+ // ─── env / mount / staged file ─────────────────────────────────────────────────
94
+ /**
95
+ * The mise boot/exec env. `MISE_DATA_DIR` points mise at the rootfs install dir (where
96
+ * chmod works); `MISE_YES=1` answers mise's trust/confirm prompts (the staged + project
97
+ * configs are symphony-managed); `npm_config_cache` points the `npm:`-backend package
98
+ * cache at the persistent sandboxfs download cache so it survives across dispatches
99
+ * (issue 222). Always populated — mise provisioning is unconditional (issue 233).
100
+ */
101
+ export function buildMiseEnv() {
102
+ return {
103
+ MISE_DATA_DIR: MISE_DATA_GUEST_DIR,
104
+ MISE_YES: '1',
105
+ npm_config_cache: `${MISE_CACHE_GUEST_DIR}/npm`,
106
+ };
107
+ }
108
+ /**
109
+ * The symphony-managed mise DOWNLOAD-CACHE mount (host `data_dir` → guest cache dir, RW).
110
+ * Always returned — mise provisioning is unconditional (issue 233). The host dir is
111
+ * bind-mounted at MISE_CACHE_GUEST_DIR — NOT the install dir: installs need chmod
112
+ * (rootfs only), but the cached downloads are pure data the sandboxfs bind mount holds
113
+ * fine (issue 222). NOT a user `gondolin.volumes` entry — the runner owns it.
114
+ */
115
+ export function buildMiseMount(cfg) {
116
+ // ensureHostDir: the cache dir is symphony-managed — the VM adapter mkdir -p's the
117
+ // host path before mounting it RW (it may not exist on a fresh host / custom dir).
118
+ return { host: cfg.gondolin.mise.data_dir, guest: MISE_CACHE_GUEST_DIR, readonly: false, ensureHostDir: true };
119
+ }
120
+ /**
121
+ * The pre-install prep argv (issue 222), run with cwd = workspace BEFORE `mise install`.
122
+ * Creates the rootfs install dir + the persistent cache subdirs, then symlinks mise's
123
+ * tool-DOWNLOAD dir (`<data>/downloads`) onto the persistent cache (`<cache>/downloads`)
124
+ * so node tarballs + extracted-source downloads survive across dispatches while the
125
+ * installs/extracts themselves stay on the chmod-capable rootfs `<data>`. `ln -sfn`
126
+ * replaces any stale link in place (the `-n` keeps it from descending into an existing
127
+ * symlinked dir). Best-effort in the shell: a failure just costs a cold re-download, not a
128
+ * broken install. Every path is a fixed symphony-owned constant (no host input → no
129
+ * shell-injection surface, unlike {@link buildMiseInstallCommand}).
130
+ */
131
+ export function buildMisePrepCommand() {
132
+ const script = `mkdir -p ${MISE_DATA_GUEST_DIR} ${MISE_CACHE_GUEST_DIR}/downloads ${MISE_CACHE_GUEST_DIR}/npm && ` +
133
+ `ln -sfn ${MISE_CACHE_GUEST_DIR}/downloads ${MISE_DATA_GUEST_DIR}/downloads`;
134
+ return ['/bin/sh', '-c', script];
135
+ }
136
+ /** The symphony-bundled mise SYSTEM config as a staged guest file. Carries no secret → 0644. */
137
+ export function miseSystemConfigFile(source) {
138
+ return { guestPath: MISE_SYSTEM_CONFIG_GUEST_PATH, content: source, mode: MISE_SYSTEM_CONFIG_MODE };
139
+ }
140
+ // ─── install command ───────────────────────────────────────────────────────────
141
+ /**
142
+ * The `mise trust … && mise install` argv the shell runs with cwd = workspace
143
+ * (installs the merged SYSTEM + project tool set). Trust is best-effort (`|| true`)
144
+ * for both the staged system config and the workspace so a project WITHOUT a mise
145
+ * config does not fail the chain; `exec mise install` then governs the exit code.
146
+ * mise provisioning is unconditional (issue 233), so the shell always runs it.
147
+ */
148
+ export function buildMiseInstallCommand(workspacePath) {
149
+ const script = `mise trust ${shQuote(MISE_SYSTEM_CONFIG_GUEST_PATH)} >/dev/null 2>&1 || true; ` +
150
+ `mise trust ${shQuote(workspacePath)} >/dev/null 2>&1 || true; ` +
151
+ `exec mise install`;
152
+ return ['/bin/sh', '-c', script];
153
+ }
154
+ /**
155
+ * Operator-facing message for a failed in-guest `mise install` (issue 209). Thrown
156
+ * by the shell dispatcher as a ByoContractError before the agent launches, so a
157
+ * toolchain-provisioning failure surfaces with the guest's own stderr tail rather
158
+ * than a later opaque ENOENT (no node / no adapter shim). `code` is the exec exit.
159
+ */
160
+ export function miseInstallFailureMessage(code, stderr) {
161
+ const tail = stderr.trim();
162
+ const detail = tail ? ` Guest stderr: ${tail}` : '';
163
+ return (`mise install failed (exit ${code}) while provisioning the agent toolchain ` +
164
+ `(node + the agent CLIs from the staged SYSTEM config, plus any project mise.toml). ` +
165
+ `Check the agent image ships \`mise\`, the egress allowlist reaches the tool hosts ` +
166
+ `(nodejs.org / registry.npmjs.org / the mise registry), and the data dir is writable.` +
167
+ detail);
168
+ }
169
+ // ─── project-config detection ──────────────────────────────────────────────────
170
+ /**
171
+ * Whether the workspace ships its own mise project config (so it contributes
172
+ * toolchains on top of the staged system config). Purely informational — the shell
173
+ * uses it for an operator log line; `mise install` picks up the project config
174
+ * regardless.
175
+ */
176
+ export function hasProjectMiseConfig(workspaceEntries) {
177
+ return workspaceEntries.some((e) => MISE_PROJECT_CONFIG_FILENAMES.includes(e));
178
+ }
179
+ // ─── node resolution (load-bearing) ────────────────────────────────────────────
180
+ /**
181
+ * The shell `$(…)` expression the BYO probe captures into $NODE_PATH to resolve the
182
+ * AGENT runtime node to a concrete, SYSTEM-scoped absolute path: `mise which node`
183
+ * run from `/`. mise provisioning is the only toolchain path (issue 233), so this is
184
+ * unconditional. Resolving from `/` matters: a project's mise.toml can override `node`
185
+ * in the workspace and the mise `node` shim re-resolves the version BY CWD, so running
186
+ * from the workspace would launch the AGENT (which must stay Node ≥ 21 for the
187
+ * launcher's global WebSocket) on the project's node. Resolving from `/` applies only
188
+ * the staged SYSTEM config, pinning the agent's node; the agent's CHILD processes still
189
+ * get the project node via the workspace shims on PATH.
190
+ */
191
+ export function miseNodeResolveExpr() {
192
+ return `$(cd / && mise which node)`;
193
+ }
194
+ /**
195
+ * The full `/bin/sh -c` BYO pre-launch probe script (issue 209 moved it into core so
196
+ * the `mise which node` resolution is a unit-testable decision). Resolves the agent
197
+ * node (system-scoped) + the adapter CLI (a mise shim on PATH), asserts Node ≥ 21 /
198
+ * the global WebSocket, confirms the staged launcher materialized, then prints
199
+ * `<node>\n<adapter>`. Every host-controlled value is shQuoted. The shell runs this
200
+ * and maps a non-zero exit via byoProbeFailureMessage.
201
+ */
202
+ export function buildByoProbeScript(adapterName, launcherGuestPath) {
203
+ return (`set -e; ` +
204
+ `NODE_PATH=${miseNodeResolveExpr()} || { echo "MISSING_NODE" >&2; exit 11; }; ` +
205
+ `ADAPTER_PATH=$(command -v ${shQuote(adapterName)}) || { echo "MISSING_ADAPTER" >&2; exit 12; }; ` +
206
+ `"$NODE_PATH" -e 'process.exit(typeof WebSocket==="function"?0:21)' || { echo "NODE_TOO_OLD" >&2; exit 21; }; ` +
207
+ `test -f ${shQuote(launcherGuestPath)} || { echo "MISSING_LAUNCHER" >&2; exit 13; }; ` +
208
+ `printf '%s\\n%s\\n' "$NODE_PATH" "$ADAPTER_PATH"`);
209
+ }
210
+ //# sourceMappingURL=mise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mise.js","sourceRoot":"","sources":["../../../../src/core/runner/mise.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,EAAE;AACF,kFAAkF;AAClF,kFAAkF;AAClF,iCAAiC;AACjC,EAAE;AACF,mFAAmF;AACnF,uFAAuF;AACvF,uFAAuF;AACvF,uFAAuF;AACvF,sFAAsF;AACtF,uFAAuF;AACvF,sFAAsF;AACtF,uFAAuF;AACvF,sFAAsF;AACtF,gCAAgC;AAChC,EAAE;AACF,0FAA0F;AAC1F,0FAA0F;AAC1F,2EAA2E;AAC3E,sFAAsF;AACtF,uCAAuC;AAMvC,kFAAkF;AAElF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,mBAAmB,QAAQ,CAAC;AAEnE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AAE/D,2FAA2F;AAC3F,MAAM,CAAC,MAAM,6BAA6B,GAAG,uBAAuB,CAAC;AAErE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,YAAY;IACZ,oBAAoB;IACpB,cAAc;IACd,uBAAuB;CACxB,CAAC;AAEF,qFAAqF;AACrF,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAsB;IAC9D,WAAW;IACX,YAAY;IACZ,iBAAiB;IACjB,kBAAkB;IAClB,gBAAgB;CACjB,CAAC;AAEF,kFAAkF;AAElF;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AAC7C,CAAC;AAED,kFAAkF;AAElF;;;;;;GAMG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO;QACL,aAAa,EAAE,mBAAmB;QAClC,QAAQ,EAAE,GAAG;QACb,gBAAgB,EAAE,GAAG,oBAAoB,MAAM;KAChD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAkB;IAC/C,mFAAmF;IACnF,mFAAmF;IACnF,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,oBAAoB,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AACjH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GACV,YAAY,mBAAmB,IAAI,oBAAoB,cAAc,oBAAoB,UAAU;QACnG,WAAW,oBAAoB,cAAc,mBAAmB,YAAY,CAAC;IAC/E,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,OAAO,EAAE,SAAS,EAAE,6BAA6B,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC;AACtG,CAAC;AAED,kFAAkF;AAElF;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,aAAqB;IAC3D,MAAM,MAAM,GACV,cAAc,OAAO,CAAC,6BAA6B,CAAC,4BAA4B;QAChF,cAAc,OAAO,CAAC,aAAa,CAAC,4BAA4B;QAChE,mBAAmB,CAAC;IACtB,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAmB,EAAE,MAAc;IAC3E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,OAAO,CACL,6BAA6B,IAAI,2CAA2C;QAC5E,qFAAqF;QACrF,oFAAoF;QACpF,sFAAsF;QACtF,MAAM,CACP,CAAC;AACJ,CAAC;AAED,kFAAkF;AAElF;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,gBAAmC;IACtE,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,6BAA6B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACjF,CAAC;AAED,kFAAkF;AAElF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,4BAA4B,CAAC;AACtC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,WAAmB,EACnB,iBAAyB;IAEzB,OAAO,CACL,UAAU;QACV,aAAa,mBAAmB,EAAE,6CAA6C;QAC/E,6BAA6B,OAAO,CAAC,WAAW,CAAC,iDAAiD;QAClG,+GAA+G;QAC/G,WAAW,OAAO,CAAC,iBAAiB,CAAC,iDAAiD;QACtF,kDAAkD,CACnD,CAAC;AACJ,CAAC"}