smol-symphony 0.2.0 → 0.3.1

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 (540) 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/bin/symphony.js +22 -786
  11. package/dist/bin/symphony.js.map +1 -1
  12. package/dist/core/actions/context.js +109 -0
  13. package/dist/core/actions/context.js.map +1 -0
  14. package/dist/{actions/parsing.js → core/actions/parse.js} +33 -114
  15. package/dist/core/actions/parse.js.map +1 -0
  16. package/dist/core/actions/plan.js +197 -0
  17. package/dist/core/actions/plan.js.map +1 -0
  18. package/dist/core/actions/predicates.js +111 -0
  19. package/dist/core/actions/predicates.js.map +1 -0
  20. package/dist/core/actions/run-fold.js +248 -0
  21. package/dist/core/actions/run-fold.js.map +1 -0
  22. package/dist/core/actions/template.js +118 -0
  23. package/dist/core/actions/template.js.map +1 -0
  24. package/dist/core/cli/args.js +116 -0
  25. package/dist/core/cli/args.js.map +1 -0
  26. package/dist/core/coerce.js +75 -0
  27. package/dist/core/coerce.js.map +1 -0
  28. package/dist/core/credential/account-id.js +20 -0
  29. package/dist/core/credential/account-id.js.map +1 -0
  30. package/dist/core/credential/adapter-config.js +136 -0
  31. package/dist/core/credential/adapter-config.js.map +1 -0
  32. package/dist/core/credential/availability.js +98 -0
  33. package/dist/core/credential/availability.js.map +1 -0
  34. package/dist/core/credential/extract.js +228 -0
  35. package/dist/core/credential/extract.js.map +1 -0
  36. package/dist/core/credential/fake-creds.js +171 -0
  37. package/dist/core/credential/fake-creds.js.map +1 -0
  38. package/dist/core/credential/identity.js +125 -0
  39. package/dist/core/credential/identity.js.map +1 -0
  40. package/dist/core/credential/shape.js +230 -0
  41. package/dist/core/credential/shape.js.map +1 -0
  42. package/dist/core/credential/strings.js +15 -0
  43. package/dist/core/credential/strings.js.map +1 -0
  44. package/dist/core/doctor/checks.js +303 -0
  45. package/dist/core/doctor/checks.js.map +1 -0
  46. package/dist/core/git/result.js +107 -0
  47. package/dist/core/git/result.js.map +1 -0
  48. package/dist/core/http/decisions.js +225 -0
  49. package/dist/core/http/decisions.js.map +1 -0
  50. package/dist/{http.js → core/http/render.js} +472 -738
  51. package/dist/core/http/render.js.map +1 -0
  52. package/dist/{http-handlers.js → core/http/routes.js} +52 -87
  53. package/dist/core/http/routes.js.map +1 -0
  54. package/dist/core/http/views.js +181 -0
  55. package/dist/core/http/views.js.map +1 -0
  56. package/dist/core/image/managed-image.js +95 -0
  57. package/dist/core/image/managed-image.js.map +1 -0
  58. package/dist/core/issue/file.js +149 -0
  59. package/dist/core/issue/file.js.map +1 -0
  60. package/dist/core/issue/parse.js +210 -0
  61. package/dist/core/issue/parse.js.map +1 -0
  62. package/dist/core/mcp/dispatch.js +239 -0
  63. package/dist/core/mcp/dispatch.js.map +1 -0
  64. package/dist/core/mcp/post-move.js +92 -0
  65. package/dist/core/mcp/post-move.js.map +1 -0
  66. package/dist/core/mcp/protocol.js +293 -0
  67. package/dist/core/mcp/protocol.js.map +1 -0
  68. package/dist/core/mcp/url.js +162 -0
  69. package/dist/core/mcp/url.js.map +1 -0
  70. package/dist/core/path.js +63 -0
  71. package/dist/core/path.js.map +1 -0
  72. package/dist/core/reconcile/image-decide.js +48 -0
  73. package/dist/core/reconcile/image-decide.js.map +1 -0
  74. package/dist/core/reconcile/ledger.js +142 -0
  75. package/dist/core/reconcile/ledger.js.map +1 -0
  76. package/dist/core/reconcile/pr-classify.js +62 -0
  77. package/dist/core/reconcile/pr-classify.js.map +1 -0
  78. package/dist/{reconciler → core/reconcile}/pr-decide.js +25 -12
  79. package/dist/core/reconcile/pr-decide.js.map +1 -0
  80. package/dist/core/reconcile/pr-loop.js +161 -0
  81. package/dist/core/reconcile/pr-loop.js.map +1 -0
  82. package/dist/core/reconcile/pr-notes.js +35 -0
  83. package/dist/core/reconcile/pr-notes.js.map +1 -0
  84. package/dist/core/reconcile/vm-decide.js +70 -0
  85. package/dist/core/reconcile/vm-decide.js.map +1 -0
  86. package/dist/core/reconcile/vm-reap.js +207 -0
  87. package/dist/core/reconcile/vm-reap.js.map +1 -0
  88. package/dist/core/reconcile/workspace-decide.js +162 -0
  89. package/dist/core/reconcile/workspace-decide.js.map +1 -0
  90. package/dist/core/runlog/summary.js +231 -0
  91. package/dist/core/runlog/summary.js.map +1 -0
  92. package/dist/core/runner/dispatch-config.js +95 -0
  93. package/dist/core/runner/dispatch-config.js.map +1 -0
  94. package/dist/core/runner/injection.js +61 -0
  95. package/dist/core/runner/injection.js.map +1 -0
  96. package/dist/core/runner/mise.js +210 -0
  97. package/dist/core/runner/mise.js.map +1 -0
  98. package/dist/core/runner/prompt.js +720 -0
  99. package/dist/core/runner/prompt.js.map +1 -0
  100. package/dist/core/runner/turn.js +242 -0
  101. package/dist/core/runner/turn.js.map +1 -0
  102. package/dist/core/runner/vm-plan.js +390 -0
  103. package/dist/core/runner/vm-plan.js.map +1 -0
  104. package/dist/core/schedule/admission.js +123 -0
  105. package/dist/core/schedule/admission.js.map +1 -0
  106. package/dist/core/schedule/circuit-breaker.js +111 -0
  107. package/dist/core/schedule/circuit-breaker.js.map +1 -0
  108. package/dist/core/schedule/eligibility.js +83 -0
  109. package/dist/core/schedule/eligibility.js.map +1 -0
  110. package/dist/core/schedule/reconcile-issue.js +82 -0
  111. package/dist/core/schedule/reconcile-issue.js.map +1 -0
  112. package/dist/core/schedule/retry.js +96 -0
  113. package/dist/core/schedule/retry.js.map +1 -0
  114. package/dist/core/schedule/sleep-cycle.js +133 -0
  115. package/dist/core/schedule/sleep-cycle.js.map +1 -0
  116. package/dist/core/schedule/slots.js +124 -0
  117. package/dist/core/schedule/slots.js.map +1 -0
  118. package/dist/core/schedule/tick.js +553 -0
  119. package/dist/core/schedule/tick.js.map +1 -0
  120. package/dist/core/schedule/token-fold.js +181 -0
  121. package/dist/core/schedule/token-fold.js.map +1 -0
  122. package/dist/core/state-resolve.js +86 -0
  123. package/dist/core/state-resolve.js.map +1 -0
  124. package/dist/core/vm-guards.js +278 -0
  125. package/dist/core/vm-guards.js.map +1 -0
  126. package/dist/core/workflow/derive.js +107 -0
  127. package/dist/core/workflow/derive.js.map +1 -0
  128. package/dist/core/workflow/parse.js +687 -0
  129. package/dist/core/workflow/parse.js.map +1 -0
  130. package/dist/core/workflow/prompt-probe.js +78 -0
  131. package/dist/core/workflow/prompt-probe.js.map +1 -0
  132. package/dist/core/workflow/validate.js +189 -0
  133. package/dist/core/workflow/validate.js.map +1 -0
  134. package/dist/core/workspace-key.js +19 -0
  135. package/dist/core/workspace-key.js.map +1 -0
  136. package/dist/shell/actions-runner.js +356 -0
  137. package/dist/shell/actions-runner.js.map +1 -0
  138. package/dist/shell/adapter/adapter-registry.js +45 -0
  139. package/dist/shell/adapter/adapter-registry.js.map +1 -0
  140. package/dist/shell/adapter/clock-random.js +96 -0
  141. package/dist/shell/adapter/clock-random.js.map +1 -0
  142. package/dist/shell/adapter/gondolin-dispatch-helpers.js +158 -0
  143. package/dist/shell/adapter/gondolin-dispatch-helpers.js.map +1 -0
  144. package/dist/shell/adapter/gondolin-dispatch.js +385 -0
  145. package/dist/shell/adapter/gondolin-dispatch.js.map +1 -0
  146. package/dist/shell/adapter/gondolin-image-converter.js +233 -0
  147. package/dist/shell/adapter/gondolin-image-converter.js.map +1 -0
  148. package/dist/shell/adapter/gondolin-image-fetch.js +180 -0
  149. package/dist/shell/adapter/gondolin-image-fetch.js.map +1 -0
  150. package/dist/shell/adapter/launcher-asset.js +57 -0
  151. package/dist/shell/adapter/launcher-asset.js.map +1 -0
  152. package/dist/shell/adapter/mise-config-asset.js +65 -0
  153. package/dist/shell/adapter/mise-config-asset.js.map +1 -0
  154. package/dist/shell/adapter/workflow-loader.js +304 -0
  155. package/dist/shell/adapter/workflow-loader.js.map +1 -0
  156. package/dist/shell/cli/doctor.js +268 -0
  157. package/dist/shell/cli/doctor.js.map +1 -0
  158. package/dist/shell/effect-interpreter-families.js +314 -0
  159. package/dist/shell/effect-interpreter-families.js.map +1 -0
  160. package/dist/shell/effect-interpreter.js +29 -0
  161. package/dist/shell/effect-interpreter.js.map +1 -0
  162. package/dist/shell/interp/acp-frame.js +137 -0
  163. package/dist/shell/interp/acp-frame.js.map +1 -0
  164. package/dist/shell/interp/acp-ws-conn.js +320 -0
  165. package/dist/shell/interp/acp-ws-conn.js.map +1 -0
  166. package/dist/shell/interp/acp-ws-frames.js +159 -0
  167. package/dist/shell/interp/acp-ws-frames.js.map +1 -0
  168. package/dist/shell/interp/acp-ws.js +197 -0
  169. package/dist/shell/interp/acp-ws.js.map +1 -0
  170. package/dist/shell/interp/acp.js +319 -0
  171. package/dist/shell/interp/acp.js.map +1 -0
  172. package/dist/shell/interp/credential-defaults.js +128 -0
  173. package/dist/shell/interp/credential-defaults.js.map +1 -0
  174. package/dist/shell/interp/credential-hooks.js +149 -0
  175. package/dist/shell/interp/credential-hooks.js.map +1 -0
  176. package/dist/shell/interp/credential-registry.js +226 -0
  177. package/dist/shell/interp/credential-registry.js.map +1 -0
  178. package/dist/shell/interp/credential.js +103 -0
  179. package/dist/shell/interp/credential.js.map +1 -0
  180. package/dist/shell/interp/gh.js +163 -0
  181. package/dist/shell/interp/gh.js.map +1 -0
  182. package/dist/shell/interp/git.js +28 -0
  183. package/dist/shell/interp/git.js.map +1 -0
  184. package/dist/shell/interp/log.js +213 -0
  185. package/dist/shell/interp/log.js.map +1 -0
  186. package/dist/shell/interp/process.js +178 -0
  187. package/dist/shell/interp/process.js.map +1 -0
  188. package/dist/shell/interp/runlog.js +193 -0
  189. package/dist/shell/interp/runlog.js.map +1 -0
  190. package/dist/shell/interp/timer.js +64 -0
  191. package/dist/shell/interp/timer.js.map +1 -0
  192. package/dist/shell/interp/tracker-disk.js +99 -0
  193. package/dist/shell/interp/tracker-disk.js.map +1 -0
  194. package/dist/shell/interp/tracker-parse.js +71 -0
  195. package/dist/shell/interp/tracker-parse.js.map +1 -0
  196. package/dist/shell/interp/tracker-scan.js +238 -0
  197. package/dist/shell/interp/tracker-scan.js.map +1 -0
  198. package/dist/shell/interp/tracker-write.js +91 -0
  199. package/dist/shell/interp/tracker-write.js.map +1 -0
  200. package/dist/shell/interp/tracker.js +41 -0
  201. package/dist/shell/interp/tracker.js.map +1 -0
  202. package/dist/shell/interp/tty.js +48 -0
  203. package/dist/shell/interp/tty.js.map +1 -0
  204. package/dist/shell/interp/vm.js +199 -0
  205. package/dist/shell/interp/vm.js.map +1 -0
  206. package/dist/shell/interp/workspace.js +310 -0
  207. package/dist/shell/interp/workspace.js.map +1 -0
  208. package/dist/shell/main-acp.js +78 -0
  209. package/dist/shell/main-acp.js.map +1 -0
  210. package/dist/shell/main-adapters.js +222 -0
  211. package/dist/shell/main-adapters.js.map +1 -0
  212. package/dist/shell/main-credential.js +122 -0
  213. package/dist/shell/main-credential.js.map +1 -0
  214. package/dist/shell/main-doctor.js +22 -0
  215. package/dist/shell/main-doctor.js.map +1 -0
  216. package/dist/shell/main-entry.js +46 -0
  217. package/dist/shell/main-entry.js.map +1 -0
  218. package/dist/shell/main-http-csrf.js +45 -0
  219. package/dist/shell/main-http-csrf.js.map +1 -0
  220. package/dist/shell/main-http-handler.js +389 -0
  221. package/dist/shell/main-http-handler.js.map +1 -0
  222. package/dist/shell/main-http-mcp.js +122 -0
  223. package/dist/shell/main-http-mcp.js.map +1 -0
  224. package/dist/shell/main-http-views.js +253 -0
  225. package/dist/shell/main-http-views.js.map +1 -0
  226. package/dist/shell/main-http.js +76 -0
  227. package/dist/shell/main-http.js.map +1 -0
  228. package/dist/shell/main-loops.js +130 -0
  229. package/dist/shell/main-loops.js.map +1 -0
  230. package/dist/shell/main-mcp.js +129 -0
  231. package/dist/shell/main-mcp.js.map +1 -0
  232. package/dist/shell/main-orchestrator.js +120 -0
  233. package/dist/shell/main-orchestrator.js.map +1 -0
  234. package/dist/shell/main-preflight.js +43 -0
  235. package/dist/shell/main-preflight.js.map +1 -0
  236. package/dist/shell/main-reconcilers-helpers.js +244 -0
  237. package/dist/shell/main-reconcilers-helpers.js.map +1 -0
  238. package/dist/shell/main-reconcilers-pr.js +148 -0
  239. package/dist/shell/main-reconcilers-pr.js.map +1 -0
  240. package/dist/shell/main-reconcilers.js +225 -0
  241. package/dist/shell/main-reconcilers.js.map +1 -0
  242. package/dist/shell/main-runner.js +355 -0
  243. package/dist/shell/main-runner.js.map +1 -0
  244. package/dist/shell/main-scaffold.js +116 -0
  245. package/dist/shell/main-scaffold.js.map +1 -0
  246. package/dist/shell/main-shutdown.js +115 -0
  247. package/dist/shell/main-shutdown.js.map +1 -0
  248. package/dist/shell/main-startup.js +48 -0
  249. package/dist/shell/main-startup.js.map +1 -0
  250. package/dist/shell/main-substrates.js +43 -0
  251. package/dist/shell/main-substrates.js.map +1 -0
  252. package/dist/shell/main.js +385 -0
  253. package/dist/shell/main.js.map +1 -0
  254. package/dist/shell/orchestrator-feedback.js +69 -0
  255. package/dist/shell/orchestrator-feedback.js.map +1 -0
  256. package/dist/shell/orchestrator-image.js +167 -0
  257. package/dist/shell/orchestrator-image.js.map +1 -0
  258. package/dist/shell/orchestrator-loop.js +468 -0
  259. package/dist/shell/orchestrator-loop.js.map +1 -0
  260. package/dist/shell/orchestrator-reconcile.js +36 -0
  261. package/dist/shell/orchestrator-reconcile.js.map +1 -0
  262. package/dist/shell/reconciler-loop.js +228 -0
  263. package/dist/shell/reconciler-loop.js.map +1 -0
  264. package/dist/shell/runner-loop-turn.js +301 -0
  265. package/dist/shell/runner-loop-turn.js.map +1 -0
  266. package/dist/shell/runner-loop.js +338 -0
  267. package/dist/shell/runner-loop.js.map +1 -0
  268. package/dist/shell/server/http.js +208 -0
  269. package/dist/shell/server/http.js.map +1 -0
  270. package/dist/shell/server/mcp-runtime-effects.js +237 -0
  271. package/dist/shell/server/mcp-runtime-effects.js.map +1 -0
  272. package/dist/shell/server/mcp-runtime.js +99 -0
  273. package/dist/shell/server/mcp-runtime.js.map +1 -0
  274. package/dist/shell/workspace-key.js +14 -0
  275. package/dist/shell/workspace-key.js.map +1 -0
  276. package/dist/types/acp.js +8 -0
  277. package/dist/types/acp.js.map +1 -0
  278. package/dist/types/actions/plan.js +6 -0
  279. package/dist/types/actions/plan.js.map +1 -0
  280. package/dist/types/actions/predicates.js +6 -0
  281. package/dist/types/actions/predicates.js.map +1 -0
  282. package/dist/types/actions/run-fold.js +8 -0
  283. package/dist/types/actions/run-fold.js.map +1 -0
  284. package/dist/types/actions.js +7 -0
  285. package/dist/types/actions.js.map +1 -0
  286. package/dist/types/adapter/clock-random.js +4 -0
  287. package/dist/types/adapter/clock-random.js.map +1 -0
  288. package/dist/types/adapter/gondolin-image-converter.js +5 -0
  289. package/dist/types/adapter/gondolin-image-converter.js.map +1 -0
  290. package/dist/types/adapter/gondolin-image-fetch.js +5 -0
  291. package/dist/types/adapter/gondolin-image-fetch.js.map +1 -0
  292. package/dist/types/adapter/workflow-loader.js +4 -0
  293. package/dist/types/adapter/workflow-loader.js.map +1 -0
  294. package/dist/types/cli/args.js +8 -0
  295. package/dist/types/cli/args.js.map +1 -0
  296. package/dist/types/config.js +8 -0
  297. package/dist/types/config.js.map +1 -0
  298. package/dist/types/credential-interp.js +6 -0
  299. package/dist/types/credential-interp.js.map +1 -0
  300. package/dist/types/credentials.js +10 -0
  301. package/dist/types/credentials.js.map +1 -0
  302. package/dist/types/doctor.js +7 -0
  303. package/dist/types/doctor.js.map +1 -0
  304. package/dist/types/domain.js +7 -0
  305. package/dist/types/domain.js.map +1 -0
  306. package/dist/types/effect.js +15 -0
  307. package/dist/types/effect.js.map +1 -0
  308. package/dist/types/errors.js +39 -0
  309. package/dist/types/errors.js.map +1 -0
  310. package/dist/types/http/decisions.js +6 -0
  311. package/dist/types/http/decisions.js.map +1 -0
  312. package/dist/types/http/render.js +10 -0
  313. package/dist/types/http/render.js.map +1 -0
  314. package/dist/types/http/views.js +6 -0
  315. package/dist/types/http/views.js.map +1 -0
  316. package/dist/types/http.js +9 -0
  317. package/dist/types/http.js.map +1 -0
  318. package/dist/types/image/managed-image.js +7 -0
  319. package/dist/types/image/managed-image.js.map +1 -0
  320. package/dist/types/interp/effect-interpreter.js +8 -0
  321. package/dist/types/interp/effect-interpreter.js.map +1 -0
  322. package/dist/types/interp/tracker.js +7 -0
  323. package/dist/types/interp/tracker.js.map +1 -0
  324. package/dist/types/issue/file.js +6 -0
  325. package/dist/types/issue/file.js.map +1 -0
  326. package/dist/types/issue/parse.js +8 -0
  327. package/dist/types/issue/parse.js.map +1 -0
  328. package/dist/types/main-acp.js +13 -0
  329. package/dist/types/main-acp.js.map +1 -0
  330. package/dist/types/main-adapters.js +5 -0
  331. package/dist/types/main-adapters.js.map +1 -0
  332. package/dist/types/main-credential.js +21 -0
  333. package/dist/types/main-credential.js.map +1 -0
  334. package/dist/types/main-doctor.js +6 -0
  335. package/dist/types/main-doctor.js.map +1 -0
  336. package/dist/types/main-http-handler.js +12 -0
  337. package/dist/types/main-http-handler.js.map +1 -0
  338. package/dist/types/main-http.js +5 -0
  339. package/dist/types/main-http.js.map +1 -0
  340. package/dist/types/main-loops.js +5 -0
  341. package/dist/types/main-loops.js.map +1 -0
  342. package/dist/types/main-mcp.js +12 -0
  343. package/dist/types/main-mcp.js.map +1 -0
  344. package/dist/types/main-orchestrator.js +5 -0
  345. package/dist/types/main-orchestrator.js.map +1 -0
  346. package/dist/types/main-reconcilers.js +11 -0
  347. package/dist/types/main-reconcilers.js.map +1 -0
  348. package/dist/types/main-runner.js +13 -0
  349. package/dist/types/main-runner.js.map +1 -0
  350. package/dist/types/main-startup.js +5 -0
  351. package/dist/types/main-startup.js.map +1 -0
  352. package/dist/types/main-substrates.js +5 -0
  353. package/dist/types/main-substrates.js.map +1 -0
  354. package/dist/types/mcp/dispatch.js +4 -0
  355. package/dist/types/mcp/dispatch.js.map +1 -0
  356. package/dist/types/mcp/post-move.js +7 -0
  357. package/dist/types/mcp/post-move.js.map +1 -0
  358. package/dist/types/mcp.js +9 -0
  359. package/dist/types/mcp.js.map +1 -0
  360. package/dist/types/ports.js +12 -0
  361. package/dist/types/ports.js.map +1 -0
  362. package/dist/types/reconcile/image-decide.js +5 -0
  363. package/dist/types/reconcile/image-decide.js.map +1 -0
  364. package/dist/types/reconcile/ledger.js +7 -0
  365. package/dist/types/reconcile/ledger.js.map +1 -0
  366. package/dist/types/reconcile/pr-loop.js +8 -0
  367. package/dist/types/reconcile/pr-loop.js.map +1 -0
  368. package/dist/types/reconcile/vm-reap.js +8 -0
  369. package/dist/types/reconcile/vm-reap.js.map +1 -0
  370. package/dist/types/reconcile/workspace-decide.js +7 -0
  371. package/dist/types/reconcile/workspace-decide.js.map +1 -0
  372. package/dist/types/reconcile.js +9 -0
  373. package/dist/types/reconcile.js.map +1 -0
  374. package/dist/types/runlog.js +7 -0
  375. package/dist/types/runlog.js.map +1 -0
  376. package/dist/types/runner/actions-runner.js +12 -0
  377. package/dist/types/runner/actions-runner.js.map +1 -0
  378. package/dist/types/runner/gondolin-dispatch.js +5 -0
  379. package/dist/types/runner/gondolin-dispatch.js.map +1 -0
  380. package/dist/types/runner/injection.js +6 -0
  381. package/dist/types/runner/injection.js.map +1 -0
  382. package/dist/types/runner/runner-loop.js +5 -0
  383. package/dist/types/runner/runner-loop.js.map +1 -0
  384. package/dist/types/runner/turn.js +4 -0
  385. package/dist/types/runner/turn.js.map +1 -0
  386. package/dist/types/runner/vm-plan.js +4 -0
  387. package/dist/types/runner/vm-plan.js.map +1 -0
  388. package/dist/types/runtime.js +9 -0
  389. package/dist/types/runtime.js.map +1 -0
  390. package/dist/types/schedule/admission.js +7 -0
  391. package/dist/types/schedule/admission.js.map +1 -0
  392. package/dist/types/schedule/circuit-breaker.js +2 -0
  393. package/dist/types/schedule/circuit-breaker.js.map +1 -0
  394. package/dist/types/schedule/eligibility.js +9 -0
  395. package/dist/types/schedule/eligibility.js.map +1 -0
  396. package/dist/types/schedule/orchestrator-loop.js +10 -0
  397. package/dist/types/schedule/orchestrator-loop.js.map +1 -0
  398. package/dist/types/schedule/sleep-cycle.js +4 -0
  399. package/dist/types/schedule/sleep-cycle.js.map +1 -0
  400. package/dist/types/schedule/slots.js +8 -0
  401. package/dist/types/schedule/slots.js.map +1 -0
  402. package/dist/types/schedule/tick.js +9 -0
  403. package/dist/types/schedule/tick.js.map +1 -0
  404. package/dist/types/server/mcp-runtime.js +8 -0
  405. package/dist/types/server/mcp-runtime.js.map +1 -0
  406. package/dist/types/workflow/parse.js +4 -0
  407. package/dist/types/workflow/parse.js.map +1 -0
  408. package/package.json +22 -10
  409. package/patches/@earendil-works+gondolin+0.12.0.patch +173 -0
  410. package/prompts/Reflect.md +91 -0
  411. package/prompts/Review.md +97 -0
  412. package/prompts/Todo.md +96 -0
  413. package/prompts/_footer.md +41 -0
  414. package/prompts/_preamble.md +42 -0
  415. package/prompts-minimal/Todo.md +26 -0
  416. package/scripts/postinstall.mjs +63 -0
  417. package/scripts/vm-agent.mjs +312 -90
  418. package/WORKFLOW.md +0 -744
  419. package/dist/acp-bridge.js +0 -324
  420. package/dist/acp-bridge.js.map +0 -1
  421. package/dist/actions/cache.js +0 -191
  422. package/dist/actions/cache.js.map +0 -1
  423. package/dist/actions/effects.js +0 -41
  424. package/dist/actions/effects.js.map +0 -1
  425. package/dist/actions/executor.js +0 -570
  426. package/dist/actions/executor.js.map +0 -1
  427. package/dist/actions/index.js +0 -13
  428. package/dist/actions/index.js.map +0 -1
  429. package/dist/actions/parsing.js.map +0 -1
  430. package/dist/actions/predicate-env.js +0 -27
  431. package/dist/actions/predicate-env.js.map +0 -1
  432. package/dist/actions/predicates.js +0 -49
  433. package/dist/actions/predicates.js.map +0 -1
  434. package/dist/actions/templating.js +0 -66
  435. package/dist/actions/templating.js.map +0 -1
  436. package/dist/actions/types.js +0 -15
  437. package/dist/actions/types.js.map +0 -1
  438. package/dist/agent/acp.js +0 -473
  439. package/dist/agent/acp.js.map +0 -1
  440. package/dist/agent/adapter-names.js +0 -159
  441. package/dist/agent/adapter-names.js.map +0 -1
  442. package/dist/agent/adapters.js +0 -511
  443. package/dist/agent/adapters.js.map +0 -1
  444. package/dist/agent/credential-extractors.js +0 -342
  445. package/dist/agent/credential-extractors.js.map +0 -1
  446. package/dist/agent/credential-secrets.js +0 -628
  447. package/dist/agent/credential-secrets.js.map +0 -1
  448. package/dist/agent/credential-ticker.js +0 -57
  449. package/dist/agent/credential-ticker.js.map +0 -1
  450. package/dist/agent/gondolin-creds-staging.js +0 -356
  451. package/dist/agent/gondolin-creds-staging.js.map +0 -1
  452. package/dist/agent/gondolin-dispatch.js +0 -375
  453. package/dist/agent/gondolin-dispatch.js.map +0 -1
  454. package/dist/agent/gondolin.js +0 -124
  455. package/dist/agent/gondolin.js.map +0 -1
  456. package/dist/agent/runner-decisions.js +0 -134
  457. package/dist/agent/runner-decisions.js.map +0 -1
  458. package/dist/agent/runner.js +0 -1456
  459. package/dist/agent/runner.js.map +0 -1
  460. package/dist/agent/tool-call-summary.js +0 -102
  461. package/dist/agent/tool-call-summary.js.map +0 -1
  462. package/dist/agent/vm-acp-mapping.js +0 -73
  463. package/dist/agent/vm-acp-mapping.js.map +0 -1
  464. package/dist/agent/vm-guards.js +0 -262
  465. package/dist/agent/vm-guards.js.map +0 -1
  466. package/dist/agent/vm-port.js +0 -22
  467. package/dist/agent/vm-port.js.map +0 -1
  468. package/dist/agent/vm-process-registry.js +0 -79
  469. package/dist/agent/vm-process-registry.js.map +0 -1
  470. package/dist/bin/cli-args.js +0 -105
  471. package/dist/bin/cli-args.js.map +0 -1
  472. package/dist/errors.js +0 -15
  473. package/dist/errors.js.map +0 -1
  474. package/dist/http-disk.js +0 -135
  475. package/dist/http-disk.js.map +0 -1
  476. package/dist/http-handlers.js.map +0 -1
  477. package/dist/http.js.map +0 -1
  478. package/dist/issues.js +0 -178
  479. package/dist/issues.js.map +0 -1
  480. package/dist/logging.js +0 -203
  481. package/dist/logging.js.map +0 -1
  482. package/dist/mcp.js +0 -706
  483. package/dist/mcp.js.map +0 -1
  484. package/dist/memory.js +0 -85
  485. package/dist/memory.js.map +0 -1
  486. package/dist/orchestrator-decisions.js +0 -331
  487. package/dist/orchestrator-decisions.js.map +0 -1
  488. package/dist/orchestrator.js +0 -1569
  489. package/dist/orchestrator.js.map +0 -1
  490. package/dist/prompt.js +0 -65
  491. package/dist/prompt.js.map +0 -1
  492. package/dist/reconciler/cache.js +0 -65
  493. package/dist/reconciler/cache.js.map +0 -1
  494. package/dist/reconciler/index.js +0 -448
  495. package/dist/reconciler/index.js.map +0 -1
  496. package/dist/reconciler/ledger.js +0 -131
  497. package/dist/reconciler/ledger.js.map +0 -1
  498. package/dist/reconciler/pr-adapters.js +0 -174
  499. package/dist/reconciler/pr-adapters.js.map +0 -1
  500. package/dist/reconciler/pr-decide.js.map +0 -1
  501. package/dist/reconciler/pr.js +0 -422
  502. package/dist/reconciler/pr.js.map +0 -1
  503. package/dist/reconciler/types.js +0 -12
  504. package/dist/reconciler/types.js.map +0 -1
  505. package/dist/reconciler/vm.js +0 -243
  506. package/dist/reconciler/vm.js.map +0 -1
  507. package/dist/reconciler/workspace-defaults.js +0 -83
  508. package/dist/reconciler/workspace-defaults.js.map +0 -1
  509. package/dist/reconciler/workspace.js +0 -272
  510. package/dist/reconciler/workspace.js.map +0 -1
  511. package/dist/runlog.js +0 -403
  512. package/dist/runlog.js.map +0 -1
  513. package/dist/scaffold.js +0 -165
  514. package/dist/scaffold.js.map +0 -1
  515. package/dist/trackers/local.js +0 -445
  516. package/dist/trackers/local.js.map +0 -1
  517. package/dist/trackers/types.js +0 -10
  518. package/dist/trackers/types.js.map +0 -1
  519. package/dist/types.js +0 -3
  520. package/dist/types.js.map +0 -1
  521. package/dist/util/clock.js +0 -12
  522. package/dist/util/clock.js.map +0 -1
  523. package/dist/util/crypto.js +0 -25
  524. package/dist/util/crypto.js.map +0 -1
  525. package/dist/util/frontmatter.js +0 -70
  526. package/dist/util/frontmatter.js.map +0 -1
  527. package/dist/util/fs-issues.js +0 -22
  528. package/dist/util/fs-issues.js.map +0 -1
  529. package/dist/util/process.js +0 -152
  530. package/dist/util/process.js.map +0 -1
  531. package/dist/util/workspace-key.js +0 -10
  532. package/dist/util/workspace-key.js.map +0 -1
  533. package/dist/workflow-loader.js +0 -147
  534. package/dist/workflow-loader.js.map +0 -1
  535. package/dist/workflow.js +0 -822
  536. package/dist/workflow.js.map +0 -1
  537. package/dist/workspace-types.js +0 -8
  538. package/dist/workspace-types.js.map +0 -1
  539. package/dist/workspace.js +0 -443
  540. package/dist/workspace.js.map +0 -1
@@ -1,628 +0,0 @@
1
- // Host credential-secrets module — homes the credential *lifecycle* (extract,
2
- // mint, refresh) onto Gondolin's secret-injection model. Instead of an HTTP
3
- // proxy that mints per-dispatch sentinels and forwards upstream (the retired
4
- // credential-proxy transport), we hand Gondolin a `createHttpHooks(...)` config
5
- // per VM (host allowlist + a token-shaped placeholder secret + request/response
6
- // hooks) and let Gondolin substitute the real access token into the outbound
7
- // request at egress (TLS-MITM). The host stays the sole owner of the durable
8
- // refresh token; the guest only ever sees a placeholder. See
9
- // `docs/research/gondolin-sandbox-migration.md` §3 (the host-only-refresh
10
- // invariant), §4.3 (the per-VM fan-out design), §4.4 (per-adapter routing).
11
- //
12
- // The host-side credential primitives (token extractors, the GitHub→Copilot
13
- // mint, the flock-serialized refresh) live in `credential-extractors.ts`; this
14
- // module reuses them + `adapter-names.ts` rather than duplicating — only the
15
- // *shape* of the output (a Gondolin hooks config + an `updateSecret` push) is new.
16
- //
17
- // The §4.3 fan-out, restated as the contract this module owns:
18
- // - Each VM gets its own `createHttpHooks` instance, so each has its own
19
- // `secretManager` whose live `value` Gondolin reads per-request. A push-based
20
- // model means a missed `updateSecret` leaves THAT VM stale (and its
21
- // `revokedValues` never learns the old token, silently dropping revocation
22
- // for that VM). So this module owns a REGISTRY of every live manager and, on
23
- // each rotation, pushes the fresh value to ALL of them.
24
- // - A manager torn down mid-push must not throw — it is dropped.
25
- // - A VM created *during* a refresh must observe the latest value at create
26
- // time (seed from the module's cached value), never start stale.
27
- // - A per-VM proactive tick keyed off `expiresAt` keeps a long dispatch fresh
28
- // without relying solely on the global ticker cadence.
29
- import path from 'node:path';
30
- import os from 'node:os';
31
- import { Buffer } from 'node:buffer';
32
- import { createHttpHooks, makePlaceholderFunc, BASE62_ALPHABET, BASE64URL_ALPHABET, } from '@earendil-works/gondolin';
33
- import { log } from '../logging.js';
34
- import { hostOpencodeCredentialPath, opencodeGithubTokenFromAuth, opencodeGithubTokenFromEnv, } from './adapter-names.js';
35
- import { validAccountId } from './gondolin-creds-staging.js';
36
- import { extractClaudeToken, extractCodexToken, codexEnvFallback, defaultClaudeRefresher, defaultCopilotExchange, defaultFlockAcquire, COPILOT_EGRESS_HEADERS, COPILOT_EXCHANGE_HOST, COPILOT_EXCHANGE_PATH, COPILOT_INFERENCE_HOST, } from './credential-extractors.js';
37
- // ---------------------------------------------------------------------------
38
- // Per-adapter static config (placeholder shape, secret env var name, hosts).
39
- // ---------------------------------------------------------------------------
40
- /**
41
- * The env var / secret name each adapter's placeholder is keyed under. These are
42
- * the SAME names the in-VM client reads its bearer from (claude reads
43
- * `ANTHROPIC_AUTH_TOKEN`, codex `OPENAI_API_KEY`); `createHttpHooks` returns an
44
- * `env` map keyed by these so the runner can stage the placeholder into the VM
45
- * env / fake creds files.
46
- */
47
- const CLAUDE_SECRET_NAME = 'ANTHROPIC_AUTH_TOKEN';
48
- const CODEX_SECRET_NAME = 'OPENAI_API_KEY';
49
- const OPENCODE_SECRET_NAME = 'OPENCODE_PROXY_TOKEN';
50
- const CLAUDE_UPSTREAM_HOST = 'api.anthropic.com';
51
- const CODEX_UPSTREAM_HOST = 'chatgpt.com';
52
- /**
53
- * Token-shaped placeholder generators. The default `GONDOLIN_SECRET_…`
54
- * placeholder can fail a client's own token-shape validation BEFORE egress
55
- * substitution, so each adapter gets a placeholder shaped like the real token it
56
- * stands in for (design §4.3). `sk-ant-` for claude, `sk-` for codex's OpenAI
57
- * key shape, `gho_`-ish for the opencode Copilot bearer. The generator is called
58
- * ONCE at `createHttpHooks()` time; the real value arrives via `seedValue` /
59
- * `updateSecret` and is never the placeholder.
60
- */
61
- function claudePlaceholder() {
62
- return makePlaceholderFunc({ prefix: 'sk-ant-', length: 64, alphabet: BASE62_ALPHABET });
63
- }
64
- /**
65
- * codex (ChatGPT-OAuth) runs in its NATIVE mode reading
66
- * `~/.codex/auth.json:tokens.access_token` as its bearer, so the placeholder must
67
- * be JWT-SHAPED (header.payload.signature) with a far-future `exp` — otherwise
68
- * codex treats it as expired and tries to refresh (egress-blocked, doomed). The
69
- * placeholder Gondolin substitutes at egress must be byte-identical to that
70
- * bearer, so the SAME assembled JWT is both the secret's placeholder here and the
71
- * staged `tokens.access_token` (see `gondolin-creds-staging.ts`, which reads this
72
- * placeholder out of `createHttpHooks().env` verbatim). The header + payload are
73
- * fixed; the signature segment is a high-entropy random string so each VM's
74
- * placeholder is unique + exact-matchable. Built once at `createHttpHooks()` time.
75
- *
76
- * GO-LIVE FINDING: codex-acp's local auth manager reads the
77
- * `https://api.openai.com/auth` claim (specifically `chatgpt_account_id`) out of
78
- * the bearer JWT *before* any egress. A placeholder with only `{ exp }` (no auth
79
- * claim) makes codex-acp consider the token incomplete and attempt a token
80
- * REFRESH mid-turn — which is egress-blocked → 403 → the turn is refused. The
81
- * spike's C7 placeholder embedded that claim and passed; production had dropped
82
- * it. So when the host `account_id` is known we embed it in the placeholder's
83
- * auth claim. The id is a NON-SECRET identifier (same one staged into auth.json's
84
- * `tokens.account_id`), never a token.
85
- */
86
- function codexPlaceholder(accountId) {
87
- const randomSig = makePlaceholderFunc({ length: 86, alphabet: BASE64URL_ALPHABET });
88
- return () => assemblePlaceholderJwt(randomSig(), accountId);
89
- }
90
- function opencodePlaceholder() {
91
- // The opencode custom provider forwards this as its bearer; a `gho_`-shaped
92
- // token keeps it indistinguishable in shape from a real Copilot/GitHub token.
93
- return makePlaceholderFunc({ prefix: 'gho_', length: 36, alphabet: BASE64URL_ALPHABET });
94
- }
95
- /**
96
- * Far-future JWT `exp` (seconds since epoch — 2100-01-01T00:00:00Z) baked into the
97
- * codex placeholder so codex's native mode treats it as a long-lived, unexpired
98
- * token and never attempts a refresh (which would be egress-blocked). Exported so
99
- * the fake-creds staging + tests can assert the same instant.
100
- */
101
- export const PLACEHOLDER_JWT_EXP_SECONDS = 4_102_444_800;
102
- /**
103
- * Assemble a structurally-valid (but cryptographically meaningless) JWT-shaped
104
- * placeholder: `base64url(header).base64url(payload).<signature>`. codex never
105
- * verifies the signature — it reads `exp` (must be far-future, so it never tries
106
- * to refresh) and the `https://api.openai.com/auth.chatgpt_account_id` claim
107
- * (which it uses to route + to consider the token complete; a missing claim
108
- * triggers a refresh, see `codexPlaceholder`). The real token replaces this whole
109
- * string at egress. The `signature` segment is the caller's high-entropy random
110
- * string, making each VM's placeholder unique + exact-matchable by Gondolin's
111
- * header substitution.
112
- *
113
- * `accountId` is the NON-SECRET `chatgpt_account_id` (when known); embedding it in
114
- * the auth claim mirrors the spike's proven C7 placeholder. When null (host has no
115
- * account_id) the claim is omitted — the JWT is still well-formed; codex may then
116
- * refresh, but there is no id to embed.
117
- *
118
- * SAFETY-CRITICAL (codex review, HIGH): this JWT becomes the guest's staged BEARER,
119
- * so this is the LAST chokepoint before a host `account_id` lands in a bearer slot.
120
- * The id is re-validated through the SHARED {@link validAccountId} UUID guard here
121
- * (defense-in-depth — independent of the caller's own validation): a non-UUID /
122
- * token-shaped value is NOT embedded; the claim is simply OMITTED (the well-formed,
123
- * SAFE failure). A real token (JWT / `sk-…` / refresh) never matches a UUID, so it
124
- * can never reach the `chatgpt_account_id` claim via this path.
125
- */
126
- export function assemblePlaceholderJwt(signature, accountId = null) {
127
- const safeAccountId = validAccountId(accountId);
128
- const header = base64urlJson({ alg: 'RS256', typ: 'JWT' });
129
- const payload = base64urlJson({
130
- exp: PLACEHOLDER_JWT_EXP_SECONDS,
131
- ...(safeAccountId !== null
132
- ? { 'https://api.openai.com/auth': { chatgpt_account_id: safeAccountId } }
133
- : {}),
134
- });
135
- return `${header}.${payload}.${signature}`;
136
- }
137
- function base64urlJson(obj) {
138
- return Buffer.from(JSON.stringify(obj), 'utf8').toString('base64url');
139
- }
140
- /** Read+parse a JSON credential file; returns null on any IO/parse failure. */
141
- async function readJsonFile(p) {
142
- // Lazy fs import keeps this module's IO surface in one place; the proxy keeps
143
- // its own readFile. (No core-purity concern: this is an adapter.)
144
- const { readFile } = await import('node:fs/promises');
145
- let raw;
146
- try {
147
- raw = await readFile(p, 'utf8');
148
- }
149
- catch (err) {
150
- log.warn('credential-secrets: cannot read credentials', {
151
- path: p,
152
- error: err.message,
153
- });
154
- return null;
155
- }
156
- try {
157
- return JSON.parse(raw);
158
- }
159
- catch (err) {
160
- log.warn('credential-secrets: credentials JSON parse failed', {
161
- path: p,
162
- error: err.message,
163
- });
164
- return null;
165
- }
166
- }
167
- function defaultClaudeCredentialsPath() {
168
- return path.join(os.homedir(), '.claude', '.credentials.json');
169
- }
170
- function defaultCodexCredentialsPath() {
171
- return path.join(os.homedir(), '.codex', 'auth.json');
172
- }
173
- function defaultLockPath() {
174
- return path.join(os.homedir(), '.symphony', 'oauth', 'refresh.lock');
175
- }
176
- /** Wrap a refresher in the shared cross-process flock + in-flight collapse. */
177
- function underLock(lockAcquire, lockTimeoutMs, refresher) {
178
- return async () => {
179
- let release = null;
180
- try {
181
- release = await lockAcquire(lockTimeoutMs);
182
- }
183
- catch (err) {
184
- // Fail closed: do NOT run the refresher unserialized (it would race a peer
185
- // against the same credentials file). The caller re-reads the cache and
186
- // picks up whatever the lock-holding peer rotated to (mirrors the proxy's
187
- // `runRefreshUnderLock`).
188
- log.warn('credential-secrets: lock acquire failed; skipping refresh', {
189
- error: err.message,
190
- });
191
- throw new Error('credential-secrets: refresh lock acquire timeout');
192
- }
193
- try {
194
- await refresher();
195
- }
196
- finally {
197
- await release().catch((err) => log.warn('credential-secrets: lock release error', { error: err.message }));
198
- }
199
- };
200
- }
201
- /**
202
- * Build the per-adapter credential specs. Reuses the proxy's extractors + mint +
203
- * flock helpers; the only new behavior is the Gondolin-shaped delivery and the
204
- * opencode `onRequest` path-allowlist (§4.4).
205
- */
206
- export function buildAdapterCredentialSpecs(opts = {}) {
207
- const lockPath = opts.lockPath ?? defaultLockPath();
208
- const lockAcquire = opts.lockAcquire ?? defaultFlockAcquire(lockPath);
209
- const lockTimeoutMs = opts.lockAcquireTimeoutMs ?? 90_000;
210
- const claudeCredsPath = opts.claudeCredentialsPath ?? defaultClaudeCredentialsPath();
211
- const codexCredsPath = opts.codexCredentialsPath ?? defaultCodexCredentialsPath();
212
- const opencodeCredsPath = opts.opencodeCredentialsPath ?? hostOpencodeCredentialPath();
213
- const claudeRefresher = underLock(lockAcquire, lockTimeoutMs, opts.claudeRefresher ?? defaultClaudeRefresher());
214
- return {
215
- claude: {
216
- adapterId: 'claude',
217
- secretName: CLAUDE_SECRET_NAME,
218
- substitutionHosts: [CLAUDE_UPSTREAM_HOST],
219
- placeholder: claudePlaceholder,
220
- readToken: async () => extractClaudeToken(await readJsonFile(claudeCredsPath)),
221
- refresh: claudeRefresher,
222
- allowWebSockets: false, // plain HTTPS
223
- },
224
- codex: {
225
- adapterId: 'codex',
226
- secretName: CODEX_SECRET_NAME,
227
- substitutionHosts: [CODEX_UPSTREAM_HOST],
228
- // codex-acp streams /backend-api/codex/responses over a WebSocket Upgrade.
229
- // It MUST be allowed: the real token is substituted on the hookable Upgrade
230
- // handshake (createHttpHooks onRequest → applySecretsToRequest), so the
231
- // handshake reaches the ALLOWLISTED inference host with the real bearer and
232
- // gets a clean 101; the post-101 frames are an opaque tunnel to that one
233
- // host. SAFE — the placeholder never egresses and a non-allowlisted refresh
234
- // host's upgrade is blocked. The earlier "post-101 tunnel drop" was a red
235
- // herring: it was caused by an INCOMPLETE staged auth.json (codex 0.135
236
- // judged the creds incomplete → sent no bearer → 401 → blocked refresh). With
237
- // a COMPLETE staged auth.json (auth_mode + last_refresh + the tokens block —
238
- // see gondolin-creds-staging.ts buildCodexFiles) the WS turn completes
239
- // end-to-end (validated 2026-05-30 through the production dispatch path).
240
- allowWebSockets: true,
241
- // Bind the host account_id into the placeholder JWT's auth claim so
242
- // codex-acp does not refresh the placeholder (go-live finding).
243
- placeholder: () => codexPlaceholder(opts.codexAccountId ?? null),
244
- // codex tokens are long-TTL (~8 days): re-read on demand, never drive an
245
- // OpenAI refresh dance — identical to the proxy's posture.
246
- readToken: async () => extractCodexToken(await readJsonFile(codexCredsPath)) ?? codexEnvFallback(),
247
- refresh: () => Promise.reject(new Error('credential-secrets: codex refresh is host-owned (long-TTL); not driven here')),
248
- },
249
- opencode: buildOpencodeSpec({
250
- credentialsPath: opencodeCredsPath,
251
- lockAcquire,
252
- lockTimeoutMs,
253
- exchange: opts.copilotExchange ?? defaultCopilotExchange(),
254
- }),
255
- };
256
- }
257
- /**
258
- * The opencode spec is HOST-MINT (operator rule: "no real tokens in the VM").
259
- * The host runs the GitHub→Copilot exchange and pushes the minted Copilot token
260
- * via `updateSecret`; the guest's custom provider sends only a placeholder
261
- * bearer against `api.githubcopilot.com`. The durable GitHub token never enters
262
- * the guest. The exchange host (`api.github.com`) is allowlisted ONLY so the
263
- * host-side exchange can reach it — guarded by the `onRequest` path-allowlist
264
- * below so a guest cannot turn that allowlist entry into a durable-token oracle.
265
- */
266
- function buildOpencodeSpec(args) {
267
- // In-memory cache of the short-lived Copilot token (the durable GitHub token
268
- // stays host-side and never lands here as the bearer).
269
- const cache = { token: null };
270
- const mint = async () => {
271
- const githubToken = await readOpencodeGithubToken(args.credentialsPath);
272
- if (githubToken === null) {
273
- throw new Error('credential-secrets: opencode has no GitHub Copilot token to exchange (auth.json + env both empty)');
274
- }
275
- cache.token = await args.exchange(githubToken);
276
- };
277
- return {
278
- adapterId: 'opencode',
279
- secretName: OPENCODE_SECRET_NAME,
280
- // Inference host + the host-mint exchange host. The exchange host is gated by
281
- // `onRequest` (only GET /copilot_internal/v2/token) — the durable-token
282
- // oracle guard (§4.4). Both are substitution hosts: the minted Copilot token
283
- // is valid on inference, and the exchange handshake is hookable on the
284
- // exchange host (the placeholder never egresses).
285
- substitutionHosts: [COPILOT_INFERENCE_HOST, COPILOT_EXCHANGE_HOST],
286
- placeholder: opencodePlaceholder,
287
- egressHeaders: COPILOT_EGRESS_HEADERS,
288
- // The minted Copilot token is the secret value; reading it returns the cache
289
- // (null until the first mint runs as `refresh`).
290
- readToken: async () => cache.token,
291
- refresh: underLock(args.lockAcquire, args.lockTimeoutMs, mint),
292
- onRequest: makeGithubExchangePathGuard(),
293
- allowWebSockets: false, // openai-compatible HTTP provider
294
- };
295
- }
296
- /** Read the durable GitHub OAuth token: opencode auth.json first, then env. */
297
- async function readOpencodeGithubToken(credentialsPath) {
298
- const parsed = await readJsonFile(credentialsPath);
299
- if (parsed !== null) {
300
- const fromFile = opencodeGithubTokenFromAuth(parsed);
301
- if (fromFile !== null)
302
- return fromFile;
303
- }
304
- return opencodeGithubTokenFromEnv(process.env);
305
- }
306
- // ---------------------------------------------------------------------------
307
- // onRequest guards.
308
- // ---------------------------------------------------------------------------
309
- /**
310
- * Egress audit. Wraps an adapter's optional `onRequest` guard with a log line for
311
- * EVERY guest egress request. Gondolin invokes `onRequest` before its host allow/deny
312
- * check, so this sees every request the guest attempts — allowed, about-to-be-blocked,
313
- * and TLS-MITM'd inference calls alike — the only host-side visibility into in-VM
314
- * egress (the ACP run log captures only ACP frames + adapter stderr). The `allowed`
315
- * flag is a best-effort match against this adapter's resolved allowlist (exact or
316
- * subdomain), so an `allowed:false` line pinpoints a blocked host the SDK reached.
317
- * NEVER logs the URL query or any header (a placeholder/real token can ride either) —
318
- * only method + host + pathname. Pure pass-through: logs, then delegates to `inner`
319
- * (if any) unchanged. (Originally added while diagnosing issue 135; kept as standing
320
- * observability.)
321
- */
322
- export function makeEgressAuditHook(adapterId, allowedHosts, inner) {
323
- return async (request) => {
324
- try {
325
- const u = new URL(request.url);
326
- const host = u.hostname;
327
- const allowed = allowedHosts.some((h) => host === h || host.endsWith(`.${h}`));
328
- log.info('egress request', {
329
- adapter: adapterId,
330
- method: request.method,
331
- host,
332
- path: u.pathname,
333
- allowed,
334
- });
335
- }
336
- catch {
337
- // Logging must never break egress.
338
- }
339
- return inner ? inner(request) : undefined;
340
- };
341
- }
342
- /**
343
- * opencode's `api.github.com` durable-token-oracle guard (§4.4). Gondolin secret
344
- * substitution is HOST-scoped, not path-scoped: once `api.github.com` is
345
- * allowlisted, a guest could otherwise spend the real GitHub token on ANY
346
- * `api.github.com` path. This guard permits ONLY the token-exchange endpoint
347
- * (`GET /copilot_internal/v2/token`) and short-circuits everything else on that
348
- * host with a 403. All other hosts pass through untouched.
349
- *
350
- * NEVER logs the Authorization header or the full URL (only host + method +
351
- * pathname for a blocked request) — the hook may run before secret substitution
352
- * and there is no guarantee it sees only placeholders (§2/§4.3).
353
- */
354
- export function makeGithubExchangePathGuard() {
355
- return (request) => {
356
- let url;
357
- try {
358
- url = new URL(request.url);
359
- }
360
- catch {
361
- // Unparseable URL → block defensively rather than forward.
362
- return new Response('blocked: unparseable request url', { status: 403 });
363
- }
364
- if (url.hostname !== COPILOT_EXCHANGE_HOST)
365
- return; // other hosts: untouched
366
- const method = request.method.toUpperCase();
367
- // Permit ONLY the exact exchange endpoint with NO query string. The legitimate
368
- // host-side exchange (`defaultCopilotExchange`) sends a bare path; a
369
- // `?…`-variant is neither needed nor trusted, so requiring an empty search
370
- // keeps the allow condition as narrow as the real call (codex review).
371
- if (method === 'GET' && url.pathname === COPILOT_EXCHANGE_PATH && url.search === '')
372
- return; // permit
373
- log.warn('credential-secrets: blocked non-exchange request to github exchange host', {
374
- host: url.hostname,
375
- method,
376
- pathname: url.pathname,
377
- });
378
- return new Response('blocked: only GET /copilot_internal/v2/token is permitted', {
379
- status: 403,
380
- });
381
- };
382
- }
383
- /**
384
- * Build the `createHttpHooks` config for a single adapter spec.
385
- *
386
- * The egress firewall (`options.allowedHosts`) = the general workspace dev-tooling
387
- * allowlist (`egress.allowed_hosts` from WORKFLOW.md — npm/git/CDNs) UNION this
388
- * adapter's `substitutionHosts` (you must be able to reach the host whose token you
389
- * substitute on). SECURITY: only `substitutionHosts` are wired into
390
- * `secrets[].hosts`, so the real token is NEVER substituted for a general egress
391
- * host — those receive plain network egress only. The firewall is the union; the
392
- * substitution scope is not.
393
- */
394
- export function buildAdapterHooksConfig(spec, egressAllowlist = []) {
395
- const allowedHosts = [...new Set([...egressAllowlist, ...spec.substitutionHosts])];
396
- // Host-side egress audit (standing observability): wrap the adapter's optional
397
- // onRequest guard so every guest egress request is logged with an `allowed` flag.
398
- // Gondolin runs onRequest BEFORE its allow/deny check, so this is the only host-side
399
- // window into in-VM egress. Safe with streaming (onRequest never disables it; only
400
- // onResponse does — see the no-onResponse note below). To quiet it, unwrap to
401
- // `spec.onRequest`.
402
- const onRequest = makeEgressAuditHook(spec.adapterId, allowedHosts, spec.onRequest);
403
- // FIX (issue 135, 2026-05-31): do NOT register an `onResponse` hook. Gondolin only
404
- // streams a response when there is no onResponse — `canStream = Boolean(body) &&
405
- // !httpHooks.onResponse` (qemu/http.js). With onResponse set, Gondolin FULLY BUFFERS
406
- // every response (`bufferResponseBodyWithLimit`) before the guest sees a byte. For a
407
- // long streaming model turn (~400 KB SSE over ~90–120 s) the in-VM SDK — a streaming
408
- // client — gets nothing for the whole generation window, trips its stream timeout,
409
- // silently retries, and after ~16 min dies with ECONNRESET → re-dispatch loop. The
410
- // old `onResponse` was a pure billing-tell (rate-limit header logging), no functional
411
- // role; dropping it restores streaming. To restore that logging without breaking
412
- // streaming, Gondolin needs a header-only response hook (it has none today) — see the
413
- // still-exported `makeBillingTellResponseHook` and the "vendor Gondolin" option.
414
- const options = {
415
- allowedHosts,
416
- secrets: {
417
- [spec.secretName]: {
418
- hosts: [...spec.substitutionHosts],
419
- // Seeded later via `updateSecret`; the empty initial value is never
420
- // forwarded on the happy path (the registry seeds before first exec).
421
- value: '',
422
- placeholder: spec.placeholder(),
423
- },
424
- },
425
- onRequest,
426
- };
427
- return {
428
- adapterId: spec.adapterId,
429
- secretName: spec.secretName,
430
- options,
431
- readToken: spec.readToken,
432
- refresh: spec.refresh,
433
- allowWebSockets: spec.allowWebSockets,
434
- };
435
- }
436
- /**
437
- * Owns the set of live per-VM `secretManager`s and the cached latest value per
438
- * adapter. Implements the §4.3 fan-out contract:
439
- * - `register` seeds the new manager from the latest cached value (or reads it
440
- * fresh) BEFORE returning, so a VM created during a refresh never starts
441
- * stale, and schedules its per-VM proactive tick keyed off `expiresAt`.
442
- * - `pushToAll(adapterId, value)` updates the cache + every live manager for
443
- * that adapter; a manager that throws (torn down mid-push) is dropped, not
444
- * propagated.
445
- * - `refreshAdapter(adapterId)` runs the host-side refresh, re-reads the token,
446
- * and fans the result out — this is what the ticker calls per rotation.
447
- */
448
- export class CredentialSecretRegistry {
449
- entries = new Map();
450
- // Latest known value per adapter, used to seed a freshly-created manager.
451
- cachedValue = new Map();
452
- seq = 0;
453
- // Per-adapter rotation counter, bumped on every `pushToAll(adapterId, …)`.
454
- // `register` snapshots its adapter's counter across the async `readToken` so it
455
- // can detect a rotation FOR THAT ADAPTER that landed mid-read and avoid
456
- // clobbering the fresher value with its own stale read. Per-adapter (not global)
457
- // so a rotation for a *different* adapter never makes a cold entry skip seeding.
458
- cacheSeq = new Map();
459
- readToken;
460
- refresh;
461
- now;
462
- setTimer;
463
- clearTimer;
464
- refreshMarginMs;
465
- constructor(opts) {
466
- this.readToken = opts.readToken;
467
- this.refresh = opts.refresh;
468
- this.now = opts.now ?? (() => Date.now());
469
- this.setTimer =
470
- opts.setTimer ??
471
- ((cb, delayMs) => {
472
- const t = setTimeout(cb, delayMs);
473
- if (typeof t.unref === 'function')
474
- t.unref();
475
- return t;
476
- });
477
- this.clearTimer = opts.clearTimer ?? ((t) => clearTimeout(t));
478
- this.refreshMarginMs = opts.refreshMarginMs ?? 60_000;
479
- }
480
- /**
481
- * Register a freshly-created VM's `secretManager`. Seeds it from the latest
482
- * cached value (or reads one if the cache is cold) so it is never stale at
483
- * birth, schedules the proactive `expiresAt` tick, and returns a handle the
484
- * caller deregisters on VM teardown.
485
- */
486
- async register(args) {
487
- const key = `vm-${++this.seq}`;
488
- const entry = {
489
- manager: args.manager,
490
- secretName: args.secretName,
491
- adapterId: args.adapterId,
492
- timer: null,
493
- };
494
- this.entries.set(key, entry);
495
- const seqBefore = this.cacheSeq.get(args.adapterId) ?? 0;
496
- const token = await this.safeReadToken(args.adapterId);
497
- this.seedUnlessRotated(key, entry, args.adapterId, seqBefore, token);
498
- if (token?.expiresAtMs != null)
499
- this.scheduleProactive(key, entry, token.expiresAtMs);
500
- return {
501
- key,
502
- deregister: () => this.deregister(key),
503
- };
504
- }
505
- /** Drop a VM's registration; clears its proactive timer. Idempotent. */
506
- deregister(key) {
507
- const entry = this.entries.get(key);
508
- if (!entry)
509
- return;
510
- if (entry.timer !== null) {
511
- this.clearTimer(entry.timer);
512
- entry.timer = null;
513
- }
514
- this.entries.delete(key);
515
- }
516
- /** Number of live managers (for tests / observability). */
517
- size() {
518
- return this.entries.size;
519
- }
520
- /**
521
- * Push a fresh secret value to EVERY live manager for `adapterId`, updating the
522
- * module cache first so a concurrent `register` seeds from it. A manager that
523
- * throws (torn down mid-push) is dropped, not propagated — the survivors still
524
- * get the update. This is the atomic fan-out the ticker relies on.
525
- */
526
- pushToAll(adapterId, value) {
527
- this.cachedValue.set(adapterId, value);
528
- this.cacheSeq.set(adapterId, (this.cacheSeq.get(adapterId) ?? 0) + 1);
529
- for (const [key, entry] of [...this.entries]) {
530
- if (entry.adapterId !== adapterId)
531
- continue;
532
- this.applyToEntry(key, entry, value);
533
- }
534
- }
535
- /**
536
- * Run a host-side refresh for `adapterId`, re-read the token, and fan the fresh
537
- * value out to all live managers (rescheduling each VM's proactive tick). This
538
- * is the entry point the ticker calls on each rotation. Errors are logged, not
539
- * thrown (a single adapter's refresh failure must not break the others' ticks).
540
- */
541
- async refreshAdapter(adapterId) {
542
- try {
543
- await this.refresh(adapterId);
544
- }
545
- catch (err) {
546
- log.warn('credential-secrets: refresh failed', {
547
- adapter: adapterId,
548
- error: err.message,
549
- });
550
- // Fall through: re-read anyway — a peer may have rotated the file under the
551
- // shared flock during our wait (mirrors the proxy's ensureFreshToken).
552
- }
553
- const token = await this.safeReadToken(adapterId);
554
- if (token === null)
555
- return;
556
- this.pushToAll(adapterId, token.accessToken);
557
- // Reschedule every live manager's proactive tick off the new expiry.
558
- if (token.expiresAtMs != null) {
559
- for (const [key, entry] of [...this.entries]) {
560
- if (entry.adapterId !== adapterId)
561
- continue;
562
- this.scheduleProactive(key, entry, token.expiresAtMs);
563
- }
564
- }
565
- }
566
- /**
567
- * Seed a freshly-registered entry from its read token — UNLESS a rotation for
568
- * the same adapter landed during the async read (codex review). The entry is
569
- * inserted synchronously before `register`'s await, so a concurrent
570
- * `pushToAll(adapterId, …)` already applied the fresher value to it; re-applying
571
- * our older read would both regress the live value and revoke the fresher one
572
- * (gondolin revokes the old value whenever the new differs). The sequence is
573
- * per-adapter, so a rotation for a *different* adapter never starves this seed.
574
- */
575
- seedUnlessRotated(key, entry, adapterId, seqBefore, token) {
576
- if ((this.cacheSeq.get(adapterId) ?? 0) !== seqBefore)
577
- return;
578
- const seedValue = token?.accessToken ?? this.cachedValue.get(adapterId) ?? '';
579
- if (token?.accessToken)
580
- this.cachedValue.set(adapterId, token.accessToken);
581
- this.applyToEntry(key, entry, seedValue);
582
- }
583
- applyToEntry(key, entry, value) {
584
- try {
585
- entry.manager.updateSecret(entry.secretName, { value });
586
- }
587
- catch (err) {
588
- // The manager was torn down mid-push (its VM closed). Drop it; never throw.
589
- log.warn('credential-secrets: dropping dead secret manager', {
590
- adapter: entry.adapterId,
591
- error: err.message,
592
- });
593
- this.deregister(key);
594
- }
595
- }
596
- async safeReadToken(adapterId) {
597
- try {
598
- return await this.readToken(adapterId);
599
- }
600
- catch (err) {
601
- log.warn('credential-secrets: readToken failed', {
602
- adapter: adapterId,
603
- error: err.message,
604
- });
605
- return null;
606
- }
607
- }
608
- /**
609
- * (Re)schedule the per-VM proactive refresh: fire `refreshMarginMs` before
610
- * `expiresAtMs` (clamped to ≥0) so a long dispatch refreshes without waiting on
611
- * the global ticker cadence. Replaces any prior timer for this entry.
612
- */
613
- scheduleProactive(key, entry, expiresAtMs) {
614
- if (entry.timer !== null) {
615
- this.clearTimer(entry.timer);
616
- entry.timer = null;
617
- }
618
- const delay = Math.max(0, expiresAtMs - this.now() - this.refreshMarginMs);
619
- entry.timer = this.setTimer(() => {
620
- entry.timer = null;
621
- // The whole-adapter refresh fans out to every live manager (incl. this
622
- // one) and reschedules; a per-VM tick driving the shared refresh is fine
623
- // because the host-side refresh is flock-serialized + single-flighted.
624
- void this.refreshAdapter(entry.adapterId);
625
- }, delay);
626
- }
627
- }
628
- //# sourceMappingURL=credential-secrets.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"credential-secrets.js","sourceRoot":"","sources":["../../src/agent/credential-secrets.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,gFAAgF;AAChF,gFAAgF;AAChF,6EAA6E;AAC7E,6EAA6E;AAC7E,6DAA6D;AAC7D,0EAA0E;AAC1E,4EAA4E;AAC5E,EAAE;AACF,4EAA4E;AAC5E,+EAA+E;AAC/E,6EAA6E;AAC7E,mFAAmF;AACnF,EAAE;AACF,+DAA+D;AAC/D,2EAA2E;AAC3E,kFAAkF;AAClF,wEAAwE;AACxE,+EAA+E;AAC/E,iFAAiF;AACjF,4DAA4D;AAC5D,mEAAmE;AACnE,8EAA8E;AAC9E,qEAAqE;AACrE,gFAAgF;AAChF,2DAA2D;AAE3D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,kBAAkB,GAInB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,GAIvB,MAAM,4BAA4B,CAAC;AAEpC,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAClD,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAC3C,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAEpD,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AACjD,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAE1C;;;;;;;;GAQG;AACH,SAAS,iBAAiB;IACxB,OAAO,mBAAmB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;AAC3F,CAAC;AACD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAS,gBAAgB,CAAC,SAAwB;IAChD,MAAM,SAAS,GAAG,mBAAmB,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACpF,OAAO,GAAG,EAAE,CAAC,sBAAsB,CAAC,SAAS,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9D,CAAC;AACD,SAAS,mBAAmB;IAC1B,4EAA4E;IAC5E,8EAA8E;IAC9E,OAAO,mBAAmB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC,CAAC;AAC3F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,aAAa,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,sBAAsB,CAAC,SAAiB,EAAE,YAA2B,IAAI;IACvF,MAAM,aAAa,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,aAAa,CAAC;QAC5B,GAAG,EAAE,2BAA2B;QAChC,GAAG,CAAC,aAAa,KAAK,IAAI;YACxB,CAAC,CAAC,EAAE,6BAA6B,EAAE,EAAE,kBAAkB,EAAE,aAAa,EAAE,EAAE;YAC1E,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IACH,OAAO,GAAG,MAAM,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;AAC7C,CAAC;AAED,SAAS,aAAa,CAAC,GAAY;IACjC,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACxE,CAAC;AA+CD,+EAA+E;AAC/E,KAAK,UAAU,YAAY,CAAC,CAAS;IACnC,8EAA8E;IAC9E,kEAAkE;IAClE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACtD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,6CAA6C,EAAE;YACtD,IAAI,EAAE,CAAC;YACP,KAAK,EAAG,GAAa,CAAC,OAAO;SAC9B,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,mDAAmD,EAAE;YAC5D,IAAI,EAAE,CAAC;YACP,KAAK,EAAG,GAAa,CAAC,OAAO;SAC9B,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B;IACnC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,mBAAmB,CAAC,CAAC;AACjE,CAAC;AACD,SAAS,2BAA2B;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;AACxD,CAAC;AACD,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;AACvE,CAAC;AAED,+EAA+E;AAC/E,SAAS,SAAS,CAChB,WAAwB,EACxB,aAAqB,EACrB,SAA8B;IAE9B,OAAO,KAAK,IAAI,EAAE;QAChB,IAAI,OAAO,GAAiC,IAAI,CAAC;QACjD,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,2EAA2E;YAC3E,wEAAwE;YACxE,0EAA0E;YAC1E,0BAA0B;YAC1B,GAAG,CAAC,IAAI,CAAC,2DAA2D,EAAE;gBACpE,KAAK,EAAG,GAAa,CAAC,OAAO;aAC9B,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,CAAC;YACH,MAAM,SAAS,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5B,GAAG,CAAC,IAAI,CAAC,wCAAwC,EAAE,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CACtF,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AA4BD;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,OAA0B,EAAE;IAE5B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,eAAe,EAAE,CAAC;IACpD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACtE,MAAM,aAAa,GAAG,IAAI,CAAC,oBAAoB,IAAI,MAAM,CAAC;IAE1D,MAAM,eAAe,GAAG,IAAI,CAAC,qBAAqB,IAAI,4BAA4B,EAAE,CAAC;IACrF,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,IAAI,2BAA2B,EAAE,CAAC;IAClF,MAAM,iBAAiB,GAAG,IAAI,CAAC,uBAAuB,IAAI,0BAA0B,EAAE,CAAC;IAEvF,MAAM,eAAe,GAAG,SAAS,CAC/B,WAAW,EACX,aAAa,EACb,IAAI,CAAC,eAAe,IAAI,sBAAsB,EAAE,CACjD,CAAC;IAEF,OAAO;QACL,MAAM,EAAE;YACN,SAAS,EAAE,QAAQ;YACnB,UAAU,EAAE,kBAAkB;YAC9B,iBAAiB,EAAE,CAAC,oBAAoB,CAAC;YACzC,WAAW,EAAE,iBAAiB;YAC9B,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,kBAAkB,CAAC,MAAM,YAAY,CAAC,eAAe,CAAC,CAAC;YAC9E,OAAO,EAAE,eAAe;YACxB,eAAe,EAAE,KAAK,EAAE,cAAc;SACvC;QACD,KAAK,EAAE;YACL,SAAS,EAAE,OAAO;YAClB,UAAU,EAAE,iBAAiB;YAC7B,iBAAiB,EAAE,CAAC,mBAAmB,CAAC;YACxC,2EAA2E;YAC3E,4EAA4E;YAC5E,wEAAwE;YACxE,4EAA4E;YAC5E,yEAAyE;YACzE,4EAA4E;YAC5E,0EAA0E;YAC1E,wEAAwE;YACxE,8EAA8E;YAC9E,6EAA6E;YAC7E,uEAAuE;YACvE,0EAA0E;YAC1E,eAAe,EAAE,IAAI;YACrB,oEAAoE;YACpE,gEAAgE;YAChE,WAAW,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC;YAChE,yEAAyE;YACzE,2DAA2D;YAC3D,SAAS,EAAE,KAAK,IAAI,EAAE,CACpB,iBAAiB,CAAC,MAAM,YAAY,CAAC,cAAc,CAAC,CAAC,IAAI,gBAAgB,EAAE;YAC7E,OAAO,EAAE,GAAG,EAAE,CACZ,OAAO,CAAC,MAAM,CACZ,IAAI,KAAK,CAAC,6EAA6E,CAAC,CACzF;SACJ;QACD,QAAQ,EAAE,iBAAiB,CAAC;YAC1B,eAAe,EAAE,iBAAiB;YAClC,WAAW;YACX,aAAa;YACb,QAAQ,EAAE,IAAI,CAAC,eAAe,IAAI,sBAAsB,EAAE;SAC3D,CAAC;KACH,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,iBAAiB,CAAC,IAK1B;IACC,6EAA6E;IAC7E,uDAAuD;IACvD,MAAM,KAAK,GAAgC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAE3D,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;QACrC,MAAM,WAAW,GAAG,MAAM,uBAAuB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACxE,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,mGAAmG,CACpG,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,UAAU;QACrB,UAAU,EAAE,oBAAoB;QAChC,8EAA8E;QAC9E,wEAAwE;QACxE,6EAA6E;QAC7E,uEAAuE;QACvE,kDAAkD;QAClD,iBAAiB,EAAE,CAAC,sBAAsB,EAAE,qBAAqB,CAAC;QAClE,WAAW,EAAE,mBAAmB;QAChC,aAAa,EAAE,sBAAsB;QACrC,6EAA6E;QAC7E,iDAAiD;QACjD,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK;QAClC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC;QAC9D,SAAS,EAAE,2BAA2B,EAAE;QACxC,eAAe,EAAE,KAAK,EAAE,kCAAkC;KAC3D,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,KAAK,UAAU,uBAAuB,CAAC,eAAuB;IAC5D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,CAAC;IACnD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,QAAQ,GAAG,2BAA2B,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,QAAQ,CAAC;IACzC,CAAC;IACD,OAAO,0BAA0B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAuB,EACvB,YAA+B,EAC/B,KAAyC;IAEzC,OAAO,KAAK,EAAE,OAAgB,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC;YACxB,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/E,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE;gBACzB,OAAO,EAAE,SAAS;gBAClB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,IAAI;gBACJ,IAAI,EAAE,CAAC,CAAC,QAAQ;gBAChB,OAAO;aACR,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,mCAAmC;QACrC,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,2BAA2B;IACzC,OAAO,CAAC,OAAgB,EAAmB,EAAE;QAC3C,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,2DAA2D;YAC3D,OAAO,IAAI,QAAQ,CAAC,kCAAkC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,qBAAqB;YAAE,OAAO,CAAC,yBAAyB;QAC7E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QAC5C,+EAA+E;QAC/E,qEAAqE;QACrE,2EAA2E;QAC3E,uEAAuE;QACvE,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,qBAAqB,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE;YAAE,OAAO,CAAC,SAAS;QACtG,GAAG,CAAC,IAAI,CAAC,0EAA0E,EAAE;YACnF,IAAI,EAAE,GAAG,CAAC,QAAQ;YAClB,MAAM;YACN,QAAQ,EAAE,GAAG,CAAC,QAAQ;SACvB,CAAC,CAAC;QACH,OAAO,IAAI,QAAQ,CAAC,2DAA2D,EAAE;YAC/E,MAAM,EAAE,GAAG;SACZ,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AA2BD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CACrC,IAA2B,EAC3B,kBAAqC,EAAE;IAEvC,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,eAAe,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IACnF,+EAA+E;IAC/E,kFAAkF;IAClF,qFAAqF;IACrF,mFAAmF;IACnF,8EAA8E;IAC9E,oBAAoB;IACpB,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACpF,mFAAmF;IACnF,iFAAiF;IACjF,qFAAqF;IACrF,qFAAqF;IACrF,qFAAqF;IACrF,mFAAmF;IACnF,mFAAmF;IACnF,sFAAsF;IACtF,iFAAiF;IACjF,sFAAsF;IACtF,iFAAiF;IACjF,MAAM,OAAO,GAA2B;QACtC,YAAY;QACZ,OAAO,EAAE;YACP,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;gBACjB,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC;gBAClC,oEAAoE;gBACpE,sEAAsE;gBACtE,KAAK,EAAE,EAAE;gBACT,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;aAChC;SACF;QACD,SAAS;KACV,CAAC;IACF,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,OAAO;QACP,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,eAAe,EAAE,IAAI,CAAC,eAAe;KACtC,CAAC;AACJ,CAAC;AA8CD;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,wBAAwB;IAClB,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC5D,0EAA0E;IACzD,WAAW,GAAG,IAAI,GAAG,EAAwB,CAAC;IACvD,GAAG,GAAG,CAAC,CAAC;IAChB,2EAA2E;IAC3E,gFAAgF;IAChF,wEAAwE;IACxE,iFAAiF;IACjF,iFAAiF;IAChE,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC3C,SAAS,CAAyD;IAClE,OAAO,CAA6C;IACpD,GAAG,CAAe;IAClB,QAAQ,CAAsD;IAC9D,UAAU,CAAkC;IAC5C,eAAe,CAAS;IAEzC,YAAY,IAAqC;QAC/C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ;YACX,IAAI,CAAC,QAAQ;gBACb,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE;oBACf,MAAM,CAAC,GAAG,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;oBAClC,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,UAAU;wBAAE,CAAC,CAAC,KAAK,EAAE,CAAC;oBAC7C,OAAO,CAAC,CAAC;gBACX,CAAC,CAAC,CAAC;QACL,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,MAAM,CAAC;IACxD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAC,IAId;QACC,MAAM,GAAG,GAAG,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAkB;YAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI;SACZ,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE7B,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACrE,IAAI,KAAK,EAAE,WAAW,IAAI,IAAI;YAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QAEtF,OAAO;YACL,GAAG;YACH,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;SACvC,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,UAAU,CAAC,GAAW;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACzB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC7B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,2DAA2D;IAC3D,IAAI;QACF,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,SAAuB,EAAE,KAAa;QAC9C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;gBAAE,SAAS;YAC5C,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,SAAuB;QAC1C,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,oCAAoC,EAAE;gBAC7C,OAAO,EAAE,SAAS;gBAClB,KAAK,EAAG,GAAa,CAAC,OAAO;aAC9B,CAAC,CAAC;YACH,4EAA4E;YAC5E,uEAAuE;QACzE,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QAC7C,qEAAqE;QACrE,IAAI,KAAK,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC;YAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7C,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;oBAAE,SAAS;gBAC5C,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACK,iBAAiB,CACvB,GAAW,EACX,KAAoB,EACpB,SAAuB,EACvB,SAAiB,EACjB,KAAuB;QAEvB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,SAAS;YAAE,OAAO;QAC9D,MAAM,SAAS,GAAG,KAAK,EAAE,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAC9E,IAAI,KAAK,EAAE,WAAW;YAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QAC3E,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAC3C,CAAC;IAEO,YAAY,CAAC,GAAW,EAAE,KAAoB,EAAE,KAAa;QACnE,IAAI,CAAC;YACH,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,4EAA4E;YAC5E,GAAG,CAAC,IAAI,CAAC,kDAAkD,EAAE;gBAC3D,OAAO,EAAE,KAAK,CAAC,SAAS;gBACxB,KAAK,EAAG,GAAa,CAAC,OAAO;aAC9B,CAAC,CAAC;YACH,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,SAAuB;QACjD,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,sCAAsC,EAAE;gBAC/C,OAAO,EAAE,SAAS;gBAClB,KAAK,EAAG,GAAa,CAAC,OAAO;aAC9B,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,iBAAiB,CAAC,GAAW,EAAE,KAAoB,EAAE,WAAmB;QAC9E,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACzB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC7B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;QAC3E,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;YAC/B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;YACnB,uEAAuE;YACvE,yEAAyE;YACzE,uEAAuE;YACvE,KAAK,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;CACF"}