@overdeck/desktop 0.45.23 → 0.45.24

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 (388) hide show
  1. package/drizzle/overdeck/0000_overdeck_init.sql +2 -0
  2. package/package.json +1 -1
  3. package/server/{acceptance-criteria-DOA0KgXx.js → acceptance-criteria-DDCnXF58.js} +2 -2
  4. package/server/{advancing-selfheal-BBu6DSNm.js → advancing-selfheal-BVwW4qRn.js} +6 -6
  5. package/server/{agent-gc-BV1q_2EV.js → agent-gc-CHcnvonI.js} +4 -4
  6. package/server/agent-state-Bc3tzUC8.js +3 -0
  7. package/server/{agent-state-service-HoK8U4jW.js → agent-state-service-BsgWxZuB.js} +5 -5
  8. package/server/{agent-state-service-CnzFKSAQ.js → agent-state-service-D5UGKIJL.js} +1 -1
  9. package/server/{agents-B4Bjbkfv.js → agents-EbI0zCJl.js} +4 -4
  10. package/server/agents-wi9NWzs2.js +3 -0
  11. package/server/{archive-planning-zkJb3BeM.js → archive-planning-BZDgzoEj.js} +1 -1
  12. package/server/{archive-planning-DYrYojxl.js → archive-planning-Du25Jtst.js} +4 -4
  13. package/server/{artifact-index-jobs-C-xy7Z5v.js → artifact-index-jobs-CbEDfCDu.js} +2 -2
  14. package/server/assemble-J2ZZ2C15.js +339 -0
  15. package/server/{backlog-auto-trigger-GtG71X8H.js → backlog-auto-trigger-2R2jog7n.js} +3 -3
  16. package/server/{behavior-B_-4EKF3.js → behavior-B3exJ42O.js} +2 -2
  17. package/server/{briefing-freshness-DWdW7vUm.js → briefing-freshness-D1wzUIWv.js} +2 -2
  18. package/server/{build-info-DgTqZkL5.js → build-info-CZk_TITh.js} +1 -1
  19. package/server/{build-info-BT096lEl.js → build-info-Ie_D0_BT.js} +3 -3
  20. package/server/{checkpoint-manager-DDqcGyu8.js → checkpoint-manager-BI1Wxoku.js} +2 -2
  21. package/server/{checkpoint-manager-B7Bt29J0.js → checkpoint-manager-DwbQoqrC.js} +1 -1
  22. package/server/checkpoint-worker.js +1 -1
  23. package/server/{checkpoints-CpgCjAlN.js → checkpoints-BJIs5QIA.js} +1 -1
  24. package/server/{checkpoints-C-AXLfYT.js → checkpoints-CQB1h765.js} +2 -2
  25. package/server/{claude-hooks-provision-C8wdRnN1.js → claude-hooks-provision-8Ngo8TpT.js} +1 -1
  26. package/server/{claude-hooks-provision-but-_qGY.js → claude-hooks-provision-D8GXF3_s.js} +2 -2
  27. package/server/{claude-permissions-H_5wHQZQ.js → claude-permissions-DNWEVV6z.js} +2 -2
  28. package/server/{claude-settings-overlay-CbSz0Dvb.js → claude-settings-overlay-CEdaqpWI.js} +2 -2
  29. package/server/{claude-settings-overlay-BTENVmYf.js → claude-settings-overlay-DWy-Bb4Y.js} +1 -1
  30. package/server/cli-B86rejVV.js +3 -0
  31. package/server/{cli-vBeXbPrq.js → cli-RoOx5DUf.js} +9 -9
  32. package/server/{cliproxy-Bgb2XCqi.js → cliproxy-C8a1vtTU.js} +2 -2
  33. package/server/{cliproxy-DW0V86F8.js → cliproxy-fHfIeiGd.js} +1 -1
  34. package/server/{close-issue-Dn_4c4G8.js → close-issue-DoOifFIK.js} +5 -5
  35. package/server/{closed-issue-reaper-hANY_ehE.js → closed-issue-reaper-Bk3SU4RC.js} +9 -9
  36. package/server/{closed-issue-reaper-CWpY2uBw.js → closed-issue-reaper-CktPXo8m.js} +1 -1
  37. package/server/{codex-TmSi-yTv.js → codex-BZXGhUVB.js} +7 -7
  38. package/server/{codex-Dg7Is5yb.js → codex-GcHuUF-k.js} +1 -1
  39. package/server/{codex-parser-C4gSH-IR.js → codex-parser-CFZ1_1Jl.js} +2 -2
  40. package/server/{config-CCvjQf27.js → config-BZ0sHTju.js} +2 -2
  41. package/server/{config-DjLOdbgT.js → config-CKxYiCmX.js} +2 -2
  42. package/server/{config-DUIhMN_T.js → config-DzV30TOm.js} +1 -1
  43. package/server/{config-yaml-DvyMuOle.js → config-yaml-DySPNmKN.js} +23 -9
  44. package/server/{conflict-gate-CmrYpa47.js → conflict-gate-BaCVrH-N.js} +3 -3
  45. package/server/{conflict-gate-BSJkNTdp.js → conflict-gate-BhAY7TUd.js} +1 -1
  46. package/server/context-layers-BrPmE__h.js +4 -0
  47. package/server/context-layers-igZ4FI4_.js +37 -0
  48. package/server/{control-settings-aP1ANIlI.js → control-settings-BQp7_4uD.js} +4 -4
  49. package/server/{conversation-compaction-CNbTLB86.js → conversation-compaction-CgrR8YYp.js} +8 -8
  50. package/server/{conversation-compaction-DiG5zWQq.js → conversation-compaction-eQB5CkOe.js} +1 -1
  51. package/server/{conversation-service-Up7FEzIC.js → conversation-service-BLd3MYsG.js} +1 -1
  52. package/server/{conversation-service-Du-MTNpJ.js → conversation-service-DPJ71F33.js} +329 -19
  53. package/server/{conversations-DbOs1e9Q.js → conversations-6AfUfbwc.js} +5 -5
  54. package/server/{conversations-6mPANqvL.js → conversations-CAsJF9kh.js} +1 -1
  55. package/server/{cost-Ca0YTWDw.js → cost-B2ddP6wq.js} +2 -2
  56. package/server/{cost-CW4WSe72.js → cost-R-m6Yi-W.js} +3 -3
  57. package/server/{cost-sync-C0VdGme1.js → cost-sync-BsN6ER0n.js} +3 -3
  58. package/server/{dag-CdOjJVDT.js → dag-B1ucnjDU.js} +2 -2
  59. package/server/{dangerous-git-ops-CT-IypG3.js → dangerous-git-ops-BXqeWVSf.js} +1 -1
  60. package/server/dashboard-db-worker.js +7 -7
  61. package/server/{deacon-pRnyD5w9.js → deacon-CU_cAYSR.js} +254 -144
  62. package/server/{deacon-DYSEJb48.js → deacon-kiQrb4ZT.js} +3 -3
  63. package/server/{deacon-nudge-log-Bjg8U4Y9.js → deacon-nudge-log-6wVqAaqz.js} +3 -3
  64. package/server/{deacon-swarm-DftYRDo8.js → deacon-swarm-BXZZ1Z2-.js} +13 -13
  65. package/server/deacon-swarm-C-GwfjJy.js +2 -0
  66. package/server/deacon.js +8 -8
  67. package/server/{deploy-patrol-Bjsho_ha.js → deploy-patrol-AiFoP8dw.js} +6 -6
  68. package/server/{deploy-window-DeP_OIRk.js → deploy-window-C3F-tihF.js} +6 -6
  69. package/server/{deploy-window-CM6W1-c6.js → deploy-window-DkZraDyj.js} +1 -1
  70. package/server/{dev-supervisor-BpMoHlkR.js → dev-supervisor-bcOWqdQE.js} +2 -2
  71. package/server/{devcontainer-renderer-CtUgrVKW.js → devcontainer-renderer-_d6XhyND.js} +3 -3
  72. package/server/dist-Bzy0y69j.js +3 -0
  73. package/server/{dist-DyRx4cI7.js → dist-Cb_0uvpS.js} +1 -1
  74. package/server/{docker-BK7HIcBj.js → docker-DcMTFTUC.js} +2 -2
  75. package/server/{dod-BrSfUHm0.js → dod-C6n9RV3G.js} +1 -1
  76. package/server/{ensure-devcontainer-DRqaAkBR.js → ensure-devcontainer-BZgOhRo7.js} +1 -1
  77. package/server/{ensure-devcontainer-DseivYEy.js → ensure-devcontainer-DNi-ono3.js} +4 -4
  78. package/server/{esm-shims-CbI3BVkl.js → esm-shims-OSHAYaS1.js} +1 -1
  79. package/server/{event-store-tdiY5eDZ.js → event-store-CQL6NeqB.js} +3 -3
  80. package/server/{event-store-Cr5PQwFC.js → event-store-EV2cMiXj.js} +1 -1
  81. package/server/{events-CvvGK6LT.js → events-BTdrdEq8.js} +1 -1
  82. package/server/{events-CC1dgUpx.js → events-DTfAe4My.js} +3 -3
  83. package/server/{factory-CynerjXO.js → factory-CFibJuaw.js} +4 -4
  84. package/server/{feature-registry-population-B0pmAz0a.js → feature-registry-population-DKZFMbFt.js} +4 -4
  85. package/server/{feature-registry-storage-_wUBRD3J.js → feature-registry-storage-BdPuLcBX.js} +2 -2
  86. package/server/{features-Dhxz-wLc.js → features-ez2271oH.js} +2 -2
  87. package/server/{feedback-target-CPS15Vte.js → feedback-target-7mqqwrX6.js} +7 -7
  88. package/server/{feedback-target-iygZwmMc.js → feedback-target-CoFDHiM8.js} +1 -1
  89. package/server/{feedback-writer-C9b6ccN1.js → feedback-writer-CY5L1lB7.js} +5 -5
  90. package/server/{feedback-writer-qmiMbqTZ.js → feedback-writer-D3a22RCd.js} +1 -1
  91. package/server/flywheel-DHrgCphM.js +1084 -0
  92. package/server/flywheel-DzGtWnJ1.js +477 -0
  93. package/server/flywheel-SVF02Jpq.js +2 -0
  94. package/server/{flywheel-merge-order-DxbQKE1d.js → flywheel-merge-order-UU0tiUld.js} +9 -8
  95. package/server/{flywheel-merge-order-C-6zRLvM.js → flywheel-merge-order-UUcsCDb6.js} +1 -1
  96. package/server/{forge-Ch9gCFod.js → forge-CNFnyqps.js} +2 -2
  97. package/server/forge-DXnS_YFH.js +2 -0
  98. package/server/{from-CJ_aH5jD.js → from-kNxT0bZC.js} +1 -1
  99. package/server/{fts-db-CKgg0VKg.js → fts-db-CE46vDkZ.js} +2 -2
  100. package/server/{fts-operations-BrL_VTRr.js → fts-operations-CqY6zl-i.js} +2 -2
  101. package/server/{git-utils-BVa07a4a.js → git-utils-CRw2zLPC.js} +68 -3
  102. package/server/git-utils-D0_yhCgF.js +3 -0
  103. package/server/{github-app-CMBdIFBQ.js → github-app-C3QrAUd0.js} +18 -7
  104. package/server/{github-app-CPfoFAdV.js → github-app-ClZ2lk8D.js} +1 -1
  105. package/server/{github-client--XVlDpwM.js → github-client-BnIsSrEN.js} +2 -2
  106. package/server/{github-client-B4QsdE-X.js → github-client-DfQYVUaw.js} +1 -1
  107. package/server/{github-pr-lookup-BRbDW-qk.js → github-pr-lookup-D16NGsSO.js} +2 -2
  108. package/server/{harness-binary-CVio2m-u.js → harness-binary-DPUi-Pv8.js} +32 -6
  109. package/server/{harness-resolve-qHJBhy3Z.js → harness-resolve-3lNZkyT4.js} +18 -9
  110. package/server/{health-events-C9B8y1Hm.js → health-events-BBcTYQKU.js} +2 -2
  111. package/server/{health-events-CpfvuVmm.js → health-events-BDOHby5Q.js} +1 -1
  112. package/server/{hooks-DUXw8A0-.js → hooks-CKZgXlJb.js} +2 -2
  113. package/server/{hooks-ltecuFqZ.js → hooks-DPVX1rwQ.js} +1 -1
  114. package/server/{hume-BEq0bUDg.js → hume-Cz8igP9E.js} +2 -2
  115. package/server/hume-ccTf4wTX.js +3 -0
  116. package/server/{idle-stack-reaper-D7w9t3fE.js → idle-stack-reaper-CuLF0j2H.js} +1 -1
  117. package/server/{idle-stack-reaper-w1ISSlhs.js → idle-stack-reaper-DDIRwxUY.js} +2 -2
  118. package/server/{in-flight-guard-aQ1IxeI3.js → in-flight-guard-CAAkqPLu.js} +2 -2
  119. package/server/{infra-CzaSOgul.js → infra-BEqFxlJc.js} +14 -4
  120. package/server/{injection-DZ0PfYa4.js → injection-C8aiVJrF.js} +191 -183
  121. package/server/{injection-oNZeoDhL.js → injection-CPUIqNhI.js} +1 -1
  122. package/server/{inspect-agent-DJKLWcVT.js → inspect-agent-BLuJ1AkT.js} +135 -79
  123. package/server/inspect-agent-Brtz0URj.js +2 -0
  124. package/server/{internal-token-DXdfprGr.js → internal-token-BrcU6qfe.js} +1 -1
  125. package/server/{internal-token-Bb4XeV2x.js → internal-token-s0-oKybJ.js} +2 -2
  126. package/server/{io-B3_AHDfr.js → io-C9kF1wtJ.js} +3 -3
  127. package/server/{issue-closed-zhdvQicO.js → issue-closed-CDJk4pIp.js} +7 -7
  128. package/server/{issue-lifecycle-Dy4vd0Oa.js → issue-lifecycle-B8sZHVHh.js} +1 -1
  129. package/server/{issue-lifecycle-CreaCkjW.js → issue-lifecycle-ojZAzDBP.js} +21 -21
  130. package/server/{issue-service-singleton-DabvBWUp.js → issue-service-singleton-BvJ09SaR.js} +1 -1
  131. package/server/{issue-service-singleton-B5ushCvE.js → issue-service-singleton-Yx5DdmVJ.js} +8 -8
  132. package/server/{issues-B6ToV6x1.js → issues-BMmP_77e.js} +2 -2
  133. package/server/{jsonl-parser-Dhflo1SH.js → jsonl-parser-BXSlHwEh.js} +3 -3
  134. package/server/{label-cleanup-BKPJm4Hv.js → label-cleanup-B0UJwnv5.js} +3 -3
  135. package/server/{label-reconciler-DdWbHEBu.js → label-reconciler-B4iOAjlC.js} +4 -4
  136. package/server/{launcher-generator-CHVm7bGT.js → launcher-generator-BBWG_SiS.js} +101 -7
  137. package/server/{lifecycle-io-D8iNBcux.js → lifecycle-io-BREGpnLk.js} +5 -5
  138. package/server/{lifecycle-io-Bsnr2K4F.js → lifecycle-io-DPo7x11I.js} +1 -1
  139. package/server/{lifecycle-sycO16hj.js → lifecycle-xmBfK2GJ.js} +6 -6
  140. package/server/{lifecycle-DfeyBDwA.js → lifecycle-yPd___5E.js} +2 -2
  141. package/server/{linear-client-D4zqMnX7.js → linear-client-BsuUvkdA.js} +2 -2
  142. package/server/{linear-client-DqhDQO9k.js → linear-client-CTskEeT_.js} +1 -1
  143. package/server/memory-fts-worker.js +1 -1
  144. package/server/{merge-DK23JEdS.js → merge-B1DiziGU.js} +1 -1
  145. package/server/{merge-C_ZEhbqI.js → merge-CefQNAnq.js} +3 -3
  146. package/server/{merge-agent-XrB80vfT.js → merge-agent-4WOWlSYA.js} +28 -28
  147. package/server/{merge-agent-BQM3a8z5.js → merge-agent-CKkgIBPB.js} +1 -1
  148. package/server/{merge-batch-Bwoyr8Je.js → merge-batch-ClFn2T-y.js} +1 -1
  149. package/server/merge-ops-CR44oU9-.js +2 -0
  150. package/server/{merge-rebase-C1KIVr0s.js → merge-rebase-BfaTyXsw.js} +2 -2
  151. package/server/merge-set-DJ8-UErs.js +83 -0
  152. package/server/{merge-set-DnSYdBEp.js → merge-set-bUqbm3yc.js} +1 -1
  153. package/server/{merge-sync-SSv3E-pl.js → merge-sync-BJYeOODr.js} +1 -1
  154. package/server/{merge-sync-DZ9dojJn.js → merge-sync-VPV28g0g.js} +2 -2
  155. package/server/{merge-train-DxDfBTjr.js → merge-train-CHopycP0.js} +3 -3
  156. package/server/{merge-train-deps-CyYQUksx.js → merge-train-deps-D1cOZzy2.js} +4 -4
  157. package/server/{merge-verification-CSizH3HY.js → merge-verification-BkaOqPsw.js} +4 -4
  158. package/server/{multipart-parser-Dt8YPN5S.js → multipart-parser-duPAfSBw.js} +2 -2
  159. package/server/{no-resume-mode-Cx3K0hHi.js → no-resume-mode-Nw29vaFb.js} +1 -1
  160. package/server/node_modules/.package-lock.json +8 -8
  161. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +3 -3
  162. package/server/node_modules/undici/README.md +5 -0
  163. package/server/node_modules/undici/docs/docs/api/Client.md +4 -0
  164. package/server/node_modules/undici/docs/docs/api/Dispatcher.md +6 -0
  165. package/server/node_modules/undici/docs/docs/api/Interceptors.md +59 -0
  166. package/server/node_modules/undici/docs/docs/api/MockAgent.md +27 -0
  167. package/server/node_modules/undici/docs/docs/api/MockPool.md +28 -1
  168. package/server/node_modules/undici/docs/docs/index.md +5 -0
  169. package/server/node_modules/undici/lib/core/request.js +1 -1
  170. package/server/node_modules/undici/lib/core/util.js +6 -1
  171. package/server/node_modules/undici/lib/dispatcher/agent.js +3 -3
  172. package/server/node_modules/undici/lib/dispatcher/client-h1.js +31 -6
  173. package/server/node_modules/undici/lib/dispatcher/client-h2.js +34 -43
  174. package/server/node_modules/undici/lib/handler/cache-handler.js +93 -5
  175. package/server/node_modules/undici/lib/handler/cache-revalidation-handler.js +10 -0
  176. package/server/node_modules/undici/lib/handler/redirect-handler.js +5 -2
  177. package/server/node_modules/undici/lib/handler/retry-handler.js +6 -4
  178. package/server/node_modules/undici/lib/interceptor/cache.js +21 -4
  179. package/server/node_modules/undici/lib/interceptor/decompress.js +4 -0
  180. package/server/node_modules/undici/lib/mock/mock-interceptor.js +25 -7
  181. package/server/node_modules/undici/lib/mock/mock-utils.js +39 -10
  182. package/server/node_modules/undici/lib/util/cache.js +49 -7
  183. package/server/node_modules/undici/lib/web/fetch/body.js +2 -1
  184. package/server/node_modules/undici/lib/web/fetch/response.js +1 -3
  185. package/server/node_modules/undici/package.json +2 -2
  186. package/server/node_modules/undici/types/client.d.ts +2 -2
  187. package/server/node_modules/undici/types/dispatcher.d.ts +3 -3
  188. package/server/node_modules/undici/types/mock-interceptor.d.ts +5 -1
  189. package/server/{orphan-proposed-reconciler-neK8dHQk.js → orphan-proposed-reconciler-BvKkWMJQ.js} +12 -12
  190. package/server/{orphan-proposed-reconciler-BTkDrl4R.js → orphan-proposed-reconciler-CTSGcK8p.js} +1 -1
  191. package/server/package-lock.json +9 -9
  192. package/server/package.json +1 -1
  193. package/server/{pan-dir-DeVUgwA7.js → pan-dir-B0c3w0Ya.js} +3 -3
  194. package/server/{paths-_zEts6wc.js → paths-D-xWGHdh.js} +2 -2
  195. package/server/{pickup-Dd0Znxxy.js → pickup-DUCLWrJY.js} +17 -16
  196. package/server/{pipeline-membership-0HaEGDlH.js → pipeline-membership-mY3GprlK.js} +7 -7
  197. package/server/{pipeline-notifier-6iCJplFZ.js → pipeline-notifier-BJr8gQX6.js} +1 -1
  198. package/server/{pipeline-notifier-D0ykk59O.js → pipeline-notifier-BXkJzDC4.js} +2 -2
  199. package/server/{project-pipelines-2sK1apsO.js → project-pipelines-C0MWUeCU.js} +2 -2
  200. package/server/project-repos-B6GycDh9.js +94 -0
  201. package/server/project-repos-DXKQsc_m.js +3 -0
  202. package/server/{projects-9SkRpES9.js → projects-vjjcmiN8.js} +1 -1
  203. package/server/{prompts-Dp4Tpk39.js → prompts-DxzFXuLl.js} +2 -2
  204. package/server/{providers-DV7ec8l7.js → providers-qQAwGQDW.js} +7 -7
  205. package/server/{providers-DKkBXhxU.js → providers-u4Ga0jOr.js} +1 -1
  206. package/server/public/assets/{chunk-BO2N2NFS-CltymLRg.js → chunk-BO2N2NFS-BamJdinX.js} +4 -4
  207. package/server/public/assets/{diagram-OG6HWLK6-D2f6pjgA.js → diagram-OG6HWLK6-DfOB8-w4.js} +1 -1
  208. package/server/public/assets/{dist-DEmlBBNQ.js → dist-ByIuzMQW.js} +3 -3
  209. package/server/public/assets/{dist-BWR4qFiV.js → dist-D7zYSEA6.js} +1 -1
  210. package/server/public/assets/{ganttDiagram-6RSMTGT7-DnfiViPK.js → ganttDiagram-6RSMTGT7-EdmRyXL3.js} +1 -1
  211. package/server/public/assets/{highlighted-body-OFNGDK62-B8Wrmj9H.js → highlighted-body-OFNGDK62-MerOfTX8.js} +1 -1
  212. package/server/public/assets/{index-CsSuZQBI.js → index-CWeMerGO.js} +146 -144
  213. package/server/public/assets/{index-CUr1xv8w.css → index-CenuJ3Cw.css} +1 -1
  214. package/server/public/assets/{linear-C9zFQpkX.js → linear-BBbArIcK.js} +1 -1
  215. package/server/public/assets/mermaid-GHXKKRXX-CpPWAFwE.js +1 -0
  216. package/server/public/assets/{pieDiagram-4H26LBE5-lR8H7Yjd.js → pieDiagram-4H26LBE5-BKIddiJN.js} +1 -1
  217. package/server/public/assets/{prod-B1jCQihw.js → prod-B8vYiu52.js} +4 -4
  218. package/server/public/assets/{quadrantDiagram-W4KKPZXB-CVQ2guem.js → quadrantDiagram-W4KKPZXB-D6RtoULk.js} +1 -1
  219. package/server/public/assets/{sankeyDiagram-5OEKKPKP-eD1RB4gm.js → sankeyDiagram-5OEKKPKP-CLrCedZX.js} +1 -1
  220. package/server/public/assets/{xychartDiagram-2RQKCTM6-ChEC6dQn.js → xychartDiagram-2RQKCTM6-hznR8DYl.js} +1 -1
  221. package/server/public/index.html +2 -2
  222. package/server/{pull-requests--Ib2jTgy.js → pull-requests-7N8WKseP.js} +1 -1
  223. package/server/{pull-requests-CXIhdCYD.js → pull-requests-_lHueOHW.js} +3 -3
  224. package/server/{queries-6d7Cdtm7.js → queries-CjNIf-Ub.js} +576 -166
  225. package/server/{rally-B708-nZn.js → rally-CyWT_lNO.js} +3 -3
  226. package/server/{rally-api-nY0ZANw3.js → rally-api-C8e_1JRi.js} +2 -2
  227. package/server/{rally-api-yjQ0TfHd.js → rally-api-ClOSd-Tt.js} +1 -1
  228. package/server/{rally-client-B1EJhfV0.js → rally-client-lc-nokqr.js} +4 -4
  229. package/server/{rally-client-CULK2XAY.js → rally-client-sgtVqzNU.js} +1 -1
  230. package/server/rally-zhhtXuDP.js +3 -0
  231. package/server/{reap-terminal-sessions-MWnqdLCJ.js → reap-terminal-sessions-7KeHv1R1.js} +1 -1
  232. package/server/{reap-terminal-sessions-N3BTkmX_.js → reap-terminal-sessions-BtHPo6Xc.js} +1 -1
  233. package/server/rebuild-stack-CFvcBHsS.js +4 -0
  234. package/server/{rebuild-stack-Dp4eLkt4.js → rebuild-stack-lwtsW0GO.js} +26 -35
  235. package/server/{reconstruct-cache-uWbZfjms.js → reconstruct-cache-C3Ui7ojV.js} +6 -6
  236. package/server/{record-t6V-3Dcj.js → record-CN0pj4_5.js} +1 -1
  237. package/server/{record-update-DACtKh6_.js → record-update-bLJxAXH4.js} +1 -1
  238. package/server/{record-update-Dq0t2uBG.js → record-update-dE1Aw83j.js} +2 -2
  239. package/server/{recovery-trip-BJtIQuag.js → recovery-trip-BvRWfUXM.js} +2 -2
  240. package/server/{release-engine-DZpmGGzb.js → release-engine-Cx48W7z8.js} +5 -5
  241. package/server/{release-set-hnXd_kga.js → release-set-CQfuN9-v.js} +3 -3
  242. package/server/{remote-Br-ZWVIP.js → remote-C_2hasl7.js} +3 -3
  243. package/server/{remote-4tiENDaI.js → remote-ChgimyYa.js} +3 -3
  244. package/server/{remote-agents-nmty1mLu.js → remote-agents-By1ige5O.js} +6 -6
  245. package/server/{remote-agents-CRCg1L4H.js → remote-agents-CA3Ihlxj.js} +1 -1
  246. package/server/{remote-completion-BbWNd10K.js → remote-completion-fVe9e_3u.js} +12 -12
  247. package/server/resume-BFv1PGpA.js +3 -0
  248. package/server/{review-agent-sKkE1FEL.js → review-agent-CIGOQYBD.js} +29 -25
  249. package/server/{review-agent-DJRO8EG8.js → review-agent-DNboMyW4.js} +1 -1
  250. package/server/{review-artifacts-BLbSC4ke.js → review-artifacts-nRDPuMxd.js} +5 -5
  251. package/server/{review-context-BgX3lcCx.js → review-context-2uj-YQ8J.js} +69 -25
  252. package/server/{review-status-C6n6-9f_.js → review-status-btEYlaxA.js} +1 -1
  253. package/server/{review-status-enrichment-tbOn_A_u.js → review-status-enrichment-Dci-ZwEt.js} +3 -3
  254. package/server/{review-status-A7quS5KJ.js → review-status-kZj_KyCk.js} +42 -26
  255. package/server/{review-status-sync-BhSQ0d0l.js → review-status-sync-BTOpxtTC.js} +10 -5
  256. package/server/{review-status-sync-To3-iS-N.js → review-status-sync-DSDK3OMy.js} +1 -1
  257. package/server/{review-verdict-feedback-CTRNtzXO.js → review-verdict-feedback-CCjVA7Uk.js} +6 -6
  258. package/server/{review-verdict-feedback-C1Kg8n7t.js → review-verdict-feedback-CTd4QMBu.js} +1 -1
  259. package/server/{rollup-B53Y81xK.js → rollup-BKQC7jp4.js} +1 -1
  260. package/server/{rollup-WA0VD-Rr.js → rollup-FGsKki9R.js} +8 -8
  261. package/server/{scanner-D2743cp8.js → scanner-CnqEZeDy.js} +41 -14
  262. package/server/{sequence-io-Cg0zYj_E.js → sequence-io-D909zgeH.js} +4 -4
  263. package/server/{sequencer-agent-BGY8gjg-.js → sequencer-agent-CzkcK6P5.js} +5 -5
  264. package/server/server.js +2194 -341
  265. package/server/{service-DCpB_SGd.js → service-CLeAoU6G.js} +51 -50
  266. package/server/{session-fork-BQ8_6H32.js → session-fork-CHI1XvL9.js} +2 -2
  267. package/server/{session-history-CVZDpS3c.js → session-history-BT3IvqhC.js} +4 -4
  268. package/server/settings-66A6uvIA.js +2 -0
  269. package/server/{settings-BZ5m1UCl.js → settings-BTMvpNFU.js} +3 -3
  270. package/server/{settings-ylxwqwQG.js → settings-C0zgxOGf.js} +2 -2
  271. package/server/{shadow-engineering-BlxG6Xye.js → shadow-engineering-BJfgm-hX.js} +2 -2
  272. package/server/{shadow-state-Dh-HzF2J.js → shadow-state-7a-524T8.js} +2 -2
  273. package/server/{shadow-state-C2_epgx2.js → shadow-state-DnDyjujH.js} +1 -1
  274. package/server/{shadow-utils-4bvjn9b3.js → shadow-utils-Db3oroFG.js} +2 -2
  275. package/server/{ship-log-ClSMIzZX.js → ship-log-D9MlVzYU.js} +1 -1
  276. package/server/{smart-compaction-CHIxLr_d.js → smart-compaction-CV2ukKND.js} +1 -1
  277. package/server/{smart-compaction-r4pHQBIr.js → smart-compaction-KCYScAU1.js} +7 -7
  278. package/server/{spawn-planning-session-DWAorh2B.js → spawn-planning-session-DKpdFyOC.js} +30 -23
  279. package/server/{spawn-planning-session-KC_UduxD.js → spawn-planning-session-qUC2VWu3.js} +1 -1
  280. package/server/{specialist-completion-BXhav38U.js → specialist-completion-Ky9wCDpb.js} +1 -1
  281. package/server/{specialist-context-DtrYvGJ-.js → specialist-context-Bn3dCGS2.js} +5 -5
  282. package/server/{specialist-handoff-logger-C45ouoZ6.js → specialist-handoff-logger-CMEwYxa2.js} +2 -2
  283. package/server/{specialist-logs-DJ3RzKxW.js → specialist-logs-C5p8G7tx.js} +3 -3
  284. package/server/{specialists-JVO00bs7.js → specialists-CC4r-c2s.js} +776 -347
  285. package/server/{specialists-D5fRZXmN.js → specialists-CShuVGWT.js} +1 -1
  286. package/server/{specialists-DVj0hvaL.js → specialists-DM6bWjsi.js} +1 -1
  287. package/server/{specialists-DyFeedjn.js → specialists-jiuuyVkp.js} +21 -19
  288. package/server/specs-C8Wsn2XO.js +3 -0
  289. package/server/{src-CG9mCkP6.js → src-CXmtj0im.js} +6 -6
  290. package/server/{src-CMTQGyCK.js → src-CdmnTM2m.js} +5 -5
  291. package/server/{src-U7_kTPEE.js → src-DtcUOZCq.js} +111 -18
  292. package/server/stack-health-Bn3o8FBX.js +3 -0
  293. package/server/{stack-health-puygdaMd.js → stack-health-DxSdG9cW.js} +63 -9
  294. package/server/{stale-task-claims-BbFwCTb0.js → stale-task-claims-KJKxxiiQ.js} +4 -4
  295. package/server/{staleness-Cbl_w4Bw.js → staleness-CT34nwr9.js} +1 -1
  296. package/server/{staleness-Bpy41ngS.js → staleness-DPm7ClwA.js} +1 -1
  297. package/server/{state-home-CIGjwNfJ.js → state-home-Cn_Qu8IX.js} +2 -2
  298. package/server/{state-migrate-Dkzaxvny.js → state-migrate-BGg2ZaOt.js} +4 -4
  299. package/server/{stuck-remediation-CzEov_fq.js → stuck-remediation-DYuPRYYw.js} +300 -23
  300. package/server/{stuck-remediation-sY_MHHgQ.js → stuck-remediation-s9_2qfi6.js} +1 -1
  301. package/server/{substrate-bug-weights-service-BH66lhm7.js → substrate-bug-weights-service-B-FwCs5V.js} +3 -3
  302. package/server/{summary-fork-DHhJIsAL.js → summary-fork-D1RAk9rJ.js} +78 -12
  303. package/server/{summary-fork-D8bXjCr7.js → summary-fork-DpcxN9tf.js} +2 -2
  304. package/server/supervisor/{injection-budget-C1iPirFS.js → injection-budget-Csw5tqfJ.js} +2 -41
  305. package/server/supervisor/pty-supervisor.js +2 -1
  306. package/server/supervisor/pty-token-x-ea28Us.js +43 -0
  307. package/server/supervisor-FTJAIsAK.js +2 -0
  308. package/server/{supervisor-BO-Zk_h-.js → supervisor-wM4ooB5O.js} +3 -3
  309. package/server/{swarm-readiness-CQ_fwUWF.js → swarm-readiness-DlP_UjHq.js} +3 -3
  310. package/server/{system-prerequisites-Bza0ffAh.js → system-prerequisites-DUDj1YHf.js} +56 -29
  311. package/server/{teardown-workspace-CEgauF4U.js → teardown-workspace-DeTTImn-.js} +15 -15
  312. package/server/{test-agent-queue-DXDt0Xa-.js → test-agent-queue-MbxX5vqq.js} +6 -6
  313. package/server/{test-verdict-CmUBK5cT.js → test-verdict-bWYBtqBg.js} +1 -1
  314. package/server/{test-verdict-DFjjIHR5.js → test-verdict-gscuksPv.js} +1 -1
  315. package/server/{tldr-daemon-DL566HbH.js → tldr-daemon-BYFkts95.js} +1 -1
  316. package/server/{tldr-daemon-BDtLOIlO.js → tldr-daemon-C-69c3OI.js} +2 -2
  317. package/server/{tmux-DoThH6aj.js → tmux-B6z7h_vZ.js} +1 -1
  318. package/server/{tmux-ftABRAmc.js → tmux-R7N7y-Mh.js} +2 -2
  319. package/server/{token-CsOhvw42.js → token-BK6t8BIT.js} +2 -2
  320. package/server/token-util-DuPuNriz.js +3 -0
  321. package/server/{token-util-CTmczIfW.js → token-util-DxXu-vd1.js} +1 -1
  322. package/server/{tracker-config-B4itFzDo.js → tracker-config-G6latr8C.js} +2 -2
  323. package/server/{tracker-utils-BePq_oj-.js → tracker-utils-B4ylXZQK.js} +1 -1
  324. package/server/{tracker-utils-tnxxqROg.js → tracker-utils-DHv5pSDT.js} +2 -2
  325. package/server/{traefik-connect-m73vGebA.js → traefik-connect-Df2uXPsQ.js} +1 -1
  326. package/server/{tunnel-B2vxjx_b.js → tunnel-CDVKJpRv.js} +3 -3
  327. package/server/{tunnel-Cgj-IGIl.js → tunnel-DGdUkGoZ.js} +1 -1
  328. package/server/{types-BBNjPcqU.js → types-5M0lupud.js} +1 -1
  329. package/server/{uat-train-cKfM-_WW.js → uat-train-B05BWkp-.js} +1 -1
  330. package/server/{uat-train-CuEn0t9M.js → uat-train-DDSrSoV1.js} +25 -25
  331. package/server/validate-IfDGkaVR.js +177 -0
  332. package/server/{validation-CIi6pnI2.js → validation-CC9OPqJZ.js} +1 -1
  333. package/server/{validation-B5JxoPUS.js → validation-Dw1pzDzr.js} +4 -4
  334. package/server/{verification-artifact-C-lIHfUa.js → verification-artifact-B3itKTxu.js} +1 -1
  335. package/server/{verification-artifact-BcnIbigL.js → verification-artifact-TVFSz_q1.js} +1 -1
  336. package/server/{verification-runner-CDj4lD4t.js → verification-runner-BW4HOKAz.js} +1 -1
  337. package/server/{verification-runner-Br0S_Ous.js → verification-runner-CkgX6EtI.js} +91 -106
  338. package/server/{vtt-parser-DKpNNW5i.js → vtt-parser-DYPbKcIJ.js} +1 -1
  339. package/server/{work-agent-prompt-Yb2bd3Fq.js → work-agent-prompt-Du8Vh2aJ.js} +9 -9
  340. package/server/workflows-BQu4RFQ-.js +2 -0
  341. package/server/{workflows-C9WmILql.js → workflows-mbQzh6mQ.js} +18 -18
  342. package/server/{workspace-DuUdndHe.js → workspace--8tnhDI0.js} +1 -1
  343. package/server/{workspace-BVl4rihN.js → workspace-BPUws1-_.js} +3 -3
  344. package/server/{workspace-config-cEGcO6UT.js → workspace-config-CIVWZOQr.js} +1 -1
  345. package/server/{workspace-manager-hLUv3ADC.js → workspace-manager-CBhNdzE4.js} +66 -15
  346. package/server/workspace-manager-CWT55qeI.js +3 -0
  347. package/server/{workspace-metadata-DNpMixRq.js → workspace-metadata-BzHnwwX4.js} +1 -1
  348. package/server/{workspace-metadata-CskwzzhL.js → workspace-metadata-_WygnyoX.js} +2 -2
  349. package/server/{workspaces-hWvy9eKs.js → workspaces-Do_9J0LQ.js} +130 -111
  350. package/sync-sources/hooks/record-cost-event.js +6 -4
  351. package/sync-sources/skills/okf/README.md +11 -3
  352. package/sync-sources/skills/okf/SKILL.md +12 -1
  353. package/sync-sources/skills/okf/docs/USAGE.md +15 -0
  354. package/sync-sources/skills/okf/references/overdeck.md +28 -0
  355. package/sync-sources/skills/pan-flywheel/SKILL.md +18 -1
  356. package/sync-sources/skills/pan-knowledge/SKILL.md +10 -0
  357. package/sync-sources/skills/pan-orders/SKILL.md +33 -0
  358. package/sync-sources/skills/pan-start/SKILL.md +4 -0
  359. package/sync-sources/templates/traefik/dynamic/overdeck.yml.template +10 -0
  360. package/server/agent-state-Bg0lhqwj.js +0 -3
  361. package/server/agents-FlIgQ3ql.js +0 -3
  362. package/server/cli-BsVIHwzC.js +0 -3
  363. package/server/context-layers-B3Nt58jl.js +0 -4
  364. package/server/context-layers-ZYFcWiyc.js +0 -165
  365. package/server/deacon-swarm-9jRLS5Ke.js +0 -2
  366. package/server/dist-Bd3vn0Hw.js +0 -3
  367. package/server/flywheel-DMCUzDWg.js +0 -2
  368. package/server/flywheel-DSSpWmqF.js +0 -522
  369. package/server/flywheel-DcBkQvgE.js +0 -207
  370. package/server/forge-B-ZWyTRm.js +0 -2
  371. package/server/git-utils-Dry_Ka_D.js +0 -3
  372. package/server/hume-B_DbflNM.js +0 -3
  373. package/server/inspect-agent-ch-F-5Ci.js +0 -2
  374. package/server/layers-DzxSTGNA.js +0 -93
  375. package/server/merge-blockers-BsFjGrQ8.js +0 -41
  376. package/server/merge-ops-DlB1IM0Y.js +0 -2
  377. package/server/merge-set-DLz0MkGT.js +0 -139
  378. package/server/public/assets/mermaid-GHXKKRXX-BUAB8hqt.js +0 -1
  379. package/server/rally-njs_mJrt.js +0 -3
  380. package/server/rebuild-stack-kA7XngID.js +0 -3
  381. package/server/resume-CcKqnTvE.js +0 -3
  382. package/server/settings-D0OSwos5.js +0 -2
  383. package/server/specs-nN45DG2X.js +0 -3
  384. package/server/stack-health-Df0YEZKa.js +0 -3
  385. package/server/supervisor-BPy-o1A8.js +0 -2
  386. package/server/token-util-DrHg8abn.js +0 -3
  387. package/server/workflows-D90rMOya.js +0 -2
  388. package/server/workspace-manager-ZTdJAy9M.js +0 -3
package/server/server.js CHANGED
@@ -1,110 +1,110 @@
1
1
  import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM, r as __exportAll, t as __commonJSMin } from "./rolldown-runtime-DNCzzKnI.js";
2
- import { A as canUseHarnessSync, Br as getOverdeckHome, Cr as LOGS_DIR, D as resolveTieredExecutionEnabled, E as resolveTieredExecutionBlock, Et as getIssueWorkspacePath, Fn as renameProject, Fr as getDocsDisableStatePath, Gr as sessionFilePath, H as init_providers, Hr as isDevMode, Ht as flushAutoCommits, I as UnknownModelError, Ir as getDocsIndexPath, J as defaultBackgroundAiFeatures, Jn as extractPrefixSync, Ln as resolveInfraRepo, Lr as getDocsTelemetryPath, M as init_harness_policy, Nr as encodeClaudeProjectDir, Nt as readIssueRecordSync, On as listProjects, Ot as init_record, Pn as registerProjectSync, Pr as getDocsBudgetStatePath, Q as computeModelOrigin, R as getBuiltInDefaultHarness, Rn as resolveProjectFromIssue, T as init_tier_table, Tn as init_projects, Un as setProjectAutoMergeDefaultSync, Ur as packageRoot, Ut as init_auto_commit, V as getProviderForModelSync, Vr as init_paths, Vt as flushAllPendingAutoCommits, Wn as setProjectSwarmPolicySync, X as DEFAULT_ROLES, Y as init_registry, Yn as init_issue_id, Z as DEFAULT_WORKHORSES, Zn as parseIssueIdSync, _ as getDefaultDocsConfig, at as getModelEffortLevelsSync, br as CLAUDE_DIR, cn as ProjectRenameError, ct as modelSupportsImagesSync, d as loadConfigNoMigration, er as require_dist$1, f as loadConfigSync, fn as findProjectByPathSync, fr as TrackerError, g as mergeConfigs, gn as getIssuePrefix, h as jsYaml, hr as AGENTS_DIR, ht as ROLE_EFFORTS, i as getConversationsConfig, ir as FsError, jr as SYNC_SOURCES, k as validateTieredExecutionConfig, kn as listProjectsSync, lt as resolveModelIdSync, m as init_js_yaml, mn as findProjectByTeamSync, mr as init_errors, mt as PARENT_MODEL_REF, n as clearConfigCache, nt as MODEL_CAPABILITIES, o as getGlobalConfigPath, or as GitHubApiError, ot as hasModelCapabilitySync, p as updateConversationsConfig, pt as COMPLIANCE_MODES, r as getConversationSearchConfigSync, rt as MODEL_DEPRECATIONS, s as init_load, st as init_model_capabilities, t as init_config_yaml, tt as resolveModel, u as isTldrEnabledSync, un as extractTeamPrefix, ur as ProcessSpawnError, v as getDefaultTtsDaemonConfig, w as TieredExecutionConfigError, wr as OVERDECK_HOME, y as mergeTtsDaemonConfigs, yn as getProjectSync, z as getKimiAnthropicBaseUrl, zn as resolveProjectFromIssueSync, zr as getLegacyHome } from "./config-yaml-DvyMuOle.js";
3
- import { a as shouldRefuseHostDashboardPort, i as readHostDashboardApiPort, n as getDashboardIdentity, r as isNonPrimaryCheckoutRoot } from "./deacon-nudge-log-Bjg8U4Y9.js";
4
- import { $ as runInBatches, A as handleConversationDelete, B as stopConversationRuntime, C as isPiControlChannelHarness, D as conversationNeedsRunningRepair, E as validateConversationControlAckOrigin, F as isInsideGitWorkTree, G as cleanupOrphanedConversationAttachments, H as waitForPiTuiReady, I as resolveAllowedHarness, J as extractConversationAttachmentPaths, K as cleanupUnreferencedConversationAttachments, L as shouldReportUnresolvedLiveSession, M as handleConversationResume, N as handleConversationStop, O as conversationSessionAliveFromState, P as handleConversationSwitchModel, Q as removeConversationAttachment, R as spawnConversationSession, S as handleConversationThinkingLevel, St as jsonStringResponse, T as resolveConversationDeliveryMethod, U as waitForTmuxSession$1, V as tmuxSessionExists, W as cleanupConversationAttachments, X as hasConversationAttachment, Y as getConversationAttachmentsRoot, Z as isManagedConversationAttachmentPath, _ as handleConversationCodexApproval, _t as validateOrigin$1, a as agentsRouteLayer, at as panCliInvocation, b as handleConversationDeliveryMethod, bt as getDefaultCwd, c as hasDashboardInternalToken, ct as resolveAgentHarness, d as rejectUnsafeDashboardMutationRequest, dt as resolveJsonlPath, et as evaluateSpawnGuardrails, f as saveAgentStateAndEmitEvent, ft as resolvePiSessionPath, g as handleConversationAbort, gt as isTrustedOriginForHost, h as deliverConversationViaControlChannel, ht as getHeaderFromMap, j as handleConversationRestartAll, k as handleConversationCreate, l as rejectUnauthorizedDashboardRequest, lt as resolveClaudeSessionId, m as codexConversationPendingInput, mt as waitForSessionRespawn, nt as resolveAgentGitInfo, o as dashboardCsrfToken, p as saveAgentStateAndEmitEventProgram, pt as isRespawnPending, q as ensureConversationAttachmentDir, rt as resolveConversationGitInfo, s as dashboardSessionCookieHeader, st as readLauncherPinnedSessionId, t as specialistsRouteLayer, tt as invalidateAgentsCache, u as rejectUnauthorizedDashboardSessionMintRequest, ut as resolveCodexRolloutPath, v as handleConversationCompact, vt as validateOriginHeaders, w as pickDeliverAs, x as handleConversationPlanAction, xt as jsonResponse, y as handleConversationControlAck, yt as httpHandler, z as startConversationModelBackfill } from "./specialists-JVO00bs7.js";
2
+ import { A as canUseHarnessSync, Br as getOverdeckHome, Cr as LOGS_DIR, D as resolveTieredExecutionEnabled, E as resolveTieredExecutionBlock, Et as getIssueWorkspacePath, Fn as renameProject, Fr as getDocsDisableStatePath, Gr as sessionFilePath, H as init_providers, Hr as isDevMode, Ht as flushAutoCommits, I as UnknownModelError, Ir as getDocsIndexPath, J as defaultBackgroundAiFeatures, Jn as extractPrefixSync, Ln as resolveInfraRepo, Lr as getDocsTelemetryPath, M as init_harness_policy, Nr as encodeClaudeProjectDir, Nt as readIssueRecordSync, On as listProjects, Ot as init_record, Pn as registerProjectSync, Pr as getDocsBudgetStatePath, Q as computeModelOrigin, R as getBuiltInDefaultHarness, Rn as resolveProjectFromIssue, T as init_tier_table, Tn as init_projects, Un as setProjectAutoMergeDefaultSync, Ur as packageRoot, Ut as init_auto_commit, V as getProviderForModelSync, Vr as init_paths, Vt as flushAllPendingAutoCommits, Wn as setProjectSwarmPolicySync, X as DEFAULT_ROLES, Y as init_registry, Yn as init_issue_id, Z as DEFAULT_WORKHORSES, Zn as parseIssueIdSync, _ as getDefaultDocsConfig, at as getModelEffortLevelsSync, br as CLAUDE_DIR, cn as ProjectRenameError, ct as modelSupportsImagesSync, d as loadConfigNoMigration, er as require_dist$1, f as loadConfigSync, fn as findProjectByPathSync, fr as TrackerError, g as mergeConfigs, gn as getIssuePrefix, h as jsYaml, hr as AGENTS_DIR, ht as ROLE_EFFORTS, i as getConversationsConfig, ir as FsError, jn as loadProjectsConfigSync, jr as SYNC_SOURCES, k as validateTieredExecutionConfig, kn as listProjectsSync, lt as resolveModelIdSync, m as init_js_yaml, mn as findProjectByTeamSync, mr as init_errors, mt as PARENT_MODEL_REF, n as clearConfigCache, nn as init_state_read_home, nt as MODEL_CAPABILITIES, o as getGlobalConfigPath, or as GitHubApiError, ot as hasModelCapabilitySync, p as updateConversationsConfig, pt as COMPLIANCE_MODES, r as getConversationSearchConfigSync, rn as resolveStateReadHomeSync, rt as MODEL_DEPRECATIONS, s as init_load, st as init_model_capabilities, t as init_config_yaml, tt as resolveModel, u as isTldrEnabledSync, un as extractTeamPrefix, ur as ProcessSpawnError, v as getDefaultTtsDaemonConfig, w as TieredExecutionConfigError, wr as OVERDECK_HOME, y as mergeTtsDaemonConfigs, yn as getProjectSync, z as getKimiAnthropicBaseUrl, zn as resolveProjectFromIssueSync, zr as getLegacyHome } from "./config-yaml-DySPNmKN.js";
3
+ import { a as shouldRefuseHostDashboardPort, i as readHostDashboardApiPort, n as getDashboardIdentity, r as isNonPrimaryCheckoutRoot } from "./deacon-nudge-log-6wVqAaqz.js";
4
+ import { $ as panCliInvocation, A as resolveAllowedHarness, B as cleanupUnreferencedConversationAttachments, C as handleConversationCreate, Ct as jsonStringResponse, D as handleConversationStop, E as handleConversationResume, F as tmuxSessionExists, G as isManagedConversationAttachmentPath, H as extractConversationAttachmentPaths, I as waitForPiTuiReady, J as evaluateSpawnGuardrails, K as removeConversationAttachment, L as waitForTmuxSession$1, M as spawnConversationSession, N as startConversationModelBackfill, O as handleConversationSwitchModel, P as stopConversationRuntime, R as cleanupConversationAttachments, S as conversationSessionAliveFromState, St as jsonResponse, T as handleConversationRestartAll, U as getConversationAttachmentsRoot, V as ensureConversationAttachmentDir, W as hasConversationAttachment, X as resolveAgentGitInfo, Y as invalidateAgentsCache, Z as resolveConversationGitInfo, _ as isPiControlChannelHarness, _t as isTrustedOriginForHost, a as agentsRouteLayer, at as resolveCodexRolloutPath, b as validateConversationControlAckOrigin, bt as httpHandler, c as codexConversationPendingInput, ct as dashboardCsrfToken, d as handleConversationCodexApproval, dt as rejectUnauthorizedDashboardRequest, f as handleConversationCompact, ft as rejectUnauthorizedDashboardSessionMintRequest, g as handleConversationThinkingLevel, gt as getHeaderFromMap, h as handleConversationPlanAction, ht as waitForSessionRespawn, it as resolveClaudeSessionId, j as shouldReportUnresolvedLiveSession, k as isInsideGitWorkTree, l as deliverConversationViaControlChannel, lt as dashboardSessionCookieHeader, m as handleConversationDeliveryMethod, mt as isRespawnPending, nt as resolveAcpTranscriptPath, o as saveAgentStateAndEmitEvent, ot as resolveJsonlPath, p as handleConversationControlAck, pt as rejectUnsafeDashboardMutationRequest, q as runInBatches, rt as resolveAgentHarness, s as saveAgentStateAndEmitEventProgram, st as resolvePiSessionPath, t as specialistsRouteLayer, tt as readLauncherPinnedSessionId, u as handleConversationAbort, ut as hasDashboardInternalToken, v as pickDeliverAs, vt as validateOrigin$1, w as handleConversationDelete, x as conversationNeedsRunningRepair, xt as getDefaultCwd, y as resolveConversationDeliveryMethod, yt as validateOriginHeaders, z as cleanupOrphanedConversationAttachments } from "./specialists-CC4r-c2s.js";
5
5
  import { a as init_activity_logger, i as emitDashboardLifecycleSync, n as emitActivityEntrySync, r as emitActivityTtsSync } from "./activity-logger-DDlOIAML.js";
6
- import { A as init_paths$1, O as OVERDECK_MIGRATION_PATH, f as init_infra, i as DbLive, k as getOverdeckDatabasePath, u as TmuxLive } from "./infra-CzaSOgul.js";
6
+ import { A as init_paths$1, O as OVERDECK_MIGRATION_PATH, f as init_infra, i as DbLive, k as getOverdeckDatabasePath, u as TmuxLive } from "./infra-BEqFxlJc.js";
7
7
  import { n as openDatabase, t as init_driver } from "./driver-CKVGi51s.js";
8
- import { n as updateIssueRecord, t as init_record_update } from "./record-update-Dq0t2uBG.js";
9
- import { $ as init_child_env, B as sendKeysAsync, C as getWindowDimensions, D as killSession, H as sessionExists, J as init_ui_theme, L as resizeWindow, M as listSessionNames, Q as buildChildEnvWithoutTmuxSync, T as isHarnessProcessAlive, Y as setUiTheme, Z as buildChildEnvSync, d as ensureManagedTmuxContextOnce, i as capturePane, l as deliveryVerifyLine, n as buildTmuxArgs, o as capturePaneText, s as createSession, w as init_tmux, z as sendKeys } from "./tmux-ftABRAmc.js";
10
- import { a as init_event_store, i as initEventStore, n as getEventStore } from "./event-store-tdiY5eDZ.js";
11
- import { D as AgentSnapshot, E as AgentRuntimeSnapshot, O as ReviewStatusSnapshot, S as SystemHealthSnapshot, _ as WS_METHODS, b as EDITORS, c as ContextPreviewRequest, g as PanRpcGroup, h as PanRpcError, l as FlywheelStats, n as compareIssueIds, o as getHarnessBehavior, s as ContextLayerSaveRequest, t as init_src, v as FlywheelRunId, w as MemoryObservation, x as DomainEvent, y as FlywheelStatus } from "./src-U7_kTPEE.js";
12
- import { a as fixStuckCommentedReviews, b as setReviewStatusSync, c as getReviewStatusSync, d as loadReviewStatuses, l as init_review_status, n as clearReviewStatus, o as fixStuckReadyForMerge, p as markWorkspaceStuck, r as clearStuckMergeStatuses, s as getReviewStatus, u as loadReadyForMergeFlags, y as setReviewStatus } from "./review-status-A7quS5KJ.js";
13
- import { a as EventStoreService, c as ReadModelService, d as init_read_model, f as toAgentResolution, i as init_issue_lifecycle, l as ReadModelServiceLive, m as toRole, n as IssueLifecycleLive, o as EventStoreServiceLive, p as toAgentStatus, s as init_domain_services, t as IssueLifecycle } from "./issue-lifecycle-CreaCkjW.js";
14
- import { c as listAllAgentsSync, n as AgentsResolverLive, o as init_agents } from "./agents-B4Bjbkfv.js";
15
- import { i as init_paths$2, l as resolveObservationsFile, r as ensureParentDir, s as resolveIssueMemoryRoot, t as assertMemorySafeSegment } from "./paths-_zEts6wc.js";
16
- import { i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, r as init_briefing_freshness, t as appendFreshBriefingUpdate } from "./briefing-freshness-DWdW7vUm.js";
17
- import { n as listFeatureRegistryEntries, t as init_feature_registry_storage } from "./feature-registry-storage-_wUBRD3J.js";
18
- import { a as diffAgainstMain, c as diffCheckpoints, d as diffPatchSinceCommit, f as findCommitAtTime, h as listCheckpoints, l as diffFilesAgainstHead, m as init_checkpoint_manager, o as diffAgainstMainFiles, s as diffCheckpointFiles, t as captureCheckpoint, u as diffPatchFilesAgainstHead } from "./checkpoint-manager-DDqcGyu8.js";
19
- import { Ar as init_codex_auth, Bn as getAgentDir, Cr as getAgentRuntimeStateSync, D as init_tier_supervisor, E as deliverCommitForReview, Ft as init_transcript_landing, Hn as getAgentState, It as probeTranscriptSince, Pt as captureTranscriptUserRecordSnapshot, Q as operatorInterventionEvent, Sr as getAgentRuntimeState, Tn as init_openai_auth, Wn as getAgentStateSync, X as messageAgent, Yt as resolveImplicitStaffing, Z as init_operator_interventions, _t as emergencyBrake, a as listRunningAgentsSync, b as init_agents$1, c as getRuntimeCensus, d as panePidsForSession, dr as readAgentHarnessModelRecordSync, f as refreshRuntimeCensus, hn as init_claude_auth, i as listRunningAgents, in as getProviderAuthMode, ir as saveAgentStateSync, j as supervisorAgentId, kr as checkCodexAuthStatus, kt as deliverAgentMessage, l as getRuntimeCensusSnapshot, mn as getClaudeAuthStatus, n as init_queries, p as runtimeCensusHasHarnessProcess, qt as init_staffing, r as listAgentStates, sn as injectPiConversationMemory, u as init_runtime_census, ur as init_agent_record_sync, vr as normalizeAgentId, wn as getOpenAIAuthStatus, xr as waitForReadySignal, yn as getProviderEnvForModel, yt as init_concurrency } from "./queries-6d7Cdtm7.js";
20
- import { a as getCostForIssueAggregateSync, c as getDailyTrendsSync, d as init_cost_sync, l as getModelRollupSync, n as getBackgroundCostBySourceSync, p as queryCostEventsSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as getTodayCostSync } from "./cost-sync-C0VdGme1.js";
21
- import { c as getAgentsNeedingAttention, d as CostResolverLive, f as CostWriter, l as CostDoorLive, n as readCloisterStateFile, o as generateHealthSummary, s as getAgentHealth, t as getCloisterService, u as CostResolver } from "./service-DCpB_SGd.js";
22
- import { u as init_agent_runtime_mirror } from "./session-history-CVZDpS3c.js";
23
- import { t as init_behavior } from "./behavior-B_-4EKF3.js";
24
- import { n as AgentStateServiceLive } from "./agent-state-service-HoK8U4jW.js";
25
- import { a as init_tracker_config, i as initTrackerConfigCache, n as getLinearApiKey, r as getRallyConfig, t as getGitHubConfig } from "./tracker-config-B4itFzDo.js";
8
+ import { n as updateIssueRecord, t as init_record_update } from "./record-update-dE1Aw83j.js";
9
+ import { $ as init_child_env, B as sendKeysAsync, C as getWindowDimensions, D as killSession, H as sessionExists, J as init_ui_theme, L as resizeWindow, M as listSessionNames, Q as buildChildEnvWithoutTmuxSync, T as isHarnessProcessAlive, Y as setUiTheme, Z as buildChildEnvSync, d as ensureManagedTmuxContextOnce, i as capturePane, l as deliveryVerifyLine, n as buildTmuxArgs, o as capturePaneText, s as createSession, w as init_tmux, z as sendKeys } from "./tmux-R7N7y-Mh.js";
10
+ import { a as init_event_store, i as initEventStore, n as getEventStore } from "./event-store-CQL6NeqB.js";
11
+ import { A as AgentSnapshot, C as EDITORS, D as MemoryObservation, S as FlywheelStatus, T as SystemHealthSnapshot, b as WS_METHODS, c as ContextLayerSaveRequest, f as FlywheelStats, j as ReviewStatusSnapshot, k as AgentRuntimeSnapshot, l as ContextPreviewRequest, n as compareIssueIds, o as getHarnessBehavior, t as init_src, v as PanRpcError, w as DomainEvent, x as FlywheelRunId, y as PanRpcGroup } from "./src-DtcUOZCq.js";
12
+ import { a as fixStuckCommentedReviews, b as setReviewStatusSync, c as getReviewStatusSync, d as loadReviewStatuses, l as init_review_status, n as clearReviewStatus, o as fixStuckReadyForMerge, p as markWorkspaceStuck, r as clearStuckMergeStatuses, s as getReviewStatus, u as loadReadyForMergeFlags, y as setReviewStatus } from "./review-status-kZj_KyCk.js";
13
+ import { a as EventStoreService, c as ReadModelService, d as init_read_model, f as toAgentResolution, i as init_issue_lifecycle, l as ReadModelServiceLive, m as toRole, n as IssueLifecycleLive, o as EventStoreServiceLive, p as toAgentStatus, s as init_domain_services, t as IssueLifecycle } from "./issue-lifecycle-ojZAzDBP.js";
14
+ import { c as listAllAgentsSync, n as AgentsResolverLive, o as init_agents } from "./agents-EbI0zCJl.js";
15
+ import { i as init_paths$2, l as resolveObservationsFile, r as ensureParentDir, s as resolveIssueMemoryRoot, t as assertMemorySafeSegment } from "./paths-D-xWGHdh.js";
16
+ import { i as recordBriefingSessionStart, n as ensureSessionContextBriefingFile, r as init_briefing_freshness, t as appendFreshBriefingUpdate } from "./briefing-freshness-D1wzUIWv.js";
17
+ import { n as listFeatureRegistryEntries, t as init_feature_registry_storage } from "./feature-registry-storage-BdPuLcBX.js";
18
+ import { a as diffAgainstMain, c as diffCheckpoints, d as diffPatchSinceCommit, f as findCommitAtTime, h as listCheckpoints, l as diffFilesAgainstHead, m as init_checkpoint_manager, o as diffAgainstMainFiles, s as diffCheckpointFiles, t as captureCheckpoint, u as diffPatchFilesAgainstHead } from "./checkpoint-manager-BI1Wxoku.js";
19
+ import { Cn as getProviderEnvForModel, Cr as normalizeAgentId, D as init_tier_supervisor, Dr as getAgentRuntimeState, E as deliverCommitForReview, Er as waitForReadySignal, Fr as init_codex_auth, Ft as init_transcript_landing, Gn as getAgentDir, It as probeTranscriptSince, On as getOpenAIAuthStatus, Or as getAgentRuntimeStateSync, Pr as checkCodexAuthStatus, Pt as captureTranscriptUserRecordSnapshot, Q as operatorInterventionEvent, X as messageAgent, Yn as getAgentStateSync, Yt as resolveImplicitStaffing, Z as init_operator_interventions, _t as emergencyBrake, a as listRunningAgentsSync, an as getProviderAuthMode, b as init_agents$1, c as getRuntimeCensus, cn as injectPiConversationMemory, d as panePidsForSession, f as refreshRuntimeCensus, gr as readAgentHarnessModelRecordSync, hr as init_agent_record_sync, i as listRunningAgents, j as supervisorAgentId, kn as init_openai_auth, kt as deliverAgentMessage, l as getRuntimeCensusSnapshot, lr as saveAgentStateSync, n as init_queries, p as runtimeCensusHasHarnessProcess, qn as getAgentState, qt as init_staffing, r as listAgentStates, u as init_runtime_census, vn as getClaudeAuthStatus, yn as init_claude_auth, yt as init_concurrency } from "./queries-CjNIf-Ub.js";
20
+ import { a as getCostForIssueAggregateSync, c as getDailyTrendsSync, d as init_cost_sync, l as getModelRollupSync, n as getBackgroundCostBySourceSync, p as queryCostEventsSync, r as getCavemanExperimentDataSync, s as getCostsByIssueSync, u as getTodayCostSync } from "./cost-sync-BsN6ER0n.js";
21
+ import { c as getAgentsNeedingAttention, d as CostResolverLive, f as CostWriter, l as CostDoorLive, n as readCloisterStateFile, o as generateHealthSummary, s as getAgentHealth, t as getCloisterService, u as CostResolver } from "./service-CLeAoU6G.js";
22
+ import { u as init_agent_runtime_mirror } from "./session-history-BT3IvqhC.js";
23
+ import { t as init_behavior } from "./behavior-B3exJ42O.js";
24
+ import { n as AgentStateServiceLive } from "./agent-state-service-BsgWxZuB.js";
25
+ import { a as init_tracker_config, i as initTrackerConfigCache, n as getLinearApiKey, r as getRallyConfig, t as getGitHubConfig } from "./tracker-config-G6latr8C.js";
26
26
  import { d as init_typed_errors, i as PlanEmpty, l as WorkspaceCreateError, n as AgentStartError, s as TrackerApiError, t as AgentAlreadyRunning, u as WorkspaceNotFound } from "./typed-errors-2BTMxkZq.js";
27
- import { i as init_linear_client, r as LinearClientOptionalLive, t as LinearClient } from "./linear-client-D4zqMnX7.js";
28
- import { i as init_github_client, r as GitHubClientOptionalLive, t as GitHubClient } from "./github-client--XVlDpwM.js";
29
- import { i as init_rally_client, r as RallyClientOptionalLive, t as RallyClient } from "./rally-client-B1EJhfV0.js";
30
- import { a as resolveTrackerTypeSync, i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-tnxxqROg.js";
31
- import { a as CacheService, i as startSharedIssueService, n as init_issue_service_singleton, o as init_cache_service, r as issue_service_singleton_exports, s as parseIntegerHeader, t as getSharedIssueService } from "./issue-service-singleton-B5ushCvE.js";
32
- import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-Bb4XeV2x.js";
33
- import { a as setPipelineHandlerSync, t as init_pipeline_notifier } from "./pipeline-notifier-D0ykk59O.js";
34
- import { c as init_review_status_sync, i as getMergeBlockerReconcileCandidates } from "./review-status-sync-BhSQ0d0l.js";
27
+ import { i as init_linear_client, r as LinearClientOptionalLive, t as LinearClient } from "./linear-client-BsuUvkdA.js";
28
+ import { i as init_github_client, r as GitHubClientOptionalLive, t as GitHubClient } from "./github-client-BnIsSrEN.js";
29
+ import { i as init_rally_client, r as RallyClientOptionalLive, t as RallyClient } from "./rally-client-lc-nokqr.js";
30
+ import { a as resolveTrackerTypeSync, i as resolveGitHubIssueSync, n as init_tracker_utils } from "./tracker-utils-DHv5pSDT.js";
31
+ import { a as CacheService, i as startSharedIssueService, n as init_issue_service_singleton, o as init_cache_service, r as issue_service_singleton_exports, s as parseIntegerHeader, t as getSharedIssueService } from "./issue-service-singleton-Yx5DdmVJ.js";
32
+ import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-s0-oKybJ.js";
33
+ import { a as setPipelineHandlerSync, t as init_pipeline_notifier } from "./pipeline-notifier-BXkJzDC4.js";
34
+ import { c as init_review_status_sync, i as getMergeBlockerReconcileCandidates } from "./review-status-sync-BTOpxtTC.js";
35
35
  import { n as init_review_status_source, t as classifyAdvancingSessionLifecycle } from "./review-status-source-CxuEjLGg.js";
36
36
  import { a as PAN_DIRNAME, d as WORKSPACE_RUNTIME_DIRNAME, f as asPanSpecDocument, i as PAN_CONTINUE_FILENAME, p as init_types } from "./types-hraoaQIp.js";
37
- import { C as transitionToMerging, _ as markFailed, c as isFlywheelGloballyPaused, d as listDuePendingAutoMerges, f as listProblemAutoMerges, g as markBlocked, n as getActionableAutoMerge, o as init_merge_sync, t as cancelPending, u as listActiveAutoMerges, v as markMerged, x as scheduleAutoMergeWithResult, y as requeueToPending } from "./merge-sync-DZ9dojJn.js";
38
- import { C as init_specs, D as writeSpecDocument, O as writeSpecForIssue, a as findWorkspaceDraftPlan, m as readWorkspacePlanSync, o as init_io, p as readWorkspacePlan, r as findPlan, s as isPlanningComplete, u as readPlan, v as init_types$1, x as findSpecByIssue, y as subItemsOf } from "./io-B3_AHDfr.js";
39
- import { C as restartCliproxy, S as readPidFile, T as stopCliproxy, b as isCliproxyInstalled, d as getCliproxyAuthDir, o as bridgeCodexAuthToCliproxy, v as init_cliproxy, w as startCliproxy, x as isCliproxyRunning, y as installCliproxy } from "./cliproxy-Bgb2XCqi.js";
40
- import { $ as updateConversationForkFallbackReason, A as isAgentConversationName, B as removeFavorite, C as getConversationByTmuxSession, D as importLegacyConversation, F as markConversationEnded, H as setClearedToConvId, I as markConversationRunning, J as setForkRequest, M as listConversations, N as listFavoritedIds, O as incrementForkRetryCount, P as markConversationActive, S as getConversationByName, T as getStuckForks, U as setConversationClaudeSessionId, X as unarchiveConversation, Y as setImportedConversationLinks, Z as updateConversationCost, _ as canRefineTitle, b as getConversationByClaudeSessionId, et as updateConversationTitle, gt as getDiscoveredSessionBySessionId, h as archiveConversation, j as listArchivedConversationsWithEnrichment, k as init_conversations, q as setFavorite, tt as updateForkStatus, v as canReplaceTitle, w as getConversationLedgerCosts, x as getConversationById, y as createConversation, yt as init_discovered_sessions, z as recordConversationHandoff } from "./conversations-DbOs1e9Q.js";
41
- import { n as isBackgroundFeatureEnabled, t as init_features } from "./features-Dhxz-wLc.js";
42
- import { i as init_settings, r as getMemoryWorkerConcurrency, t as areMemoryObservationsEnabled } from "./settings-BZ5m1UCl.js";
43
- import { i as updateMemoryHealth, n as extractWithProviderPolicy, r as init_health, t as init_providers$1 } from "./providers-DV7ec8l7.js";
44
- import { i as normalizeModelOverrideSync, n as init_launcher_generator, r as init_model_validation, t as generateLauncherScriptSync } from "./launcher-generator-CHVm7bGT.js";
45
- import { a as init_claude_permissions, r as getClaudePermissionFlagsStringSync } from "./claude-permissions-H_5wHQZQ.js";
46
- import { a as globalContextFile$1, f as resolveProjectContextFile, h as workspaceContextFile, n as codexGlobalContextFile, o as init_layers, p as resolveWorkspaceContextFile, r as ensureProjectLayer } from "./layers-DzxSTGNA.js";
47
- import { l as init_codex, s as findRolloutPath } from "./codex-TmSi-yTv.js";
48
- import { n as init_harness_binary, r as prepareHarnessLaunch } from "./harness-binary-CVio2m-u.js";
49
- import { f as init_config, m as loadConfigSync$1, s as getDashboardApiUrlSync } from "./config-CCvjQf27.js";
50
- import { C as setMergeTrainEnabled, S as setFlywheelRequireUatBeforeMerge, b as setFlywheelAutoPickupBacklog, c as isCloisterSpawnsPausedSync, d as isFlywheelAutoPickupBacklog, f as isFlywheelGloballyPaused$1, g as setCloisterSpawnsPausedSync, h as setBootReconciliationDecision, m as isMergeTrainEnabled, o as getSetting, p as isFlywheelRequireUatBeforeMerge, r as getBootReconciliationState, s as init_control_settings, u as isDeaconGloballyPausedSync, v as setDeaconGloballyPausedSync, w as setSetting } from "./control-settings-aP1ANIlI.js";
51
- import { l as init_dag, r as compileGlob } from "./dag-CdOjJVDT.js";
52
- import { a as loadCloisterConfigSync, o as saveCloisterConfigSync, r as init_config$1, s as shouldAutoStart } from "./config-DjLOdbgT.js";
53
- import { c as isStateMigrated, i as ensureStateWorktree, o as init_state_home, r as clearStateMigrationCache, s as inspectStateMigration } from "./state-home-CIGjwNfJ.js";
54
- import { i as checkPrdGateSync, s as promoteWorkspacePrdDraft, t as init_pan_dir } from "./pan-dir-DeVUgwA7.js";
55
- import { a as init_lifecycle_io, t as appendContinueSessionEntryForIssue } from "./lifecycle-io-D8iNBcux.js";
56
- import { r as init_swarm_readiness, t as analyzeSwarmReadiness } from "./swarm-readiness-CQ_fwUWF.js";
57
- import { n as require_auth_errors, r as require_token_error, t as require_token_util } from "./token-util-CTmczIfW.js";
58
- import { A as withConcurrencyLimit, D as createPromiseConcurrencyLimiter, E as verifyAppCanMerge, O as createSettledTtlPromiseCache, d as getPullRequestState, f as init_github_app, k as init_concurrency$1, l as getMergeBackendStatus, p as isGitHubAppConfigured } from "./github-app-CMBdIFBQ.js";
59
- import { C as getWorkspacePathForIssue, E as stopAgentOutputService, S as resolveIssueHeadlineCost, T as startAgentOutputService, _ as getCostsForIssueSync, b as processPendingFeedbackDeliveries, d as resumeQueuedMerges, f as syncWalFromAllProjects, g as migrateAllSessionsSync, h as reclassifyUnknownCostEventsSync, l as internalEventsRouteLayer, m as reconcilePiTranscripts, p as reconcile$1, t as workspacesRouteLayer, u as eventsRouteLayer, v as rebuildCacheSync, w as retainAgentOutputInterest, x as getCachedRunningAgents, y as syncCacheSync } from "./workspaces-hWvy9eKs.js";
60
- import { _ as init_codex_conversation_parser, a as contextUsageFromParseResult, c as parseEntireConversation, d as init_pi_conversation_parser, f as isPiSessionFile, g as parseOhmypiConversationMessages, h as isOhmypiSessionFile, i as computeContextUsage, l as parseFromLastCompactBoundary, m as init_ohmypi_conversation_parser, n as gateSnapshotEmission, o as summarizeConversationActivity, p as parsePiConversationMessages, r as watchConversation, s as parseConversationMessages, t as init_conversation_service, v as parseCodexConversationMessages } from "./conversation-service-Du-MTNpJ.js";
61
- import { c as countPendingAskUserQuestionsForAgent, h as detectAwaitingInputFromPaneSync, l as getAgentJsonlMtime, m as detectAwaitingInputForAgent, o as getRuntimeForAgent, p as scanPendingInputsPromise, s as computeAgentEnrichment } from "./stuck-remediation-CzEov_fq.js";
62
- import { i as CostThresholdError, l as embed, s as parseRelativeTime } from "./scanner-D2743cp8.js";
63
- import { c as tailEventsSync, n as deduplicateEventsSync, o as readEventsSync } from "./events-CC1dgUpx.js";
64
- import { n as recordBackgroundAiCost, t as init_cost } from "./cost-CW4WSe72.js";
65
- import { a as getByIssueId, i as parseFlywheelStatsWindow, n as derivePipelineRunStatsInputs, o as markFixed, r as computeFlywheelStats, s as upsert } from "./substrate-bug-weights-service-BH66lhm7.js";
66
- import { c as startUatTrainReconciler, d as openFlywheelRunReportForDashboard, f as pauseFlywheelRunForDashboard, g as runDashboardDbJob, h as startFlywheelRunForDashboard, l as stopUatTrainReconciler, m as resumeFlywheelRunForDashboard, p as readCurrentFlywheelStatusForDashboard, u as abortFlywheelRunForDashboard } from "./uat-train-CuEn0t9M.js";
67
- import { C as writeLatestFlywheelStatus, b as resolveLiveFlywheelRunId, g as listFlywheelRuns, h as isFlywheelRunId, p as getFlywheelRunDetail, u as buildClassifyLookups, v as readCurrentLatestFlywheelStatus, x as subscribeLatestFlywheelStatus } from "./flywheel-DSSpWmqF.js";
68
- import { At as getContainerHistory, Ct as paneShowsClaudeBootBlockingScreen, F as setAgentStatusChangedNotifier, Ft as getSystemHealthEvidenceSnapshot, I as setAgentStoppedNotifier, J as startBootReconciliation, K as isBootReconciliationCandidate, L as setMergeReadyNotifier, Lt as isSmeeConfiguredSync, Mt as getAcceptedSystemHealthSnapshot, Nt as getDeployStaleness, O as loadConfig, Ot as getResourceStacks, Rt as startSmeeProcessSync, jt as getCurrentDockerStats, k as loadState, kt as formatUptime, n as assessDeaconPatrolFreshness, q as listBootReconciliationCandidates, t as applyBootReconciliationDecision, x as getDeaconLogs, zt as classifyAgentHealth } from "./deacon-pRnyD5w9.js";
69
- import { l as detectPlatform, u as init_platform } from "./workspace-manager-hLUv3ADC.js";
70
- import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-C9b6ccN1.js";
71
- import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-aQ1IxeI3.js";
72
- import { V as getReviewerSessionName, t as init_specialists } from "./specialists-DyFeedjn.js";
73
- import { c as findPrdAnywhereSync, l as init_prd_locations } from "./archive-planning-DYrYojxl.js";
74
- import { a as getShadowState, s as init_shadow_state } from "./shadow-state-Dh-HzF2J.js";
75
- import { n as init_issue_closed, t as clearIssueClosedCache } from "./issue-closed-zhdvQicO.js";
76
- import { b as resolveSwarmPolicy } from "./deacon-swarm-DftYRDo8.js";
77
- import { a as init_boot_gates, i as formatBootGateState, o as resolveBootGates } from "./no-resume-mode-Cx3K0hHi.js";
78
- import { _ as selectNeedsPlanning, c as classifyIssue, d as computeLanes, f as computeStats, g as normalizeGate, l as computeCohort, m as init_pickup, p as computeWaves, u as computeEpicGroups } from "./pickup-Dd0Znxxy.js";
79
- import { a as applyIssueObjectionLabel, c as applyIssueReleasedLabel, d as removeIssueBlocksMainLabel, f as removeIssueObjectionLabel, g as removeIssueVetoedLabel, h as removeIssueReleasedLabel, i as applyIssueBlocksMainLabel, l as applyIssueVetoedLabel, m as removeIssueReadyLabel, o as applyIssueParkedLabel, p as removeIssueParkedLabel, s as applyIssueReadyLabel, u as init_label_ops } from "./label-reconciler-DdWbHEBu.js";
80
- import { n as parseSequenceMd, r as writeSequenceMd, t as init_sequence_io } from "./sequence-io-Cg0zYj_E.js";
81
- import { c as init_resource_utils, i as gatherProjectLensSignals, l as parseIssueIdFromTextSync, n as init_pipeline_membership, o as init_pipeline_membership_gather, r as resolvePipelineMembership, s as listOpenPullRequestsSnapshot } from "./pipeline-membership-0HaEGDlH.js";
82
- import { a as loadWorkspaceMetadataSync } from "./workspace-metadata-CskwzzhL.js";
83
- import { i as resolveAutoSpawnOnFinalize, o as spawnPlanningSession } from "./spawn-planning-session-DWAorh2B.js";
84
- import { d as killRemoteAgent, m as loadRemoteAgentState, o as getRemoteAgentOutput, r as checkRemoteSpendCap, s as init_remote_agents, v as sendToRemoteAgent, y as spawnRemoteAgent } from "./remote-agents-nmty1mLu.js";
85
- import { r as spawnInspectAgent } from "./inspect-agent-DJKLWcVT.js";
86
- import { n as init_github_pr_lookup, r as lookupPullRequestNumberForBranch, t as githubPrLookupSource } from "./github-pr-lookup-BRbDW-qk.js";
87
- import { a as fetchIssuePullRequestDiff, c as getCachedIssuePrTabResponse, d as setCachedIssuePrTabResponse, i as fetchIssuePullRequestDetails, l as getIssuePrTabCacheGeneration, n as fetchIssueCheckRuns, o as init_pull_requests, r as fetchIssuePullRequest, s as bumpIssuePrTabCacheGeneration, u as init_pr_tab_cache } from "./pull-requests-CXIhdCYD.js";
88
- import { t as DOD_ROWS } from "./dod-BrSfUHm0.js";
89
- import { t as enrichReviewStatus } from "./review-status-enrichment-tbOn_A_u.js";
90
- import { i as runMemoryFtsTransaction, n as init_fts_db, r as runMemoryFtsStatement, t as closeMemoryFtsDatabases } from "./fts-db-CKgg0VKg.js";
91
- import { c as init_pending, l as maybeTriggerStatusRollup, o as readRecentObservations, r as init_rollup, u as writePendingTurn } from "./rollup-WA0VD-Rr.js";
92
- import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-BDtLOIlO.js";
93
- import { T as listGitOperationsSync, w as init_git_activity } from "./merge-agent-XrB80vfT.js";
94
- import { t as readVerificationArtifact } from "./verification-artifact-BcnIbigL.js";
95
- import { t as getAgentCommandSync } from "./settings-ylxwqwQG.js";
96
- import { n as init_review_agent, r as isExtendedReviewEnabled } from "./review-agent-sKkE1FEL.js";
97
- import { r as isRemoteAvailable, t as createFlyProviderFromConfig } from "./remote-Br-ZWVIP.js";
98
- import { n as init_claude_settings_overlay, t as detectProviderEnvConflicts } from "./claude-settings-overlay-CbSz0Dvb.js";
99
- import { a as init_query_expansion, i as clearQueryExpansionCache, n as init_injection, o as buildMatchQuery, r as injectPromptTimeMemory, s as init_search } from "./injection-DZ0PfYa4.js";
100
- import { _ as init_transcript_adapter, a as generateFallbackSummary, c as handoffPreconditionFallbackReason, d as prependFallbackFocus, f as requestHandoffFromAgent, g as getTranscriptAdapter, i as copySessionFromCompactBoundary, l as init_summary_fork, o as generateSummaryForFork, p as reserveSummaryForkSession, r as authorHandoffExternal, s as handoffFailureReason, u as logHandoffFallback } from "./summary-fork-DHhJIsAL.js";
101
- import { a as init_conversation_compaction, c as shouldInterceptManualCompact, n as compactConversationNative, o as isCompacting } from "./conversation-compaction-CNbTLB86.js";
102
- import { a as init_render, d as validateTemplate, i as hasManagedRegion, l as init_harness, o as userContentOutsideRegion, t as init_context_layers, u as renderForHarness } from "./context-layers-ZYFcWiyc.js";
103
- import { r as parseArtifactRef } from "./forge-Ch9gCFod.js";
104
- import { t as getMergeBlockersPayload } from "./merge-blockers-BsFjGrQ8.js";
105
- import { a as spawnSequencerAgent, i as init_sequencer_agent, n as clearFinishedSequencerRun, r as getSequencerRunStatus, t as SEQUENCER_AGENT_ID } from "./sequencer-agent-BGY8gjg-.js";
106
- import "./supervisor-BO-Zk_h-.js";
107
- import { i as listTranscriptCheckpoints, r as getTranscriptCheckpoint$1 } from "./checkpoints-C-AXLfYT.js";
37
+ import { C as transitionToMerging, _ as markFailed, c as isFlywheelGloballyPaused, d as listDuePendingAutoMerges, f as listProblemAutoMerges, g as markBlocked, n as getActionableAutoMerge, o as init_merge_sync, t as cancelPending, u as listActiveAutoMerges, v as markMerged, x as scheduleAutoMergeWithResult, y as requeueToPending } from "./merge-sync-VPV28g0g.js";
38
+ import { C as init_specs, D as writeSpecDocument, O as writeSpecForIssue, a as findWorkspaceDraftPlan, m as readWorkspacePlanSync, o as init_io, p as readWorkspacePlan, r as findPlan, s as isPlanningComplete, u as readPlan, v as init_types$1, x as findSpecByIssue, y as subItemsOf } from "./io-C9kF1wtJ.js";
39
+ import { C as restartCliproxy, S as readPidFile, T as stopCliproxy, b as isCliproxyInstalled, d as getCliproxyAuthDir, o as bridgeCodexAuthToCliproxy, v as init_cliproxy, w as startCliproxy, x as isCliproxyRunning, y as installCliproxy } from "./cliproxy-C8a1vtTU.js";
40
+ import { $ as updateConversationForkFallbackReason, A as isAgentConversationName, B as removeFavorite, C as getConversationByTmuxSession, D as importLegacyConversation, F as markConversationEnded, H as setClearedToConvId, I as markConversationRunning, J as setForkRequest, M as listConversations, N as listFavoritedIds, O as incrementForkRetryCount, P as markConversationActive, S as getConversationByName, T as getStuckForks, U as setConversationClaudeSessionId, X as unarchiveConversation, Y as setImportedConversationLinks, Z as updateConversationCost, _ as canRefineTitle, b as getConversationByClaudeSessionId, et as updateConversationTitle, gt as getDiscoveredSessionBySessionId, h as archiveConversation, j as listArchivedConversationsWithEnrichment, k as init_conversations, q as setFavorite, tt as updateForkStatus, v as canReplaceTitle, w as getConversationLedgerCosts, x as getConversationById, y as createConversation, yt as init_discovered_sessions, z as recordConversationHandoff } from "./conversations-6AfUfbwc.js";
41
+ import { n as isBackgroundFeatureEnabled, t as init_features } from "./features-ez2271oH.js";
42
+ import { i as init_settings, r as getMemoryWorkerConcurrency, t as areMemoryObservationsEnabled } from "./settings-BTMvpNFU.js";
43
+ import { i as updateMemoryHealth, n as extractWithProviderPolicy, r as init_health, t as init_providers$1 } from "./providers-qQAwGQDW.js";
44
+ import { a as normalizeModelOverrideSync, i as init_model_validation, n as init_launcher_generator, o as requireModelOverrideSync, r as MODEL_ID_PATTERN, t as generateLauncherScriptSync } from "./launcher-generator-BBWG_SiS.js";
45
+ import { a as init_claude_permissions, r as getClaudePermissionFlagsStringSync } from "./claude-permissions-DNWEVV6z.js";
46
+ import { C as ensureProjectLayer, E as init_layers, I as workspaceContextFile, N as resolveProjectContextFile, P as resolveWorkspaceContextFile, S as codexGlobalContextFile, T as globalContextFile$1, b as validateTemplate, c as init_render, d as userContentOutsideRegion, i as workspaceContextWithoutProjectLayer, r as init_assemble, s as hasManagedRegion, v as init_harness, y as renderForHarness } from "./assemble-J2ZZ2C15.js";
47
+ import { l as init_codex, s as findRolloutPath } from "./codex-BZXGhUVB.js";
48
+ import { i as prepareHarnessLaunch, r as init_harness_binary } from "./harness-binary-DPUi-Pv8.js";
49
+ import { f as init_config, m as loadConfigSync$1, s as getDashboardApiUrlSync } from "./config-BZ0sHTju.js";
50
+ import { C as setMergeTrainEnabled, S as setFlywheelRequireUatBeforeMerge, b as setFlywheelAutoPickupBacklog, c as isCloisterSpawnsPausedSync, d as isFlywheelAutoPickupBacklog, f as isFlywheelGloballyPaused$1, g as setCloisterSpawnsPausedSync, h as setBootReconciliationDecision, m as isMergeTrainEnabled, o as getSetting, p as isFlywheelRequireUatBeforeMerge, r as getBootReconciliationState, s as init_control_settings, u as isDeaconGloballyPausedSync, v as setDeaconGloballyPausedSync, w as setSetting } from "./control-settings-BQp7_4uD.js";
51
+ import { l as init_dag, r as compileGlob } from "./dag-B1ucnjDU.js";
52
+ import { a as loadCloisterConfigSync, o as saveCloisterConfigSync, r as init_config$1, s as shouldAutoStart } from "./config-CKxYiCmX.js";
53
+ import { c as isStateMigrated, i as ensureStateWorktree, o as init_state_home, r as clearStateMigrationCache, s as inspectStateMigration } from "./state-home-Cn_Qu8IX.js";
54
+ import { i as checkPrdGateSync, s as promoteWorkspacePrdDraft, t as init_pan_dir } from "./pan-dir-B0c3w0Ya.js";
55
+ import { a as init_lifecycle_io, t as appendContinueSessionEntryForIssue } from "./lifecycle-io-BREGpnLk.js";
56
+ import { r as init_swarm_readiness, t as analyzeSwarmReadiness } from "./swarm-readiness-DlP_UjHq.js";
57
+ import { a as buildMatchQuery, c as init_query_expansion, i as resolveKnowledgeBundleRoot, n as init_injection, o as init_search, r as injectPromptTimeMemory, s as clearQueryExpansionCache } from "./injection-C8aiVJrF.js";
58
+ import { i as runMemoryFtsTransaction, n as init_fts_db, r as runMemoryFtsStatement, t as closeMemoryFtsDatabases } from "./fts-db-CE46vDkZ.js";
59
+ import { n as require_auth_errors, r as require_token_error, t as require_token_util } from "./token-util-DxXu-vd1.js";
60
+ import { A as createSettledTtlPromiseCache, D as init_advisory_checks, E as verifyAppCanMerge, M as withConcurrencyLimit, O as isAdvisoryCheckName, d as getPullRequestState, f as init_github_app, j as init_concurrency$1, k as createPromiseConcurrencyLimiter, l as getMergeBackendStatus, p as isGitHubAppConfigured } from "./github-app-C3QrAUd0.js";
61
+ import { C as getWorkspacePathForIssue, E as stopAgentOutputService, S as resolveIssueHeadlineCost, T as startAgentOutputService, _ as getCostsForIssueSync, b as processPendingFeedbackDeliveries, d as resumeQueuedMerges, f as syncWalFromAllProjects, g as migrateAllSessionsSync, h as reclassifyUnknownCostEventsSync, l as internalEventsRouteLayer, m as reconcilePiTranscripts, p as reconcile$1, t as workspacesRouteLayer, u as eventsRouteLayer, v as rebuildCacheSync, w as retainAgentOutputInterest, x as getCachedRunningAgents, y as syncCacheSync } from "./workspaces-Do_9J0LQ.js";
62
+ import { _ as init_codex_conversation_parser, a as contextUsageFromParseResult, b as parseAcpConversationMessages, c as parseEntireConversation, d as init_pi_conversation_parser, f as isPiSessionFile, g as parseOhmypiConversationMessages, h as isOhmypiSessionFile, i as computeContextUsage, l as parseFromLastCompactBoundary, m as init_ohmypi_conversation_parser, n as gateSnapshotEmission, o as summarizeConversationActivity, p as parsePiConversationMessages, r as watchConversation, s as parseConversationMessages, t as init_conversation_service, v as parseCodexConversationMessages, y as init_acp_conversation_parser } from "./conversation-service-DPJ71F33.js";
63
+ import { c as countPendingAskUserQuestionsForAgent, h as detectAwaitingInputFromPaneSync, l as getAgentJsonlMtime, m as detectAwaitingInputForAgent, o as getRuntimeForAgent, p as scanPendingInputsPromise, s as computeAgentEnrichment } from "./stuck-remediation-DYuPRYYw.js";
64
+ import { i as CostThresholdError, l as embed, s as parseRelativeTime } from "./scanner-CnqEZeDy.js";
65
+ import { c as tailEventsSync, n as deduplicateEventsSync, o as readEventsSync } from "./events-DTfAe4My.js";
66
+ import { n as recordBackgroundAiCost, t as init_cost } from "./cost-R-m6Yi-W.js";
67
+ import { a as getByIssueId, i as parseFlywheelStatsWindow, n as derivePipelineRunStatsInputs, o as markFixed, r as computeFlywheelStats, s as upsert } from "./substrate-bug-weights-service-B-FwCs5V.js";
68
+ import { c as startUatTrainReconciler, d as openFlywheelRunReportForDashboard, f as pauseFlywheelRunForDashboard, g as runDashboardDbJob, h as startFlywheelRunForDashboard, l as stopUatTrainReconciler, m as resumeFlywheelRunForDashboard, p as readCurrentFlywheelStatusForDashboard, u as abortFlywheelRunForDashboard } from "./uat-train-DDSrSoV1.js";
69
+ import { n as parseSequenceMd, r as writeSequenceMd, t as init_sequence_io } from "./sequence-io-D909zgeH.js";
70
+ import { _ as selectNeedsPlanning, c as classifyIssue, d as computeLanes, f as computeStats, g as normalizeGate, l as computeCohort, m as init_pickup, p as computeWaves, u as computeEpicGroups } from "./pickup-DUCLWrJY.js";
71
+ import { B as getBook, C as readCurrentLatestFlywheelStatus, E as subscribeLatestFlywheelStatus, F as setItemRequirements, H as liveOrderIssueLookup, I as setSettings, L as setStatus, M as moveItem, N as removeItem, O as writeLatestFlywheelStatus, P as renameBook, R as backlogCandidates, T as resolveLiveFlywheelRunId, V as listBooks, b as isFlywheelRunId, j as createBook, k as addItems, p as buildClassifyLookups, v as getFlywheelRunDetail, x as listFlywheelRuns, z as computeBookProgress } from "./flywheel-DHrgCphM.js";
72
+ import { At as getContainerHistory, Ct as paneShowsClaudeBootBlockingScreen, F as setAgentStatusChangedNotifier, Ft as getSystemHealthEvidenceSnapshot, I as setAgentStoppedNotifier, J as startBootReconciliation, K as isBootReconciliationCandidate, L as setMergeReadyNotifier, Lt as isSmeeConfiguredSync, Mt as getAcceptedSystemHealthSnapshot, Nt as getDeployStaleness, O as loadConfig, Ot as getResourceStacks, Rt as startSmeeProcessSync, jt as getCurrentDockerStats, k as loadState, kt as formatUptime, n as assessDeaconPatrolFreshness, q as listBootReconciliationCandidates, t as applyBootReconciliationDecision, x as getDeaconLogs, zt as classifyAgentHealth } from "./deacon-CU_cAYSR.js";
73
+ import { d as init_platform, u as detectPlatform } from "./workspace-manager-CBhNdzE4.js";
74
+ import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-CY5L1lB7.js";
75
+ import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-CAAkqPLu.js";
76
+ import { V as getReviewerSessionName, t as init_specialists } from "./specialists-jiuuyVkp.js";
77
+ import { c as findPrdAnywhereSync, l as init_prd_locations } from "./archive-planning-Du25Jtst.js";
78
+ import { a as getShadowState, s as init_shadow_state } from "./shadow-state-7a-524T8.js";
79
+ import { n as init_issue_closed, t as clearIssueClosedCache } from "./issue-closed-CDJk4pIp.js";
80
+ import { b as resolveSwarmPolicy } from "./deacon-swarm-BXZZ1Z2-.js";
81
+ import { a as init_boot_gates, i as formatBootGateState, o as resolveBootGates } from "./no-resume-mode-Nw29vaFb.js";
82
+ import { a as applyIssueObjectionLabel, c as applyIssueReleasedLabel, d as removeIssueBlocksMainLabel, f as removeIssueObjectionLabel, g as removeIssueVetoedLabel, h as removeIssueReleasedLabel, i as applyIssueBlocksMainLabel, l as applyIssueVetoedLabel, m as removeIssueReadyLabel, o as applyIssueParkedLabel, p as removeIssueParkedLabel, s as applyIssueReadyLabel, u as init_label_ops } from "./label-reconciler-B4iOAjlC.js";
83
+ import { c as init_resource_utils, i as gatherProjectLensSignals, l as parseIssueIdFromTextSync, n as init_pipeline_membership, o as init_pipeline_membership_gather, r as resolvePipelineMembership, s as listOpenPullRequestsSnapshot } from "./pipeline-membership-mY3GprlK.js";
84
+ import { a as loadWorkspaceMetadataSync } from "./workspace-metadata-_WygnyoX.js";
85
+ import { i as resolveAutoSpawnOnFinalize, o as spawnPlanningSession } from "./spawn-planning-session-DKpdFyOC.js";
86
+ import { d as killRemoteAgent, m as loadRemoteAgentState, o as getRemoteAgentOutput, r as checkRemoteSpendCap, s as init_remote_agents, v as sendToRemoteAgent, y as spawnRemoteAgent } from "./remote-agents-By1ige5O.js";
87
+ import { r as spawnInspectAgent } from "./inspect-agent-BLuJ1AkT.js";
88
+ import { n as init_github_pr_lookup, r as lookupPullRequestNumberForBranch, t as githubPrLookupSource } from "./github-pr-lookup-D16NGsSO.js";
89
+ import { a as fetchIssuePullRequestDiff, c as getCachedIssuePrTabResponse, d as setCachedIssuePrTabResponse, i as fetchIssuePullRequestDetails, l as getIssuePrTabCacheGeneration, n as fetchIssueCheckRuns, o as init_pull_requests, r as fetchIssuePullRequest, s as bumpIssuePrTabCacheGeneration, u as init_pr_tab_cache } from "./pull-requests-_lHueOHW.js";
90
+ import { t as DOD_ROWS } from "./dod-C6n9RV3G.js";
91
+ import { t as enrichReviewStatus } from "./review-status-enrichment-Dci-ZwEt.js";
92
+ import { c as init_pending, l as maybeTriggerStatusRollup, o as readRecentObservations, r as init_rollup, u as writePendingTurn } from "./rollup-FGsKki9R.js";
93
+ import { n as getTldrDaemonServiceSync, r as init_tldr_daemon } from "./tldr-daemon-C-69c3OI.js";
94
+ import { T as listGitOperationsSync, w as init_git_activity } from "./merge-agent-4WOWlSYA.js";
95
+ import { t as readVerificationArtifact } from "./verification-artifact-TVFSz_q1.js";
96
+ import { t as getAgentCommandSync } from "./settings-C0zgxOGf.js";
97
+ import { n as init_review_agent, r as isExtendedReviewEnabled } from "./review-agent-CIGOQYBD.js";
98
+ import { r as isRemoteAvailable, t as createFlyProviderFromConfig } from "./remote-C_2hasl7.js";
99
+ import { n as init_claude_settings_overlay, t as detectProviderEnvConflicts } from "./claude-settings-overlay-CEdaqpWI.js";
100
+ import { _ as init_transcript_adapter, a as generateFallbackSummary, c as handoffPreconditionFallbackReason, d as prependFallbackFocus, f as requestHandoffFromAgent, g as getTranscriptAdapter, i as copySessionFromCompactBoundary, l as init_summary_fork, o as generateSummaryForFork, p as reserveSummaryForkSession, r as authorHandoffExternal, s as handoffFailureReason, u as logHandoffFallback } from "./summary-fork-D1RAk9rJ.js";
101
+ import { a as init_conversation_compaction, c as shouldInterceptManualCompact, n as compactConversationNative, o as isCompacting } from "./conversation-compaction-CgrR8YYp.js";
102
+ import { t as init_context_layers } from "./context-layers-igZ4FI4_.js";
103
+ import { r as parseArtifactRef } from "./forge-CNFnyqps.js";
104
+ import { i as getMergeBlockersPayload, n as hasOrderIssuePrd, r as validateBookForStart, t as createOrderPrdLookup } from "./validate-IfDGkaVR.js";
105
+ import { a as spawnSequencerAgent, i as init_sequencer_agent, n as clearFinishedSequencerRun, r as getSequencerRunStatus, t as SEQUENCER_AGENT_ID } from "./sequencer-agent-CzkcK6P5.js";
106
+ import "./supervisor-wM4ooB5O.js";
107
+ import { i as listTranscriptCheckpoints, r as getTranscriptCheckpoint$1 } from "./checkpoints-CQB1h765.js";
108
108
  import { createRequire } from "node:module";
109
109
  import * as sp from "node:path";
110
110
  import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
@@ -116,20 +116,23 @@ import { homedir as homedir$1, type } from "node:os";
116
116
  import { constants, createReadStream as createReadStream$1, existsSync as existsSync$1, mkdirSync as mkdirSync$1, promises as promises$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, readlinkSync, renameSync as renameSync$1, rmSync as rmSync$1, stat, statSync as statSync$1, symlinkSync as symlinkSync$1, unwatchFile, watch, watchFile } from "node:fs";
117
117
  import { FetchHttpClient, HttpRouter, HttpServer, HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
118
118
  import { EventEmitter } from "node:events";
119
- import { access, appendFile, chmod, lstat, mkdir, open, readFile, readdir, realpath, rename, rm, stat as stat$1, unlink, writeFile } from "node:fs/promises";
119
+ import { access, appendFile, chmod, cp, lstat, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, stat as stat$1, unlink, writeFile } from "node:fs/promises";
120
120
  import { createHash, randomUUID } from "crypto";
121
121
  import { appendFile as appendFile$1, chmod as chmod$1, mkdir as mkdir$1, open as open$1, readFile as readFile$1, readdir as readdir$1, rename as rename$1, stat as stat$2, unlink as unlink$1, writeFile as writeFile$1 } from "fs/promises";
122
122
  import { exec, execFile, execFileSync, fork, spawn } from "node:child_process";
123
123
  import { promisify } from "node:util";
124
- import { createHmac, randomBytes, randomUUID as randomUUID$1, timingSafeEqual } from "node:crypto";
124
+ import { createHash as createHash$1, createHmac, randomBytes, randomUUID as randomUUID$1, timingSafeEqual } from "node:crypto";
125
125
  import * as pty from "@lydell/node-pty";
126
126
  import { fileURLToPath } from "node:url";
127
+ import http from "node:http";
127
128
  import { layer } from "@effect/platform-node/NodeServices";
129
+ import https from "node:https";
130
+ import { createServer } from "node:net";
131
+ import { Worker } from "node:worker_threads";
128
132
  import { Buffer as Buffer$1 } from "node:buffer";
129
133
  import { PassThrough, Readable } from "node:stream";
130
134
  import { RpcSerialization, RpcServer } from "effect/unstable/rpc";
131
135
  import { createInterface } from "readline";
132
- import { Worker } from "node:worker_threads";
133
136
  import { monitorEventLoopDelay } from "node:perf_hooks";
134
137
  import * as Result$1 from "effect/Result";
135
138
  import * as Multipart from "effect/unstable/http/Multipart";
@@ -383,6 +386,7 @@ init_driver();
383
386
  var import_dist = /* @__PURE__ */ __toESM(require_dist$1(), 1);
384
387
  init_issue_id();
385
388
  init_projects();
389
+ init_state_read_home();
386
390
  init_auto_commit();
387
391
  init_record();
388
392
  init_record_update();
@@ -709,7 +713,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
709
713
  if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
710
714
  const plan = readWorkspacePlanSync(workspacePath);
711
715
  if (!plan || plan.plan.items.length === 0) throw new PlanEmpty({ id: issueId });
712
- const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-FlIgQ3ql.js");
716
+ const { getAgentState, spawnAgent, normalizeAgentId } = await import("./agents-wi9NWzs2.js");
713
717
  const normalizedId = normalizeAgentId(issueId);
714
718
  if ((await Effect.runPromise(getAgentState(normalizedId)))?.status === "running") throw new AgentAlreadyRunning({ id: issueId });
715
719
  return {
@@ -740,7 +744,7 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
740
744
  const { workspacePath, projectPath, issue } = opts;
741
745
  if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
742
746
  const sessionName = opts.sessionName ?? `planning-${issueId.toLowerCase()}`;
743
- const { spawnPlanningSession } = await import("./spawn-planning-session-KC_UduxD.js");
747
+ const { spawnPlanningSession } = await import("./spawn-planning-session-qUC2VWu3.js");
744
748
  const result = await spawnPlanningSession({
745
749
  issue: {
746
750
  id: issue.id,
@@ -773,14 +777,14 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
773
777
  }),
774
778
  kill: (agentId) => Effect.tryPromise({
775
779
  try: async () => {
776
- const { stopAgent } = await import("./agents-FlIgQ3ql.js");
780
+ const { stopAgent } = await import("./agents-wi9NWzs2.js");
777
781
  await Effect.runPromise(stopAgent(agentId));
778
782
  },
779
783
  catch: () => void 0
780
784
  }).pipe(Effect.ignore),
781
785
  message: (agentId, msg) => Effect.tryPromise({
782
786
  try: async () => {
783
- const { messageAgent } = await import("./agents-FlIgQ3ql.js");
787
+ const { messageAgent } = await import("./agents-wi9NWzs2.js");
784
788
  await messageAgent(agentId, msg);
785
789
  },
786
790
  catch: (err) => new AgentStartError({
@@ -791,8 +795,8 @@ const AgentSpawnerLive = Layer.effect(AgentSpawner, Effect.sync(() => ({
791
795
  }),
792
796
  deepWipe: (issueId, opts) => Effect.tryPromise({
793
797
  try: async () => {
794
- const { deepWipe } = await import("./workflows-D90rMOya.js");
795
- const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
798
+ const { deepWipe } = await import("./workflows-BQu4RFQ-.js");
799
+ const { resolveProjectFromIssueSync } = await import("./projects-vjjcmiN8.js");
796
800
  const project = resolveProjectFromIssueSync(issueId);
797
801
  const projectPath = project?.projectPath ?? process.cwd();
798
802
  await Effect.runPromise(deepWipe({
@@ -851,8 +855,8 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
851
855
  const { workspacePath, branch } = getWorkspacePath(issueId);
852
856
  const issueLower = issueId.toLowerCase();
853
857
  if (existsSync$1(workspacePath)) return workspacePath;
854
- const { createWorkspace } = await import("./workspace-manager-ZTdJAy9M.js");
855
- const { loadProjectsConfigSync } = await import("./projects-9SkRpES9.js");
858
+ const { createWorkspace } = await import("./workspace-manager-CWT55qeI.js");
859
+ const { loadProjectsConfigSync } = await import("./projects-vjjcmiN8.js");
856
860
  const { projects } = loadProjectsConfigSync();
857
861
  const project = resolveProjectFromIssueSync(issueId);
858
862
  if (!project) throw new WorkspaceCreateError({
@@ -887,7 +891,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
887
891
  const { workspacePath } = getWorkspacePath(issueId);
888
892
  const issueLower = issueId.toLowerCase();
889
893
  if (!existsSync$1(workspacePath)) throw new WorkspaceNotFound({ id: issueId });
890
- const { removeWorkspace } = await import("./workspace-manager-ZTdJAy9M.js");
894
+ const { removeWorkspace } = await import("./workspace-manager-CWT55qeI.js");
891
895
  const project = resolveProjectFromIssueSync(issueId);
892
896
  if (!project) throw new WorkspaceCreateError({
893
897
  id: issueId,
@@ -918,7 +922,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
918
922
  try: async () => {
919
923
  const { workspacePath } = getWorkspacePath(issueId);
920
924
  const issueLower = issueId.toLowerCase();
921
- const { stopWorkspaceDocker } = await import("./workspace-manager-ZTdJAy9M.js");
925
+ const { stopWorkspaceDocker } = await import("./workspace-manager-CWT55qeI.js");
922
926
  await Effect.runPromise(stopWorkspaceDocker(workspacePath, issueLower));
923
927
  },
924
928
  catch: () => void 0
@@ -987,7 +991,7 @@ const WorkspaceServiceLive = Layer.effect(WorkspaceService, Effect.sync(() => {
987
991
  join(workspacePath, ".devcontainer", "docker-compose.devcontainer.yml")
988
992
  ];
989
993
  if (!composePaths.find((p) => existsSync$1(p))) {
990
- const { ensureDevcontainerSync } = await import("./ensure-devcontainer-DRqaAkBR.js");
994
+ const { ensureDevcontainerSync } = await import("./ensure-devcontainer-BZgOhRo7.js");
991
995
  const ensure = ensureDevcontainerSync({
992
996
  workspacePath,
993
997
  issueId
@@ -3236,8 +3240,8 @@ var require_extension = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3236
3240
  //#region ../../../node_modules/.bun/ws@8.20.1/node_modules/ws/lib/websocket.js
3237
3241
  var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3238
3242
  const EventEmitter$2 = __require("events");
3239
- const https = __require("https");
3240
- const http$1 = __require("http");
3243
+ const https$1 = __require("https");
3244
+ const http$2 = __require("http");
3241
3245
  const net = __require("net");
3242
3246
  const tls = __require("tls");
3243
3247
  const { randomBytes: randomBytes$1, createHash: createHash$3 } = __require("crypto");
@@ -3796,7 +3800,7 @@ var require_websocket = /* @__PURE__ */ __commonJSMin(((exports, module) => {
3796
3800
  }
3797
3801
  const defaultPort = isSecure ? 443 : 80;
3798
3802
  const key = randomBytes$1(16).toString("base64");
3799
- const request = isSecure ? https.request : http$1.request;
3803
+ const request = isSecure ? https$1.request : http$2.request;
3800
3804
  const protocolSet = /* @__PURE__ */ new Set();
3801
3805
  let perMessageDeflate;
3802
3806
  opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect);
@@ -4366,7 +4370,7 @@ var require_subprotocol = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4366
4370
  //#region ../../../node_modules/.bun/ws@8.20.1/node_modules/ws/lib/websocket-server.js
4367
4371
  var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4368
4372
  const EventEmitter$1 = __require("events");
4369
- const http = __require("http");
4373
+ const http$1 = __require("http");
4370
4374
  const { Duplex } = __require("stream");
4371
4375
  const { createHash: createHash$2 } = __require("crypto");
4372
4376
  const extension = require_extension();
@@ -4441,8 +4445,8 @@ var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module)
4441
4445
  };
4442
4446
  if (options.port == null && !options.server && !options.noServer || options.port != null && (options.server || options.noServer) || options.server && options.noServer) throw new TypeError("One and only one of the \"port\", \"server\", or \"noServer\" options must be specified");
4443
4447
  if (options.port != null) {
4444
- this._server = http.createServer((req, res) => {
4445
- const body = http.STATUS_CODES[426];
4448
+ this._server = http$1.createServer((req, res) => {
4449
+ const body = http$1.STATUS_CODES[426];
4446
4450
  res.writeHead(426, {
4447
4451
  "Content-Length": body.length,
4448
4452
  "Content-Type": "text/plain"
@@ -4710,7 +4714,7 @@ var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module)
4710
4714
  * @private
4711
4715
  */
4712
4716
  function abortHandshake(socket, code, message, headers) {
4713
- message = message || http.STATUS_CODES[code];
4717
+ message = message || http$1.STATUS_CODES[code];
4714
4718
  headers = {
4715
4719
  Connection: "close",
4716
4720
  "Content-Type": "text/html",
@@ -4718,7 +4722,7 @@ var require_websocket_server = /* @__PURE__ */ __commonJSMin(((exports, module)
4718
4722
  ...headers
4719
4723
  };
4720
4724
  socket.once("finish", socket.destroy);
4721
- socket.end(`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\n` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message);
4725
+ socket.end(`HTTP/1.1 ${code} ${http$1.STATUS_CODES[code]}\r\n` + Object.keys(headers).map((h) => `${h}: ${headers[h]}`).join("\r\n") + "\r\n\r\n" + message);
4722
4726
  }
4723
4727
  /**
4724
4728
  * Emit a `'wsClientError'` event on a `WebSocketServer` if there is at least
@@ -4857,7 +4861,7 @@ init_tmux();
4857
4861
  init_config();
4858
4862
  const reauthSessions = /* @__PURE__ */ new Map();
4859
4863
  const SESSION_MAX_AGE_MS = 3600 * 1e3;
4860
- const readJsonBody$18 = Effect.gen(function* () {
4864
+ const readJsonBody$19 = Effect.gen(function* () {
4861
4865
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
4862
4866
  return text ? JSON.parse(text) : {};
4863
4867
  });
@@ -4962,7 +4966,7 @@ const postCodexReauthRoute = HttpRouter.add("POST", "/api/settings/codex-reauth"
4962
4966
  const postCodexReauthStatusRoute = HttpRouter.add("POST", "/api/settings/codex-reauth/status", httpHandler(Effect.gen(function* () {
4963
4967
  const originError = rejectInvalidOrigin(yield* HttpServerRequest.HttpServerRequest);
4964
4968
  if (originError) return originError;
4965
- const body = yield* readJsonBody$18;
4969
+ const body = yield* readJsonBody$19;
4966
4970
  const sessionName = typeof body.session === "string" ? body.session : "";
4967
4971
  const token = typeof body.token === "string" ? body.token : "";
4968
4972
  const session = getLiveReauthSession(sessionName);
@@ -5033,7 +5037,7 @@ function parseControlMessage(message) {
5033
5037
  function sendControl(ws, payload) {
5034
5038
  if (ws.readyState === import_websocket.default.OPEN) ws.send(`\u0000${JSON.stringify(payload)}`);
5035
5039
  }
5036
- function rejectUpgrade(socket, status, message) {
5040
+ function rejectUpgrade$1(socket, status, message) {
5037
5041
  socket.write(`HTTP/1.1 ${status} ${message}\r\nConnection: close\r\nContent-Length: 0\r\n\r\n`);
5038
5042
  socket.destroy();
5039
5043
  }
@@ -5127,7 +5131,7 @@ function setupTerminalWebSocket(server) {
5127
5131
  if (new URL(request.url || "", `http://${request.headers.host}`).pathname === "/ws/terminal") {
5128
5132
  const auth = authorizeTerminalUpgrade(request);
5129
5133
  if (!auth.ok) {
5130
- rejectUpgrade(socket, auth.status, auth.message);
5134
+ rejectUpgrade$1(socket, auth.status, auth.message);
5131
5135
  return;
5132
5136
  }
5133
5137
  wss.handleUpgrade(request, socket, head, (ws) => {
@@ -5470,7 +5474,7 @@ function setupTerminalWebSocket(server) {
5470
5474
  console.log("[ws-terminal] Raw WebSocket terminal handler installed on /ws/terminal");
5471
5475
  }
5472
5476
  //#endregion
5473
- //#region ../../../node_modules/.bun/@ai-sdk+provider@3.0.10/node_modules/@ai-sdk/provider/dist/index.mjs
5477
+ //#region ../../lib/installers/node-runtime.ts
5474
5478
  init_briefing_freshness();
5475
5479
  init_agent_runtime_mirror();
5476
5480
  init_behavior();
@@ -5489,6 +5493,1289 @@ init_transcript_landing();
5489
5493
  init_operator_interventions();
5490
5494
  init_agents$1();
5491
5495
  init_runtime_census();
5496
+ const MINIMUM_NODE_MAJOR = 24;
5497
+ const OPEN_KNOWLEDGE_NODE_ENV = "OVERDECK_OPEN_KNOWLEDGE_NODE";
5498
+ const OVERDECK_SHIM_MARKER = "overdeck-managed shim";
5499
+ const MANAGERS = [
5500
+ {
5501
+ name: "nvm",
5502
+ envVar: "NVM_DIR",
5503
+ defaultRoots: (home) => [join(home, ".nvm"), join(home, ".config", "nvm")],
5504
+ versionsDirectory: (root) => join(root, "versions", "node"),
5505
+ nodePath: (versionsDirectory, versionDirectory) => join(versionsDirectory, versionDirectory, "bin", "node")
5506
+ },
5507
+ {
5508
+ name: "fnm",
5509
+ envVar: "FNM_DIR",
5510
+ defaultRoots: (home) => [join(home, ".local", "share", "fnm"), join(home, "Library", "Application Support", "fnm")],
5511
+ versionsDirectory: (root) => join(root, "node-versions"),
5512
+ nodePath: (versionsDirectory, versionDirectory) => join(versionsDirectory, versionDirectory, "installation", "bin", "node")
5513
+ },
5514
+ {
5515
+ name: "volta",
5516
+ envVar: "VOLTA_HOME",
5517
+ defaultRoots: (home) => [join(home, ".volta")],
5518
+ versionsDirectory: (root) => join(root, "tools", "image", "node"),
5519
+ nodePath: (versionsDirectory, versionDirectory) => join(versionsDirectory, versionDirectory, "bin", "node")
5520
+ },
5521
+ {
5522
+ name: "mise",
5523
+ envVar: "MISE_DATA_DIR",
5524
+ defaultRoots: (home) => [join(home, ".local", "share", "mise")],
5525
+ versionsDirectory: (root) => join(root, "installs", "node"),
5526
+ nodePath: (versionsDirectory, versionDirectory) => join(versionsDirectory, versionDirectory, "bin", "node")
5527
+ },
5528
+ {
5529
+ name: "asdf",
5530
+ envVar: "ASDF_DATA_DIR",
5531
+ defaultRoots: (home) => [join(home, ".asdf")],
5532
+ versionsDirectory: (root) => join(root, "installs", "nodejs"),
5533
+ nodePath: (versionsDirectory, versionDirectory) => join(versionsDirectory, versionDirectory, "bin", "node")
5534
+ }
5535
+ ];
5536
+ async function resolveNode24Runtime(options) {
5537
+ const env = options.env ?? process.env;
5538
+ const listDir = options.listDir ?? readdir;
5539
+ const home = (options.homedir ?? homedir$1)();
5540
+ const override = env[OPEN_KNOWLEDGE_NODE_ENV]?.trim();
5541
+ if (override) try {
5542
+ if (!isAbsolute(override)) throw new Error("the path must be absolute");
5543
+ const nodePath = await (options.realpath ?? realpath)(override);
5544
+ await validateNode24(nodePath, options.runCommand);
5545
+ return {
5546
+ kind: "runtime",
5547
+ nodePath,
5548
+ source: "override"
5549
+ };
5550
+ } catch (error) {
5551
+ throw new Error(`${OPEN_KNOWLEDGE_NODE_ENV} points to an invalid Node 24+ binary at ${override}: ${errorMessage$3(error)}`);
5552
+ }
5553
+ const detectedManagers = await detectManagers(env, home, listDir);
5554
+ if (detectedManagers.length === 0) return { kind: "none" };
5555
+ const eligibleCandidates = (await Promise.all(detectedManagers.map((manager) => listRuntimeCandidates(manager, listDir)))).flat().filter((candidate) => candidate.version.major >= MINIMUM_NODE_MAJOR).sort((left, right) => compareVersions(right.version, left.version));
5556
+ for (const candidate of eligibleCandidates) try {
5557
+ await validateNode24(candidate.nodePath, options.runCommand);
5558
+ return {
5559
+ kind: "runtime",
5560
+ nodePath: candidate.nodePath,
5561
+ source: candidate.manager
5562
+ };
5563
+ } catch {}
5564
+ return {
5565
+ kind: "manager-without-24",
5566
+ manager: detectedManagers[0].definition.name
5567
+ };
5568
+ }
5569
+ async function readShimOwnership(shimPath) {
5570
+ try {
5571
+ return (await readFile(shimPath, "utf8")).includes(OVERDECK_SHIM_MARKER) ? "overdeck" : "foreign";
5572
+ } catch (error) {
5573
+ if (error.code === "ENOENT") return "absent";
5574
+ throw error;
5575
+ }
5576
+ }
5577
+ async function writeOkShim(options) {
5578
+ const shimPath = options.shimPath ?? join(homedir$1(), ".local", "bin", "ok");
5579
+ if (await readShimOwnership(shimPath) === "foreign") throw new Error(`Refusing to overwrite ${shimPath} because it is not an Overdeck-managed shim. Delete or fix that file, then retry.`);
5580
+ const content = [
5581
+ "#!/bin/sh",
5582
+ "# overdeck-managed shim (PAN-2984): pins open-knowledge to a Node 24 runtime.",
5583
+ "# Regenerate with `pan knowledge open`; safe to delete.",
5584
+ `exec "${escapeDoubleQuotedShell(options.nodePath)}" "${escapeDoubleQuotedShell(options.entryScript)}" "$@"`,
5585
+ ""
5586
+ ].join("\n");
5587
+ await mkdir(dirname(shimPath), { recursive: true });
5588
+ await writeFile(shimPath, content, { mode: 493 });
5589
+ await chmod(shimPath, 493);
5590
+ return shimPath;
5591
+ }
5592
+ async function detectManagers(env, home, listDir) {
5593
+ const detected = [];
5594
+ for (const definition of MANAGERS) {
5595
+ const configuredRoot = env[definition.envVar]?.trim();
5596
+ const roots = unique([...configuredRoot ? [configuredRoot] : [], ...definition.defaultRoots(home)]);
5597
+ for (const root of roots) if (await directoryExists(root, listDir)) {
5598
+ detected.push({
5599
+ definition,
5600
+ root
5601
+ });
5602
+ break;
5603
+ }
5604
+ }
5605
+ return detected;
5606
+ }
5607
+ async function listRuntimeCandidates(manager, listDir) {
5608
+ const versionsDirectory = manager.definition.versionsDirectory(manager.root);
5609
+ let versionDirectories;
5610
+ try {
5611
+ versionDirectories = await listDir(versionsDirectory);
5612
+ } catch {
5613
+ return [];
5614
+ }
5615
+ const candidates = [];
5616
+ for (const versionDirectory of versionDirectories) {
5617
+ const version = parseVersion$1(versionDirectory);
5618
+ if (!version) continue;
5619
+ const nodePath = manager.definition.nodePath(versionsDirectory, versionDirectory);
5620
+ if (!await fileAppearsInDirectory(nodePath, listDir)) continue;
5621
+ candidates.push({
5622
+ manager: manager.definition.name,
5623
+ nodePath,
5624
+ version
5625
+ });
5626
+ }
5627
+ return candidates;
5628
+ }
5629
+ async function directoryExists(directory, listDir) {
5630
+ try {
5631
+ await listDir(directory);
5632
+ return true;
5633
+ } catch {
5634
+ return false;
5635
+ }
5636
+ }
5637
+ async function fileAppearsInDirectory(filePath, listDir) {
5638
+ try {
5639
+ return (await listDir(dirname(filePath))).includes("node");
5640
+ } catch {
5641
+ return false;
5642
+ }
5643
+ }
5644
+ async function validateNode24(nodePath, runCommand) {
5645
+ const result = await runCommand(nodePath, ["--version"]);
5646
+ const version = parseVersion$1(result.stdout.trim());
5647
+ if (!version || version.major < MINIMUM_NODE_MAJOR) {
5648
+ const reported = result.stdout.trim() || "no version";
5649
+ throw new Error(`expected Node 24+ but ${nodePath} reported ${reported}`);
5650
+ }
5651
+ }
5652
+ function parseVersion$1(value) {
5653
+ const match = /^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?/.exec(value);
5654
+ if (!match) return null;
5655
+ return {
5656
+ major: Number(match[1]),
5657
+ minor: Number(match[2] ?? 0),
5658
+ patch: Number(match[3] ?? 0)
5659
+ };
5660
+ }
5661
+ function compareVersions(left, right) {
5662
+ return left.major - right.major || left.minor - right.minor || left.patch - right.patch;
5663
+ }
5664
+ function unique(values) {
5665
+ return [...new Set(values)];
5666
+ }
5667
+ function escapeDoubleQuotedShell(value) {
5668
+ return value.replace(/[\\"$`]/g, "\\$&");
5669
+ }
5670
+ function errorMessage$3(error) {
5671
+ return error instanceof Error ? error.message : String(error);
5672
+ }
5673
+ //#endregion
5674
+ //#region ../../lib/installers/open-knowledge.ts
5675
+ init_paths();
5676
+ const OPEN_KNOWLEDGE_PACKAGE = "@inkeep/open-knowledge";
5677
+ const MANUAL_INSTALL_COMMAND = `npm install -g ${OPEN_KNOWLEDGE_PACKAGE}`;
5678
+ const DEFAULT_START_RETRY_DELAY_MS = 250;
5679
+ const DEFAULT_START_MAX_ATTEMPTS = 40;
5680
+ const NVM_INSTALL_COMMAND = "PROFILE=/dev/null bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash'";
5681
+ var OpenKnowledgeError = class extends Error {
5682
+ constructor(message) {
5683
+ super(message);
5684
+ this.name = "OpenKnowledgeError";
5685
+ }
5686
+ };
5687
+ var OpenKnowledgeSetupRequiredError = class extends OpenKnowledgeError {
5688
+ constructor(plan) {
5689
+ super(plan.steps.join(" "));
5690
+ this.plan = plan;
5691
+ this.name = "OpenKnowledgeSetupRequiredError";
5692
+ }
5693
+ };
5694
+ async function ensureOpenKnowledge(options = {}) {
5695
+ const runCommand = options.runCommand ?? runCommandWithSpawn;
5696
+ const existingCommand = await findExistingOpenKnowledgeCommand(runCommand, resolveShimPath(options));
5697
+ if (existingCommand) return {
5698
+ status: "already-installed",
5699
+ command: existingCommand
5700
+ };
5701
+ if (!options.autoInstall) throw new OpenKnowledgeError(`open-knowledge is not installed. Install it manually with \`${MANUAL_INSTALL_COMMAND}\`.`);
5702
+ const plan = await (options.resolveSetupPlan ?? (() => resolveOpenKnowledgeInstallPlan({
5703
+ ...options,
5704
+ runCommand
5705
+ })))();
5706
+ if (plan.kind === "ready") return {
5707
+ status: "already-installed",
5708
+ command: plan.command
5709
+ };
5710
+ if (plan.kind === "install-node-via-manager" || plan.kind === "install-nvm") throw new OpenKnowledgeSetupRequiredError(plan);
5711
+ let command;
5712
+ try {
5713
+ command = await (options.executeSetupPlan ?? ((setupPlan) => executeOpenKnowledgeSetupPlan(setupPlan, {
5714
+ ...options,
5715
+ runCommand
5716
+ })))(plan);
5717
+ } catch (error) {
5718
+ throw await installationError(error, runCommand);
5719
+ }
5720
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
5721
+ const retryDelayMs = options.retryDelayMs ?? 500;
5722
+ const maxHealthAttempts = options.maxHealthAttempts ?? 10;
5723
+ for (let attempt = 1; attempt <= maxHealthAttempts; attempt += 1) {
5724
+ if (await openKnowledgeBinaryWorks(command, runCommand)) return {
5725
+ status: "installed",
5726
+ command
5727
+ };
5728
+ if (attempt < maxHealthAttempts) await sleep(retryDelayMs);
5729
+ }
5730
+ throw await installationError(/* @__PURE__ */ new Error(`the ok binary did not pass \`${command} --version\` after installation`), runCommand);
5731
+ }
5732
+ async function resolveOpenKnowledgeSetupPlan(options = {}) {
5733
+ const runCommand = options.runCommand ?? runCommandWithSpawn;
5734
+ const existingCommand = await findExistingOpenKnowledgeCommand(runCommand, resolveShimPath(options));
5735
+ if (existingCommand) return {
5736
+ kind: "ready",
5737
+ command: existingCommand
5738
+ };
5739
+ return resolveOpenKnowledgeInstallPlan({
5740
+ ...options,
5741
+ runCommand
5742
+ });
5743
+ }
5744
+ async function executeOpenKnowledgeSetupPlan(plan, options = {}) {
5745
+ const runCommand = options.runCommand ?? runCommandWithSpawn;
5746
+ if (plan.kind === "ready") return plan.command;
5747
+ if (plan.kind === "install-under-runtime") return installOpenKnowledgeUnderRuntime(plan.nodePath, {
5748
+ ...options,
5749
+ runCommand
5750
+ });
5751
+ const installCommand = plan.kind === "install-nvm" ? NVM_INSTALL_COMMAND : plan.installCommand;
5752
+ await runCommand("bash", ["-c", installCommand]);
5753
+ const nextPlan = await resolveOpenKnowledgeInstallPlan({
5754
+ ...options,
5755
+ runCommand
5756
+ });
5757
+ if (nextPlan.kind === plan.kind) throw new OpenKnowledgeError(`Setup command completed but did not make a Node 24 runtime available: ${installCommand}`);
5758
+ return executeOpenKnowledgeSetupPlan(nextPlan, {
5759
+ ...options,
5760
+ runCommand
5761
+ });
5762
+ }
5763
+ async function startReadOnlyOpenKnowledgeServer(bundlePath, options = {}) {
5764
+ const prepareSnapshot = options.prepareSnapshot ?? prepareOpenKnowledgeSnapshot;
5765
+ const runtimeBundlePath = await readOnlyOpenKnowledgeSnapshotPath(bundlePath, options.snapshotRoot);
5766
+ const getStatus = options.getStatus ?? ((path) => getOpenKnowledgeStatus(path, options.runCommand, options.okCommand));
5767
+ if (!liveStatus(await getStatus(runtimeBundlePath))) await prepareSnapshot(bundlePath, options.snapshotRoot);
5768
+ return startOpenKnowledgeServer(runtimeBundlePath, {
5769
+ ...options,
5770
+ getStatus
5771
+ });
5772
+ }
5773
+ async function prepareOpenKnowledgeSnapshot(bundlePath, snapshotRoot = join(getOverdeckHome(), "cache", "knowledge-viewer")) {
5774
+ const source = await realpath(bundlePath);
5775
+ const destination = await readOnlyOpenKnowledgeSnapshotPath(source, snapshotRoot);
5776
+ const parent = dirname(destination);
5777
+ await mkdir(parent, { recursive: true });
5778
+ const temporaryRoot = await mkdtemp(join(parent, ".snapshot-"));
5779
+ const temporaryBundle = join(temporaryRoot, "bundle");
5780
+ try {
5781
+ await cp(source, temporaryBundle, {
5782
+ recursive: true,
5783
+ dereference: true,
5784
+ filter: (path) => {
5785
+ const relativePath = relative(source, path);
5786
+ if (!relativePath) return true;
5787
+ const firstSegment = relativePath.split(sep)[0];
5788
+ return firstSegment !== ".git" && firstSegment !== ".ok";
5789
+ }
5790
+ });
5791
+ await runCommandWithSpawn("git", [
5792
+ "init",
5793
+ "--quiet",
5794
+ temporaryBundle
5795
+ ]);
5796
+ await rm(destination, {
5797
+ recursive: true,
5798
+ force: true
5799
+ });
5800
+ await rename(temporaryBundle, destination);
5801
+ } finally {
5802
+ await rm(temporaryRoot, {
5803
+ recursive: true,
5804
+ force: true
5805
+ });
5806
+ }
5807
+ return destination;
5808
+ }
5809
+ async function readOnlyOpenKnowledgeSnapshotPath(bundlePath, snapshotRoot = join(getOverdeckHome(), "cache", "knowledge-viewer")) {
5810
+ let resolved = bundlePath;
5811
+ try {
5812
+ resolved = await realpath(bundlePath);
5813
+ } catch {}
5814
+ return join(snapshotRoot, createHash$1("sha256").update(resolved).digest("hex").slice(0, 24), "bundle");
5815
+ }
5816
+ async function getOpenKnowledgeStatus(bundlePath, runCommand = runCommandWithSpawn, okCommand = "ok") {
5817
+ try {
5818
+ const result = await runCommand(okCommand, [
5819
+ "--cwd",
5820
+ bundlePath,
5821
+ "status",
5822
+ "--json"
5823
+ ]);
5824
+ const parsed = JSON.parse(result.stdout);
5825
+ return {
5826
+ server: normalizeProcessStatus(parsed.server, "server"),
5827
+ ui: normalizeProcessStatus(parsed.ui, "ui")
5828
+ };
5829
+ } catch {
5830
+ return missingStatus();
5831
+ }
5832
+ }
5833
+ async function startOpenKnowledgeServer(bundlePath, options = {}) {
5834
+ const runCommand = options.runCommand ?? runCommandWithSpawn;
5835
+ const okCommand = options.okCommand ?? "ok";
5836
+ const getStatus = options.getStatus ?? ((path) => getOpenKnowledgeStatus(path, runCommand, okCommand));
5837
+ const fetchImpl = options.fetchImpl ?? fetch;
5838
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
5839
+ const retryDelayMs = options.retryDelayMs ?? DEFAULT_START_RETRY_DELAY_MS;
5840
+ const maxHealthAttempts = options.maxHealthAttempts ?? DEFAULT_START_MAX_ATTEMPTS;
5841
+ const reused = await readyResult(await getStatus(bundlePath), options.host ?? "127.0.0.1", fetchImpl);
5842
+ if (reused) return {
5843
+ ...reused,
5844
+ process: null,
5845
+ owned: false,
5846
+ reused: true,
5847
+ runtimeBundlePath: bundlePath
5848
+ };
5849
+ if (!await (options.isInitialized ?? openKnowledgeIsInitialized)(bundlePath)) {
5850
+ if (options.initializeIfNeeded === false) throw new OpenKnowledgeError(`open-knowledge is not initialized for ${bundlePath}. Run \`ok init\` first.`);
5851
+ await runCommand(okCommand, [
5852
+ "--cwd",
5853
+ bundlePath,
5854
+ "init",
5855
+ "--no-mcp",
5856
+ "--no-skills",
5857
+ "--local-only",
5858
+ "--content-dir",
5859
+ ".",
5860
+ "--json"
5861
+ ]);
5862
+ }
5863
+ const host = options.host ?? "127.0.0.1";
5864
+ const missingPortCount = Number(options.apiPort === void 0) + Number(options.uiPort === void 0);
5865
+ const availablePorts = missingPortCount > 0 ? await (options.getAvailablePorts ?? findAvailablePorts)(missingPortCount, host) : [];
5866
+ const apiPort = options.apiPort ?? availablePorts.shift();
5867
+ const uiPort = options.uiPort ?? availablePorts.shift();
5868
+ if (apiPort === void 0 || uiPort === void 0 || apiPort === uiPort) throw new OpenKnowledgeError("Could not allocate distinct API and UI ports for open-knowledge.");
5869
+ const args = [
5870
+ "--cwd",
5871
+ bundlePath,
5872
+ "start",
5873
+ "--port",
5874
+ String(apiPort),
5875
+ "--ui-port",
5876
+ String(uiPort),
5877
+ "--host",
5878
+ host,
5879
+ "--mode",
5880
+ options.mode ?? "browser"
5881
+ ];
5882
+ if (options.openBrowser) args.push("--open");
5883
+ const child = (options.spawnProcess ?? ((command, commandArgs, spawnOptions) => spawn(command, commandArgs, spawnOptions)))(okCommand, args, { stdio: "ignore" });
5884
+ await waitForSpawn(child);
5885
+ for (let attempt = 1; attempt <= maxHealthAttempts; attempt += 1) {
5886
+ if (child.exitCode != null) throw new OpenKnowledgeError(`open-knowledge exited before becoming ready (code ${child.exitCode})`);
5887
+ const ready = await readyResult(await getStatus(bundlePath), host, fetchImpl);
5888
+ if (ready) return {
5889
+ ...ready,
5890
+ process: child,
5891
+ owned: true,
5892
+ reused: false,
5893
+ runtimeBundlePath: bundlePath
5894
+ };
5895
+ if (attempt < maxHealthAttempts) await sleep(retryDelayMs);
5896
+ }
5897
+ child.kill("SIGTERM");
5898
+ throw new OpenKnowledgeError(`open-knowledge viewer did not become healthy for ${bundlePath}`);
5899
+ }
5900
+ function liveStatus(status) {
5901
+ return status.server.alive && status.ui.alive && Number.isInteger(status.server.port) && Number.isInteger(status.ui.port);
5902
+ }
5903
+ async function readyResult(status, host, fetchImpl) {
5904
+ if (!liveStatus(status)) return null;
5905
+ const apiPort = status.server.port;
5906
+ const port = status.ui.port;
5907
+ const url = `http://${formatUrlHost(host)}:${port}`;
5908
+ try {
5909
+ if (!(await fetchImpl(url, { method: "GET" })).ok) return null;
5910
+ } catch {
5911
+ return null;
5912
+ }
5913
+ return {
5914
+ port,
5915
+ apiPort,
5916
+ url
5917
+ };
5918
+ }
5919
+ function normalizeProcessStatus(value, name) {
5920
+ if (!value || typeof value !== "object") return {
5921
+ name,
5922
+ state: "missing",
5923
+ alive: false
5924
+ };
5925
+ return {
5926
+ name,
5927
+ state: typeof value.state === "string" ? value.state : "missing",
5928
+ alive: value.alive === true,
5929
+ ...Number.isInteger(value.pid) ? { pid: value.pid } : {},
5930
+ ...Number.isInteger(value.port) ? { port: value.port } : {}
5931
+ };
5932
+ }
5933
+ function missingStatus() {
5934
+ return {
5935
+ server: {
5936
+ name: "server",
5937
+ state: "missing",
5938
+ alive: false
5939
+ },
5940
+ ui: {
5941
+ name: "ui",
5942
+ state: "missing",
5943
+ alive: false
5944
+ }
5945
+ };
5946
+ }
5947
+ async function findExistingOpenKnowledgeCommand(runCommand, shimPath) {
5948
+ if (await openKnowledgeBinaryWorks("ok", runCommand)) return "ok";
5949
+ if (await openKnowledgeBinaryWorks(shimPath, runCommand)) return shimPath;
5950
+ return null;
5951
+ }
5952
+ async function openKnowledgeBinaryWorks(command, runCommand) {
5953
+ try {
5954
+ await runCommand(command, ["--version"]);
5955
+ return true;
5956
+ } catch {
5957
+ return false;
5958
+ }
5959
+ }
5960
+ async function resolveOpenKnowledgeInstallPlan(options) {
5961
+ const runtime = await (options.resolveRuntime ?? resolveNode24Runtime)({
5962
+ env: options.env,
5963
+ homedir: options.homedir,
5964
+ listDir: options.listDir,
5965
+ realpath: options.realpath,
5966
+ runCommand: options.runCommand
5967
+ });
5968
+ if (runtime.kind === "runtime") return {
5969
+ kind: "install-under-runtime",
5970
+ source: runtime.source,
5971
+ nodePath: runtime.nodePath,
5972
+ steps: [`Install ${OPEN_KNOWLEDGE_PACKAGE} under the Node 24+ runtime at ${runtime.nodePath}.`, "Write an Overdeck-managed shim at ~/.local/bin/ok that pins only the viewer to this runtime. Your default Node and shell configuration will not change."]
5973
+ };
5974
+ if (runtime.kind === "manager-without-24") {
5975
+ const installCommand = managerInstallCommand(runtime.manager);
5976
+ return {
5977
+ kind: "install-node-via-manager",
5978
+ manager: runtime.manager,
5979
+ installCommand,
5980
+ steps: [managerInstallStep(runtime.manager, installCommand)]
5981
+ };
5982
+ }
5983
+ return {
5984
+ kind: "install-nvm",
5985
+ steps: [
5986
+ `Install nvm with the official installer while suppressing shell-profile edits: \`${NVM_INSTALL_COMMAND}\`.`,
5987
+ "Install Node 24 inside the setup subprocess, then restore the existing nvm default alias exactly—or remove the alias if none existed—before pinning only the OpenKnowledge viewer to that runtime.",
5988
+ `For manual setup instead, install Node 24+ yourself, run \`${MANUAL_INSTALL_COMMAND}\`, and retry.`
5989
+ ],
5990
+ manualCommand: MANUAL_INSTALL_COMMAND
5991
+ };
5992
+ }
5993
+ async function installOpenKnowledgeUnderRuntime(nodePath, options) {
5994
+ const runtimeBin = dirname(nodePath);
5995
+ const runtimePrefix = dirname(runtimeBin);
5996
+ const env = options.env ?? process.env;
5997
+ const pathValue = env.PATH ? `${runtimeBin}${delimiter}${env.PATH}` : runtimeBin;
5998
+ await options.runCommand(join(runtimeBin, "npm"), [
5999
+ "install",
6000
+ "-g",
6001
+ OPEN_KNOWLEDGE_PACKAGE
6002
+ ], { env: {
6003
+ ...env,
6004
+ PATH: pathValue
6005
+ } });
6006
+ const entryScript = await (options.realpath ?? realpath)(join(runtimePrefix, "bin", "ok"));
6007
+ const shimPath = resolveShimPath(options);
6008
+ return (options.writeShim ?? writeOkShim)({
6009
+ nodePath,
6010
+ entryScript,
6011
+ shimPath
6012
+ });
6013
+ }
6014
+ function resolveShimPath(options) {
6015
+ return options.shimPath ?? join((options.homedir ?? homedir$1)(), ".local", "bin", "ok");
6016
+ }
6017
+ function managerInstallCommand(manager) {
6018
+ switch (manager) {
6019
+ case "nvm": return "bash -c 'NVM_ROOT=\"${NVM_DIR:-$HOME/.nvm}\"; [ -f \"$NVM_ROOT/nvm.sh\" ] || NVM_ROOT=\"$HOME/.config/nvm\"; . \"$NVM_ROOT/nvm.sh\"; DEFAULT_ALIAS_PATH=\"$NVM_ROOT/alias/default\"; DEFAULT_ALIAS_BACKUP=\"$(mktemp)\"; HAD_DEFAULT=0; if [ -f \"$DEFAULT_ALIAS_PATH\" ]; then HAD_DEFAULT=1; cp \"$DEFAULT_ALIAS_PATH\" \"$DEFAULT_ALIAS_BACKUP\"; fi; restore_default() { if [ \"$HAD_DEFAULT\" -eq 1 ]; then mkdir -p \"$(dirname \"$DEFAULT_ALIAS_PATH\")\"; cp \"$DEFAULT_ALIAS_BACKUP\" \"$DEFAULT_ALIAS_PATH\"; else rm -f \"$DEFAULT_ALIAS_PATH\"; fi; rm -f \"$DEFAULT_ALIAS_BACKUP\"; }; trap restore_default EXIT; nvm install --no-progress 24'";
6020
+ case "fnm": return "fnm install 24";
6021
+ case "volta": return "volta fetch node@24";
6022
+ case "mise": return "mise install node@24";
6023
+ case "asdf": return "asdf install nodejs latest:24";
6024
+ }
6025
+ }
6026
+ function managerInstallStep(manager, installCommand) {
6027
+ return `Install Node 24 with ${manager === "nvm" ? "nvm" : manager === "fnm" ? "fnm" : manager[0].toUpperCase() + manager.slice(1)} by running \`${installCommand}\`. ${manager === "nvm" ? "This shell-local install restores the existing default alias exactly, removes any newly created alias when none existed, and does not change your shell configuration." : `This installs a runtime for OpenKnowledge without changing your default Node or shell configuration.`}`;
6028
+ }
6029
+ async function installationError(error, runCommand) {
6030
+ const version = await readNodeVersion(runCommand);
6031
+ const major = version ? Number.parseInt(version.replace(/^v/, "").split(".")[0] ?? "", 10) : NaN;
6032
+ if (version && Number.isFinite(major) && major < 24) return new OpenKnowledgeError(`open-knowledge requires Node 24+; found ${version}. Install Node 24+ or run '/okf open --no-install' after installing manually.`);
6033
+ return new OpenKnowledgeError(`Failed to install open-knowledge with \`${MANUAL_INSTALL_COMMAND}\`: ${error instanceof Error ? error.message : String(error)}`);
6034
+ }
6035
+ async function readNodeVersion(runCommand) {
6036
+ try {
6037
+ const result = await runCommand("node", ["--version"]);
6038
+ return result.stdout.trim() || result.stderr.trim() || null;
6039
+ } catch {
6040
+ return null;
6041
+ }
6042
+ }
6043
+ async function openKnowledgeIsInitialized(bundlePath) {
6044
+ try {
6045
+ await access(join(bundlePath, ".ok", "config.yml"));
6046
+ return true;
6047
+ } catch {
6048
+ return false;
6049
+ }
6050
+ }
6051
+ async function findAvailablePorts(count, host) {
6052
+ const servers = Array.from({ length: count }, () => createServer());
6053
+ try {
6054
+ return await Promise.all(servers.map((server) => new Promise((resolve, reject) => {
6055
+ server.once("error", reject);
6056
+ server.listen(0, host, () => {
6057
+ const address = server.address();
6058
+ if (!address || typeof address === "string") {
6059
+ reject(new OpenKnowledgeError("Could not resolve an available open-knowledge port."));
6060
+ return;
6061
+ }
6062
+ resolve(address.port);
6063
+ });
6064
+ })));
6065
+ } finally {
6066
+ await Promise.all(servers.map((server) => new Promise((resolve) => {
6067
+ if (!server.listening) {
6068
+ resolve();
6069
+ return;
6070
+ }
6071
+ server.close(() => resolve());
6072
+ })));
6073
+ }
6074
+ }
6075
+ async function waitForSpawn(child) {
6076
+ await new Promise((resolve, reject) => {
6077
+ const onError = (error) => {
6078
+ child.removeListener("spawn", onSpawn);
6079
+ reject(error);
6080
+ };
6081
+ const onSpawn = () => {
6082
+ child.removeListener("error", onError);
6083
+ resolve();
6084
+ };
6085
+ child.once("error", onError);
6086
+ child.once("spawn", onSpawn);
6087
+ });
6088
+ }
6089
+ async function runCommandWithSpawn(command, args, options = {}) {
6090
+ return new Promise((resolve, reject) => {
6091
+ const child = spawn(command, args, {
6092
+ ...options,
6093
+ stdio: [
6094
+ "ignore",
6095
+ "pipe",
6096
+ "pipe"
6097
+ ]
6098
+ });
6099
+ let stdout = "";
6100
+ let stderr = "";
6101
+ child.stdout?.setEncoding("utf8");
6102
+ child.stderr?.setEncoding("utf8");
6103
+ child.stdout?.on("data", (chunk) => {
6104
+ stdout += chunk;
6105
+ });
6106
+ child.stderr?.on("data", (chunk) => {
6107
+ stderr += chunk;
6108
+ });
6109
+ child.once("error", reject);
6110
+ child.once("exit", (code) => {
6111
+ if (code === 0) {
6112
+ resolve({
6113
+ stdout,
6114
+ stderr
6115
+ });
6116
+ return;
6117
+ }
6118
+ reject(new OpenKnowledgeError(`${command} ${args.join(" ")} exited with code ${code}: ${stderr.trim()}`));
6119
+ });
6120
+ });
6121
+ }
6122
+ function formatUrlHost(host) {
6123
+ return host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
6124
+ }
6125
+ //#endregion
6126
+ //#region services/knowledge-viewer.ts
6127
+ init_injection();
6128
+ init_projects();
6129
+ function createKnowledgeViewerService(dependencies = {}) {
6130
+ const resolveBundle = dependencies.resolveBundle ?? resolveBundleForProject;
6131
+ const ensure = dependencies.ensure ?? ((options) => ensureOpenKnowledge(options));
6132
+ const resolveSetupPlan = dependencies.resolveSetupPlan ?? resolveOpenKnowledgeSetupPlan;
6133
+ const start = dependencies.start ?? ((bundlePath, options) => startReadOnlyOpenKnowledgeServer(bundlePath, options));
6134
+ const stop = dependencies.stop ?? stopOpenKnowledgeWithSpawn;
6135
+ const fetchImpl = dependencies.fetchImpl ?? fetch;
6136
+ const entries = /* @__PURE__ */ new Map();
6137
+ const starts = /* @__PURE__ */ new Map();
6138
+ let installedCache = null;
6139
+ let missingInstallationCache = null;
6140
+ async function getStatus(projectKey) {
6141
+ const bundlePath = await resolveBundle(projectKey);
6142
+ if (!bundlePath) return unavailableStatus(projectKey, starts.has(projectKey), "No OKF bundle is configured. Run `/okf init` first.");
6143
+ if (!installedCache && !missingInstallationCache) try {
6144
+ installedCache = await ensure({ autoInstall: false });
6145
+ } catch (error) {
6146
+ let message = errorMessage$2(error);
6147
+ let setupPlan;
6148
+ try {
6149
+ const plan = await resolveSetupPlan();
6150
+ if (plan.kind !== "ready") setupPlan = {
6151
+ kind: plan.kind,
6152
+ steps: plan.steps
6153
+ };
6154
+ } catch (planError) {
6155
+ message = errorMessage$2(planError);
6156
+ }
6157
+ missingInstallationCache = {
6158
+ message,
6159
+ ...setupPlan ? { setupPlan } : {}
6160
+ };
6161
+ }
6162
+ const installed = installedCache !== null;
6163
+ const installMessage = missingInstallationCache?.message;
6164
+ const setupPlan = missingInstallationCache?.setupPlan;
6165
+ const entry = entries.get(projectKey);
6166
+ if (entry && isProcessLive(entry)) {
6167
+ const probe = await probeViewer(entry.url, fetchImpl);
6168
+ if (probe.healthy) return {
6169
+ projectKey,
6170
+ bundleConfigured: true,
6171
+ installed,
6172
+ starting: starts.has(projectKey),
6173
+ running: true,
6174
+ bundlePath,
6175
+ port: entry.port,
6176
+ apiPort: entry.apiPort,
6177
+ url: entry.url,
6178
+ embeddable: probe.embeddable,
6179
+ ...installMessage ? { message: installMessage } : {},
6180
+ ...setupPlan ? { setupPlan } : {}
6181
+ };
6182
+ }
6183
+ if (entry) await stopEntry(projectKey, entry);
6184
+ return {
6185
+ projectKey,
6186
+ bundleConfigured: true,
6187
+ installed,
6188
+ starting: starts.has(projectKey),
6189
+ running: false,
6190
+ bundlePath,
6191
+ ...installMessage ? { message: installMessage } : {},
6192
+ ...setupPlan ? { setupPlan } : {}
6193
+ };
6194
+ }
6195
+ function getOrStartViewer(projectKey) {
6196
+ const inFlight = starts.get(projectKey);
6197
+ if (inFlight) return inFlight;
6198
+ const promise = startViewer(projectKey).finally(() => {
6199
+ if (starts.get(projectKey) === promise) starts.delete(projectKey);
6200
+ });
6201
+ starts.set(projectKey, promise);
6202
+ return promise;
6203
+ }
6204
+ async function startViewer(projectKey) {
6205
+ const status = await getStatus(projectKey);
6206
+ if (!status.bundleConfigured || !status.installed || status.running) return status;
6207
+ const okCommand = installedCache?.command ?? "ok";
6208
+ let started;
6209
+ try {
6210
+ started = await start(status.bundlePath, {
6211
+ openBrowser: false,
6212
+ okCommand
6213
+ });
6214
+ } catch (error) {
6215
+ installedCache = null;
6216
+ missingInstallationCache = null;
6217
+ throw error;
6218
+ }
6219
+ const entry = {
6220
+ bundlePath: status.bundlePath,
6221
+ runtimeBundlePath: started.runtimeBundlePath,
6222
+ okCommand,
6223
+ process: started.process,
6224
+ owned: started.owned,
6225
+ port: started.port,
6226
+ apiPort: started.apiPort,
6227
+ url: started.url,
6228
+ exited: false
6229
+ };
6230
+ entries.set(projectKey, entry);
6231
+ started.process?.once("exit", () => {
6232
+ entry.exited = true;
6233
+ if (entries.get(projectKey) === entry) entries.delete(projectKey);
6234
+ });
6235
+ const probe = await probeViewer(started.url, fetchImpl);
6236
+ if (!probe.healthy) {
6237
+ await stopEntry(projectKey, entry);
6238
+ throw new Error(`open-knowledge viewer did not remain healthy at ${started.url}`);
6239
+ }
6240
+ return {
6241
+ projectKey,
6242
+ bundleConfigured: true,
6243
+ installed: true,
6244
+ starting: false,
6245
+ running: true,
6246
+ bundlePath: entry.bundlePath,
6247
+ port: entry.port,
6248
+ apiPort: entry.apiPort,
6249
+ url: entry.url,
6250
+ embeddable: probe.embeddable
6251
+ };
6252
+ }
6253
+ async function stopEntry(projectKey, entry) {
6254
+ if (entries.get(projectKey) === entry) entries.delete(projectKey);
6255
+ if (!entry.owned) return;
6256
+ try {
6257
+ await stop(entry.runtimeBundlePath, entry.okCommand);
6258
+ } catch {}
6259
+ if (isProcessLive(entry)) entry.process?.kill("SIGTERM");
6260
+ }
6261
+ function invalidateInstallationCache() {
6262
+ installedCache = null;
6263
+ missingInstallationCache = null;
6264
+ }
6265
+ async function stopAll() {
6266
+ await Promise.allSettled(starts.values());
6267
+ starts.clear();
6268
+ const active = [...entries.entries()];
6269
+ entries.clear();
6270
+ await Promise.all(active.map(async ([projectKey, entry]) => stopEntry(projectKey, entry)));
6271
+ }
6272
+ return {
6273
+ getStatus,
6274
+ getOrStartViewer,
6275
+ invalidateInstallationCache,
6276
+ stopAll
6277
+ };
6278
+ }
6279
+ async function resolveBundleForProject(projectKey) {
6280
+ const project = loadProjectsConfigSync().projects[projectKey];
6281
+ if (!project) return null;
6282
+ return resolveKnowledgeBundleRoot({ projectPath: project.path });
6283
+ }
6284
+ function unavailableStatus(projectKey, starting, message) {
6285
+ return {
6286
+ projectKey,
6287
+ bundleConfigured: false,
6288
+ installed: false,
6289
+ starting,
6290
+ running: false,
6291
+ message
6292
+ };
6293
+ }
6294
+ function isProcessLive(entry) {
6295
+ return entry.process === null || !entry.exited && entry.process.exitCode == null;
6296
+ }
6297
+ async function probeViewer(url, fetchImpl) {
6298
+ try {
6299
+ const response = await fetchImpl(url, { method: "GET" });
6300
+ return {
6301
+ healthy: response.ok,
6302
+ embeddable: response.ok && responseAllowsEmbedding(response.headers)
6303
+ };
6304
+ } catch {
6305
+ return {
6306
+ healthy: false,
6307
+ embeddable: false
6308
+ };
6309
+ }
6310
+ }
6311
+ function responseAllowsEmbedding(headers) {
6312
+ const frameOptions = headers.get("x-frame-options")?.trim().toLowerCase();
6313
+ if (frameOptions === "deny" || frameOptions === "sameorigin") return false;
6314
+ const frameAncestors = (headers.get("content-security-policy")?.toLowerCase() ?? "").match(/(?:^|;)\s*frame-ancestors\s+([^;]+)/)?.[1]?.trim();
6315
+ if (!frameAncestors) return true;
6316
+ return frameAncestors !== "'none'" && frameAncestors !== "'self'";
6317
+ }
6318
+ async function stopOpenKnowledgeWithSpawn(bundlePath, okCommand = "ok") {
6319
+ await new Promise((resolve, reject) => {
6320
+ const child = spawn(okCommand, [
6321
+ "--cwd",
6322
+ bundlePath,
6323
+ "stop"
6324
+ ], { stdio: "ignore" });
6325
+ child.once("error", reject);
6326
+ child.once("exit", (code) => {
6327
+ if (code === 0) resolve();
6328
+ else reject(/* @__PURE__ */ new Error(`ok stop exited with code ${code}`));
6329
+ });
6330
+ });
6331
+ }
6332
+ function errorMessage$2(error) {
6333
+ return error instanceof Error ? error.message : String(error);
6334
+ }
6335
+ const defaultKnowledgeViewerService = createKnowledgeViewerService();
6336
+ const getKnowledgeViewerStatus = (projectKey) => defaultKnowledgeViewerService.getStatus(projectKey);
6337
+ const getOrStartViewer = (projectKey) => defaultKnowledgeViewerService.getOrStartViewer(projectKey);
6338
+ const invalidateKnowledgeViewerInstallationCache = () => defaultKnowledgeViewerService.invalidateInstallationCache();
6339
+ const stopAllKnowledgeViewers = () => defaultKnowledgeViewerService.stopAll();
6340
+ //#endregion
6341
+ //#region routes/knowledge-viewer.ts
6342
+ const VIEWER_HOST_PREFIX = "knowledge-";
6343
+ const VIEWER_ACCESS_COOKIE = "overdeck_knowledge_viewer";
6344
+ const MAX_QUEUED_WEBSOCKET_MESSAGES = 128;
6345
+ const MAX_QUEUED_WEBSOCKET_BYTES = 1024 * 1024;
6346
+ const MAX_CONFIG_RESPONSE_BYTES = 64 * 1024;
6347
+ const viewerAccessTokens = /* @__PURE__ */ new Map();
6348
+ const REQUEST_HEADER_ALLOWLIST = new Set([
6349
+ "accept",
6350
+ "accept-language",
6351
+ "cache-control",
6352
+ "content-type",
6353
+ "if-match",
6354
+ "if-modified-since",
6355
+ "if-none-match",
6356
+ "if-unmodified-since",
6357
+ "range",
6358
+ "user-agent"
6359
+ ]);
6360
+ const RESPONSE_HEADER_ALLOWLIST = new Set([
6361
+ "accept-ranges",
6362
+ "cache-control",
6363
+ "content-disposition",
6364
+ "content-language",
6365
+ "content-length",
6366
+ "content-range",
6367
+ "content-security-policy",
6368
+ "content-type",
6369
+ "etag",
6370
+ "expires",
6371
+ "last-modified",
6372
+ "location",
6373
+ "vary",
6374
+ "x-frame-options"
6375
+ ]);
6376
+ function createKnowledgeViewerRouteHandlers(dependencies = {}) {
6377
+ const getStatus = dependencies.getStatus ?? getKnowledgeViewerStatus;
6378
+ const ensure = dependencies.ensure ?? ((options) => ensureOpenKnowledge(options));
6379
+ const executeSetupPlan = dependencies.executeSetupPlan ?? executeOpenKnowledgeSetupPlan;
6380
+ const startViewer = dependencies.start ?? getOrStartViewer;
6381
+ const invalidateInstallationCache = dependencies.invalidateInstallationCache ?? invalidateKnowledgeViewerInstallationCache;
6382
+ async function status(projectKey) {
6383
+ return getStatus(projectKey);
6384
+ }
6385
+ async function install(projectKey) {
6386
+ try {
6387
+ await ensure({ autoInstall: true });
6388
+ } catch (error) {
6389
+ if (!(error instanceof OpenKnowledgeSetupRequiredError)) throw error;
6390
+ await executeSetupPlan(error.plan);
6391
+ await ensure({ autoInstall: true });
6392
+ }
6393
+ invalidateInstallationCache();
6394
+ return status(projectKey);
6395
+ }
6396
+ async function start(projectKey) {
6397
+ return startViewer(projectKey);
6398
+ }
6399
+ async function resolveTarget(projectKey) {
6400
+ const result = await status(projectKey);
6401
+ return result.running && result.url ? result.url : null;
6402
+ }
6403
+ return {
6404
+ status,
6405
+ install,
6406
+ start,
6407
+ resolveTarget
6408
+ };
6409
+ }
6410
+ function knowledgeViewerUpstreamUrl(requestUrl, targetUrl, websocket) {
6411
+ const incoming = new URL(requestUrl, "http://localhost");
6412
+ incoming.searchParams.delete("access");
6413
+ const target = new URL(targetUrl);
6414
+ target.protocol = websocket ? target.protocol === "https:" ? "wss:" : "ws:" : target.protocol;
6415
+ target.pathname = incoming.pathname || "/";
6416
+ target.search = incoming.search;
6417
+ target.hash = "";
6418
+ return target.toString();
6419
+ }
6420
+ function knowledgeViewerHost(projectKey, dashboardHost) {
6421
+ const parsed = splitHostAndPort(dashboardHost);
6422
+ const baseHost = isIpAddress(parsed.hostname) ? "localhost" : parsed.hostname;
6423
+ return `${VIEWER_HOST_PREFIX}${Buffer.from(projectKey, "utf8").toString("hex")}.${baseHost}${parsed.port ? `:${parsed.port}` : ""}`;
6424
+ }
6425
+ function projectFromKnowledgeViewerHost(host) {
6426
+ if (!host) return null;
6427
+ const { hostname } = splitHostAndPort(host);
6428
+ const firstDot = hostname.indexOf(".");
6429
+ if (firstDot < 0) return null;
6430
+ const label = hostname.slice(0, firstDot);
6431
+ if (!label.startsWith(VIEWER_HOST_PREFIX)) return null;
6432
+ const encoded = label.slice(10);
6433
+ if (!encoded || encoded.length % 2 !== 0 || !/^[a-f0-9]+$/.test(encoded)) return null;
6434
+ try {
6435
+ const projectKey = Buffer.from(encoded, "hex").toString("utf8");
6436
+ return Buffer.from(projectKey, "utf8").toString("hex") === encoded ? projectKey : null;
6437
+ } catch {
6438
+ return null;
6439
+ }
6440
+ }
6441
+ function knowledgeViewerProxyUrl(projectKey, dashboardHost) {
6442
+ const token = viewerAccessTokens.get(projectKey) ?? randomBytes(32).toString("base64url");
6443
+ viewerAccessTokens.set(projectKey, token);
6444
+ return `//${knowledgeViewerHost(projectKey, dashboardHost)}/?access=${encodeURIComponent(token)}`;
6445
+ }
6446
+ function filterKnowledgeViewerRequestHeaders(headers) {
6447
+ const filtered = {};
6448
+ for (const [name, value] of Object.entries(headers)) {
6449
+ const lower = name.toLowerCase();
6450
+ if (!value || !REQUEST_HEADER_ALLOWLIST.has(lower)) continue;
6451
+ filtered[lower] = value;
6452
+ }
6453
+ return filtered;
6454
+ }
6455
+ function filterKnowledgeViewerResponseHeaders(headers) {
6456
+ const filtered = {};
6457
+ if (headers instanceof Headers) {
6458
+ headers.forEach((value, name) => {
6459
+ if (RESPONSE_HEADER_ALLOWLIST.has(name.toLowerCase())) filtered[name.toLowerCase()] = value;
6460
+ });
6461
+ return filtered;
6462
+ }
6463
+ for (const [name, value] of Object.entries(headers)) {
6464
+ if (!value || !RESPONSE_HEADER_ALLOWLIST.has(name.toLowerCase())) continue;
6465
+ filtered[name.toLowerCase()] = value;
6466
+ }
6467
+ return filtered;
6468
+ }
6469
+ function projectFromRequestUrl(requestUrl) {
6470
+ return new URL(requestUrl, "http://localhost").searchParams.get("project");
6471
+ }
6472
+ function parseProjectBody(text) {
6473
+ try {
6474
+ const parsed = JSON.parse(text);
6475
+ return typeof parsed.project === "string" && parsed.project.trim() ? parsed.project.trim() : null;
6476
+ } catch {
6477
+ return null;
6478
+ }
6479
+ }
6480
+ function withProxyUrl(status, request) {
6481
+ const host = request.headers.host;
6482
+ if (!status.running || !status.url || !host) return status;
6483
+ return {
6484
+ ...status,
6485
+ proxyUrl: knowledgeViewerProxyUrl(status.projectKey, host)
6486
+ };
6487
+ }
6488
+ const handlers = createKnowledgeViewerRouteHandlers();
6489
+ const statusRoute = HttpRouter.add("GET", "/api/knowledge-viewer/status", httpHandler(Effect.gen(function* () {
6490
+ const request = yield* HttpServerRequest.HttpServerRequest;
6491
+ const authError = rejectUnauthorizedDashboardRequest(request);
6492
+ if (authError) return authError;
6493
+ const projectKey = projectFromRequestUrl(request.url);
6494
+ if (!projectKey) return jsonResponse({ error: "project query parameter is required" }, { status: 400 });
6495
+ return jsonResponse(withProxyUrl(yield* Effect.promise(() => handlers.status(projectKey)), request));
6496
+ })));
6497
+ const installRoute = HttpRouter.add("POST", "/api/knowledge-viewer/install", httpHandler(Effect.gen(function* () {
6498
+ const request = yield* HttpServerRequest.HttpServerRequest;
6499
+ const authError = rejectUnsafeDashboardMutationRequest(request);
6500
+ if (authError) return authError;
6501
+ const projectKey = parseProjectBody(yield* request.text);
6502
+ if (!projectKey) return jsonResponse({ error: "project is required in the request body" }, { status: 400 });
6503
+ try {
6504
+ return jsonResponse(withProxyUrl(yield* Effect.promise(() => handlers.install(projectKey)), request));
6505
+ } catch (error) {
6506
+ return jsonResponse({ error: errorMessage$1(error) }, { status: 500 });
6507
+ }
6508
+ })));
6509
+ const startRoute$1 = HttpRouter.add("POST", "/api/knowledge-viewer/start", httpHandler(Effect.gen(function* () {
6510
+ const request = yield* HttpServerRequest.HttpServerRequest;
6511
+ const authError = rejectUnsafeDashboardMutationRequest(request);
6512
+ if (authError) return authError;
6513
+ const projectKey = parseProjectBody(yield* request.text);
6514
+ if (!projectKey) return jsonResponse({ error: "project is required in the request body" }, { status: 400 });
6515
+ try {
6516
+ const status = yield* Effect.promise(() => handlers.start(projectKey));
6517
+ return jsonResponse(withProxyUrl(status, request), { status: status.running ? 200 : 409 });
6518
+ } catch (error) {
6519
+ return jsonResponse({ error: errorMessage$1(error) }, { status: 500 });
6520
+ }
6521
+ })));
6522
+ const legacyProxyRedirectRoute = HttpRouter.add("GET", "/knowledge-viewer/*", httpHandler(Effect.gen(function* () {
6523
+ const request = yield* HttpServerRequest.HttpServerRequest;
6524
+ const authError = rejectUnauthorizedDashboardRequest(request);
6525
+ if (authError) return authError;
6526
+ const projectKey = projectFromRequestUrl(request.url);
6527
+ if (!projectKey) return jsonResponse({ error: "project query parameter is required" }, { status: 400 });
6528
+ const result = withProxyUrl(yield* Effect.promise(() => handlers.status(projectKey)), request);
6529
+ if (!result.proxyUrl) return jsonResponse({ error: "Knowledge viewer is not running" }, { status: 503 });
6530
+ return HttpServerResponse.redirect(result.proxyUrl);
6531
+ })));
6532
+ const knowledgeViewerRouteLayer = Layer.mergeAll(statusRoute, installRoute, startRoute$1, legacyProxyRedirectRoute);
6533
+ function setupKnowledgeViewerProxy(server, routeHandlers = handlers) {
6534
+ const wss = new import_websocket_server.default({ noServer: true });
6535
+ const originalOn = server.on.bind(server);
6536
+ server.on = function(event, listener) {
6537
+ if (event === "request") {
6538
+ const wrapped = (request, response) => {
6539
+ const projectKey = projectFromKnowledgeViewerHost(request.headers.host);
6540
+ if (projectKey) {
6541
+ proxyKnowledgeViewerHttp(request, response, projectKey, routeHandlers);
6542
+ return;
6543
+ }
6544
+ listener(request, response);
6545
+ };
6546
+ return originalOn(event, wrapped);
6547
+ }
6548
+ if (event === "upgrade") {
6549
+ const wrapped = (request, socket, head) => {
6550
+ if (projectFromKnowledgeViewerHost(request.headers.host)) return;
6551
+ listener(request, socket, head);
6552
+ };
6553
+ return originalOn(event, wrapped);
6554
+ }
6555
+ return originalOn(event, listener);
6556
+ };
6557
+ originalOn("upgrade", (request, socket, head) => {
6558
+ const projectKey = projectFromKnowledgeViewerHost(request.headers.host);
6559
+ if (!projectKey) return;
6560
+ if (!authorizeViewerRequest(request, projectKey).ok) {
6561
+ rejectUpgrade(socket, 401, "Unauthorized");
6562
+ return;
6563
+ }
6564
+ if (!viewerOriginIsAllowed(request)) {
6565
+ rejectUpgrade(socket, 403, "Invalid origin");
6566
+ return;
6567
+ }
6568
+ routeHandlers.resolveTarget(projectKey).then((target) => {
6569
+ if (!target) {
6570
+ rejectUpgrade(socket, 503, "Knowledge viewer is not running");
6571
+ return;
6572
+ }
6573
+ wss.handleUpgrade(request, socket, head, (client) => {
6574
+ bridgeWebSocket(client, request, knowledgeViewerUpstreamUrl(request.url || "/", target, true));
6575
+ });
6576
+ }).catch((error) => rejectUpgrade(socket, 502, errorMessage$1(error)));
6577
+ });
6578
+ }
6579
+ async function proxyKnowledgeViewerHttp(request, response, projectKey, routeHandlers) {
6580
+ const access = authorizeViewerRequest(request, projectKey);
6581
+ if (!access.ok) {
6582
+ writeJsonError(response, 401, "unauthorized");
6583
+ return;
6584
+ }
6585
+ const target = await routeHandlers.resolveTarget(projectKey);
6586
+ if (!target) {
6587
+ writeJsonError(response, 503, "Knowledge viewer is not running");
6588
+ return;
6589
+ }
6590
+ const upstreamUrl = knowledgeViewerUpstreamUrl(request.url || "/", target, false);
6591
+ const upstreamRequest = (upstreamUrl.startsWith("https:") ? https : http).request(upstreamUrl, {
6592
+ method: request.method,
6593
+ headers: filterKnowledgeViewerRequestHeaders(request.headers)
6594
+ }, (upstreamResponse) => {
6595
+ const headers = filterKnowledgeViewerResponseHeaders(upstreamResponse.headers);
6596
+ headers["referrer-policy"] = "no-referrer";
6597
+ const location = upstreamResponse.headers.location;
6598
+ if (location) headers.location = rewriteLocation(location, upstreamUrl, target);
6599
+ if (access.grantCookie) headers["set-cookie"] = viewerCookieHeader(access.token, request);
6600
+ if (new URL(request.url || "/", "http://localhost").pathname === "/api/config") {
6601
+ proxyKnowledgeViewerConfigResponse(request, response, upstreamResponse, headers);
6602
+ return;
6603
+ }
6604
+ response.writeHead(upstreamResponse.statusCode ?? 502, headers);
6605
+ upstreamResponse.pipe(response);
6606
+ });
6607
+ upstreamRequest.on("error", (error) => {
6608
+ if (!response.headersSent) writeJsonError(response, 502, errorMessage$1(error));
6609
+ else response.destroy(error);
6610
+ });
6611
+ request.on("aborted", () => upstreamRequest.destroy());
6612
+ request.pipe(upstreamRequest);
6613
+ }
6614
+ async function proxyKnowledgeViewerConfigResponse(request, response, upstreamResponse, headers) {
6615
+ try {
6616
+ const chunks = [];
6617
+ let size = 0;
6618
+ for await (const chunk of upstreamResponse) {
6619
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
6620
+ size += buffer.length;
6621
+ if (size > MAX_CONFIG_RESPONSE_BYTES) throw new Error("open-knowledge config response exceeded 64 KiB");
6622
+ chunks.push(buffer);
6623
+ }
6624
+ const config = JSON.parse(Buffer.concat(chunks).toString("utf8"));
6625
+ const host = request.headers.host;
6626
+ if (!host) throw new Error("knowledge viewer request host is missing");
6627
+ const secure = firstHeader(request.headers["x-forwarded-proto"]) === "https" || "encrypted" in request.socket;
6628
+ if (typeof config.collabUrl === "string") {
6629
+ const collabUrl = new URL(config.collabUrl);
6630
+ config.collabUrl = `${secure ? "wss" : "ws"}://${host}${collabUrl.pathname}${collabUrl.search}`;
6631
+ }
6632
+ if (typeof config.previewUrl === "string") {
6633
+ const previewUrl = new URL(config.previewUrl);
6634
+ config.previewUrl = `${secure ? "https" : "http"}://${host}${previewUrl.pathname}${previewUrl.search}`;
6635
+ }
6636
+ const body = Buffer.from(JSON.stringify(config));
6637
+ headers["content-length"] = body.length;
6638
+ response.writeHead(upstreamResponse.statusCode ?? 502, headers);
6639
+ response.end(body);
6640
+ } catch (error) {
6641
+ if (!response.headersSent) writeJsonError(response, 502, errorMessage$1(error));
6642
+ else response.destroy(error instanceof Error ? error : void 0);
6643
+ }
6644
+ }
6645
+ function authorizeViewerRequest(request, projectKey) {
6646
+ const expected = viewerAccessTokens.get(projectKey);
6647
+ if (!expected) return { ok: false };
6648
+ const queryToken = new URL(request.url || "/", "http://localhost").searchParams.get("access");
6649
+ const cookieToken = cookieValue(request.headers.cookie, VIEWER_ACCESS_COOKIE);
6650
+ if (constantTimeEqual(queryToken, expected)) return {
6651
+ ok: true,
6652
+ token: expected,
6653
+ grantCookie: true
6654
+ };
6655
+ if (constantTimeEqual(cookieToken, expected)) return {
6656
+ ok: true,
6657
+ token: expected,
6658
+ grantCookie: false
6659
+ };
6660
+ return { ok: false };
6661
+ }
6662
+ function viewerOriginIsAllowed(request) {
6663
+ const origin = request.headers.origin;
6664
+ if (origin) try {
6665
+ if (new URL(origin).host === request.headers.host) return true;
6666
+ } catch {
6667
+ return false;
6668
+ }
6669
+ return validateOriginHeaders(request.headers, request.method ?? "GET").ok;
6670
+ }
6671
+ function viewerCookieHeader(token, _request) {
6672
+ return `${VIEWER_ACCESS_COOKIE}=${encodeURIComponent(token)}; HttpOnly; SameSite=None; Secure; Path=/`;
6673
+ }
6674
+ function bridgeWebSocket(client, request, upstreamUrl) {
6675
+ const protocols = (request.headers["sec-websocket-protocol"] ?? "").split(",").map((value) => value.trim()).filter(Boolean);
6676
+ const upstream = new import_websocket.default(upstreamUrl, protocols.length > 0 ? protocols : void 0, { headers: { origin: new URL(upstreamUrl).origin.replace(/^ws/, "http") } });
6677
+ const queued = [];
6678
+ let queuedBytes = 0;
6679
+ client.on("message", (data, binary) => {
6680
+ const payload = Buffer.isBuffer(data) ? data : Buffer.from(data);
6681
+ if (upstream.readyState === import_websocket.default.OPEN) {
6682
+ upstream.send(payload, { binary });
6683
+ return;
6684
+ }
6685
+ if (queued.length >= MAX_QUEUED_WEBSOCKET_MESSAGES || queuedBytes + payload.byteLength > MAX_QUEUED_WEBSOCKET_BYTES) {
6686
+ client.close(1009, "knowledge-viewer-queue-limit");
6687
+ upstream.terminate();
6688
+ return;
6689
+ }
6690
+ queued.push({
6691
+ data: payload,
6692
+ binary
6693
+ });
6694
+ queuedBytes += payload.byteLength;
6695
+ });
6696
+ upstream.once("open", () => {
6697
+ for (const message of queued.splice(0)) upstream.send(message.data, { binary: message.binary });
6698
+ queuedBytes = 0;
6699
+ });
6700
+ upstream.on("message", (data, binary) => {
6701
+ if (client.readyState === import_websocket.default.OPEN) client.send(data, { binary });
6702
+ });
6703
+ upstream.on("close", (code, reason) => {
6704
+ if (client.readyState === import_websocket.default.OPEN) client.close(code, reason.toString());
6705
+ });
6706
+ upstream.on("error", () => {
6707
+ if (client.readyState === import_websocket.default.OPEN) client.close(1011, "knowledge-viewer-upstream-error");
6708
+ });
6709
+ client.on("close", () => {
6710
+ if (upstream.readyState === import_websocket.default.OPEN || upstream.readyState === import_websocket.default.CONNECTING) upstream.close();
6711
+ });
6712
+ }
6713
+ function rewriteLocation(location, upstreamUrl, targetUrl) {
6714
+ const resolved = new URL(location, upstreamUrl);
6715
+ const target = new URL(targetUrl);
6716
+ if (resolved.origin !== target.origin) return location;
6717
+ return `${resolved.pathname}${resolved.search}${resolved.hash}`;
6718
+ }
6719
+ function splitHostAndPort(host) {
6720
+ try {
6721
+ const parsed = new URL(`http://${host}`);
6722
+ return {
6723
+ hostname: parsed.hostname.toLowerCase(),
6724
+ port: parsed.port
6725
+ };
6726
+ } catch {
6727
+ return {
6728
+ hostname: host.toLowerCase(),
6729
+ port: ""
6730
+ };
6731
+ }
6732
+ }
6733
+ function isIpAddress(hostname) {
6734
+ return /^\d{1,3}(?:\.\d{1,3}){3}$/.test(hostname) || hostname.includes(":");
6735
+ }
6736
+ function cookieValue(cookieHeader, name) {
6737
+ if (!cookieHeader) return null;
6738
+ for (const part of cookieHeader.split(";")) {
6739
+ const [key, ...rest] = part.trim().split("=");
6740
+ if (key === name) return decodeURIComponent(rest.join("="));
6741
+ }
6742
+ return null;
6743
+ }
6744
+ function constantTimeEqual(value, expected) {
6745
+ if (!value) return false;
6746
+ const actualBuffer = Buffer.from(value);
6747
+ const expectedBuffer = Buffer.from(expected);
6748
+ return actualBuffer.length === expectedBuffer.length && timingSafeEqual(actualBuffer, expectedBuffer);
6749
+ }
6750
+ function firstHeader(value) {
6751
+ return Array.isArray(value) ? value[0] : value;
6752
+ }
6753
+ function writeJsonError(response, status, message) {
6754
+ const body = JSON.stringify({ error: message });
6755
+ response.writeHead(status, {
6756
+ "content-type": "application/json",
6757
+ "content-length": Buffer.byteLength(body)
6758
+ });
6759
+ response.end(body);
6760
+ }
6761
+ function rejectUpgrade(socket, status, message) {
6762
+ socket.write(`HTTP/1.1 ${status} ${message}\r\nConnection: close\r\nContent-Length: 0\r\n\r\n`);
6763
+ socket.destroy();
6764
+ }
6765
+ function errorMessage$1(error) {
6766
+ return error instanceof Error ? error.message : String(error);
6767
+ }
6768
+ //#endregion
6769
+ //#region ../../../node_modules/.bun/@ai-sdk+provider@3.0.10/node_modules/@ai-sdk/provider/dist/index.mjs
6770
+ init_paths$2();
6771
+ init_cost_sync();
6772
+ init_features();
6773
+ init_settings();
6774
+ init_health();
6775
+ init_providers$1();
6776
+ init_query_expansion();
6777
+ init_fts_db();
6778
+ init_search();
5492
6779
  var marker$2 = "vercel.ai.error";
5493
6780
  var symbol$3 = Symbol.for(marker$2);
5494
6781
  var _a$5, _b$2;
@@ -5869,7 +7156,7 @@ function mergeDefs(...defs) {
5869
7156
  function esc(str) {
5870
7157
  return JSON.stringify(str);
5871
7158
  }
5872
- function slugify(input) {
7159
+ function slugify$1(input) {
5873
7160
  return input.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
5874
7161
  }
5875
7162
  const captureStackTrace = "captureStackTrace" in Error ? Error.captureStackTrace : (..._args) => {};
@@ -8593,7 +9880,7 @@ function _toUpperCase() {
8593
9880
  }
8594
9881
  /* @__NO_SIDE_EFFECTS__ */
8595
9882
  function _slugify() {
8596
- return /* @__PURE__ */ _overwrite((input) => slugify(input));
9883
+ return /* @__PURE__ */ _overwrite((input) => slugify$1(input));
8597
9884
  }
8598
9885
  /* @__NO_SIDE_EFFECTS__ */
8599
9886
  function _array(Class, element, params) {
@@ -10058,7 +11345,7 @@ const ZodRecord$1 = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
10058
11345
  inst.keyType = def.keyType;
10059
11346
  inst.valueType = def.valueType;
10060
11347
  });
10061
- function record(keyType, valueType, params) {
11348
+ function record$1(keyType, valueType, params) {
10062
11349
  if (!valueType || !valueType._zod) return new ZodRecord$1({
10063
11350
  type: "record",
10064
11351
  keyType: string(),
@@ -15968,7 +17255,7 @@ var require_get_vercel_oidc_token = /* @__PURE__ */ __commonJSMin(((exports, mod
15968
17255
  err = error;
15969
17256
  }
15970
17257
  try {
15971
- const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([await import("./token-util-DrHg8abn.js").then((m) => /* @__PURE__ */ __toESM(m.default)), await import("./token-CsOhvw42.js").then((m) => /* @__PURE__ */ __toESM(m.default))]);
17258
+ const [{ getTokenPayload, isExpired }, { refreshToken }] = await Promise.all([await import("./token-util-DuPuNriz.js").then((m) => /* @__PURE__ */ __toESM(m.default)), await import("./token-BK6t8BIT.js").then((m) => /* @__PURE__ */ __toESM(m.default))]);
15972
17259
  if (!token || isExpired(getTokenPayload(token), options?.expirationBufferMs)) {
15973
17260
  await refreshToken(options);
15974
17261
  token = getVercelOidcTokenSync();
@@ -16738,7 +18025,7 @@ var GatewayEmbeddingModel = class {
16738
18025
  var gatewayEmbeddingResponseSchema = lazySchema(() => zodSchema(object$1({
16739
18026
  embeddings: array$1(array$1(number$1())),
16740
18027
  usage: object$1({ tokens: number$1() }).nullish(),
16741
- providerMetadata: record(string(), record(string(), unknown())).optional()
18028
+ providerMetadata: record$1(string(), record$1(string(), unknown())).optional()
16742
18029
  })));
16743
18030
  var GatewayImageModel = class {
16744
18031
  constructor(modelId, config) {
@@ -16836,7 +18123,7 @@ var gatewayImageUsageSchema = object$1({
16836
18123
  var gatewayImageResponseSchema = object$1({
16837
18124
  images: array$1(string()),
16838
18125
  warnings: array$1(gatewayImageWarningSchema).optional(),
16839
- providerMetadata: record(string(), providerMetadataEntrySchema).optional(),
18126
+ providerMetadata: record$1(string(), providerMetadataEntrySchema).optional(),
16840
18127
  usage: gatewayImageUsageSchema.optional()
16841
18128
  });
16842
18129
  var GatewayVideoModel = class {
@@ -16984,7 +18271,7 @@ var gatewayVideoEventSchema = discriminatedUnion("type", [object$1({
16984
18271
  type: literal("result"),
16985
18272
  videos: array$1(gatewayVideoDataSchema),
16986
18273
  warnings: array$1(gatewayVideoWarningSchema).optional(),
16987
- providerMetadata: record(string(), providerMetadataEntrySchema2).optional()
18274
+ providerMetadata: record$1(string(), providerMetadataEntrySchema2).optional()
16988
18275
  }), object$1({
16989
18276
  type: literal("error"),
16990
18277
  message: string(),
@@ -17049,7 +18336,7 @@ var gatewayRerankingResponseSchema = lazySchema(() => zodSchema(object$1({
17049
18336
  index: number$1(),
17050
18337
  relevanceScore: number$1()
17051
18338
  })),
17052
- providerMetadata: record(string(), record(string(), unknown())).optional()
18339
+ providerMetadata: record$1(string(), record$1(string(), unknown())).optional()
17053
18340
  })));
17054
18341
  var parallelSearchToolFactory = createProviderToolFactoryWithOutputSchema({
17055
18342
  id: "gateway.parallel_search",
@@ -19169,10 +20456,10 @@ var jsonValueSchema$1 = lazy(() => union([
19169
20456
  string(),
19170
20457
  number$1(),
19171
20458
  boolean(),
19172
- record(string(), jsonValueSchema$1.optional()),
20459
+ record$1(string(), jsonValueSchema$1.optional()),
19173
20460
  array$1(jsonValueSchema$1)
19174
20461
  ]));
19175
- var providerMetadataSchema = record(string(), record(string(), jsonValueSchema$1.optional()));
20462
+ var providerMetadataSchema = record$1(string(), record$1(string(), jsonValueSchema$1.optional()));
19176
20463
  var textPartSchema = object$1({
19177
20464
  type: literal("text"),
19178
20465
  text: string(),
@@ -19257,7 +20544,7 @@ var outputSchema = discriminatedUnion("type", [
19257
20544
  }),
19258
20545
  object$1({
19259
20546
  type: literal("file-id"),
19260
- fileId: union([string(), record(string(), string())]),
20547
+ fileId: union([string(), record$1(string(), string())]),
19261
20548
  providerOptions: providerMetadataSchema.optional()
19262
20549
  }),
19263
20550
  object$1({
@@ -19273,7 +20560,7 @@ var outputSchema = discriminatedUnion("type", [
19273
20560
  }),
19274
20561
  object$1({
19275
20562
  type: literal("image-file-id"),
19276
- fileId: union([string(), record(string(), string())]),
20563
+ fileId: union([string(), record$1(string(), string())]),
19277
20564
  providerOptions: providerMetadataSchema.optional()
19278
20565
  }),
19279
20566
  object$1({
@@ -21398,7 +22685,7 @@ function asContent({ content, toolCalls, toolOutputs, toolApprovalRequests, tool
21398
22685
  ];
21399
22686
  }
21400
22687
  TransformStream;
21401
- var toolMetadataSchema = record(string(), jsonValueSchema$1.optional());
22688
+ var toolMetadataSchema = record$1(string(), jsonValueSchema$1.optional());
21402
22689
  lazySchema(() => zodSchema(union([
21403
22690
  strictObject({
21404
22691
  type: literal("text-start"),
@@ -21561,7 +22848,7 @@ createIdGenerator({
21561
22848
  prefix: "aitxt",
21562
22849
  size: 24
21563
22850
  });
21564
- var toolMetadataSchema2 = record(string(), jsonValueSchema$1.optional());
22851
+ var toolMetadataSchema2 = record$1(string(), jsonValueSchema$1.optional());
21565
22852
  lazySchema(() => zodSchema(array$1(object$1({
21566
22853
  id: string(),
21567
22854
  role: _enum([
@@ -22383,7 +23670,7 @@ var openaiLanguageModelChatOptions = lazySchema(() => zodSchema(object$1({
22383
23670
  * Accepts a JSON object that maps tokens (specified by their token ID in
22384
23671
  * the GPT tokenizer) to an associated bias value from -100 to 100.
22385
23672
  */
22386
- logitBias: record(number(), number$1()).optional(),
23673
+ logitBias: record$1(number(), number$1()).optional(),
22387
23674
  /**
22388
23675
  * Return the log probabilities of the tokens.
22389
23676
  *
@@ -22425,11 +23712,11 @@ var openaiLanguageModelChatOptions = lazySchema(() => zodSchema(object$1({
22425
23712
  /**
22426
23713
  * Metadata to associate with the request.
22427
23714
  */
22428
- metadata: record(string().max(64), string().max(512)).optional(),
23715
+ metadata: record$1(string().max(64), string().max(512)).optional(),
22429
23716
  /**
22430
23717
  * Parameters for prediction mode.
22431
23718
  */
22432
- prediction: record(string(), any()).optional(),
23719
+ prediction: record$1(string(), any()).optional(),
22433
23720
  /**
22434
23721
  * Service tier for the request.
22435
23722
  * - 'auto': Default service tier. The request will be processed with the service tier configured in the
@@ -23093,7 +24380,7 @@ var openaiCompletionResponseSchema = lazySchema(() => zodSchema(object$1({
23093
24380
  logprobs: object$1({
23094
24381
  tokens: array$1(string()),
23095
24382
  token_logprobs: array$1(number$1()),
23096
- top_logprobs: array$1(record(string(), number$1())).nullish()
24383
+ top_logprobs: array$1(record$1(string(), number$1())).nullish()
23097
24384
  }).nullish()
23098
24385
  })),
23099
24386
  usage: object$1({
@@ -23113,7 +24400,7 @@ var openaiCompletionChunkSchema = lazySchema(() => zodSchema(union([object$1({
23113
24400
  logprobs: object$1({
23114
24401
  tokens: array$1(string()),
23115
24402
  token_logprobs: array$1(number$1()),
23116
- top_logprobs: array$1(record(string(), number$1())).nullish()
24403
+ top_logprobs: array$1(record$1(string(), number$1())).nullish()
23117
24404
  }).nullish()
23118
24405
  })),
23119
24406
  usage: object$1({
@@ -23141,7 +24428,7 @@ var openaiLanguageModelCompletionOptions = lazySchema(() => zodSchema(object$1({
23141
24428
  * As an example, you can pass {"50256": -100} to prevent the <|endoftext|>
23142
24429
  * token from being generated.
23143
24430
  */
23144
- logitBias: record(string(), number$1()).optional(),
24431
+ logitBias: record$1(string(), number$1()).optional(),
23145
24432
  /**
23146
24433
  * The suffix that comes after a completion of inserted text.
23147
24434
  */
@@ -23802,7 +25089,7 @@ var fileSearchArgsSchema = lazySchema(() => zodSchema(object$1({
23802
25089
  var fileSearchOutputSchema = lazySchema(() => zodSchema(object$1({
23803
25090
  queries: array$1(string()),
23804
25091
  results: array$1(object$1({
23805
- attributes: record(string(), unknown()),
25092
+ attributes: record$1(string(), unknown()),
23806
25093
  fileId: string(),
23807
25094
  filename: string(),
23808
25095
  score: number$1(),
@@ -23861,7 +25148,7 @@ var localShellInputSchema = lazySchema(() => zodSchema(object$1({ action: object
23861
25148
  timeoutMs: number$1().optional(),
23862
25149
  user: string().optional(),
23863
25150
  workingDirectory: string().optional(),
23864
- env: record(string(), string()).optional()
25151
+ env: record$1(string(), string()).optional()
23865
25152
  }) })));
23866
25153
  var localShellOutputSchema = lazySchema(() => zodSchema(object$1({ output: string() })));
23867
25154
  var localShell = createProviderToolFactoryWithOutputSchema({
@@ -23938,13 +25225,13 @@ var shell = createProviderToolFactoryWithOutputSchema({
23938
25225
  var toolSearchArgsSchema = lazySchema(() => zodSchema(object$1({
23939
25226
  execution: _enum(["server", "client"]).optional(),
23940
25227
  description: string().optional(),
23941
- parameters: record(string(), unknown()).optional()
25228
+ parameters: record$1(string(), unknown()).optional()
23942
25229
  })));
23943
25230
  var toolSearchInputSchema = lazySchema(() => zodSchema(object$1({
23944
25231
  arguments: unknown().optional(),
23945
25232
  call_id: string().nullish()
23946
25233
  })));
23947
- var toolSearchOutputSchema = lazySchema(() => zodSchema(object$1({ tools: array$1(record(string(), unknown())) })));
25234
+ var toolSearchOutputSchema = lazySchema(() => zodSchema(object$1({ tools: array$1(record$1(string(), unknown())) })));
23948
25235
  var toolSearchToolFactory = createProviderToolFactoryWithOutputSchema({
23949
25236
  id: "openai.tool_search",
23950
25237
  inputSchema: toolSearchInputSchema,
@@ -24035,7 +25322,7 @@ var jsonValueSchema = lazy(() => union([
24035
25322
  boolean(),
24036
25323
  _null(),
24037
25324
  array$1(jsonValueSchema),
24038
- record(string(), jsonValueSchema)
25325
+ record$1(string(), jsonValueSchema)
24039
25326
  ]));
24040
25327
  var mcpArgsSchema = lazySchema(() => zodSchema(object$1({
24041
25328
  serverLabel: string(),
@@ -24045,7 +25332,7 @@ var mcpArgsSchema = lazySchema(() => zodSchema(object$1({
24045
25332
  })]).optional(),
24046
25333
  authorization: string().optional(),
24047
25334
  connectorId: string().optional(),
24048
- headers: record(string(), string()).optional(),
25335
+ headers: record$1(string(), string()).optional(),
24049
25336
  requireApproval: union([_enum(["always", "never"]), object$1({ never: object$1({ toolNames: array$1(string()).optional() }).optional() })]).optional(),
24050
25337
  serverDescription: string().optional(),
24051
25338
  serverUrl: string().optional()
@@ -24781,7 +26068,7 @@ var jsonValueSchema2 = lazy(() => union([
24781
26068
  boolean(),
24782
26069
  _null(),
24783
26070
  array$1(jsonValueSchema2),
24784
- record(string(), jsonValueSchema2.optional())
26071
+ record$1(string(), jsonValueSchema2.optional())
24785
26072
  ]));
24786
26073
  var openaiResponsesChunkSchema = lazySchema(() => zodSchema(union([
24787
26074
  object$1({
@@ -24984,7 +26271,7 @@ var openaiResponsesChunkSchema = lazySchema(() => zodSchema(union([
24984
26271
  "completed",
24985
26272
  "incomplete"
24986
26273
  ]),
24987
- tools: array$1(record(string(), jsonValueSchema2.optional()))
26274
+ tools: array$1(record$1(string(), jsonValueSchema2.optional()))
24988
26275
  })
24989
26276
  ])
24990
26277
  }),
@@ -25069,7 +26356,7 @@ var openaiResponsesChunkSchema = lazySchema(() => zodSchema(union([
25069
26356
  id: string(),
25070
26357
  queries: array$1(string()),
25071
26358
  results: array$1(object$1({
25072
- attributes: record(string(), union([
26359
+ attributes: record$1(string(), union([
25073
26360
  string(),
25074
26361
  number$1(),
25075
26362
  boolean()
@@ -25090,7 +26377,7 @@ var openaiResponsesChunkSchema = lazySchema(() => zodSchema(union([
25090
26377
  timeout_ms: number$1().optional(),
25091
26378
  user: string().optional(),
25092
26379
  working_directory: string().optional(),
25093
- env: record(string(), string()).optional()
26380
+ env: record$1(string(), string()).optional()
25094
26381
  })
25095
26382
  }),
25096
26383
  object$1({
@@ -25121,7 +26408,7 @@ var openaiResponsesChunkSchema = lazySchema(() => zodSchema(union([
25121
26408
  name: string(),
25122
26409
  description: string().optional(),
25123
26410
  input_schema: any(),
25124
- annotations: record(string(), unknown()).optional()
26411
+ annotations: record$1(string(), unknown()).optional()
25125
26412
  })),
25126
26413
  error: union([string(), object$1({
25127
26414
  type: string().optional(),
@@ -25210,7 +26497,7 @@ var openaiResponsesChunkSchema = lazySchema(() => zodSchema(union([
25210
26497
  "completed",
25211
26498
  "incomplete"
25212
26499
  ]),
25213
- tools: array$1(record(string(), jsonValueSchema2.optional()))
26500
+ tools: array$1(record$1(string(), jsonValueSchema2.optional()))
25214
26501
  })
25215
26502
  ])
25216
26503
  }),
@@ -25408,7 +26695,7 @@ var openaiResponsesResponseSchema = lazySchema(() => zodSchema(object$1({
25408
26695
  id: string(),
25409
26696
  queries: array$1(string()),
25410
26697
  results: array$1(object$1({
25411
- attributes: record(string(), union([
26698
+ attributes: record$1(string(), union([
25412
26699
  string(),
25413
26700
  number$1(),
25414
26701
  boolean()
@@ -25447,7 +26734,7 @@ var openaiResponsesResponseSchema = lazySchema(() => zodSchema(object$1({
25447
26734
  timeout_ms: number$1().optional(),
25448
26735
  user: string().optional(),
25449
26736
  working_directory: string().optional(),
25450
- env: record(string(), string()).optional()
26737
+ env: record$1(string(), string()).optional()
25451
26738
  })
25452
26739
  }),
25453
26740
  object$1({
@@ -25502,7 +26789,7 @@ var openaiResponsesResponseSchema = lazySchema(() => zodSchema(object$1({
25502
26789
  name: string(),
25503
26790
  description: string().optional(),
25504
26791
  input_schema: any(),
25505
- annotations: record(string(), unknown()).optional()
26792
+ annotations: record$1(string(), unknown()).optional()
25506
26793
  })),
25507
26794
  error: union([string(), object$1({
25508
26795
  type: string().optional(),
@@ -25591,7 +26878,7 @@ var openaiResponsesResponseSchema = lazySchema(() => zodSchema(object$1({
25591
26878
  "completed",
25592
26879
  "incomplete"
25593
26880
  ]),
25594
- tools: array$1(record(string(), jsonValueSchema2.optional()))
26881
+ tools: array$1(record$1(string(), jsonValueSchema2.optional()))
25595
26882
  })
25596
26883
  ])).optional(),
25597
26884
  service_tier: string().nullish(),
@@ -28285,7 +29572,7 @@ var GoogleCloudTranscription = class {
28285
29572
  }
28286
29573
  async start(apiKey, model) {
28287
29574
  try {
28288
- const { SpeechClient } = await import("./src-CG9mCkP6.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1)).then((module) => module.v1p1beta1 ?? module.v1);
29575
+ const { SpeechClient } = await import("./src-CXmtj0im.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1)).then((module) => module.v1p1beta1 ?? module.v1);
28289
29576
  if (this.closed) return;
28290
29577
  const stream = new SpeechClient({ apiKey }).streamingRecognize({
28291
29578
  config: {
@@ -28549,7 +29836,7 @@ const DEFAULT_VOICE_SETTINGS = {
28549
29836
  model: "gpt-4.1-mini"
28550
29837
  }
28551
29838
  };
28552
- const readJsonBody$17 = Effect.gen(function* () {
29839
+ const readJsonBody$18 = Effect.gen(function* () {
28553
29840
  const request = yield* HttpServerRequest.HttpServerRequest;
28554
29841
  const contentLength = Number(request.headers["content-length"] ?? 0);
28555
29842
  if (Number.isFinite(contentLength) && contentLength > MAX_VOICE_SETTINGS_BODY_BYTES) return {
@@ -28672,7 +29959,7 @@ const getVoiceSettingsRoute = HttpRouter.add("GET", "/api/voice/settings", httpH
28672
29959
  const putVoiceSettingsRoute = HttpRouter.add("PUT", "/api/voice/settings", httpHandler(Effect.gen(function* () {
28673
29960
  const originError = requireTrustedOrigin$2(yield* HttpServerRequest.HttpServerRequest);
28674
29961
  if (originError) return originError;
28675
- const parsed = yield* readJsonBody$17;
29962
+ const parsed = yield* readJsonBody$18;
28676
29963
  if (!parsed.ok) return jsonResponse({ error: parsed.error }, { status: 413 });
28677
29964
  const body = parsed.body;
28678
29965
  if (!isVoiceSettings(body)) return jsonResponse({ error: "Invalid voice settings payload" }, { status: 400 });
@@ -28966,6 +30253,7 @@ function streamAgentOutput(eventStore, agentId) {
28966
30253
  }
28967
30254
  //#endregion
28968
30255
  //#region services/read-workspace-file.ts
30256
+ init_acp_conversation_parser();
28969
30257
  init_codex_conversation_parser();
28970
30258
  init_ohmypi_conversation_parser();
28971
30259
  init_pi_conversation_parser();
@@ -29472,8 +30760,10 @@ function ohmypiSnapshotParser(harness) {
29472
30760
  }
29473
30761
  function streamHarnessFullParseSnapshots(sessionName, harness, model, unresolvedMeansEmpty = false) {
29474
30762
  const behavior = getHarnessBehavior(harness);
29475
- if (behavior.transcriptKind === "ohmypi-jsonl") return streamResolvedFullParseSnapshots(() => resolvePiSessionPath(sessionName), ohmypiSnapshotParser(harness), model, unresolvedMeansEmpty);
29476
- if (behavior.transcriptKind === "codex-rollout-jsonl") return streamResolvedFullParseSnapshots(() => resolveCodexRolloutPath(sessionName), parseCodexConversationMessages, model, unresolvedMeansEmpty);
30763
+ const streamResolved = (resolve, parse) => streamResolvedFullParseSnapshots(resolve, parse, model, unresolvedMeansEmpty);
30764
+ if (behavior.transcriptKind === "ohmypi-jsonl") return streamResolved(() => resolvePiSessionPath(sessionName), ohmypiSnapshotParser(harness));
30765
+ if (behavior.transcriptKind === "codex-rollout-jsonl") return streamResolved(() => resolveCodexRolloutPath(sessionName), parseCodexConversationMessages);
30766
+ if (behavior.transcriptKind === "acp-jsonl") return streamResolved(() => resolveAcpTranscriptPath(sessionName), parseAcpConversationMessages);
29477
30767
  return null;
29478
30768
  }
29479
30769
  function buildAgentIssueLookup(agents) {
@@ -30456,7 +31746,7 @@ const execFileAsync$18 = promisify(execFile);
30456
31746
  async function loadTrackerIssues() {
30457
31747
  const map = /* @__PURE__ */ new Map();
30458
31748
  try {
30459
- const { getSharedIssueService } = await import("./issue-service-singleton-DabvBWUp.js");
31749
+ const { getSharedIssueService } = await import("./issue-service-singleton-BvJ09SaR.js");
30460
31750
  const issues = (await getSharedIssueService()).getIssues();
30461
31751
  for (const issue of issues) if (issue.identifier) map.set(issue.identifier.toUpperCase(), issue);
30462
31752
  } catch {}
@@ -30479,7 +31769,7 @@ async function loadDockerContainers() {
30479
31769
  }
30480
31770
  async function loadActiveRemoteAgentStates() {
30481
31771
  try {
30482
- const { listActiveRemoteAgentStates } = await import("./remote-agents-CRCg1L4H.js");
31772
+ const { listActiveRemoteAgentStates } = await import("./remote-agents-CA3Ihlxj.js");
30483
31773
  return listActiveRemoteAgentStates();
30484
31774
  } catch {
30485
31775
  return [];
@@ -30508,6 +31798,7 @@ async function captureSharedResourceSignals() {
30508
31798
  //#endregion
30509
31799
  //#region review-status.ts
30510
31800
  init_concurrency$1();
31801
+ init_advisory_checks();
30511
31802
  init_github_app();
30512
31803
  init_resource_utils();
30513
31804
  init_pipeline_membership_gather();
@@ -30532,7 +31823,13 @@ function refreshMembershipSnapshot(project, snapshot, getMembership, now) {
30532
31823
  snapshot.refresh = scheduleMembershipRefresh(() => getMembership(project)).then((value) => {
30533
31824
  snapshot.value = value;
30534
31825
  snapshot.refreshedAt = now();
30535
- }).catch(() => {}).finally(() => {
31826
+ snapshot.lastError = void 0;
31827
+ snapshot.lastErrorAt = void 0;
31828
+ }).catch((error) => {
31829
+ snapshot.lastError = error instanceof Error ? error.message : String(error);
31830
+ snapshot.lastErrorAt = now();
31831
+ console.warn(`[pipeline-membership] refresh failed for ${project.name ?? project.path}; keeping last-good snapshot:`, snapshot.lastError);
31832
+ }).finally(() => {
30536
31833
  snapshot.refresh = void 0;
30537
31834
  });
30538
31835
  return snapshot.refresh;
@@ -30541,12 +31838,13 @@ function refreshMembershipSnapshot(project, snapshot, getMembership, now) {
30541
31838
  function readPipelineMembershipSnapshotsForProjects(projects) {
30542
31839
  return projects.map((project) => {
30543
31840
  const snapshot = membershipSnapshots.get(project.path);
30544
- return snapshot?.refreshedAt ? {
31841
+ if (snapshot?.refreshedAt) return {
30545
31842
  project,
30546
31843
  memberships: snapshot.value
30547
- } : {
31844
+ };
31845
+ return {
30548
31846
  project,
30549
- error: /* @__PURE__ */ new Error("Pipeline membership snapshot is loading")
31847
+ error: /* @__PURE__ */ new Error(snapshot?.lastError ? `Pipeline membership refresh failed: ${snapshot.lastError}` : "Pipeline membership snapshot is loading")
30550
31848
  };
30551
31849
  });
30552
31850
  }
@@ -32182,7 +33480,7 @@ async function closeIssuePullRequest(issueId, reason = "Canceled via Overdeck")
32182
33480
  timeout: 15e3
32183
33481
  });
32184
33482
  try {
32185
- const { setReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
33483
+ const { setReviewStatusSync } = await import("./review-status-btEYlaxA.js");
32186
33484
  setReviewStatusSync(issueId.toUpperCase(), { prUrl: void 0 });
32187
33485
  } catch {}
32188
33486
  return [`Closed PR #${prNumber} on ${githubCheck.owner}/${githubCheck.repo}`];
@@ -32236,7 +33534,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
32236
33534
  const { ctx, projectConfig } = buildLifecycleContext(id, getIssueDataService$8().getIssueSource(id) ?? void 0);
32237
33535
  const deleteWorkspace = opts.deleteWorkspace ?? true;
32238
33536
  cleanupLog.push(...await closeIssuePullRequest(id, mode === "cancel" ? "Canceled via Overdeck" : "Reset to Todo via Overdeck"));
32239
- const { resetToTodo, cancelIssueWorkflow } = await import("./lifecycle-sycO16hj.js");
33537
+ const { resetToTodo, cancelIssueWorkflow } = await import("./lifecycle-xmBfK2GJ.js");
32240
33538
  const workflow = mode === "cancel" ? cancelIssueWorkflow : resetToTodo;
32241
33539
  const result = await Effect.runPromise(workflow(ctx, {
32242
33540
  deleteWorkspace,
@@ -32251,7 +33549,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
32251
33549
  }));
32252
33550
  cleanupLog.push(...result.steps.flatMap((step) => step.details || [step.error].filter(Boolean)));
32253
33551
  if (mode === "cancel") try {
32254
- const { transitionXBriefOnMain } = await import("./lifecycle-io-Bsnr2K4F.js");
33552
+ const { transitionXBriefOnMain } = await import("./lifecycle-io-DPo7x11I.js");
32255
33553
  const tx = await Effect.runPromise(transitionXBriefOnMain(ctx.projectPath, id, "cancelled", "cancelled", `scope: cancel ${id.toUpperCase()} xBRIEF`));
32256
33554
  if (tx.moved) cleanupLog.push(`xBRIEF moved ${tx.fromDir} → cancelled`);
32257
33555
  if (tx.committed) cleanupLog.push(`Committed xBRIEF cancellation on main`);
@@ -32259,8 +33557,8 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
32259
33557
  cleanupLog.push(`xBRIEF cancel transition failed (non-fatal): ${err?.message ?? err}`);
32260
33558
  }
32261
33559
  try {
32262
- const { killAllReviewerSessions } = await import("./review-agent-DJRO8EG8.js");
32263
- const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
33560
+ const { killAllReviewerSessions } = await import("./review-agent-DNboMyW4.js");
33561
+ const { resolveProjectFromIssueSync } = await import("./projects-vjjcmiN8.js");
32264
33562
  const projectKey = resolveProjectFromIssueSync(id)?.projectKey;
32265
33563
  if (projectKey) {
32266
33564
  const { killed } = await Effect.runPromise(killAllReviewerSessions(projectKey, id.toUpperCase()));
@@ -32274,7 +33572,7 @@ async function runDestructiveIssueLifecycle(id, mode, opts = {}) {
32274
33572
  cleanupLog.push("Cleared review status");
32275
33573
  } catch {}
32276
33574
  try {
32277
- const { resetPostMergeState } = await import("./merge-agent-BQM3a8z5.js");
33575
+ const { resetPostMergeState } = await import("./merge-agent-CKkgIBPB.js");
32278
33576
  resetPostMergeState(id);
32279
33577
  resetPostMergeState(id.toUpperCase());
32280
33578
  cleanupLog.push("Cleared merge state");
@@ -32294,7 +33592,7 @@ function closeIssueTransition(options) {
32294
33592
  const { issueId, body, eventStore } = options;
32295
33593
  const { reason } = body;
32296
33594
  const projectPath = getProjectPath$3(void 0, extractPrefixSync(issueId) ?? issueId.split("-")[0]);
32297
- const { close: closeWorkflow } = yield* Effect.promise(() => import("./lifecycle-sycO16hj.js"));
33595
+ const { close: closeWorkflow } = yield* Effect.promise(() => import("./lifecycle-xmBfK2GJ.js"));
32298
33596
  const githubCheck = isGitHubIssue$4(issueId);
32299
33597
  const issueDataService = getIssueDataService$8();
32300
33598
  const issueSource = issueDataService.getIssueSource(issueId);
@@ -32561,7 +33859,7 @@ function reopenIssueTransition(options) {
32561
33859
  else clearReviewStatus(id.toUpperCase());
32562
33860
  } catch {}
32563
33861
  try {
32564
- const { resetPostMergeState } = await import("./merge-agent-BQM3a8z5.js");
33862
+ const { resetPostMergeState } = await import("./merge-agent-CKkgIBPB.js");
32565
33863
  resetPostMergeState(id);
32566
33864
  resetPostMergeState(id.toUpperCase());
32567
33865
  } catch {}
@@ -32625,7 +33923,7 @@ function moveIssueStatus(options) {
32625
33923
  "done"
32626
33924
  ];
32627
33925
  if (!targetStatus || !validStatuses.includes(targetStatus)) return jsonResponse({ error: `Invalid targetStatus. Must be one of: ${validStatuses.join(", ")}` }, { status: 400 });
32628
- const { updateShadowState } = yield* Effect.promise(() => import("./shadow-state-C2_epgx2.js"));
33926
+ const { updateShadowState } = yield* Effect.promise(() => import("./shadow-state-DnDyjujH.js"));
32629
33927
  const issueState = {
32630
33928
  backlog: "open",
32631
33929
  todo: "open",
@@ -32852,7 +34150,7 @@ async function copySettingsToWorkspace(id) {
32852
34150
  success: false,
32853
34151
  error: "Workspace not found"
32854
34152
  }, { status: 404 });
32855
- const { copyOverdeckSettingsToWorkspaceSync } = await import("./workspace-manager-ZTdJAy9M.js");
34153
+ const { copyOverdeckSettingsToWorkspaceSync } = await import("./workspace-manager-CWT55qeI.js");
32856
34154
  const result = copyOverdeckSettingsToWorkspaceSync(workspacePath);
32857
34155
  return jsonResponse({
32858
34156
  success: result.errors.length === 0 || result.copied.length > 0,
@@ -32962,7 +34260,25 @@ function startPlanningForIssue(options) {
32962
34260
  return Effect.gen(function* () {
32963
34261
  const { id, body, eventStore, linear, github, rally, lifecycle } = options;
32964
34262
  const { skipWorkspace = false, startDocker = false, workspaceLocation = "local", shadowMode = false, model: modelOverride, effort, auto = false, autoStart = false, probe = false, harness = "claude-code" } = body;
32965
- const requestedHarness = harness === "ohmypi" || harness === "claude-code" || harness === "codex" ? harness : "claude-code";
34263
+ const requestedHarness = harness === "ohmypi" || harness === "claude-code" || harness === "codex" || harness === "acp" ? harness : "claude-code";
34264
+ const workModelRaw = body.workModel;
34265
+ if (typeof workModelRaw === "string" && workModelRaw.trim()) {
34266
+ const staffingProject = (() => {
34267
+ const resolved = resolveProjectFromIssueSync(id);
34268
+ return resolved ? getProjectSync(resolved.projectKey) : null;
34269
+ })();
34270
+ if (!staffingProject) return jsonResponse({ error: `Issue project not found for ${id}` }, { status: 404 });
34271
+ let normalizedWorkModel;
34272
+ try {
34273
+ normalizedWorkModel = requireModelOverrideSync(workModelRaw.trim());
34274
+ } catch (err) {
34275
+ return jsonResponse({ error: err instanceof Error ? err.message : String(err) }, { status: 400 });
34276
+ }
34277
+ yield* Effect.promise(() => updateIssueRecord(staffingProject, id.toUpperCase(), (record) => {
34278
+ record.workModel = normalizedWorkModel;
34279
+ }));
34280
+ console.log(`[start-planning] ${id} work agent model recorded: ${normalizedWorkModel} (planning agent uses the configured default)`);
34281
+ }
32966
34282
  console.log(`[start-planning] START for ${id}, workspaceLocation=${workspaceLocation}, shadow=${shadowMode}`);
32967
34283
  emitActivityEntrySync({
32968
34284
  source: "plan",
@@ -33315,7 +34631,7 @@ function restartFromPlan(options) {
33315
34631
  });
33316
34632
  const resetResult = yield* Effect.promise(async () => {
33317
34633
  try {
33318
- const { runGitResetHard } = await import("./dangerous-git-ops-CT-IypG3.js");
34634
+ const { runGitResetHard } = await import("./dangerous-git-ops-BXqeWVSf.js");
33319
34635
  async function findPlanningCommit(grep, label) {
33320
34636
  try {
33321
34637
  const { stdout } = await execAsync$6(`git log --grep="${grep.replace(/"/g, "\\\"")}" --format=%H -1`, {
@@ -33461,7 +34777,6 @@ function getPlanningState(id) {
33461
34777
  }
33462
34778
  //#endregion
33463
34779
  //#region ../../lib/overdeck/discussions.ts
33464
- init_cost_sync();
33465
34780
  init_pull_requests();
33466
34781
  init_issue_id();
33467
34782
  init_github_pr_lookup();
@@ -33768,7 +35083,7 @@ function closeOutIssue(id, opts = {}) {
33768
35083
  }
33769
35084
  const closeOutResult = yield* Effect.promise(async () => {
33770
35085
  try {
33771
- const { closeOut } = await import("./lifecycle-sycO16hj.js");
35086
+ const { closeOut } = await import("./lifecycle-xmBfK2GJ.js");
33772
35087
  return {
33773
35088
  ok: true,
33774
35089
  result: await Effect.runPromise(closeOut(ctx, {
@@ -33857,7 +35172,7 @@ function bulkCloseOut(body) {
33857
35172
  const invalidIds = issueIds.filter((id) => !isValidIssueId(id));
33858
35173
  if (invalidIds.length > 0) return jsonResponse({ error: `Invalid issue ID format: ${invalidIds.join(", ")}` }, { status: 400 });
33859
35174
  const eventStore = yield* EventStoreService;
33860
- const { closeOut } = yield* Effect.promise(() => import("./lifecycle-sycO16hj.js"));
35175
+ const { closeOut } = yield* Effect.promise(() => import("./lifecycle-xmBfK2GJ.js"));
33861
35176
  const issueDataService = getIssueDataService$5();
33862
35177
  const tasks = [];
33863
35178
  const agentChecks = yield* withConcurrencyLimit(issueIds.map((id) => Effect.promise(async () => {
@@ -34025,7 +35340,7 @@ const execFileAsync$13 = promisify(execFile);
34025
35340
  function getIssueDataService$4() {
34026
35341
  return getSharedIssueService();
34027
35342
  }
34028
- const readJsonBody$16 = Effect.gen(function* () {
35343
+ const readJsonBody$17 = Effect.gen(function* () {
34029
35344
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
34030
35345
  try {
34031
35346
  return text ? JSON.parse(text) : {};
@@ -34083,8 +35398,8 @@ const getIssueShipLogRoute = HttpRouter.add("GET", "/api/issues/:id/ship-log", h
34083
35398
  const id = (yield* HttpRouter.params)["id"] ?? "";
34084
35399
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34085
35400
  return yield* Effect.promise(async () => {
34086
- const { getShipLog } = await import("./ship-log-ClSMIzZX.js");
34087
- const { getReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
35401
+ const { getShipLog } = await import("./ship-log-D9MlVzYU.js");
35402
+ const { getReviewStatusSync } = await import("./review-status-btEYlaxA.js");
34088
35403
  const log = getShipLog(id);
34089
35404
  const rs = getReviewStatusSync(id);
34090
35405
  return jsonResponse({
@@ -34099,8 +35414,8 @@ const getIssueVerificationRoute = HttpRouter.add("GET", "/api/issues/:id/verific
34099
35414
  const id = (yield* HttpRouter.params)["id"] ?? "";
34100
35415
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34101
35416
  return yield* Effect.promise(async () => {
34102
- const { readVerificationArtifact } = await import("./verification-artifact-C-lIHfUa.js");
34103
- const { getReviewStatusSync } = await import("./review-status-C6n6-9f_.js");
35417
+ const { readVerificationArtifact } = await import("./verification-artifact-B3itKTxu.js");
35418
+ const { getReviewStatusSync } = await import("./review-status-btEYlaxA.js");
34104
35419
  const { join } = await import("node:path");
34105
35420
  const resolved = resolveProjectFromIssueSync(id);
34106
35421
  const workspacePath = resolved ? join(resolved.projectPath, "workspaces", `feature-${id.toLowerCase()}`) : null;
@@ -34118,7 +35433,7 @@ const postIssueCloseRoute = HttpRouter.add("POST", "/api/issues/:issueId/close",
34118
35433
  if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34119
35434
  return yield* closeIssueTransition({
34120
35435
  issueId,
34121
- body: yield* readJsonBody$16,
35436
+ body: yield* readJsonBody$17,
34122
35437
  eventStore: yield* EventStoreService
34123
35438
  });
34124
35439
  })));
@@ -34127,7 +35442,7 @@ const postIssueStartPlanningRoute = HttpRouter.add("POST", "/api/issues/:id/star
34127
35442
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34128
35443
  return yield* startPlanningForIssue({
34129
35444
  id,
34130
- body: yield* readJsonBody$16,
35445
+ body: yield* readJsonBody$17,
34131
35446
  eventStore: yield* EventStoreService,
34132
35447
  linear: yield* LinearClient,
34133
35448
  github: yield* GitHubClient,
@@ -34140,7 +35455,7 @@ const postIssueAbortPlanningRoute = HttpRouter.add("POST", "/api/issues/:id/abor
34140
35455
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34141
35456
  return yield* abortPlanningForIssue({
34142
35457
  id,
34143
- body: yield* readJsonBody$16,
35458
+ body: yield* readJsonBody$17,
34144
35459
  lifecycle: yield* IssueLifecycle,
34145
35460
  linear: yield* LinearClient,
34146
35461
  eventStore: yield* EventStoreService
@@ -34150,7 +35465,7 @@ const postIssueCompletePlanningRoute = HttpRouter.add("POST", "/api/issues/:id/c
34150
35465
  const request = yield* HttpServerRequest.HttpServerRequest;
34151
35466
  const id = (yield* HttpRouter.params)["id"] ?? "";
34152
35467
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34153
- const body = yield* readJsonBody$16;
35468
+ const body = yield* readJsonBody$17;
34154
35469
  const eventStore = yield* EventStoreService;
34155
35470
  const linear = yield* LinearClient;
34156
35471
  const lifecycle = yield* IssueLifecycle;
@@ -34176,7 +35491,7 @@ const postIssueResetRoute = HttpRouter.add("POST", "/api/issues/:id/reset", http
34176
35491
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34177
35492
  return yield* resetIssueTransition({
34178
35493
  id,
34179
- body: yield* readJsonBody$16,
35494
+ body: yield* readJsonBody$17,
34180
35495
  eventStore: yield* EventStoreService
34181
35496
  });
34182
35497
  })));
@@ -34200,7 +35515,7 @@ const postIssueCancelRoute = HttpRouter.add("POST", "/api/issues/:id/cancel", ht
34200
35515
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34201
35516
  return yield* cancelIssueTransition({
34202
35517
  id,
34203
- body: yield* readJsonBody$16,
35518
+ body: yield* readJsonBody$17,
34204
35519
  eventStore: yield* EventStoreService
34205
35520
  });
34206
35521
  })));
@@ -34211,7 +35526,7 @@ const postIssueReopenRoute = HttpRouter.add("POST", "/api/issues/:id/reopen", ht
34211
35526
  if (authError) return authError;
34212
35527
  return yield* reopenIssueTransition({
34213
35528
  id,
34214
- body: yield* readJsonBody$16,
35529
+ body: yield* readJsonBody$17,
34215
35530
  lifecycle: yield* IssueLifecycle,
34216
35531
  linear: yield* LinearClient,
34217
35532
  eventStore: yield* EventStoreService
@@ -34231,7 +35546,7 @@ const postIssueMoveStatusRoute = HttpRouter.add("POST", "/api/issues/:id/move-st
34231
35546
  if (!parseIssueIdSync(id)) return jsonResponse({ error: "Invalid issue ID" }, { status: 400 });
34232
35547
  return yield* moveIssueStatus({
34233
35548
  id,
34234
- body: yield* readJsonBody$16,
35549
+ body: yield* readJsonBody$17,
34235
35550
  eventStore: yield* EventStoreService,
34236
35551
  lifecycle: yield* IssueLifecycle
34237
35552
  });
@@ -34243,7 +35558,7 @@ const postIssueCleanupWorkspaceRoute = HttpRouter.add("POST", "/api/issues/:id/c
34243
35558
  })));
34244
35559
  const postIssueDeepWipeRoute = HttpRouter.add("POST", "/api/issues/:id/deep-wipe", httpHandler(Effect.gen(function* () {
34245
35560
  const id = (yield* HttpRouter.params)["id"] ?? "";
34246
- const body = yield* readJsonBody$16;
35561
+ const body = yield* readJsonBody$17;
34247
35562
  const eventStore = yield* EventStoreService;
34248
35563
  return yield* Effect.promise(() => deepWipeIssue(id, body, eventStore));
34249
35564
  })));
@@ -34299,7 +35614,7 @@ const postIssueTaskInspectRoute = HttpRouter.add("POST", "/api/issues/:id/tasks/
34299
35614
  return yield* inspectIssueTask({
34300
35615
  id: (params["id"] ?? "").toUpperCase(),
34301
35616
  itemId: params["itemId"] ?? "",
34302
- body: yield* readJsonBody$16
35617
+ body: yield* readJsonBody$17
34303
35618
  });
34304
35619
  })));
34305
35620
  const getIssuePlanningStateRoute = HttpRouter.add("GET", "/api/issues/:id/planning-state", httpHandler(Effect.gen(function* () {
@@ -34418,6 +35733,21 @@ const getIssueCostsRoute = HttpRouter.add("GET", "/api/issues/:id/costs", httpHa
34418
35733
  const getResourceAllocatedIssuesRoute = HttpRouter.add("GET", "/api/issues/resource-allocated", httpHandler(Effect.gen(function* () {
34419
35734
  return yield* getResourceAllocatedIssues();
34420
35735
  })));
35736
+ const getIssueResourceDetailsRoute = HttpRouter.add("GET", "/api/issues/:id/resource-details", httpHandler(Effect.gen(function* () {
35737
+ return yield* getIssueResourceDetails((yield* HttpRouter.params)["id"] ?? "");
35738
+ })));
35739
+ const issuesRouteLayer = Layer.mergeAll(getIssuesRoute, getIssueAnalyzeRoute, getIssueShipLogRoute, getIssueVerificationRoute, postIssueCloseRoute, postIssueStartPlanningRoute, postIssueAbortPlanningRoute, postIssueCompletePlanningRoute, postIssueAbortRoute, postIssueResetRoute, postIssueResetToPlannedRoute, postIssueCancelRoute, postIssueReopenRoute, postIssueRestartFromPlanRoute, postIssueMoveStatusRoute, postIssueCleanupWorkspaceRoute, postIssueDeepWipeRoute, postIssueCopySettingsRoute, postIssueCloseOutRoute, postIssuesBulkCloseOutRoute, getIssueTasksRoute, postIssueTaskInspectRoute, getIssuePlanningStateRoute, postIssueGenerateTasksRoute, getIssueCostsRoute, getResourceAllocatedIssuesRoute, getIssueResourceDetailsRoute, getIssuePrRoute, getIssuePrDiffRoute, getIssuePrDetailsRoute, getIssueCheckRunsRoute, getIssueDiscussionsRoute);
35740
+ //#endregion
35741
+ //#region routes/pipeline-membership.ts
35742
+ /**
35743
+ * Pipeline-membership route module — the dashboard read/retry doors over the
35744
+ * cached membership snapshots (docs/PIPELINE-MEMBERSHIP.md).
35745
+ *
35746
+ * Endpoints:
35747
+ * GET /api/pipeline/membership?project=<key> — snapshot read only
35748
+ * POST /api/pipeline/membership/refresh?project=<key> — operator retry (PAN-2972)
35749
+ */
35750
+ init_projects();
34421
35751
  const getPipelineMembershipRoute = HttpRouter.add("GET", "/api/pipeline/membership", httpHandler(Effect.gen(function* () {
34422
35752
  const request = yield* HttpServerRequest.HttpServerRequest;
34423
35753
  const projectKey = new URL(request.url, "http://localhost").searchParams.get("project");
@@ -34426,12 +35756,22 @@ const getPipelineMembershipRoute = HttpRouter.add("GET", "/api/pipeline/membersh
34426
35756
  if (!project) return jsonResponse({ error: `Project not found: ${projectKey}` }, { status: 404 });
34427
35757
  const snapshot = readPipelineMembershipSnapshotsForProjects([project])[0];
34428
35758
  if (snapshot?.memberships) return jsonResponse(snapshot.memberships);
34429
- return jsonResponse({ error: "Pipeline membership snapshot is loading" }, { status: 503 });
35759
+ return jsonResponse({ error: snapshot?.error instanceof Error ? snapshot.error.message : "Pipeline membership snapshot is loading" }, { status: 503 });
34430
35760
  })));
34431
- const getIssueResourceDetailsRoute = HttpRouter.add("GET", "/api/issues/:id/resource-details", httpHandler(Effect.gen(function* () {
34432
- return yield* getIssueResourceDetails((yield* HttpRouter.params)["id"] ?? "");
35761
+ const postPipelineMembershipRefreshRoute = HttpRouter.add("POST", "/api/pipeline/membership/refresh", httpHandler(Effect.gen(function* () {
35762
+ const request = yield* HttpServerRequest.HttpServerRequest;
35763
+ const authError = rejectUnsafeDashboardMutationRequest(request);
35764
+ if (authError) return authError;
35765
+ const projectKey = new URL(request.url, "http://localhost").searchParams.get("project");
35766
+ if (!projectKey) return jsonResponse({ error: "project query parameter is required" }, { status: 400 });
35767
+ const project = getProjectSync(projectKey);
35768
+ if (!project) return jsonResponse({ error: `Project not found: ${projectKey}` }, { status: 404 });
35769
+ yield* Effect.promise(() => refreshMembershipSnapshotsForProjects([project]));
35770
+ const snapshot = readPipelineMembershipSnapshotsForProjects([project])[0];
35771
+ if (snapshot?.memberships) return jsonResponse(snapshot.memberships);
35772
+ return jsonResponse({ error: snapshot?.error instanceof Error ? snapshot.error.message : "Pipeline membership refresh failed" }, { status: 502 });
34433
35773
  })));
34434
- const issuesRouteLayer = Layer.mergeAll(getIssuesRoute, getIssueAnalyzeRoute, getIssueShipLogRoute, getIssueVerificationRoute, postIssueCloseRoute, postIssueStartPlanningRoute, postIssueAbortPlanningRoute, postIssueCompletePlanningRoute, postIssueAbortRoute, postIssueResetRoute, postIssueResetToPlannedRoute, postIssueCancelRoute, postIssueReopenRoute, postIssueRestartFromPlanRoute, postIssueMoveStatusRoute, postIssueCleanupWorkspaceRoute, postIssueDeepWipeRoute, postIssueCopySettingsRoute, postIssueCloseOutRoute, postIssuesBulkCloseOutRoute, getIssueTasksRoute, postIssueTaskInspectRoute, getIssuePlanningStateRoute, postIssueGenerateTasksRoute, getIssueCostsRoute, getResourceAllocatedIssuesRoute, getPipelineMembershipRoute, getIssueResourceDetailsRoute, getIssuePrRoute, getIssuePrDiffRoute, getIssuePrDetailsRoute, getIssueCheckRunsRoute, getIssueDiscussionsRoute);
35774
+ const pipelineMembershipRouteLayer = Layer.mergeAll(getPipelineMembershipRoute, postPipelineMembershipRefreshRoute);
34435
35775
  //#endregion
34436
35776
  //#region routes/costs.ts
34437
35777
  /**
@@ -34968,7 +36308,7 @@ function reloadDurableCloisterConfig(deps = {}) {
34968
36308
  */
34969
36309
  init_config$1();
34970
36310
  init_agents$1();
34971
- const readJsonBody$15 = Effect.gen(function* () {
36311
+ const readJsonBody$16 = Effect.gen(function* () {
34972
36312
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
34973
36313
  try {
34974
36314
  return text ? JSON.parse(text) : {};
@@ -35071,7 +36411,7 @@ const getCloisterConfigRoute = HttpRouter.add("GET", "/api/cloister/config", htt
35071
36411
  catch: (err) => new Error(err instanceof Error ? err.message : String(err))
35072
36412
  })));
35073
36413
  const putCloisterConfigRoute = HttpRouter.add("PUT", "/api/cloister/config", httpHandler(Effect.gen(function* () {
35074
- const updates = yield* readJsonBody$15;
36414
+ const updates = yield* readJsonBody$16;
35075
36415
  yield* Effect.try({
35076
36416
  try: () => {
35077
36417
  saveCloisterConfigSync(updates);
@@ -36444,7 +37784,7 @@ const getStackTeardownEstimateRoute = HttpRouter.add("GET", "/api/resources/stac
36444
37784
  })));
36445
37785
  const postStackTeardownRoute = HttpRouter.add("POST", "/api/resources/stacks/:issueId/teardown", httpHandler(Effect.gen(function* () {
36446
37786
  const params = yield* HttpRouter.params;
36447
- const body = yield* readJsonBody$14;
37787
+ const body = yield* readJsonBody$15;
36448
37788
  return yield* postStackTeardownEffect(params["issueId"] ?? "", body);
36449
37789
  })));
36450
37790
  function getStackTeardownEstimateEffect(issue) {
@@ -36618,7 +37958,7 @@ function lines(value) {
36618
37958
  function isDockerIdentifier(value) {
36619
37959
  return /^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,127}$/.test(value);
36620
37960
  }
36621
- const readJsonBody$14 = Effect.gen(function* () {
37961
+ const readJsonBody$15 = Effect.gen(function* () {
36622
37962
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
36623
37963
  try {
36624
37964
  return text ? JSON.parse(text) : {};
@@ -36990,7 +38330,7 @@ function validateModelRef(fieldPath, ref, effectiveWorkhorses, errors, warnings,
36990
38330
  }
36991
38331
  function validateRoleFields(fieldPath, roleConfig, errors) {
36992
38332
  const harness = roleConfig.harness;
36993
- if (harness !== void 0 && harness !== null && harness !== "" && harness !== "claude-code" && harness !== "ohmypi" && harness !== "codex") errors.push(`${fieldPath}.harness must be claude-code, ohmypi, codex, null, or empty string`);
38333
+ if (harness !== void 0 && harness !== null && harness !== "" && harness !== "claude-code" && harness !== "ohmypi" && harness !== "codex" && harness !== "acp") errors.push(`${fieldPath}.harness must be claude-code, ohmypi, codex, acp, null, or empty string`);
36994
38334
  const effort = roleConfig.effort;
36995
38335
  if (effort !== void 0 && !ROLE_EFFORTS.includes(effort)) errors.push(`${fieldPath}.effort must be one of ${ROLE_EFFORTS.join(", ")}`);
36996
38336
  const maxAgents = roleConfig.maxAgents;
@@ -37449,7 +38789,7 @@ function validateSettingsApi(settings) {
37449
38789
  errors.push(`Unknown provider harness entry "${provider}"`);
37450
38790
  continue;
37451
38791
  }
37452
- if (harness !== void 0 && harness !== "" && harness !== "claude-code" && harness !== "ohmypi" && harness !== "codex") errors.push(`models.provider_harnesses.${provider} must be claude-code, ohmypi, codex, or empty string`);
38792
+ if (harness !== void 0 && harness !== "" && harness !== "claude-code" && harness !== "ohmypi" && harness !== "codex" && harness !== "acp") errors.push(`models.provider_harnesses.${provider} must be claude-code, ohmypi, codex, acp, or empty string`);
37453
38793
  }
37454
38794
  if (settings.models?.overrides) {
37455
38795
  const validModelIds = Object.keys(MODEL_CAPABILITIES);
@@ -38002,7 +39342,7 @@ function getProjectPath$1(issuePrefix) {
38002
39342
  }
38003
39343
  return setProjectPathCache(issuePrefix, join(homedir$1(), "Projects"));
38004
39344
  }
38005
- const readJsonBody$13 = Effect.gen(function* () {
39345
+ const readJsonBody$14 = Effect.gen(function* () {
38006
39346
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
38007
39347
  try {
38008
39348
  return text ? JSON.parse(text) : {};
@@ -38052,21 +39392,22 @@ async function fetchActivityDataWithContext(issueId, context = {}) {
38052
39392
  const planningAgentId = `planning-${issueLower}`;
38053
39393
  const planRunAgentId = `agent-${issueLower}-plan`;
38054
39394
  const knowledgeAgentId = `agent-${issueLower}-knowledge`;
39395
+ const strikeAgentId = `strike-${issueLower}`;
38055
39396
  const agentsDir = join(homedir$1(), ".overdeck", "agents");
38056
39397
  let hasPlanningSection = false;
38057
39398
  for (const checkId of [
38058
39399
  planningAgentId,
38059
39400
  agentId,
38060
39401
  planRunAgentId,
38061
- knowledgeAgentId
39402
+ knowledgeAgentId,
39403
+ strikeAgentId
38062
39404
  ]) {
38063
39405
  const agentDir = join(agentsDir, checkId);
38064
- if (!await pathExists$4(agentDir)) continue;
38065
39406
  const state = getAgentStateSync(checkId);
38066
39407
  if (!state) continue;
38067
39408
  try {
38068
39409
  const isPlanning = checkId.startsWith("planning-") || state.role === "plan";
38069
- const sectionType = isPlanning ? "planning" : checkId.endsWith("-knowledge") ? "knowledge" : "work";
39410
+ const sectionType = isPlanning ? "planning" : checkId.startsWith("strike-") ? "strike" : checkId.endsWith("-knowledge") ? "knowledge" : "work";
38070
39411
  if (isPlanning) hasPlanningSection = true;
38071
39412
  let transcript = "";
38072
39413
  let transcriptFromPane = false;
@@ -38089,7 +39430,7 @@ async function fetchActivityDataWithContext(issueId, context = {}) {
38089
39430
  const projectedAwaitingInput = awaitingInputFromProjection$1(checkId, context.agentSnapshotsById);
38090
39431
  const awaitingInput = projectedAwaitingInput !== void 0 ? projectedAwaitingInput : transcriptFromPane ? detectAwaitingInputFromPaneSync(transcript, { isPlanning }) : tmuxSessionNames.has(checkId) ? await Effect.runPromise(detectAwaitingInputForAgent(checkId, { isPlanning })) : null;
38091
39432
  const jsonlPath = await resolveJsonlPath(checkId, workspacePath);
38092
- const exposeInteractiveTerminal = sectionType === "work" || sectionType === "planning";
39433
+ const exposeInteractiveTerminal = sectionType === "work" || sectionType === "planning" || sectionType === "strike";
38093
39434
  const tmuxAlive = tmuxSessionNames.has(checkId);
38094
39435
  const endedAt = rtState?.state === "suspended" || presence === "ended" || !!state.stoppedAt && !tmuxAlive ? state.stoppedAt || state.lastActivity || state.startedAt : void 0;
38095
39436
  sections.push({
@@ -38690,7 +40031,7 @@ Be specific: reference actual file names, function names, requirement text, disc
38690
40031
  const { command: cliCmd, args: cliArgs } = getAgentCommandSync(statusModelId);
38691
40032
  const modelFlag = cliArgs.length > 0 ? ` ${cliArgs.join(" ")}` : "";
38692
40033
  const promptFile = join(planningDir, ".status-review-prompt.tmp");
38693
- const { getProviderForModelSync, getProviderEnvSync } = await import("./providers-DKkBXhxU.js");
40034
+ const { getProviderForModelSync, getProviderEnvSync } = await import("./providers-u4Ga0jOr.js");
38694
40035
  let providerEnvStr = "";
38695
40036
  let providerEnv = {};
38696
40037
  const statusProvider = getProviderForModelSync(statusModelId);
@@ -38765,7 +40106,7 @@ ${issueContext ? `## Issue Tracker Data\n${issueContext}\n` : ""}---
38765
40106
  }
38766
40107
  const postMissionControlUploadRoute = HttpRouter.add("POST", "/api/command-deck/planning/:issueId/upload", httpHandler(Effect.gen(function* () {
38767
40108
  const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
38768
- const { type, filename, content } = yield* readJsonBody$13;
40109
+ const { type, filename, content } = yield* readJsonBody$14;
38769
40110
  const issueLower = issueId.toLowerCase();
38770
40111
  const issuePrefix = extractPrefixSync(issueId) ?? issueId.split("-")[0];
38771
40112
  if (!type || !filename || !content) return jsonResponse({ error: "type, filename, and content are required" }, { status: 400 });
@@ -38773,7 +40114,7 @@ const postMissionControlUploadRoute = HttpRouter.add("POST", "/api/command-deck/
38773
40114
  let safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "-");
38774
40115
  let processedContent = content;
38775
40116
  if (safeName.endsWith(".vtt")) {
38776
- const { vttToMarkdown } = yield* Effect.promise(() => import("./vtt-parser-DKpNNW5i.js"));
40117
+ const { vttToMarkdown } = yield* Effect.promise(() => import("./vtt-parser-DYPbKcIJ.js"));
38777
40118
  processedContent = vttToMarkdown(content);
38778
40119
  safeName = safeName.replace(/\.vtt$/, ".md");
38779
40120
  }
@@ -38794,7 +40135,7 @@ const postMissionControlUploadRoute = HttpRouter.add("POST", "/api/command-deck/
38794
40135
  const postMissionControlSyncDiscussionsRoute = HttpRouter.add("POST", "/api/command-deck/planning/:issueId/sync-discussions", httpHandler(Effect.gen(function* () {
38795
40136
  const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
38796
40137
  if (!parseIssueIdSync(issueId)) return jsonResponse({ error: "Invalid issue id: " + issueId }, { status: 400 });
38797
- const body = yield* readJsonBody$13;
40138
+ const body = yield* readJsonBody$14;
38798
40139
  const linear = yield* LinearClient;
38799
40140
  const { tracker } = body;
38800
40141
  const issueLower = issueId.toLowerCase();
@@ -38940,7 +40281,7 @@ const postMissionControlSyncDiscussionsRoute = HttpRouter.add("POST", "/api/comm
38940
40281
  })));
38941
40282
  const postMissionControlPlanningInitRoute = HttpRouter.add("POST", "/api/command-deck/planning/:issueId/init", httpHandler(Effect.gen(function* () {
38942
40283
  const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
38943
- const body = yield* readJsonBody$13;
40284
+ const body = yield* readJsonBody$14;
38944
40285
  const eventStore = yield* EventStoreService;
38945
40286
  const { shadow } = body;
38946
40287
  const issueLower = issueId.toLowerCase();
@@ -39025,7 +40366,7 @@ async function listRemoteWorkspaceMetadata() {
39025
40366
  }
39026
40367
  return workspaces;
39027
40368
  }
39028
- const readJsonBody$12 = Effect.gen(function* () {
40369
+ const readJsonBody$13 = Effect.gen(function* () {
39029
40370
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
39030
40371
  try {
39031
40372
  return text ? JSON.parse(text) : {};
@@ -39140,7 +40481,7 @@ const stopRemoteWorkspaceRoute = HttpRouter.add("POST", "/api/remote/workspaces/
39140
40481
  })));
39141
40482
  const startRemoteAgentRoute = HttpRouter.add("POST", "/api/remote/workspaces/:issueId/agent/start", httpHandler(Effect.gen(function* () {
39142
40483
  const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
39143
- const body = yield* readJsonBody$12;
40484
+ const body = yield* readJsonBody$13;
39144
40485
  const eventStore = yield* EventStoreService;
39145
40486
  const { prompt, model } = body;
39146
40487
  const metadata = yield* Effect.promise(() => loadRemoteWorkspaceMetadata(issueId));
@@ -39204,7 +40545,7 @@ const getRemoteAgentOutputRoute = HttpRouter.add("GET", "/api/remote/workspaces/
39204
40545
  })));
39205
40546
  const tellRemoteAgentRoute = HttpRouter.add("POST", "/api/remote/workspaces/:issueId/agent/tell", httpHandler(Effect.gen(function* () {
39206
40547
  const issueId = (yield* HttpRouter.params)["issueId"] ?? "";
39207
- const { message } = yield* readJsonBody$12;
40548
+ const { message } = yield* readJsonBody$13;
39208
40549
  if (!message) return jsonResponse({ error: "Message is required" }, { status: 400 });
39209
40550
  const metadata = yield* Effect.promise(() => loadRemoteWorkspaceMetadata(issueId));
39210
40551
  if (!metadata) return jsonResponse({ error: "Remote workspace not found" }, { status: 404 });
@@ -39240,7 +40581,8 @@ async function buildHarnessPolicyDecisions(models, resolveAuthMode) {
39240
40581
  decisions[model] = {
39241
40582
  "claude-code": canUseHarnessSync("claude-code", model, authMode),
39242
40583
  ohmypi: canUseHarnessSync("ohmypi", model, authMode),
39243
- codex: canUseHarnessSync("codex", model, authMode)
40584
+ codex: canUseHarnessSync("codex", model, authMode),
40585
+ acp: canUseHarnessSync("acp", model, authMode)
39244
40586
  };
39245
40587
  }
39246
40588
  return decisions;
@@ -40033,7 +41375,7 @@ const state$1 = {
40033
41375
  queue: [],
40034
41376
  processing: false
40035
41377
  };
40036
- function optionalString(value) {
41378
+ function optionalString$1(value) {
40037
41379
  return typeof value === "string" ? value : void 0;
40038
41380
  }
40039
41381
  function eventPriority(event) {
@@ -40062,9 +41404,9 @@ async function speakActivityTts(event) {
40062
41404
  try {
40063
41405
  if (await Effect.runPromise(resolveAndSpeak({
40064
41406
  text: payload.utterance,
40065
- source: optionalString(payload.source),
40066
- eventType: optionalString(payload.eventType),
40067
- issueId: optionalString(payload.issueId),
41407
+ source: optionalString$1(payload.source),
41408
+ eventType: optionalString$1(payload.eventType),
41409
+ issueId: optionalString$1(payload.issueId),
40068
41410
  priority: typeof payload.priority === "number" ? payload.priority : void 0
40069
41411
  }, { config })) === "daemon-unavailable") console.warn("[tts-playback] TTS daemon unavailable");
40070
41412
  } catch (error) {
@@ -41953,6 +43295,12 @@ function prepareStmts(db) {
41953
43295
  DELETE FROM chunks_vec WHERE rowid IN (
41954
43296
  SELECT rowid FROM chunks WHERE session_id = ?
41955
43297
  )
43298
+ `),
43299
+ listFileCursors: db.prepare(`
43300
+ SELECT file_path FROM file_cursors
43301
+ `),
43302
+ deleteCursor: db.prepare(`
43303
+ DELETE FROM file_cursors WHERE file_path = ?
41956
43304
  `)
41957
43305
  };
41958
43306
  }
@@ -42002,6 +43350,8 @@ function openEmbeddingsDb(dbPath, dimensions, options = {}) {
42002
43350
  lastIndexedAt: null
42003
43351
  }),
42004
43352
  deleteSession: () => {},
43353
+ listFileCursors: () => [],
43354
+ deleteCursor: () => {},
42005
43355
  close: () => {}
42006
43356
  });
42007
43357
  if (!Number.isInteger(dimensions) || dimensions <= 0) return unavailable(`Invalid embedding dimensions: ${dimensions}`);
@@ -42090,6 +43440,12 @@ function openEmbeddingsDb(dbPath, dimensions, options = {}) {
42090
43440
  stmts.deleteEmbeddingsBySession.run(sessionId);
42091
43441
  stmts.deleteChunksBySession.run(sessionId);
42092
43442
  },
43443
+ listFileCursors() {
43444
+ return stmts.listFileCursors.all().map((row) => row.file_path);
43445
+ },
43446
+ deleteCursor(filePath) {
43447
+ stmts.deleteCursor.run(filePath);
43448
+ },
42093
43449
  close() {
42094
43450
  db.close();
42095
43451
  }
@@ -42510,6 +43866,7 @@ const EMPTY_RESULT = {
42510
43866
  filesIndexed: 0,
42511
43867
  chunksIndexed: 0,
42512
43868
  chunksSkipped: 0,
43869
+ sessionsPruned: 0,
42513
43870
  errors: [],
42514
43871
  disabled: false
42515
43872
  };
@@ -42547,6 +43904,7 @@ async function indexConversationSearch(options = {}) {
42547
43904
  };
42548
43905
  }
42549
43906
  try {
43907
+ result.sessionsPruned = await pruneStaleIndexedSessions(owned.db, files);
42550
43908
  let processed = 0;
42551
43909
  for (const filePath of files) {
42552
43910
  throwIfAborted(options.signal);
@@ -42776,6 +44134,25 @@ async function discoverConversationJsonlFiles(roots, signal) {
42776
44134
  for (const root of roots) await collectJsonlFiles(root, files, signal);
42777
44135
  return files.sort();
42778
44136
  }
44137
+ /**
44138
+ * Drop index rows whose JSONL transcript no longer exists on disk. Without this,
44139
+ * chunks and cursors outlive deleted sessions forever and palette search surfaces
44140
+ * hits that 404 when opened. Cursor paths are absolute, so the check is exact;
44141
+ * a session id still present in the discovered set keeps its chunks (the file was
44142
+ * moved or renamed, not deleted).
44143
+ */
44144
+ async function pruneStaleIndexedSessions(db, files) {
44145
+ const liveSessionIds = new Set(files.map(sessionIdFromPath));
44146
+ let pruned = 0;
44147
+ for (const cursorPath of db.listFileCursors()) {
44148
+ if (await promises$1.stat(cursorPath).then(() => true, () => false)) continue;
44149
+ db.deleteCursor(cursorPath);
44150
+ if (liveSessionIds.has(sessionIdFromPath(cursorPath))) continue;
44151
+ db.deleteSession(sessionIdFromPath(cursorPath));
44152
+ pruned += 1;
44153
+ }
44154
+ return pruned;
44155
+ }
42779
44156
  async function collectJsonlFiles(dir, files, signal) {
42780
44157
  throwIfAborted(signal);
42781
44158
  let entries;
@@ -42831,6 +44208,18 @@ const DEFAULT_DEBOUNCE_MS = 250;
42831
44208
  const DEFAULT_WRITE_STABILITY_MS = 250;
42832
44209
  const DEFAULT_WRITE_POLL_MS = 50;
42833
44210
  let activeWatcher = null;
44211
+ /** Drop a deleted transcript's chunks and indexing cursor so search stops surfacing it. */
44212
+ async function defaultRemoveFile(options) {
44213
+ const { filePath, config } = options;
44214
+ const db = openEmbeddingsDb(config.dbPath, dimensionsForModel(config.model));
44215
+ try {
44216
+ if (!db.available) return;
44217
+ db.deleteCursor(filePath);
44218
+ db.deleteSession(sessionIdFromPath(filePath));
44219
+ } finally {
44220
+ db.close();
44221
+ }
44222
+ }
42834
44223
  function watcherSignature(config, roots) {
42835
44224
  return JSON.stringify({
42836
44225
  enabled: config.enabled,
@@ -42848,6 +44237,7 @@ var ConversationSearchWatcher = class {
42848
44237
  watchFactory;
42849
44238
  indexAll;
42850
44239
  indexFile;
44240
+ removeFile;
42851
44241
  maxConcurrentIndexers;
42852
44242
  log;
42853
44243
  signature;
@@ -42869,6 +44259,7 @@ var ConversationSearchWatcher = class {
42869
44259
  this.watchFactory = options.watchFactory ?? ((paths, watchOptions) => watch$2(paths, watchOptions));
42870
44260
  this.indexAll = options.indexAll ?? indexConversationSearch;
42871
44261
  this.indexFile = options.indexFile ?? indexConversationFile;
44262
+ this.removeFile = options.removeFile ?? defaultRemoveFile;
42872
44263
  this.maxConcurrentIndexers = Math.max(1, options.maxConcurrentIndexers ?? 1);
42873
44264
  this.log = options.log ?? console;
42874
44265
  }
@@ -42884,7 +44275,10 @@ var ConversationSearchWatcher = class {
42884
44275
  }).then((result) => {
42885
44276
  if (signal.aborted || this.stopped) return;
42886
44277
  if (result.disabled) this.log.warn(`[conversation-search] startup index skipped: ${result.unavailableReason ?? "disabled"}`);
42887
- else this.log.log(`[conversation-search] startup indexed ${result.chunksIndexed} chunk${result.chunksIndexed === 1 ? "" : "s"} across ${result.filesScanned} file${result.filesScanned === 1 ? "" : "s"}`);
44278
+ else {
44279
+ const prunedNote = result.sessionsPruned > 0 ? `, pruned ${result.sessionsPruned} stale session${result.sessionsPruned === 1 ? "" : "s"}` : "";
44280
+ this.log.log(`[conversation-search] startup indexed ${result.chunksIndexed} chunk${result.chunksIndexed === 1 ? "" : "s"} across ${result.filesScanned} file${result.filesScanned === 1 ? "" : "s"}${prunedNote}`);
44281
+ }
42888
44282
  this.log.log(`[boot-timing] conversation-search startup index completed at +${Math.round(performance.now() - startupT0)}ms`);
42889
44283
  }).catch((error) => {
42890
44284
  if (!isAbortError(error)) this.log.warn("[conversation-search] startup index failed:", error);
@@ -42900,7 +44294,7 @@ var ConversationSearchWatcher = class {
42900
44294
  pollInterval: DEFAULT_WRITE_POLL_MS
42901
44295
  }
42902
44296
  });
42903
- this.watcher.on("add", (filePath) => this.schedule(filePath)).on("change", (filePath) => this.schedule(filePath)).on("error", (error) => this.log.warn("[conversation-search] watcher error:", error));
44297
+ this.watcher.on("add", (filePath) => this.schedule(filePath)).on("change", (filePath) => this.schedule(filePath)).on("unlink", (filePath) => this.remove(filePath)).on("error", (error) => this.log.warn("[conversation-search] watcher error:", error));
42904
44298
  }
42905
44299
  async stop() {
42906
44300
  if (this.stopped) return;
@@ -42935,6 +44329,23 @@ var ConversationSearchWatcher = class {
42935
44329
  this.queued.add(filePath);
42936
44330
  this.drainQueue();
42937
44331
  }
44332
+ remove(filePath) {
44333
+ if (this.stopped || !filePath.endsWith(".jsonl")) return;
44334
+ const timer = this.pending.get(filePath);
44335
+ if (timer) clearTimeout(timer);
44336
+ this.pending.delete(filePath);
44337
+ this.queued.delete(filePath);
44338
+ this.rerun.delete(filePath);
44339
+ const task = Promise.resolve().then(() => this.removeFile({
44340
+ filePath,
44341
+ config: this.config
44342
+ })).catch((error) => {
44343
+ this.log.warn(`[conversation-search] failed to prune deleted session ${filePath}:`, error);
44344
+ }).finally(() => {
44345
+ this.activeTasks.delete(task);
44346
+ });
44347
+ this.activeTasks.add(task);
44348
+ }
42938
44349
  drainQueue() {
42939
44350
  if (this.stopped || this.startupTask) return;
42940
44351
  const signal = this.abortController?.signal;
@@ -43275,7 +44686,7 @@ function consumeReindexConfirmationNonce(nonce, estimatedUsd) {
43275
44686
  reindexConfirmationNonces.delete(nonce);
43276
44687
  return !!entry && entry.expiresAt > Date.now() && Math.abs(entry.estimatedUsd - estimatedUsd) < 1e-6;
43277
44688
  }
43278
- const readJsonBody$11 = Effect.gen(function* () {
44689
+ const readJsonBody$12 = Effect.gen(function* () {
43279
44690
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
43280
44691
  try {
43281
44692
  return text ? JSON.parse(text) : {};
@@ -43348,7 +44759,7 @@ const getOpenAIAuthRoute = HttpRouter.add("GET", "/api/settings/openai-auth", ht
43348
44759
  return jsonResponse(yield* getOpenAIAuthStatus());
43349
44760
  })));
43350
44761
  const postTestApiKeyRoute = HttpRouter.add("POST", "/api/settings/test-api-key", httpHandler(Effect.gen(function* () {
43351
- const { provider, apiKey, model } = yield* readJsonBody$11;
44762
+ const { provider, apiKey, model } = yield* readJsonBody$12;
43352
44763
  if (!provider || !apiKey) return jsonResponse({ error: "Provider and apiKey are required" }, { status: 400 });
43353
44764
  return yield* Effect.promise(async () => {
43354
44765
  let success = false;
@@ -43658,7 +45069,7 @@ const postTestApiKeyRoute = HttpRouter.add("POST", "/api/settings/test-api-key",
43658
45069
  });
43659
45070
  })));
43660
45071
  const postValidateApiKeyRoute = HttpRouter.add("POST", "/api/settings/validate-api-key", httpHandler(Effect.gen(function* () {
43661
- const { provider, apiKey } = yield* readJsonBody$11;
45072
+ const { provider, apiKey } = yield* readJsonBody$12;
43662
45073
  if (!provider || !apiKey) return jsonResponse({ error: "Provider and apiKey are required" }, { status: 400 });
43663
45074
  if (![
43664
45075
  "openai",
@@ -43893,7 +45304,7 @@ const getConversationSearchReindexEstimateRoute = HttpRouter.add("GET", "/api/se
43893
45304
  const postConversationSearchReindexRoute = HttpRouter.add("POST", "/api/settings/conversation-search/reindex", httpHandler(Effect.gen(function* () {
43894
45305
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
43895
45306
  if (authError) return authError;
43896
- const body = yield* readJsonBody$11;
45307
+ const body = yield* readJsonBody$12;
43897
45308
  return yield* Effect.promise(async () => {
43898
45309
  if (activeConversationSearchReindex) return jsonResponse({ error: "Conversation search reindex already in progress" }, { status: 409 });
43899
45310
  const job = (async () => {
@@ -43943,7 +45354,7 @@ const getConversationSearchReindexProgressRoute = HttpRouter.add("GET", "/api/se
43943
45354
  return jsonResponse(conversationReindexProgress);
43944
45355
  })));
43945
45356
  const putSettingsRoute = HttpRouter.add("PUT", "/api/settings", httpHandler(Effect.gen(function* () {
43946
- const body = yield* readJsonBody$11;
45357
+ const body = yield* readJsonBody$12;
43947
45358
  return yield* Effect.promise(async () => {
43948
45359
  try {
43949
45360
  const newSettings = body;
@@ -43964,7 +45375,7 @@ const putSettingsRoute = HttpRouter.add("PUT", "/api/settings", httpHandler(Effe
43964
45375
  });
43965
45376
  })));
43966
45377
  const putUiThemeRoute = HttpRouter.add("PUT", "/api/settings/ui-theme", httpHandler(Effect.gen(function* () {
43967
- const body = yield* readJsonBody$11;
45378
+ const body = yield* readJsonBody$12;
43968
45379
  return yield* Effect.promise(async () => {
43969
45380
  const theme = body?.theme;
43970
45381
  if (theme !== "light" && theme !== "dark") return jsonResponse({ error: "theme must be 'light' or 'dark'" }, { status: 400 });
@@ -43979,7 +45390,7 @@ const getOpenRouterModelsRoute = HttpRouter.add("GET", "/api/settings/openrouter
43979
45390
  });
43980
45391
  })));
43981
45392
  const putOpenRouterFavoritesRoute = HttpRouter.add("PUT", "/api/settings/openrouter/favorites", httpHandler(Effect.gen(function* () {
43982
- const { favorites } = yield* readJsonBody$11;
45393
+ const { favorites } = yield* readJsonBody$12;
43983
45394
  if (!Array.isArray(favorites)) return jsonResponse({ error: "favorites must be an array of model IDs" }, { status: 400 });
43984
45395
  const modelIds = favorites.filter((f) => typeof f === "string");
43985
45396
  return yield* Effect.promise(async () => {
@@ -43995,7 +45406,7 @@ const putOpenRouterFavoritesRoute = HttpRouter.add("PUT", "/api/settings/openrou
43995
45406
  });
43996
45407
  })));
43997
45408
  const putOpenRouterApiKeyRoute = HttpRouter.add("PUT", "/api/settings/openrouter/api-key", httpHandler(Effect.gen(function* () {
43998
- const { apiKey } = yield* readJsonBody$11;
45409
+ const { apiKey } = yield* readJsonBody$12;
43999
45410
  if (apiKey !== void 0 && typeof apiKey !== "string") return jsonResponse({ error: "apiKey must be a string when provided" }, { status: 400 });
44000
45411
  return yield* Effect.promise(async () => {
44001
45412
  try {
@@ -44010,7 +45421,7 @@ const putOpenRouterApiKeyRoute = HttpRouter.add("PUT", "/api/settings/openrouter
44010
45421
  });
44011
45422
  })));
44012
45423
  const postOpenRouterTestKeyRoute = HttpRouter.add("POST", "/api/settings/openrouter/test-key", httpHandler(Effect.gen(function* () {
44013
- const { apiKey } = yield* readJsonBody$11;
45424
+ const { apiKey } = yield* readJsonBody$12;
44014
45425
  if (!apiKey) return jsonResponse({ error: "apiKey is required" }, { status: 400 });
44015
45426
  return jsonResponse(yield* (yield* OpenRouterService).validateApiKey(apiKey));
44016
45427
  })));
@@ -44063,7 +45474,7 @@ const getLegacyImportPreviewRoute = HttpRouter.add("GET", "/api/settings/legacy-
44063
45474
  const postLegacyImportRoute = HttpRouter.add("POST", "/api/settings/legacy-import/conversations", httpHandler(Effect.gen(function* () {
44064
45475
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
44065
45476
  if (authError) return authError;
44066
- const body = yield* readJsonBody$11;
45477
+ const body = yield* readJsonBody$12;
44067
45478
  return yield* Effect.try({
44068
45479
  try: () => {
44069
45480
  const { path, names } = body;
@@ -44075,7 +45486,7 @@ const postLegacyImportRoute = HttpRouter.add("POST", "/api/settings/legacy-impor
44075
45486
  const settingsRouteLayer = Layer.mergeAll(getSettingsRoute, getAvailableModelsRoute, getOptimalDefaultsRoute, getMiniMaxDefaultsRoute, getClaudeAuthRoute, getOpenAIAuthRoute, postTestApiKeyRoute, postValidateApiKeyRoute, getConversationSearchStatusRoute, getConversationSearchReindexEstimateRoute, postConversationSearchReindexRoute, getConversationSearchReindexProgressRoute, putSettingsRoute, putUiThemeRoute, getOpenRouterModelsRoute, putOpenRouterFavoritesRoute, putOpenRouterApiKeyRoute, postOpenRouterTestKeyRoute, getHarnessPolicyRoute, getProviderEnvConflictsRoute, getLegacyImportPreviewRoute, postLegacyImportRoute);
44076
45487
  //#endregion
44077
45488
  //#region routes/autopreso.ts
44078
- const readJsonBody$10 = Effect.gen(function* () {
45489
+ const readJsonBody$11 = Effect.gen(function* () {
44079
45490
  const request = yield* HttpServerRequest.HttpServerRequest;
44080
45491
  const contentLength = Number(request.headers["content-length"] ?? 0);
44081
45492
  if (Number.isFinite(contentLength) && contentLength > 256e3) return {
@@ -44106,7 +45517,7 @@ function requireTrustedOrigin$1(request) {
44106
45517
  const startRoute = HttpRouter.add("POST", "/api/autopreso/start", httpHandler(Effect.gen(function* () {
44107
45518
  const originError = requireTrustedOrigin$1(yield* HttpServerRequest.HttpServerRequest);
44108
45519
  if (originError) return originError;
44109
- const parsed = yield* readJsonBody$10;
45520
+ const parsed = yield* readJsonBody$11;
44110
45521
  if (!parsed.ok) return jsonResponse({ error: parsed.error }, { status: 413 });
44111
45522
  const elements = readElementLikes(parsed.body);
44112
45523
  const validation = validateAutoPresoCanvasElements(elements);
@@ -44312,7 +45723,7 @@ const metricsRouteLayer = Layer.mergeAll(getMetricsSummaryRoute, getMetricsCosts
44312
45723
  //#region routes/boot-reconciliation.ts
44313
45724
  init_tmux();
44314
45725
  init_control_settings();
44315
- const readJsonBody$9 = Effect.gen(function* () {
45726
+ const readJsonBody$10 = Effect.gen(function* () {
44316
45727
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
44317
45728
  try {
44318
45729
  return text ? JSON.parse(text) : {};
@@ -44368,7 +45779,7 @@ function parsePerAgentMap(value) {
44368
45779
  return parsed;
44369
45780
  }
44370
45781
  const postBootReconciliationDecisionRoute = HttpRouter.add("POST", "/api/boot-reconciliation/decision", httpHandler(Effect.gen(function* () {
44371
- const body = yield* readJsonBody$9;
45782
+ const body = yield* readJsonBody$10;
44372
45783
  if (!isBootReconciliationDecision(body.decision)) return jsonResponse({
44373
45784
  ok: false,
44374
45785
  error: "Body must include decision resume_all, hold_all, or per_agent"
@@ -44465,7 +45876,7 @@ function getGitHubLocalPaths() {
44465
45876
  }
44466
45877
  return out;
44467
45878
  }
44468
- const readJsonBody$8 = Effect.gen(function* () {
45879
+ const readJsonBody$9 = Effect.gen(function* () {
44469
45880
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
44470
45881
  try {
44471
45882
  return text ? JSON.parse(text) : {};
@@ -44477,7 +45888,7 @@ const readJsonBody$8 = Effect.gen(function* () {
44477
45888
  //#region routes/misc/project-mappings.ts
44478
45889
  const getProjectMappingsRoute = HttpRouter.add("GET", "/api/project-mappings", httpHandler(Effect.promise(() => getProjectMappings().then((m) => jsonResponse(m)))));
44479
45890
  const putProjectMappingsRoute = HttpRouter.add("PUT", "/api/project-mappings", Effect.gen(function* () {
44480
- const mappings = yield* readJsonBody$8;
45891
+ const mappings = yield* readJsonBody$9;
44481
45892
  if (!Array.isArray(mappings)) return jsonResponse({ error: "Expected array of mappings" }, { status: 400 });
44482
45893
  yield* Effect.promise(() => saveProjectMappings(mappings));
44483
45894
  return jsonResponse({
@@ -44486,7 +45897,7 @@ const putProjectMappingsRoute = HttpRouter.add("PUT", "/api/project-mappings", E
44486
45897
  });
44487
45898
  }));
44488
45899
  const postProjectMappingsRoute = HttpRouter.add("POST", "/api/project-mappings", Effect.gen(function* () {
44489
- const { linearProjectId, linearProjectName, linearPrefix, localPath } = yield* readJsonBody$8;
45900
+ const { linearProjectId, linearProjectName, linearPrefix, localPath } = yield* readJsonBody$9;
44490
45901
  if (!linearProjectId || !localPath) return jsonResponse({ error: "linearProjectId and localPath required" }, { status: 400 });
44491
45902
  return yield* Effect.promise(async () => {
44492
45903
  try {
@@ -44593,14 +46004,14 @@ const getTrackerStatusRoute = HttpRouter.add("GET", "/api/tracker-status", Effec
44593
46004
  }
44594
46005
  }));
44595
46006
  const postRallyValidateRoute = HttpRouter.add("POST", "/api/rally/validate", Effect.gen(function* () {
44596
- const { apiKey, server, workspace, project } = yield* readJsonBody$8;
46007
+ const { apiKey, server, workspace, project } = yield* readJsonBody$9;
44597
46008
  if (!apiKey) return jsonResponse({
44598
46009
  valid: false,
44599
46010
  error: "API key is required"
44600
46011
  }, { status: 400 });
44601
46012
  return yield* Effect.promise(async () => {
44602
46013
  try {
44603
- const { RallyRestApi } = await import("./rally-api-yjQ0TfHd.js");
46014
+ const { RallyRestApi } = await import("./rally-api-ClOSd-Tt.js");
44604
46015
  const api = new RallyRestApi({
44605
46016
  apiKey,
44606
46017
  server: server || "https://rally1.rallydev.com"
@@ -44942,7 +46353,7 @@ const getDeaconPauseRoute = HttpRouter.add("GET", "/api/deacon/pause", Effect.tr
44942
46353
  * Persists to `app_settings` so the flag survives dashboard restarts.
44943
46354
  */
44944
46355
  const postDeaconPauseRoute = HttpRouter.add("POST", "/api/deacon/pause", httpHandler(Effect.gen(function* () {
44945
- const body = yield* readJsonBody$8;
46356
+ const body = yield* readJsonBody$9;
44946
46357
  if (typeof body.paused !== "boolean") return jsonResponse({ error: "Body must include { paused: boolean }" }, { status: 400 });
44947
46358
  setDeaconGloballyPausedSync(body.paused);
44948
46359
  console.log(`[deacon] Global pause flag set to ${body.paused}`);
@@ -44985,7 +46396,7 @@ const getPlanningStatusRoute = HttpRouter.add("GET", "/api/planning/:issueId/sta
44985
46396
  const remoteState = loadRemoteAgentState(sessionName);
44986
46397
  const isRemote = !!remoteState;
44987
46398
  const vmName = remoteState?.vmName ?? "";
44988
- const { getAgentStateSync } = await import("./agents-FlIgQ3ql.js");
46399
+ const { getAgentStateSync } = await import("./agents-wi9NWzs2.js");
44989
46400
  const agentStarting = getAgentStateSync(sessionName)?.status === "starting";
44990
46401
  let tmuxSessionAlive = false;
44991
46402
  if (!isRemote) try {
@@ -45037,7 +46448,7 @@ const postPlanningMessageRoute = HttpRouter.add("POST", "/api/planning/:issueId/
45037
46448
  const issueId = new URL(request.url, "http://localhost").pathname.split("/")[3] || "";
45038
46449
  const sessionName = `planning-${issueId.toLowerCase()}`;
45039
46450
  const issueLower = issueId.toLowerCase();
45040
- const { message } = yield* readJsonBody$8;
46451
+ const { message } = yield* readJsonBody$9;
45041
46452
  const eventStore = yield* EventStoreService;
45042
46453
  if (!message) return jsonResponse({ error: "Message required" }, { status: 400 });
45043
46454
  return yield* Effect.promise(async () => {
@@ -45129,7 +46540,7 @@ Continue the PLANNING session. Do NOT implement anything.
45129
46540
  const agentCwd = workspacePath;
45130
46541
  const harnessLaunch = await prepareHarnessLaunch("claude-code");
45131
46542
  if (existsSync$1(outputFile)) await rename(outputFile, join(planningDir, `output-${Date.now()}.jsonl`));
45132
- const { getAgentCommandSync } = await import("./settings-D0OSwos5.js");
46543
+ const { getAgentCommandSync } = await import("./settings-66A6uvIA.js");
45133
46544
  let msgPlanningModel = "claude-sonnet-5";
45134
46545
  try {
45135
46546
  msgPlanningModel = resolveModel("plan", void 0, loadConfigSync().config);
@@ -45251,7 +46662,7 @@ async function getIndexStats(rootPath, isMain) {
45251
46662
  }
45252
46663
  const getTldrStatusRoute = HttpRouter.add("GET", "/api/services/tldr/status", Effect.promise(async () => {
45253
46664
  try {
45254
- const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DL566HbH.js");
46665
+ const { getTldrDaemonServiceSync } = await import("./tldr-daemon-BYFkts95.js");
45255
46666
  const projectRoot = process.cwd();
45256
46667
  const venvPath = join(projectRoot, ".venv");
45257
46668
  const results = [];
@@ -45296,7 +46707,7 @@ const getTldrStatusRoute = HttpRouter.add("GET", "/api/services/tldr/status", Ef
45296
46707
  }));
45297
46708
  const postTldrStartRoute = HttpRouter.add("POST", "/api/services/tldr/start", Effect.promise(async () => {
45298
46709
  try {
45299
- const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DL566HbH.js");
46710
+ const { getTldrDaemonServiceSync } = await import("./tldr-daemon-BYFkts95.js");
45300
46711
  const projectRoot = process.cwd();
45301
46712
  const venvPath = join(projectRoot, ".venv");
45302
46713
  if (!existsSync$1(venvPath)) return jsonResponse({ error: "No .venv found in project root" }, { status: 404 });
@@ -45313,7 +46724,7 @@ const postTldrStartRoute = HttpRouter.add("POST", "/api/services/tldr/start", Ef
45313
46724
  }));
45314
46725
  const postTldrStopRoute = HttpRouter.add("POST", "/api/services/tldr/stop", Effect.promise(async () => {
45315
46726
  try {
45316
- const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DL566HbH.js");
46727
+ const { getTldrDaemonServiceSync } = await import("./tldr-daemon-BYFkts95.js");
45317
46728
  const projectRoot = process.cwd();
45318
46729
  const venvPath = join(projectRoot, ".venv");
45319
46730
  if (!existsSync$1(venvPath)) return jsonResponse({ error: "No .venv found in project root" }, { status: 404 });
@@ -45330,7 +46741,7 @@ const postTldrStopRoute = HttpRouter.add("POST", "/api/services/tldr/stop", Effe
45330
46741
  }));
45331
46742
  const postTldrReloadRoute = HttpRouter.add("POST", "/api/services/tldr/reload", Effect.promise(async () => {
45332
46743
  try {
45333
- const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DL566HbH.js");
46744
+ const { getTldrDaemonServiceSync } = await import("./tldr-daemon-BYFkts95.js");
45334
46745
  const enabled = isTldrEnabledSync();
45335
46746
  const projectRoot = process.cwd();
45336
46747
  const targets = [];
@@ -45518,7 +46929,7 @@ const getVersionRoute = HttpRouter.add("GET", "/api/version", Effect.promise(asy
45518
46929
  const version = await getOverdeckVersion();
45519
46930
  let supervisorUrl = null;
45520
46931
  try {
45521
- const { getSupervisorUrlSync } = await import("./supervisor-BPy-o1A8.js");
46932
+ const { getSupervisorUrlSync } = await import("./supervisor-FTJAIsAK.js");
45522
46933
  supervisorUrl = getSupervisorUrlSync();
45523
46934
  } catch {}
45524
46935
  return jsonResponse({
@@ -45528,11 +46939,11 @@ const getVersionRoute = HttpRouter.add("GET", "/api/version", Effect.promise(asy
45528
46939
  });
45529
46940
  }));
45530
46941
  const getPrerequisitesRoute = HttpRouter.add("GET", "/api/prerequisites", Effect.promise(async () => {
45531
- const { checkSystemPrerequisites } = await import("./system-prerequisites-Bza0ffAh.js");
46942
+ const { checkSystemPrerequisites } = await import("./system-prerequisites-DUDj1YHf.js");
45532
46943
  return jsonResponse(await checkSystemPrerequisites());
45533
46944
  }));
45534
46945
  const getSetupDiagnosticsRoute = HttpRouter.add("GET", "/api/diagnostics/setup", Effect.promise(async () => {
45535
- const { collectSetupDiagnostics } = await import("./system-prerequisites-Bza0ffAh.js");
46946
+ const { collectSetupDiagnostics } = await import("./system-prerequisites-DUDj1YHf.js");
45536
46947
  return jsonResponse(await collectSetupDiagnostics(await getOverdeckVersion()));
45537
46948
  }));
45538
46949
  const getSyncStatusRoute = HttpRouter.add("GET", "/api/sync-status", Effect.sync(() => {
@@ -45576,7 +46987,7 @@ const getConfirmationsRoute = HttpRouter.add("GET", "/api/confirmations", Effect
45576
46987
  const postConfirmationRespondRoute = HttpRouter.add("POST", "/api/confirmations/:id/respond", Effect.gen(function* () {
45577
46988
  const request = yield* HttpServerRequest.HttpServerRequest;
45578
46989
  const id = new URL(request.url, "http://localhost").pathname.split("/")[3] || "";
45579
- const { confirmed } = yield* readJsonBody$8;
46990
+ const { confirmed } = yield* readJsonBody$9;
45580
46991
  const confirmationRequest = pendingConfirmations.get(id);
45581
46992
  if (!confirmationRequest) return jsonResponse({ error: "Confirmation request not found" }, { status: 404 });
45582
46993
  return yield* Effect.promise(async () => {
@@ -45712,7 +47123,7 @@ const postShadowMonitorRoute = HttpRouter.add("POST", "/api/shadow/:issueId/moni
45712
47123
  const projectPath = await getProjectPath(issuePrefix);
45713
47124
  const workspacePath = join(projectPath, "workspaces", `feature-${issueLower}`);
45714
47125
  if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
45715
- const { gatherArtifacts, generateBasicInference, updateInferenceDocumentSync } = await import("./shadow-engineering-BlxG6Xye.js");
47126
+ const { gatherArtifacts, generateBasicInference, updateInferenceDocumentSync } = await import("./shadow-engineering-BJfgm-hX.js");
45716
47127
  const config = {
45717
47128
  issueId,
45718
47129
  workspacePath,
@@ -45734,7 +47145,7 @@ const postShadowObserveRoute = HttpRouter.add("POST", "/api/shadow/:issueId/obse
45734
47145
  const issueId = new URL(request.url, "http://localhost").pathname.split("/")[3] || "";
45735
47146
  const issueLower = issueId.toLowerCase();
45736
47147
  const issuePrefix = extractPrefixSync(issueId) ?? issueId.split("-")[0];
45737
- const { mode } = yield* readJsonBody$8;
47148
+ const { mode } = yield* readJsonBody$9;
45738
47149
  return yield* Effect.promise(async () => {
45739
47150
  try {
45740
47151
  const projectPath = await getProjectPath(issuePrefix);
@@ -45742,7 +47153,7 @@ const postShadowObserveRoute = HttpRouter.add("POST", "/api/shadow/:issueId/obse
45742
47153
  if (!existsSync$1(workspacePath)) return jsonResponse({ error: "Workspace not found" }, { status: 404 });
45743
47154
  const ghConfig = getGitHubConfig();
45744
47155
  if (!ghConfig) return jsonResponse({ error: "GitHub not configured - Observer requires GitHub" }, { status: 400 });
45745
- const { runObserverCycle } = await import("./shadow-engineering-BlxG6Xye.js");
47156
+ const { runObserverCycle } = await import("./shadow-engineering-BJfgm-hX.js");
45746
47157
  const firstRepo = ghConfig.repos[0];
45747
47158
  const config = {
45748
47159
  issueId,
@@ -46023,8 +47434,6 @@ const updatesRouteLayer = Layer.mergeAll(getUpdateStatusRoute, postUpdateCheckRo
46023
47434
  const miscRouteLayer = Layer.mergeAll(trackersRouteLayer, projectMappingsRouteLayer, healthRouteLayer$1, deaconRouteLayer, bootReconciliationRouteLayer, planningRouteLayer, tldrRouteLayer, metaRouteLayer, updatesRouteLayer);
46024
47435
  //#endregion
46025
47436
  //#region ../../lib/conversation-search/ranker.ts
46026
- init_fts_db();
46027
- init_search();
46028
47437
  const DEFAULT_LIMIT$1 = 10;
46029
47438
  const DEFAULT_CANDIDATE_LIMIT = 50;
46030
47439
  const DEFAULT_RRF_K = 60;
@@ -46175,13 +47584,30 @@ async function searchConversationChunks(input) {
46175
47584
  searchVector: (embedding, candidateLimit) => handle.db.searchVector(embedding, candidateLimit)
46176
47585
  },
46177
47586
  provider: handle.provider
46178
- }).then(resolve, (error) => {
47587
+ }).then((hits) => filterLiveHits(handle.db, hits)).then(resolve, (error) => {
46179
47588
  console.error("[conversation-search] service search failed:", error);
46180
47589
  resolve([]);
46181
47590
  });
46182
47591
  });
46183
47592
  });
46184
47593
  }
47594
+ /**
47595
+ * Drop hits whose transcript no longer exists on disk. Index pruning lags behind
47596
+ * file deletion (and only runs on full passes), so without this the palette can
47597
+ * surface a session whose JSONL is already gone — opening it 404s. Cursor paths
47598
+ * are the absolute paths the indexer wrote, so the stat is exact.
47599
+ */
47600
+ async function filterLiveHits(db, hits) {
47601
+ if (hits.length === 0) return hits;
47602
+ const pathBySessionId = /* @__PURE__ */ new Map();
47603
+ for (const filePath of db.listFileCursors()) pathBySessionId.set(sessionIdFromPath(filePath), filePath);
47604
+ const live = await Promise.all(hits.map(async (hit) => {
47605
+ const filePath = pathBySessionId.get(hit.sessionId);
47606
+ if (!filePath) return false;
47607
+ return stat$1(filePath).then(() => true, () => false);
47608
+ }));
47609
+ return hits.filter((_, index) => live[index]);
47610
+ }
46185
47611
  //#endregion
46186
47612
  //#region routes/palette.ts
46187
47613
  /**
@@ -46850,7 +48276,7 @@ function parseArchivedConversationListOptions(params) {
46850
48276
  const rawLimit = parseOptionalNumberParam(params, "limit");
46851
48277
  const rawOffset = parseOptionalNumberParam(params, "offset");
46852
48278
  if (workspacePath) options.workspacePath = workspacePath;
46853
- if (harness === "claude-code" || harness === "ohmypi" || harness === "codex") options.harness = harness;
48279
+ if (harness === "claude-code" || harness === "ohmypi" || harness === "codex" || harness === "acp") options.harness = harness;
46854
48280
  if (primaryModel) options.primaryModel = primaryModel;
46855
48281
  if (since) options.since = parseRelativeTime(since);
46856
48282
  if (params.get("enriched") === "true") options.enriched = true;
@@ -47112,7 +48538,6 @@ async function getConversationDiffTurn(name, turnId, fileFilter, deps) {
47112
48538
  }
47113
48539
  //#endregion
47114
48540
  //#region ../../lib/conversations/discovered-session-file.ts
47115
- init_features();
47116
48541
  async function resolveDiscoveredSessionFile(locator) {
47117
48542
  if (!locator) return null;
47118
48543
  const discovered = getDiscoveredSessionBySessionId(locator);
@@ -48791,6 +50216,7 @@ function isInGraphQLCooldown() {
48791
50216
  *
48792
50217
  * Dispatches verified webhook events to per-type handlers that update
48793
50218
  * review_status blockerReasons based on GitHub-native merge blockers.
50219
+ * Shared advisory-check classification excludes signals such as CodeRabbit from merge gates.
48794
50220
  */
48795
50221
  init_review_status();
48796
50222
  init_tracker_config();
@@ -48926,7 +50352,7 @@ async function refreshMergeStateFromGitHub(issueId, repo, prNumber) {
48926
50352
  let mergeState;
48927
50353
  let isDraft;
48928
50354
  let checksFailed;
48929
- const { isGitHubAppConfigured, getPullRequestState } = await import("./github-app-CPfoFAdV.js");
50355
+ const { isGitHubAppConfigured, getPullRequestState } = await import("./github-app-ClZ2lk8D.js");
48930
50356
  if (isGitHubAppConfigured()) {
48931
50357
  const prState = await Effect.runPromise(getPullRequestState(owner, repoName, prNumber));
48932
50358
  mergeable = prState.mergeable === null ? "UNKNOWN" : prState.mergeable ? "MERGEABLE" : "CONFLICTING";
@@ -48961,7 +50387,7 @@ async function refreshMergeStateFromGitHub(issueId, repo, prNumber) {
48961
50387
  mergeable = (pr.mergeable ?? "").toUpperCase();
48962
50388
  mergeState = (pr.mergeStateStatus ?? "").toUpperCase();
48963
50389
  isDraft = pr.isDraft === true;
48964
- checksFailed = (pr.statusCheckRollup ?? []).some((c) => FAILING_CHECK_CONCLUSIONS.has((c.conclusion || c.state || "").toUpperCase()));
50390
+ checksFailed = (pr.statusCheckRollup ?? []).some((check) => !isAdvisoryCheckName(check.name ?? check.context) && FAILING_CHECK_CONCLUSIONS.has((check.conclusion || check.state || "").toUpperCase()));
48965
50391
  }
48966
50392
  const status = await Effect.runPromise(getReviewStatus(issueId));
48967
50393
  if (!status) return;
@@ -49040,10 +50466,12 @@ async function handleCheckRunPromise(payload) {
49040
50466
  if (!run.pull_requests || run.pull_requests.length === 0) return;
49041
50467
  const repo = payload.repository.full_name;
49042
50468
  const sourceKey = `check_run:${run.name ?? String(run.id ?? "unknown")}`;
50469
+ const isAdvisory = isAdvisoryCheckName(run.name);
49043
50470
  for (const pr of run.pull_requests) {
49044
50471
  const issueId = issueIdFromBranch(pr.head.ref);
49045
50472
  if (!issueId) continue;
49046
50473
  bumpIssuePrTabCacheGeneration(issueId);
50474
+ if (isAdvisory) continue;
49047
50475
  const status = await loadAndValidateStatus(issueId, repo, pr.number, pr.head.sha);
49048
50476
  if (!status) continue;
49049
50477
  let blockers = [...status.blockerReasons ?? []];
@@ -49075,8 +50503,8 @@ async function handlePullRequestPromise(payload) {
49075
50503
  bumpIssuePrTabCacheGeneration(issueId);
49076
50504
  const repo = payload.repository.full_name;
49077
50505
  if (payload.action === "closed" && pr.merged === true) try {
49078
- const { postMergeLifecycle } = await import("./merge-agent-BQM3a8z5.js");
49079
- const { resolveProjectFromIssueSync } = await import("./projects-9SkRpES9.js");
50506
+ const { postMergeLifecycle } = await import("./merge-agent-CKkgIBPB.js");
50507
+ const { resolveProjectFromIssueSync } = await import("./projects-vjjcmiN8.js");
49080
50508
  const project = resolveProjectFromIssueSync(issueId);
49081
50509
  if (project) {
49082
50510
  const branchName = pr.head.ref;
@@ -49241,11 +50669,14 @@ async function handleStatusPromise(payload) {
49241
50669
  const branches = payload.branches;
49242
50670
  if (!state || !branches || branches.length === 0) return;
49243
50671
  const repo = payload.repository.full_name;
49244
- const sourceKey = `status:${payload.context ?? "default"}`;
50672
+ const context = payload.context ?? "default";
50673
+ const sourceKey = `status:${context}`;
50674
+ const isAdvisory = isAdvisoryCheckName(context);
49245
50675
  for (const branch of branches) {
49246
50676
  const issueId = issueIdFromBranch(branch.name);
49247
50677
  if (issueId) {
49248
50678
  bumpIssuePrTabCacheGeneration(issueId);
50679
+ if (isAdvisory) continue;
49249
50680
  const status = await loadAndValidateStatus(issueId, repo, void 0, payload.sha);
49250
50681
  if (!status) continue;
49251
50682
  let blockers = [...status.blockerReasons ?? []];
@@ -49371,6 +50802,7 @@ async function reconcileStaleGitHubBlockers() {
49371
50802
  //#endregion
49372
50803
  //#region ../../lib/overdeck/conversation-forks.ts
49373
50804
  init_issue_id();
50805
+ init_model_validation();
49374
50806
  init_conversations();
49375
50807
  init_agents$1();
49376
50808
  init_providers();
@@ -49378,7 +50810,7 @@ init_paths();
49378
50810
  init_behavior();
49379
50811
  init_tmux();
49380
50812
  const execFileAsync$4 = promisify(execFile);
49381
- const SAFE_MODEL_PATTERN = /^[a-zA-Z0-9_.:\/-]+$/;
50813
+ const SAFE_MODEL_PATTERN = MODEL_ID_PATTERN;
49382
50814
  const SESSION_FILE_MISS_TTL_MS = 2e3;
49383
50815
  const sessionFileByIdCache = /* @__PURE__ */ new Map();
49384
50816
  async function findClaudeSessionFileById(sessionId) {
@@ -49919,7 +51351,7 @@ startConversationModelBackfill(resolveSessionFile);
49919
51351
  function conversationReadJson(response) {
49920
51352
  return jsonResponse(response.body, response.status === void 0 ? void 0 : { status: response.status });
49921
51353
  }
49922
- const readJsonBody$7 = Effect.gen(function* () {
51354
+ const readJsonBody$8 = Effect.gen(function* () {
49923
51355
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
49924
51356
  try {
49925
51357
  return text ? JSON.parse(text) : {};
@@ -49979,7 +51411,7 @@ const postConversationRoute = HttpRouter.add("POST", "/api/conversations", Effec
49979
51411
  const request = yield* HttpServerRequest.HttpServerRequest;
49980
51412
  const originCheck = validateOrigin$1(request);
49981
51413
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
49982
- const body = yield* readJsonBody$7;
51414
+ const body = yield* readJsonBody$8;
49983
51415
  const reqOrigin = getHeader(request, "origin") ?? "none";
49984
51416
  const reqReferer = getHeader(request, "referer") ?? "none";
49985
51417
  const reqUserAgent = getHeader(request, "user-agent") ?? "none";
@@ -49998,14 +51430,14 @@ const postConversationResumeRoute = HttpRouter.add("POST", "/api/conversations/:
49998
51430
  const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
49999
51431
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50000
51432
  const name = (yield* HttpRouter.params)["name"] ?? "";
50001
- const body = yield* readJsonBody$7;
51433
+ const body = yield* readJsonBody$8;
50002
51434
  return yield* Effect.promise(async () => handleConversationResume(name, body, { resolveSessionFile }));
50003
51435
  }));
50004
51436
  const postConversationSwitchModelRoute = HttpRouter.add("POST", "/api/conversations/:name/switch-model", Effect.gen(function* () {
50005
51437
  const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
50006
51438
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50007
51439
  const name = (yield* HttpRouter.params)["name"] ?? "";
50008
- const body = yield* readJsonBody$7;
51440
+ const body = yield* readJsonBody$8;
50009
51441
  return yield* Effect.promise(async () => {
50010
51442
  try {
50011
51443
  return await handleConversationSwitchModel(name, body);
@@ -50020,7 +51452,7 @@ const postConversationThinkingLevelRoute = HttpRouter.add("POST", "/api/conversa
50020
51452
  const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
50021
51453
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50022
51454
  const name = (yield* HttpRouter.params)["name"] ?? "";
50023
- const body = yield* readJsonBody$7;
51455
+ const body = yield* readJsonBody$8;
50024
51456
  return yield* Effect.promise(async () => {
50025
51457
  try {
50026
51458
  return await handleConversationThinkingLevel(name, body);
@@ -50116,7 +51548,7 @@ const postConversationDeleteImageRoute = HttpRouter.add("POST", "/api/conversati
50116
51548
  const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
50117
51549
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50118
51550
  const name = (yield* HttpRouter.params)["name"] ?? "";
50119
- const body = yield* readJsonBody$7;
51551
+ const body = yield* readJsonBody$8;
50120
51552
  return yield* Effect.promise(async () => {
50121
51553
  try {
50122
51554
  return await handleConversationImageDelete(name, body);
@@ -50131,7 +51563,7 @@ const postConversationMessageRoute = HttpRouter.add("POST", "/api/conversations/
50131
51563
  const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
50132
51564
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50133
51565
  const name = (yield* HttpRouter.params)["name"] ?? "";
50134
- const body = yield* readJsonBody$7;
51566
+ const body = yield* readJsonBody$8;
50135
51567
  return yield* Effect.promise(async () => {
50136
51568
  try {
50137
51569
  return await handleConversationMessage(name, body, conversationMessageDependencies);
@@ -50151,14 +51583,14 @@ const postConversationCodexApprovalRoute = HttpRouter.add("POST", "/api/conversa
50151
51583
  const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
50152
51584
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50153
51585
  const rawId = (yield* HttpRouter.params)["id"] ?? "";
50154
- const body = yield* readJsonBody$7;
51586
+ const body = yield* readJsonBody$8;
50155
51587
  return yield* Effect.promise(() => handleConversationCodexApproval(rawId, body));
50156
51588
  }));
50157
51589
  const postConversationDeliveryMethodRoute = HttpRouter.add("POST", "/api/conversations/:name/delivery-method", Effect.gen(function* () {
50158
51590
  const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
50159
51591
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50160
51592
  const name = (yield* HttpRouter.params)["name"] ?? "";
50161
- const body = yield* readJsonBody$7;
51593
+ const body = yield* readJsonBody$8;
50162
51594
  return yield* Effect.promise(async () => {
50163
51595
  try {
50164
51596
  return await handleConversationDeliveryMethod(name, body);
@@ -50173,7 +51605,7 @@ const postConversationControlAckRoute = HttpRouter.add("POST", "/api/conversatio
50173
51605
  const request = yield* HttpServerRequest.HttpServerRequest;
50174
51606
  const originCheck = validateConversationControlAckOrigin(request.headers, request.method);
50175
51607
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50176
- const body = yield* readJsonBody$7;
51608
+ const body = yield* readJsonBody$8;
50177
51609
  return yield* Effect.promise(async () => {
50178
51610
  try {
50179
51611
  const result = handleConversationControlAck(body);
@@ -50189,7 +51621,7 @@ const patchConversationRoute = HttpRouter.add("PATCH", "/api/conversations/:name
50189
51621
  const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
50190
51622
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50191
51623
  const name = (yield* HttpRouter.params)["name"] ?? "";
50192
- const body = yield* readJsonBody$7;
51624
+ const body = yield* readJsonBody$8;
50193
51625
  return yield* Effect.promise(async () => {
50194
51626
  try {
50195
51627
  const result = patchConversationTitle(name, body);
@@ -50276,14 +51708,14 @@ const postConversationSummaryForkRoute = HttpRouter.add("POST", "/api/conversati
50276
51708
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50277
51709
  const params = yield* HttpRouter.params;
50278
51710
  const name = decodeURIComponent(params["name"] ?? "");
50279
- const body = yield* readJsonBody$7;
51711
+ const body = yield* readJsonBody$8;
50280
51712
  return yield* Effect.promise(() => handleConversationSummaryFork(name, body));
50281
51713
  }));
50282
51714
  const postConversationPlanActionRoute = HttpRouter.add("POST", "/api/conversations/:name/plan-action", Effect.gen(function* () {
50283
51715
  const originCheck = validateOrigin$1(yield* HttpServerRequest.HttpServerRequest);
50284
51716
  if (!originCheck.ok) return jsonResponse({ error: originCheck.error }, { status: 403 });
50285
51717
  const name = (yield* HttpRouter.params)["name"] ?? "";
50286
- const body = yield* readJsonBody$7;
51718
+ const body = yield* readJsonBody$8;
50287
51719
  return yield* Effect.promise(() => handleConversationPlanAction(name, body));
50288
51720
  }));
50289
51721
  const conversationDiffDependencies = {
@@ -50385,7 +51817,7 @@ const showRouteLayer = Layer.mergeAll(getShowRoute, getShowShadowRoute, getShowH
50385
51817
  //#endregion
50386
51818
  //#region routes/project-rename.ts
50387
51819
  init_projects();
50388
- const readJsonBody$6 = Effect.gen(function* () {
51820
+ const readJsonBody$7 = Effect.gen(function* () {
50389
51821
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
50390
51822
  try {
50391
51823
  return text ? JSON.parse(text) : {};
@@ -50397,7 +51829,7 @@ const postProjectRenameRoute = HttpRouter.add("POST", "/api/projects/:projectKey
50397
51829
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
50398
51830
  if (authError) return authError;
50399
51831
  const projectIdentifier = (yield* HttpRouter.params)["projectKey"] ?? "";
50400
- const body = yield* readJsonBody$6;
51832
+ const body = yield* readJsonBody$7;
50401
51833
  if (typeof body.name !== "string") return jsonResponse({ error: "Project name must be a string" }, { status: 400 });
50402
51834
  const result = yield* Effect.result(renameProject(projectIdentifier, body.name));
50403
51835
  if (Result$1.isFailure(result)) {
@@ -50472,7 +51904,7 @@ async function registerProjectFromPath(opts) {
50472
51904
  registerProjectSync(key, projectConfig);
50473
51905
  const seededContextLayer = ensureProjectLayer(fullPath);
50474
51906
  try {
50475
- const { preTrustDirectorySync } = await import("./workspace-manager-ZTdJAy9M.js");
51907
+ const { preTrustDirectorySync } = await import("./workspace-manager-CWT55qeI.js");
50476
51908
  preTrustDirectorySync(fullPath);
50477
51909
  } catch {}
50478
51910
  let hooksInstalled = 0;
@@ -50489,6 +51921,7 @@ async function registerProjectFromPath(opts) {
50489
51921
  //#region ../../lib/overdeck/specs.ts
50490
51922
  init_harness();
50491
51923
  init_render();
51924
+ init_assemble();
50492
51925
  init_specs();
50493
51926
  const findSpecByIssueThroughOverdeck = findSpecByIssue;
50494
51927
  //#endregion
@@ -50496,8 +51929,10 @@ const findSpecByIssueThroughOverdeck = findSpecByIssue;
50496
51929
  /** Projects route module — Effect HttpRouter.Layer (PAN-821). */
50497
51930
  init_projects();
50498
51931
  init_record();
51932
+ init_record_update();
50499
51933
  init_config_yaml();
50500
51934
  init_tier_table();
51935
+ init_model_validation();
50501
51936
  init_issue_id();
50502
51937
  init_tmux();
50503
51938
  init_concurrency$1();
@@ -50510,7 +51945,7 @@ init_specs();
50510
51945
  init_paths();
50511
51946
  const execAsync$2 = promisify(exec);
50512
51947
  async function getIssueDataService() {
50513
- const { getSharedIssueService } = await import("./issue-service-singleton-DabvBWUp.js");
51948
+ const { getSharedIssueService } = await import("./issue-service-singleton-BvJ09SaR.js");
50514
51949
  return getSharedIssueService();
50515
51950
  }
50516
51951
  /** Returns true if the path exists (any type). */
@@ -50651,7 +52086,6 @@ async function collectSessionTreeNodes(issueId, workspacePath, projectPath, cont
50651
52086
  }
50652
52087
  for (const sessionName of context.tmuxSessionNames) if (slotWorkSessionPattern.test(sessionName)) candidateSessionIds.add(sessionName);
50653
52088
  for (const checkId of [...candidateSessionIds].sort((a, b) => compareSessionTreeSessionIds(a, b, issueLower))) {
50654
- if (!await pathExists$1(join(agentsDir, checkId))) continue;
50655
52089
  const state = getAgentStateSync(checkId);
50656
52090
  if (!state) continue;
50657
52091
  try {
@@ -50896,17 +52330,19 @@ async function fetchProjectSessionTree(projectKey, sharedContext) {
50896
52330
  const agentDir = join(getOverdeckHome(), "agents", `agent-${c.issueLower}`);
50897
52331
  const planningAgentDir = join(getOverdeckHome(), "agents", `planning-${c.issueLower}`);
50898
52332
  const planRunAgentDir = join(getOverdeckHome(), "agents", `agent-${c.issueLower}-plan`);
52333
+ const strikeAgentDir = join(getOverdeckHome(), "agents", `strike-${c.issueLower}`);
50899
52334
  const panDir = join(workspacesDir, c.name, PAN_DIRNAME);
50900
52335
  const overdeckDir = join(workspacesDir, c.name, WORKSPACE_RUNTIME_DIRNAME);
50901
52336
  const hasIssueTmux = liveTmuxIssueIds.has(c.issueLower);
50902
- const [hasAgent, hasPlanning, hasPlanningAgent, hasPlanRunAgent, hasOverdeck] = await Promise.all([
52337
+ const [hasAgent, hasPlanning, hasPlanningAgent, hasPlanRunAgent, hasStrikeAgent, hasOverdeck] = await Promise.all([
50903
52338
  pathExists$1(agentDir),
50904
52339
  pathExists$1(panDir),
50905
52340
  pathExists$1(planningAgentDir),
50906
52341
  pathExists$1(planRunAgentDir),
52342
+ pathExists$1(strikeAgentDir),
50907
52343
  pathExists$1(overdeckDir)
50908
52344
  ]);
50909
- const hasAnySignal = hasAgent || hasPlanning || hasPlanningAgent || hasPlanRunAgent || hasOverdeck || hasIssueTmux;
52345
+ const hasAnySignal = hasAgent || hasPlanning || hasPlanningAgent || hasPlanRunAgent || hasStrikeAgent || hasOverdeck || hasIssueTmux;
50910
52346
  if (!hasAnySignal) return null;
50911
52347
  try {
50912
52348
  const workspacePath = join(workspacesDir, c.name);
@@ -50967,7 +52403,7 @@ const getProjectReleaseStatusRoute = HttpRouter.add("GET", "/api/projects/:proje
50967
52403
  const projectKey = (yield* HttpRouter.params)["projectKey"] ?? "";
50968
52404
  return jsonResponse(yield* Effect.tryPromise({
50969
52405
  try: async () => {
50970
- const { fetchProjectReleaseStatus } = await import("./project-pipelines-2sK1apsO.js");
52406
+ const { fetchProjectReleaseStatus } = await import("./project-pipelines-C0MWUeCU.js");
50971
52407
  return fetchProjectReleaseStatus(projectKey);
50972
52408
  },
50973
52409
  catch: (err) => new Error(err instanceof Error ? err.message : String(err))
@@ -51213,7 +52649,8 @@ init_domain_services();
51213
52649
  const PREVIEW_HARNESSES = [
51214
52650
  "claude-code",
51215
52651
  "ohmypi",
51216
- "codex"
52652
+ "codex",
52653
+ "acp"
51217
52654
  ];
51218
52655
  const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
51219
52656
  const execFileAsync$3 = promisify(execFile);
@@ -51377,7 +52814,7 @@ async function buildSyncTargets(projects) {
51377
52814
  for (const { key, config } of projects) {
51378
52815
  if (!(await readOptionalFile(resolveProjectContextFile(config.path))).exists) continue;
51379
52816
  targets.push(await describeSyncTarget("claude-code", "project", key, `${config.name} · CLAUDE.md`, join(config.path, "CLAUDE.md")));
51380
- targets.push(await describeSyncTarget("pi", "project", key, `${config.name} · AGENTS.md`, join(config.path, "AGENTS.md")));
52817
+ targets.push(await describeSyncTarget("ohmypi", "project", key, `${config.name} · AGENTS.md`, join(config.path, "AGENTS.md")));
51381
52818
  }
51382
52819
  return targets;
51383
52820
  }
@@ -51450,7 +52887,8 @@ async function renderBundledRulesAsync(harness) {
51450
52887
  }
51451
52888
  function renderLayerSections(layers, drafts, harness) {
51452
52889
  return layers.map((layer) => {
51453
- const rendered = renderForHarness(contentForLayer(layer, drafts), harness).trim();
52890
+ const raw = contentForLayer(layer, drafts);
52891
+ const rendered = renderForHarness(harness === "acp" && layer.kind === "workspace" ? workspaceContextWithoutProjectLayer(raw) : raw, harness).trim();
51454
52892
  return `## ${layer.kind === "global" ? "Global layer" : layer.kind === "project" ? `Project layer: ${layer.projectKey}` : `Workspace layer: ${layer.workspacePath}`}\n\n${rendered || "_No context in this layer._"}`;
51455
52893
  }).join("\n\n---\n\n");
51456
52894
  }
@@ -51479,6 +52917,10 @@ function fullPromptPreview(previews) {
51479
52917
  "",
51480
52918
  previews.codex || "(no rendered context)",
51481
52919
  "",
52920
+ "## Overdeck-controlled ACP bundle",
52921
+ "",
52922
+ previews.acp || "(no rendered context)",
52923
+ "",
51482
52924
  "## Runtime-only sections",
51483
52925
  "",
51484
52926
  "- Memory retrieval: injected at agent spawn when enabled; unavailable in this layer editor preview.",
@@ -51516,6 +52958,7 @@ async function previewContextLayers(projects, requestOrSelectedLayer, maybeDraft
51516
52958
  "claude-code": previews["claude-code"],
51517
52959
  ohmypi: previews.ohmypi,
51518
52960
  codex: previews.codex,
52961
+ acp: previews.acp,
51519
52962
  fullPrompt: fullPromptPreview(previews)
51520
52963
  },
51521
52964
  diagnostics: diagnosticsForLayers(layers, drafts)
@@ -51594,7 +53037,7 @@ function issueIdFromWorkspacePath(workspacePath) {
51594
53037
  const match = /(?:^|[^a-z0-9])([a-z]+-\d+)(?:[^a-z0-9]|$)/i.exec(workspacePath);
51595
53038
  return match ? match[1].toUpperCase() : null;
51596
53039
  }
51597
- function readJsonBody$5() {
53040
+ function readJsonBody$6() {
51598
53041
  return Effect.gen(function* () {
51599
53042
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
51600
53043
  return text ? JSON.parse(text) : {};
@@ -51608,7 +53051,7 @@ const getContextLayersRoute = HttpRouter.add("GET", "/api/context/layers", httpH
51608
53051
  return jsonResponse(yield* Effect.promise(() => loadContextLayers(projects)));
51609
53052
  })));
51610
53053
  const postContextPreviewRoute = HttpRouter.add("POST", "/api/context/preview", httpHandler(Effect.gen(function* () {
51611
- const body = yield* readJsonBody$5();
53054
+ const body = yield* readJsonBody$6();
51612
53055
  const parsed = yield* Effect.try({
51613
53056
  try: () => decodePreviewRequest(body),
51614
53057
  catch: (error) => new Error(error instanceof Error ? error.message : String(error))
@@ -51617,7 +53060,7 @@ const postContextPreviewRoute = HttpRouter.add("POST", "/api/context/preview", h
51617
53060
  return jsonResponse(yield* Effect.promise(() => previewContextLayers(projects, parsed)));
51618
53061
  })));
51619
53062
  const putContextLayerRoute = HttpRouter.add("PUT", "/api/context/layers", httpHandler(Effect.gen(function* () {
51620
- const body = yield* readJsonBody$5();
53063
+ const body = yield* readJsonBody$6();
51621
53064
  const parsed = yield* Effect.try({
51622
53065
  try: () => decodeSaveRequest(body),
51623
53066
  catch: (error) => new Error(error instanceof Error ? error.message : String(error))
@@ -51934,7 +53377,7 @@ async function installOx() {
51934
53377
  * GET /api/prereqs/:feature — check which tools are missing for a feature
51935
53378
  * POST /api/prereqs/install — install a specific tool by name
51936
53379
  */
51937
- const readJsonBody$4 = Effect.gen(function* () {
53380
+ const readJsonBody$5 = Effect.gen(function* () {
51938
53381
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
51939
53382
  try {
51940
53383
  return text ? JSON.parse(text) : {};
@@ -51971,7 +53414,7 @@ const checkFeatureRoute = HttpRouter.add("GET", "/api/prereqs/:feature", httpHan
51971
53414
  });
51972
53415
  })));
51973
53416
  const installToolRoute = HttpRouter.add("POST", "/api/prereqs/install", httpHandler(Effect.gen(function* () {
51974
- const tool = (yield* readJsonBody$4).tool;
53417
+ const tool = (yield* readJsonBody$5).tool;
51975
53418
  if (!tool) return jsonResponse({ error: "Missing 'tool' in request body" }, { status: 400 });
51976
53419
  if (!INSTALLABLE_TOOLS.some((t) => t === tool)) return jsonResponse({ error: `Tool '${tool}' is not auto-installable` }, { status: 400 });
51977
53420
  const result = yield* Effect.promise(() => installTool(tool));
@@ -52491,7 +53934,6 @@ const webhooksRouteLayer = HttpRouter.add("POST", "/api/webhooks/github", httpHa
52491
53934
  })));
52492
53935
  //#endregion
52493
53936
  //#region ../../lib/overdeck/title-refinement.ts
52494
- init_paths$2();
52495
53937
  /**
52496
53938
  * Hook-driven progressive conversation title refinement.
52497
53939
  *
@@ -52600,12 +54042,7 @@ function isCurrentSessionMiss(observation, identity) {
52600
54042
  }
52601
54043
  //#endregion
52602
54044
  //#region ../../lib/memory/checkpoint-client.ts
52603
- init_settings();
52604
- init_health();
52605
- init_providers$1();
52606
54045
  init_pending();
52607
- init_query_expansion();
52608
- init_injection();
52609
54046
  let worker = null;
52610
54047
  let nextRequestId = 1;
52611
54048
  const pendingRequests = /* @__PURE__ */ new Map();
@@ -52638,7 +54075,7 @@ function getCheckpointWorker() {
52638
54075
  return worker;
52639
54076
  }
52640
54077
  async function runInline(operation, payload) {
52641
- const { claimTranscriptRange, commitTranscriptRange, releaseTranscriptRange, getTranscriptCheckpoint, listTranscriptCheckpoints } = await import("./checkpoints-CpgCjAlN.js");
54078
+ const { claimTranscriptRange, commitTranscriptRange, releaseTranscriptRange, getTranscriptCheckpoint, listTranscriptCheckpoints } = await import("./checkpoints-BJIs5QIA.js");
52642
54079
  switch (operation) {
52643
54080
  case "claimTranscriptRange": return claimTranscriptRange(payload);
52644
54081
  case "commitTranscriptRange": return commitTranscriptRange(payload);
@@ -53792,7 +55229,7 @@ function buildPendingTurn(input, fromOffset, toOffset, compressed) {
53792
55229
  };
53793
55230
  }
53794
55231
  async function emitMemoryObservationCreated(observation, timestamp) {
53795
- const { initEventStore } = await import("./event-store-Cr5PQwFC.js");
55232
+ const { initEventStore } = await import("./event-store-EV2cMiXj.js");
53796
55233
  await (await initEventStore()).appendAsync({
53797
55234
  type: "memory.observation_created",
53798
55235
  timestamp,
@@ -54818,6 +56255,7 @@ init_paths$2();
54818
56255
  init_read_model();
54819
56256
  init_conversations();
54820
56257
  init_briefing_freshness();
56258
+ init_injection();
54821
56259
  init_settings();
54822
56260
  const MEMORY_INJECT_FAST_RESPONSE_TIMEOUT_MS = 750;
54823
56261
  const CLEAR_ON = new Set([
@@ -55472,7 +56910,7 @@ const diffsRouteLayer = Layer.mergeAll(getDiffsRoute, getTurnDiffRoute, getFullD
55472
56910
  * folded into that RPC surface.
55473
56911
  */
55474
56912
  init_tmux();
55475
- const readJsonBody$3 = Effect.gen(function* () {
56913
+ const readJsonBody$4 = Effect.gen(function* () {
55476
56914
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
55477
56915
  return text ? JSON.parse(text) : {};
55478
56916
  });
@@ -55496,7 +56934,7 @@ function generateTerminalSessionName() {
55496
56934
  const postTerminalRoute = HttpRouter.add("POST", "/api/terminals", httpHandler(Effect.gen(function* () {
55497
56935
  const authError = rejectUnauthorized(yield* HttpServerRequest.HttpServerRequest);
55498
56936
  if (authError) return authError;
55499
- const cwd = resolveCwd((yield* readJsonBody$3).cwd);
56937
+ const cwd = resolveCwd((yield* readJsonBody$4).cwd);
55500
56938
  const sessionName = generateTerminalSessionName();
55501
56939
  yield* createSession(sessionName, cwd, void 0, { env: { PATH: process.env.PATH || "" } });
55502
56940
  return jsonResponse({
@@ -56579,7 +58017,7 @@ async function assertWritePathInsideRoot(projectRoot, candidate) {
56579
58017
  }
56580
58018
  return { ok: true };
56581
58019
  }
56582
- const readJsonBody$2 = Effect.gen(function* () {
58020
+ const readJsonBody$3 = Effect.gen(function* () {
56583
58021
  const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
56584
58022
  try {
56585
58023
  return {
@@ -56804,7 +58242,7 @@ async function getFlywheelConversationPayload() {
56804
58242
  };
56805
58243
  }
56806
58244
  async function postFlywheelReportPayload() {
56807
- const { flywheelReportCommand } = await import("./flywheel-DcBkQvgE.js");
58245
+ const { flywheelReportCommand } = await import("./flywheel-DzGtWnJ1.js");
56808
58246
  await flywheelReportCommand({ cwd: process.cwd() });
56809
58247
  return {
56810
58248
  status: 200,
@@ -56962,11 +58400,11 @@ const getMergeBlockersRoute = HttpRouter.add("GET", "/api/flywheel/merge-blocker
56962
58400
  async function defaultGetOrderedIssueIds() {
56963
58401
  const status = await readCurrentFlywheelStatusForDashboard();
56964
58402
  if (!status) return [];
56965
- const { computeMergeQueue } = await import("./flywheel-merge-order-C-6zRLvM.js");
58403
+ const { computeMergeQueue } = await import("./flywheel-merge-order-UUcsCDb6.js");
56966
58404
  return (await Effect.runPromise(computeMergeQueue(status.activePipeline, process.cwd()).pipe(Effect.provide(layer)))).map((i) => i.issueId);
56967
58405
  }
56968
58406
  async function defaultMergeOne(issueId) {
56969
- const { triggerMerge } = await import("./merge-ops-DlB1IM0Y.js");
58407
+ const { triggerMerge } = await import("./merge-ops-CR44oU9-.js");
56970
58408
  const r = await triggerMerge(issueId);
56971
58409
  return r.success ? { ok: true } : {
56972
58410
  ok: false,
@@ -56986,7 +58424,7 @@ async function postFlywheelMergeNextPayload(payload, deps = {}) {
56986
58424
  body: { error: "n must be a positive integer" }
56987
58425
  };
56988
58426
  const issueIds = (await (deps.getOrderedIssueIds ?? defaultGetOrderedIssueIds)()).slice(0, n);
56989
- const { shipMergeBatch } = await import("./merge-batch-Bwoyr8Je.js");
58427
+ const { shipMergeBatch } = await import("./merge-batch-ClFn2T-y.js");
56990
58428
  return {
56991
58429
  status: 200,
56992
58430
  body: { outcomes: await shipMergeBatch(issueIds, { merge: deps.merge ?? defaultMergeOne }) }
@@ -57120,7 +58558,7 @@ const getFlywheelBriefRoute = HttpRouter.add("GET", "/api/flywheel/brief", httpH
57120
58558
  const postFlywheelBriefRoute = HttpRouter.add("POST", "/api/flywheel/brief", httpHandler(Effect.gen(function* () {
57121
58559
  const authError = rejectUnauthorizedDashboardRequest(yield* HttpServerRequest.HttpServerRequest);
57122
58560
  if (authError) return authError;
57123
- const parsed = yield* readJsonBody$2;
58561
+ const parsed = yield* readJsonBody$3;
57124
58562
  if (!parsed.ok) return jsonResponse({ error: parsed.error }, { status: 400 });
57125
58563
  const body = parsed.body;
57126
58564
  if (typeof body.content !== "string") return jsonResponse({ error: "content must be a string" }, { status: 400 });
@@ -57143,7 +58581,7 @@ const getFlywheelMergeQueueRoute = HttpRouter.add("GET", "/api/flywheel/merge-qu
57143
58581
  return yield* Effect.promise(async () => {
57144
58582
  const status = await readCurrentFlywheelStatusForDashboard();
57145
58583
  if (!status) return jsonResponse([]);
57146
- const { computeMergeQueue, resolveMergeQueuePrUrl } = await import("./flywheel-merge-order-C-6zRLvM.js");
58584
+ const { computeMergeQueue, resolveMergeQueuePrUrl } = await import("./flywheel-merge-order-UUcsCDb6.js");
57147
58585
  return jsonResponse(await Effect.runPromise(computeMergeQueue(status.activePipeline, process.cwd(), { getPrUrl: resolveMergeQueuePrUrl }).pipe(Effect.provide(layer))));
57148
58586
  });
57149
58587
  })));
@@ -57157,18 +58595,18 @@ function uatGenerationNameFromParam(param) {
57157
58595
  return decoded.startsWith("uat/") ? decoded : `uat/${decoded}`;
57158
58596
  }
57159
58597
  const getUatGenerationsRoute = HttpRouter.add("GET", "/api/flywheel/uat-generations", httpHandler(Effect.gen(function* () {
57160
- const { getUatGenerationsPayload } = yield* Effect.promise(() => import("./uat-train-cKfM-_WW.js"));
58598
+ const { getUatGenerationsPayload } = yield* Effect.promise(() => import("./uat-train-B05BWkp-.js"));
57161
58599
  return jsonResponse(yield* Effect.promise(() => getUatGenerationsPayload()));
57162
58600
  })));
57163
58601
  const getUatCandidateRoute = HttpRouter.add("GET", "/api/flywheel/uat-candidate", httpHandler(Effect.gen(function* () {
57164
- const { getUatCandidatePayload } = yield* Effect.promise(() => import("./uat-train-cKfM-_WW.js"));
58602
+ const { getUatCandidatePayload } = yield* Effect.promise(() => import("./uat-train-B05BWkp-.js"));
57165
58603
  return jsonResponse(yield* Effect.promise(() => getUatCandidatePayload()));
57166
58604
  })));
57167
58605
  const postUatGenerationStackRoute = HttpRouter.add("POST", "/api/flywheel/uat-generations/:name/stack", httpHandler(Effect.gen(function* () {
57168
58606
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
57169
58607
  if (authError) return authError;
57170
58608
  const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
57171
- const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-cKfM-_WW.js"));
58609
+ const { postUatGenerationStackPayload } = yield* Effect.promise(() => import("./uat-train-B05BWkp-.js"));
57172
58610
  const result = yield* Effect.promise(() => postUatGenerationStackPayload(name));
57173
58611
  if (!result.ok) return jsonResponse({ error: result.error }, { status: result.status });
57174
58612
  return jsonResponse({
@@ -57180,8 +58618,8 @@ const postUatGenerationPromoteRoute = HttpRouter.add("POST", "/api/flywheel/uat-
57180
58618
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
57181
58619
  if (authError) return authError;
57182
58620
  const name = uatGenerationNameFromParam((yield* HttpRouter.params)["name"] ?? "");
57183
- const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-cKfM-_WW.js"));
57184
- const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-D5fRZXmN.js"));
58621
+ const { postUatGenerationPromotePayload } = yield* Effect.promise(() => import("./uat-train-B05BWkp-.js"));
58622
+ const { firePostMergeLifecycle } = yield* Effect.promise(() => import("./specialists-CShuVGWT.js"));
57185
58623
  const result = yield* Effect.promise(() => postUatGenerationPromotePayload(name, firePostMergeLifecycle));
57186
58624
  if (!result.success) return jsonResponse(result, { status: result.reason === "not-found" ? 404 : result.reason === "merge-failed" ? 500 : 409 });
57187
58625
  return jsonResponse(result);
@@ -57194,7 +58632,7 @@ const postUatGenerationPromoteRoute = HttpRouter.add("POST", "/api/flywheel/uat-
57194
58632
  const postFlywheelAssembleUatRoute = HttpRouter.add("POST", "/api/flywheel/assemble-uat", httpHandler(Effect.gen(function* () {
57195
58633
  const authError = rejectUnsafeDashboardMutationRequest(yield* HttpServerRequest.HttpServerRequest);
57196
58634
  if (authError) return authError;
57197
- const { runUatTrainReconcile } = yield* Effect.promise(() => import("./uat-train-cKfM-_WW.js"));
58635
+ const { runUatTrainReconcile } = yield* Effect.promise(() => import("./uat-train-B05BWkp-.js"));
57198
58636
  return jsonResponse(yield* Effect.promise(() => runUatTrainReconcile({ force: true })));
57199
58637
  })));
57200
58638
  const getFlywheelStateRoute = HttpRouter.add("GET", "/api/flywheel/state", httpHandler(Effect.gen(function* () {
@@ -57202,6 +58640,419 @@ const getFlywheelStateRoute = HttpRouter.add("GET", "/api/flywheel/state", httpH
57202
58640
  })));
57203
58641
  const flywheelRouteLayer = Layer.mergeAll(getFlywheelRunsRoute, getFlywheelRunRoute, getFlywheelConversationRoute, getFlywheelCurrentRoute, getFlywheelStatsRoute, getSubstrateBugWeightsRoute, getFlywheelConfigRoute, postFlywheelConfigRoute, getPendingAutoMergeRoute, getAutoMergeProblemsRoute, getMergeBlockersRoute, getMergeBackendRoute, postAutoMergeScheduleRoute, postFlywheelMergeNextRoute, deleteAutoMergeRoute, getFlywheelMergeQueueRoute, getUatGenerationsRoute, getUatCandidateRoute, postUatGenerationStackRoute, postUatGenerationPromoteRoute, postFlywheelAssembleUatRoute, getFlywheelStateRoute, postFlywheelStatusRoute, postFlywheelStartRoute, postFlywheelPauseRoute, postFlywheelResumeRoute, postFlywheelAbortRoute, postFlywheelReportRoute, postFlywheelReportOpenRoute, getFlywheelBriefRoute, postFlywheelBriefRoute);
57204
58642
  //#endregion
58643
+ //#region routes/orders.ts
58644
+ init_projects();
58645
+ function stateRootFor(deps) {
58646
+ if (deps.stateRoot) return deps.stateRoot();
58647
+ const project = findProjectByPathSync(process.cwd());
58648
+ if (!project) throw new Error(`No configured project contains ${process.cwd()}`);
58649
+ return resolveStateReadHomeSync(project).root;
58650
+ }
58651
+ function errorResult(error) {
58652
+ const message = error instanceof Error ? error.message : String(error);
58653
+ if (/not found/i.test(message)) return {
58654
+ status: 404,
58655
+ body: { error: message }
58656
+ };
58657
+ if (/already (exists|belongs|running|active)|multiple non-complete/i.test(message)) return {
58658
+ status: 409,
58659
+ body: { error: message }
58660
+ };
58661
+ if (/invalid|required|must be|cannot be empty|positive integer|server-controlled|may only transition/i.test(message)) return {
58662
+ status: 400,
58663
+ body: { error: message }
58664
+ };
58665
+ return {
58666
+ status: 500,
58667
+ body: { error: message }
58668
+ };
58669
+ }
58670
+ async function routeResult(action) {
58671
+ try {
58672
+ return {
58673
+ status: 200,
58674
+ body: await action()
58675
+ };
58676
+ } catch (error) {
58677
+ return errorResult(error);
58678
+ }
58679
+ }
58680
+ function resultResponse(result) {
58681
+ return jsonResponse(result.body, { status: result.status });
58682
+ }
58683
+ function requireBook(stateRoot, bookId) {
58684
+ const book = getBook(stateRoot, bookId);
58685
+ if (!book) throw new Error(`Order book not found: ${bookId}`);
58686
+ return book;
58687
+ }
58688
+ function requireString(value, field) {
58689
+ if (typeof value !== "string" || !value.trim()) throw new Error(`${field} is required`);
58690
+ return value.trim();
58691
+ }
58692
+ function optionalString(value, field) {
58693
+ if (value === void 0) return void 0;
58694
+ if (typeof value !== "string") throw new Error(`${field} must be a string`);
58695
+ return value;
58696
+ }
58697
+ function optionalBoolean(value, field) {
58698
+ if (value === void 0) return void 0;
58699
+ if (typeof value !== "boolean") throw new Error(`${field} must be a boolean`);
58700
+ return value;
58701
+ }
58702
+ function lane(value, fallback) {
58703
+ if (value === void 0 && fallback) return fallback;
58704
+ if (value !== "A" && value !== "B") throw new Error("lane must be A or B");
58705
+ return value;
58706
+ }
58707
+ function positiveInteger(value, field, fallback) {
58708
+ if (value === void 0 && fallback !== void 0) return fallback;
58709
+ if (!Number.isInteger(value) || Number(value) < 1) throw new Error(`${field} must be a positive integer`);
58710
+ return Number(value);
58711
+ }
58712
+ function stringArray(value, field) {
58713
+ if (value === void 0) return [];
58714
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string" || !entry.trim())) throw new Error(`${field} must be an array of non-empty strings`);
58715
+ return value.map((entry) => entry.trim().toUpperCase());
58716
+ }
58717
+ function record(value, field) {
58718
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`${field} must be an object`);
58719
+ return value;
58720
+ }
58721
+ function settingsPatch(value) {
58722
+ const raw = record(value, "settings");
58723
+ if ("postureSetAt" in raw || "postureSetBy" in raw) throw new Error("postureSetAt and postureSetBy are server-controlled");
58724
+ const result = {};
58725
+ if ("laneAConcurrency" in raw) result.laneAConcurrency = positiveInteger(raw["laneAConcurrency"], "laneAConcurrency");
58726
+ if ("briefOverlay" in raw) result.briefOverlay = optionalString(raw["briefOverlay"], "briefOverlay");
58727
+ if ("posture" in raw) {
58728
+ if (raw["posture"] !== "open" && raw["posture"] !== "drain") throw new Error("posture must be open or drain");
58729
+ result.posture = raw["posture"];
58730
+ }
58731
+ if ("postureReason" in raw) result.postureReason = optionalString(raw["postureReason"], "postureReason");
58732
+ return result;
58733
+ }
58734
+ function slugify(value) {
58735
+ return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "order-book";
58736
+ }
58737
+ function nextBookId(stateRoot, name, now) {
58738
+ const base = `${now.toISOString().slice(0, 10)}-${slugify(name)}`;
58739
+ if (!getBook(stateRoot, base)) return base;
58740
+ let suffix = 2;
58741
+ while (getBook(stateRoot, `${base}-${suffix}`)) suffix += 1;
58742
+ return `${base}-${suffix}`;
58743
+ }
58744
+ function buildOrdersReadSnapshot(deps) {
58745
+ const stateRoot = stateRootFor(deps);
58746
+ const books = listBooks(stateRoot);
58747
+ const issueIds = [...new Set(books.flatMap((book) => book.items.flatMap((item) => [item.issue, ...item.prereqs])))];
58748
+ const issueState = (deps.issueLookup ?? liveOrderIssueLookup)(issueIds);
58749
+ const issueLookup = (requested) => new Map(requested.flatMap((issueId) => {
58750
+ const state = issueState.get(issueId.toUpperCase());
58751
+ return state ? [[issueId.toUpperCase(), state]] : [];
58752
+ }));
58753
+ return {
58754
+ stateRoot,
58755
+ books,
58756
+ issueState,
58757
+ issueLookup,
58758
+ hasPrd: deps.hasPrd ?? createOrderPrdLookup(stateRoot)
58759
+ };
58760
+ }
58761
+ function enrichedBook(book, deps, snapshot) {
58762
+ const stateRoot = snapshot?.stateRoot ?? stateRootFor(deps);
58763
+ const hasPrd = snapshot?.hasPrd ?? deps.hasPrd ?? ((issueId) => hasOrderIssuePrd(stateRoot, issueId));
58764
+ const issueLookup = snapshot?.issueLookup ?? deps.issueLookup;
58765
+ const prerequisiteIds = [...new Set(book.items.flatMap((item) => item.prereqs.map((prereq) => prereq.toUpperCase())))];
58766
+ const prerequisiteState = snapshot?.issueState ?? issueLookup?.(prerequisiteIds) ?? /* @__PURE__ */ new Map();
58767
+ return {
58768
+ ...book,
58769
+ progress: computeBookProgress(book, issueLookup),
58770
+ validation: validateBookForStart(stateRoot, book, {
58771
+ issueLookup,
58772
+ hasPrd,
58773
+ books: snapshot?.books
58774
+ }),
58775
+ itemReadiness: Object.fromEntries(book.items.map((item) => [item.issue, { hasPrd: hasPrd(item.issue) }])),
58776
+ prerequisiteTerminal: Object.fromEntries(prerequisiteIds.map((issue) => {
58777
+ const state = prerequisiteState.get(issue);
58778
+ return [issue, state ? !state.open || state.parked : false];
58779
+ }))
58780
+ };
58781
+ }
58782
+ function parseItems(book, value) {
58783
+ const rawItems = Array.isArray(value) ? value : [value];
58784
+ if (rawItems.length === 0) throw new Error("items is required");
58785
+ const laneCounts = new Map([["A", book.items.filter((item) => item.lane === "A").length], ["B", book.items.filter((item) => item.lane === "B").length]]);
58786
+ return rawItems.map((entry, index) => {
58787
+ const raw = record(entry, `items[${index}]`);
58788
+ const itemLane = lane(raw["lane"], "A");
58789
+ const nextOrder = (laneCounts.get(itemLane) ?? 0) + 1;
58790
+ laneCounts.set(itemLane, nextOrder);
58791
+ const planAtPickup = optionalBoolean(raw["planAtPickup"], "planAtPickup");
58792
+ return {
58793
+ issue: requireString(raw["issue"], "issue").toUpperCase(),
58794
+ lane: itemLane,
58795
+ order: positiveInteger(raw["order"], "order", nextOrder),
58796
+ prereqs: stringArray(raw["prereqs"], "prereqs"),
58797
+ reVerify: optionalBoolean(raw["reVerify"], "reVerify") ?? false,
58798
+ ...planAtPickup === void 0 ? {} : { planAtPickup }
58799
+ };
58800
+ });
58801
+ }
58802
+ function previewBrief(book) {
58803
+ const lines = [
58804
+ `# Special orders: ${book.name}`,
58805
+ "",
58806
+ `Order book: ${book.id}`,
58807
+ `Posture: ${book.settings.posture.toUpperCase()}`,
58808
+ "",
58809
+ "This order book defines the operator-released scope. Standard flywheel doctrine and the standard brief remain in force."
58810
+ ];
58811
+ for (const laneName of ["A", "B"]) {
58812
+ lines.push("", `## Lane ${laneName}`);
58813
+ const items = book.items.filter((item) => item.lane === laneName).sort((left, right) => left.order - right.order);
58814
+ if (items.length === 0) {
58815
+ lines.push("- Empty");
58816
+ continue;
58817
+ }
58818
+ for (const item of items) {
58819
+ const flags = [
58820
+ item.prereqs.length > 0 ? `after ${item.prereqs.join(", ")}` : "",
58821
+ item.reVerify ? "re-verify PRD" : "",
58822
+ item.planAtPickup ? "plan at pickup" : ""
58823
+ ].filter(Boolean);
58824
+ lines.push(`- ${laneName}${item.order} ${item.issue}${flags.length ? ` — ${flags.join("; ")}` : ""}`);
58825
+ }
58826
+ }
58827
+ return `${lines.join("\n")}\n`;
58828
+ }
58829
+ async function defaultStartOrderBook(book) {
58830
+ const { startFlywheelRun } = await import("./flywheel-DzGtWnJ1.js");
58831
+ return startFlywheelRun({
58832
+ cwd: process.cwd(),
58833
+ orders: book.id
58834
+ });
58835
+ }
58836
+ async function getOrdersPayload(deps = {}) {
58837
+ return routeResult(async () => {
58838
+ const snapshot = buildOrdersReadSnapshot(deps);
58839
+ return { books: snapshot.books.map((book) => enrichedBook(book, deps, snapshot)) };
58840
+ });
58841
+ }
58842
+ async function postOrderPayload(body, deps = {}) {
58843
+ return routeResult(async () => {
58844
+ const stateRoot = stateRootFor(deps);
58845
+ const name = requireString(body["name"], "name");
58846
+ return enrichedBook(await createBook(stateRoot, {
58847
+ id: body["id"] === void 0 ? nextBookId(stateRoot, name, (deps.now ?? (() => /* @__PURE__ */ new Date()))()) : requireString(body["id"], "id"),
58848
+ name,
58849
+ settings: body["settings"] === void 0 ? void 0 : settingsPatch(body["settings"])
58850
+ }), deps);
58851
+ });
58852
+ }
58853
+ async function getOrderPayload(bookId, deps = {}) {
58854
+ return routeResult(async () => enrichedBook(requireBook(stateRootFor(deps), bookId), deps));
58855
+ }
58856
+ async function patchOrderPayload(bookId, body, deps = {}) {
58857
+ return routeResult(async () => {
58858
+ const stateRoot = stateRootFor(deps);
58859
+ const patch = body["settings"] === void 0 ? void 0 : settingsPatch(body["settings"]);
58860
+ if (patch?.posture !== void 0) {
58861
+ patch.postureSetAt = (deps.now ?? (() => /* @__PURE__ */ new Date()))().toISOString();
58862
+ patch.postureSetBy = (deps.actor ?? (() => "dashboard"))();
58863
+ }
58864
+ if (body["status"] !== void 0) {
58865
+ if (body["status"] !== "ready") throw new Error("status may only transition to ready through this route");
58866
+ if (body["runId"] !== void 0) throw new Error("runId is server-controlled");
58867
+ if (requireBook(stateRoot, bookId).status !== "draft") throw new Error(`Order book ${bookId} must be draft before it can be queued`);
58868
+ }
58869
+ let changed = false;
58870
+ if (body["name"] !== void 0) {
58871
+ await renameBook(stateRoot, bookId, requireString(body["name"], "name"));
58872
+ changed = true;
58873
+ }
58874
+ if (patch !== void 0) {
58875
+ await setSettings(stateRoot, bookId, patch);
58876
+ changed = true;
58877
+ }
58878
+ if (body["status"] !== void 0) {
58879
+ await setStatus(stateRoot, bookId, "ready");
58880
+ changed = true;
58881
+ }
58882
+ if (!changed) throw new Error("name, settings, or status is required");
58883
+ return enrichedBook(requireBook(stateRoot, bookId), deps);
58884
+ });
58885
+ }
58886
+ async function postOrderItemsPayload(bookId, body, deps = {}) {
58887
+ return routeResult(async () => {
58888
+ const stateRoot = stateRootFor(deps);
58889
+ const book = requireBook(stateRoot, bookId);
58890
+ const input = body["items"] ?? body["item"];
58891
+ if (input === void 0) throw new Error("items is required");
58892
+ const actor = (deps.actor ?? (() => "dashboard"))();
58893
+ return enrichedBook(await addItems(stateRoot, bookId, parseItems(book, input), actor), deps);
58894
+ });
58895
+ }
58896
+ async function deleteOrderItemPayload(bookId, issueId, deps = {}) {
58897
+ return routeResult(async () => enrichedBook(await removeItem(stateRootFor(deps), bookId, issueId), deps));
58898
+ }
58899
+ async function patchOrderItemPayload(bookId, issueId, body, deps = {}) {
58900
+ return routeResult(async () => {
58901
+ const stateRoot = stateRootFor(deps);
58902
+ const existing = requireBook(stateRoot, bookId).items.find((item) => item.issue.toUpperCase() === issueId.toUpperCase());
58903
+ if (!existing) throw new Error(`Issue ${issueId.toUpperCase()} is not in order book ${bookId}`);
58904
+ let changed = false;
58905
+ if (body["lane"] !== void 0 || body["order"] !== void 0) {
58906
+ await moveItem(stateRoot, bookId, issueId, lane(body["lane"], existing.lane), positiveInteger(body["order"], "order", existing.order));
58907
+ changed = true;
58908
+ }
58909
+ if (body["prereqs"] !== void 0 || body["reVerify"] !== void 0 || body["planAtPickup"] !== void 0) {
58910
+ await setItemRequirements(stateRoot, bookId, issueId, {
58911
+ prereqs: body["prereqs"] === void 0 ? void 0 : stringArray(body["prereqs"], "prereqs"),
58912
+ reVerify: optionalBoolean(body["reVerify"], "reVerify"),
58913
+ planAtPickup: optionalBoolean(body["planAtPickup"], "planAtPickup")
58914
+ });
58915
+ changed = true;
58916
+ }
58917
+ if (!changed) throw new Error("lane, order, prereqs, reVerify, or planAtPickup is required");
58918
+ return enrichedBook(requireBook(stateRoot, bookId), deps);
58919
+ });
58920
+ }
58921
+ async function getBacklogCandidatesPayload(limit, deps = {}) {
58922
+ return routeResult(async () => ({ candidates: backlogCandidates(stateRootFor(deps), Math.max(1, Math.min(100, limit))) }));
58923
+ }
58924
+ async function postOrderStartPayload(bookId, deps = {}) {
58925
+ return routeResult(async () => {
58926
+ const stateRoot = stateRootFor(deps);
58927
+ const book = requireBook(stateRoot, bookId);
58928
+ const validation = validateBookForStart(stateRoot, book, {
58929
+ issueLookup: deps.issueLookup,
58930
+ hasPrd: deps.hasPrd
58931
+ });
58932
+ if (validation.blocks.length > 0) return {
58933
+ __routeStatus: 422,
58934
+ error: `Order book ${bookId} cannot start`,
58935
+ findings: validation.blocks,
58936
+ warnings: validation.warns
58937
+ };
58938
+ return {
58939
+ ok: true,
58940
+ runId: (await (deps.startOrderBook ?? defaultStartOrderBook)(book)).runId,
58941
+ warnings: validation.warns
58942
+ };
58943
+ }).then((result) => {
58944
+ if (result.status === 200 && result.body && typeof result.body === "object" && "__routeStatus" in result.body) {
58945
+ const { __routeStatus, ...body } = result.body;
58946
+ return {
58947
+ status: Number(__routeStatus),
58948
+ body
58949
+ };
58950
+ }
58951
+ return result;
58952
+ });
58953
+ }
58954
+ async function getPreviewBriefPayload(bookId, deps = {}) {
58955
+ return routeResult(async () => {
58956
+ const book = requireBook(stateRootFor(deps), bookId);
58957
+ return {
58958
+ bookId: book.id,
58959
+ brief: previewBrief(book)
58960
+ };
58961
+ });
58962
+ }
58963
+ const readJsonBody$2 = Effect.gen(function* () {
58964
+ const text = yield* (yield* HttpServerRequest.HttpServerRequest).text;
58965
+ if (!text) return {
58966
+ ok: true,
58967
+ body: {}
58968
+ };
58969
+ try {
58970
+ const parsed = JSON.parse(text);
58971
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {
58972
+ ok: false,
58973
+ body: {}
58974
+ };
58975
+ return {
58976
+ ok: true,
58977
+ body: parsed
58978
+ };
58979
+ } catch {
58980
+ return {
58981
+ ok: false,
58982
+ body: {}
58983
+ };
58984
+ }
58985
+ });
58986
+ function mutationAuth(request) {
58987
+ return rejectUnsafeDashboardMutationRequest(request);
58988
+ }
58989
+ function makeOrdersRouteLayer(deps = {}) {
58990
+ const getBacklogCandidatesRoute = HttpRouter.add("GET", "/api/orders/backlog-candidates", httpHandler(Effect.gen(function* () {
58991
+ const request = yield* HttpServerRequest.HttpServerRequest;
58992
+ const url = HttpServerRequest.toURL(request);
58993
+ const rawLimit = url._tag === "Some" ? url.value.searchParams.get("limit") : null;
58994
+ const limit = rawLimit === null ? 10 : Number.parseInt(rawLimit, 10);
58995
+ if (!Number.isInteger(limit) || limit < 1) return jsonResponse({ error: "limit must be a positive integer" }, { status: 400 });
58996
+ return resultResponse(yield* Effect.promise(() => getBacklogCandidatesPayload(limit, deps)));
58997
+ })));
58998
+ const getOrdersRoute = HttpRouter.add("GET", "/api/orders", httpHandler(Effect.gen(function* () {
58999
+ return resultResponse(yield* Effect.promise(() => getOrdersPayload(deps)));
59000
+ })));
59001
+ const postOrderRoute = HttpRouter.add("POST", "/api/orders", httpHandler(Effect.gen(function* () {
59002
+ const authError = mutationAuth(yield* HttpServerRequest.HttpServerRequest);
59003
+ if (authError) return authError;
59004
+ const parsed = yield* readJsonBody$2;
59005
+ if (!parsed.ok) return jsonResponse({ error: "Request body must be a JSON object" }, { status: 400 });
59006
+ return resultResponse(yield* Effect.promise(() => postOrderPayload(parsed.body, deps)));
59007
+ })));
59008
+ const getOrderRoute = HttpRouter.add("GET", "/api/orders/:id", httpHandler(Effect.gen(function* () {
59009
+ const id = (yield* HttpRouter.params)["id"] ?? "";
59010
+ return resultResponse(yield* Effect.promise(() => getOrderPayload(id, deps)));
59011
+ })));
59012
+ const patchOrderRoute = HttpRouter.add("PATCH", "/api/orders/:id", httpHandler(Effect.gen(function* () {
59013
+ const authError = mutationAuth(yield* HttpServerRequest.HttpServerRequest);
59014
+ if (authError) return authError;
59015
+ const parsed = yield* readJsonBody$2;
59016
+ if (!parsed.ok) return jsonResponse({ error: "Request body must be a JSON object" }, { status: 400 });
59017
+ const id = (yield* HttpRouter.params)["id"] ?? "";
59018
+ return resultResponse(yield* Effect.promise(() => patchOrderPayload(id, parsed.body, deps)));
59019
+ })));
59020
+ const postOrderItemsRoute = HttpRouter.add("POST", "/api/orders/:id/items", httpHandler(Effect.gen(function* () {
59021
+ const authError = mutationAuth(yield* HttpServerRequest.HttpServerRequest);
59022
+ if (authError) return authError;
59023
+ const parsed = yield* readJsonBody$2;
59024
+ if (!parsed.ok) return jsonResponse({ error: "Request body must be a JSON object" }, { status: 400 });
59025
+ const id = (yield* HttpRouter.params)["id"] ?? "";
59026
+ return resultResponse(yield* Effect.promise(() => postOrderItemsPayload(id, parsed.body, deps)));
59027
+ })));
59028
+ const deleteOrderItemRoute = HttpRouter.add("DELETE", "/api/orders/:id/items/:issue", httpHandler(Effect.gen(function* () {
59029
+ const authError = mutationAuth(yield* HttpServerRequest.HttpServerRequest);
59030
+ if (authError) return authError;
59031
+ const params = yield* HttpRouter.params;
59032
+ return resultResponse(yield* Effect.promise(() => deleteOrderItemPayload(params["id"] ?? "", params["issue"] ?? "", deps)));
59033
+ })));
59034
+ const patchOrderItemRoute = HttpRouter.add("PATCH", "/api/orders/:id/items/:issue", httpHandler(Effect.gen(function* () {
59035
+ const authError = mutationAuth(yield* HttpServerRequest.HttpServerRequest);
59036
+ if (authError) return authError;
59037
+ const parsed = yield* readJsonBody$2;
59038
+ if (!parsed.ok) return jsonResponse({ error: "Request body must be a JSON object" }, { status: 400 });
59039
+ const params = yield* HttpRouter.params;
59040
+ return resultResponse(yield* Effect.promise(() => patchOrderItemPayload(params["id"] ?? "", params["issue"] ?? "", parsed.body, deps)));
59041
+ })));
59042
+ const postOrderStartRoute = HttpRouter.add("POST", "/api/orders/:id/start", httpHandler(Effect.gen(function* () {
59043
+ const authError = mutationAuth(yield* HttpServerRequest.HttpServerRequest);
59044
+ if (authError) return authError;
59045
+ const id = (yield* HttpRouter.params)["id"] ?? "";
59046
+ return resultResponse(yield* Effect.promise(() => postOrderStartPayload(id, deps)));
59047
+ })));
59048
+ const getPreviewBriefRoute = HttpRouter.add("GET", "/api/orders/:id/preview-brief", httpHandler(Effect.gen(function* () {
59049
+ const id = (yield* HttpRouter.params)["id"] ?? "";
59050
+ return resultResponse(yield* Effect.promise(() => getPreviewBriefPayload(id, deps)));
59051
+ })));
59052
+ return Layer.mergeAll(getBacklogCandidatesRoute, getOrdersRoute, postOrderRoute, getPreviewBriefRoute, postOrderStartRoute, postOrderItemsRoute, deleteOrderItemRoute, patchOrderItemRoute, getOrderRoute, patchOrderRoute);
59053
+ }
59054
+ const ordersRouteLayer = makeOrdersRouteLayer();
59055
+ //#endregion
57205
59056
  //#region ../../lib/artifacts/thumbnails.ts
57206
59057
  init_paths();
57207
59058
  const DEFAULT_THUMBNAIL_WIDTH = 640;
@@ -57615,9 +59466,9 @@ const postArtifactUnshareRoute = HttpRouter.add("POST", "/api/artifacts/:slug/un
57615
59466
  const artifactsRouteLayer = Layer.mergeAll(getRawArtifactRoute, getArtifactDetailRoute, getWorkspaceArtifactsRoute, getArtifactThumbnailRoute, postArtifactUnshareRoute);
57616
59467
  //#endregion
57617
59468
  //#region ../../lib/database/agent-mappers.ts
59469
+ init_sequence_io();
57618
59470
  init_pickup();
57619
59471
  init_label_ops();
57620
- init_sequence_io();
57621
59472
  function agentStateToDbAgent(state) {
57622
59473
  return {
57623
59474
  id: state.id,
@@ -60066,6 +61917,7 @@ const HttpServerLive = Layer.unwrap(Effect.gen(function* () {
60066
61917
  const bind = retryDashboardBind(NodeHttpServer.make(() => {
60067
61918
  const nodeServer = NodeHttp.createServer();
60068
61919
  setupTerminalWebSocket(nodeServer);
61920
+ setupKnowledgeViewerProxy(nodeServer);
60069
61921
  setupVoiceWebSocket(nodeServer);
60070
61922
  setupAutoPresoWebSocket(nodeServer);
60071
61923
  return nodeServer;
@@ -60155,7 +62007,7 @@ const staticRouteLayer = HttpRouter.add("GET", "*", Effect.gen(function* () {
60155
62007
  if (filePath.endsWith("index.html")) return HttpServerResponse.setHeader(res, "Cache-Control", "no-cache, no-store, must-revalidate");
60156
62008
  return res;
60157
62009
  }));
60158
- const makeRoutesLayer = Layer.mergeAll(healthRouteLayer, dashboardSessionPreflightRouteLayer, dashboardSessionRouteLayer, websocketRpcRouteLayer, issuesRouteLayer, agentsRouteLayer, workspacesRouteLayer, specialistsRouteLayer, costsRouteLayer, cloisterRouteLayer, resourcesRouteLayer, commandDeckRouteLayer, remoteRouteLayer, settingsRouteLayer, voiceRouteLayer, autopresoRouteLayer, metricsRouteLayer, miscRouteLayer, paletteRouteLayer, conversationsRouteLayer, eventsRouteLayer, showRouteLayer, projectsRouteLayer, contextRouteLayer, adminRouteLayer, prereqsRouteLayer, cliproxyRouteLayer, ttsRouteLayer, webhooksRouteLayer, hooksRouteLayer, diffsRouteLayer, codexAuthRouteLayer, terminalsRouteLayer, discoveredSessionsRouteLayer, flywheelRouteLayer, artifactsRouteLayer, featureRegistryRouteLayer, fsRouteLayer, tieredCalloutsRouteLayer, backlogRouteLayer, internalEventsRouteLayer, staticRouteLayer);
62010
+ const makeRoutesLayer = Layer.mergeAll(healthRouteLayer, dashboardSessionPreflightRouteLayer, dashboardSessionRouteLayer, websocketRpcRouteLayer, issuesRouteLayer, pipelineMembershipRouteLayer, agentsRouteLayer, workspacesRouteLayer, specialistsRouteLayer, costsRouteLayer, cloisterRouteLayer, resourcesRouteLayer, commandDeckRouteLayer, remoteRouteLayer, settingsRouteLayer, voiceRouteLayer, autopresoRouteLayer, metricsRouteLayer, miscRouteLayer, paletteRouteLayer, conversationsRouteLayer, eventsRouteLayer, showRouteLayer, projectsRouteLayer, contextRouteLayer, adminRouteLayer, prereqsRouteLayer, cliproxyRouteLayer, ttsRouteLayer, webhooksRouteLayer, hooksRouteLayer, diffsRouteLayer, codexAuthRouteLayer, terminalsRouteLayer, discoveredSessionsRouteLayer, flywheelRouteLayer, ordersRouteLayer, artifactsRouteLayer, featureRegistryRouteLayer, fsRouteLayer, tieredCalloutsRouteLayer, backlogRouteLayer, internalEventsRouteLayer, knowledgeViewerRouteLayer, staticRouteLayer);
60159
62011
  const OverdeckAgentsResolverLive = AgentsResolverLive.pipe(Layer.provide(Layer.mergeAll(DbLive, TmuxLive)));
60160
62012
  const OverdeckCostResolverLive = CostResolverLive.pipe(Layer.provide(DbLive));
60161
62013
  const ReadModelWithOverdeckLive = ReadModelServiceLive.pipe(Layer.provide(OverdeckAgentsResolverLive));
@@ -62176,7 +64028,7 @@ const RESTART_MARKER = join$1(homedir(), ".overdeck", "dashboard-restarting.json
62176
64028
  * loads new content-hashed chunk filenames (no ERR_MODULE_NOT_FOUND after rebuild).
62177
64029
  */
62178
64030
  async function defaultLifecycleRunner(pending) {
62179
- const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-BQM3a8z5.js");
64031
+ const { postMergeLifecycle, notifyTldrDaemon } = await import("./merge-agent-CKkgIBPB.js");
62180
64032
  await postMergeLifecycle(pending.issueId, pending.projectPath, pending.sourceBranch, { skipDeploy: true });
62181
64033
  if (pending.sourceBranch) await notifyTldrDaemon(pending.projectPath, pending.sourceBranch);
62182
64034
  }
@@ -62497,7 +64349,7 @@ function failureReason(result) {
62497
64349
  return result.error ?? result.message ?? `merge returned status ${result.statusCode ?? "unknown"}`;
62498
64350
  }
62499
64351
  async function defaultMergeIssue(issueId) {
62500
- const { triggerMerge } = await import("./merge-ops-DlB1IM0Y.js");
64352
+ const { triggerMerge } = await import("./merge-ops-CR44oU9-.js");
62501
64353
  return triggerMerge(issueId);
62502
64354
  }
62503
64355
  function defaultAnnounceFailure(issueId, reason) {
@@ -62744,7 +64596,7 @@ const defaultDependencies = {
62744
64596
  inspect: inspectStateMigration,
62745
64597
  ensureWorktree: ensureStateWorktree,
62746
64598
  migrate: async (projectKey, project, signal) => {
62747
- const { migrateProjectState } = await import("./state-migrate-Dkzaxvny.js");
64599
+ const { migrateProjectState } = await import("./state-migrate-BGg2ZaOt.js");
62748
64600
  await migrateProjectState(projectKey, { signal }, project);
62749
64601
  },
62750
64602
  clearCache: clearStateMigrationCache,
@@ -62952,7 +64804,7 @@ if (shouldStartStaleCheckRetriggerService()) {
62952
64804
  }
62953
64805
  if (process.env.OVERDECK_MODE === "desktop") (async () => {
62954
64806
  try {
62955
- const { provisionClaudeHooks } = await import("./claude-hooks-provision-C8wdRnN1.js");
64807
+ const { provisionClaudeHooks } = await import("./claude-hooks-provision-8Ngo8TpT.js");
62956
64808
  const result = await provisionClaudeHooks();
62957
64809
  if (!result.ok) console.warn(`[overdeck] Claude hook provisioning skipped: ${result.reason}`);
62958
64810
  else if (result.changed) console.log(`[overdeck] Claude hooks provisioned: ${result.binariesSynced} scripts, registered ${result.registered.length} hook(s)${result.pruned.length ? `, pruned ${result.pruned.length} stale` : ""}`);
@@ -63293,9 +65145,10 @@ const handleShutdownSignal = async (signal) => {
63293
65145
  stopCostReconcileService();
63294
65146
  stopStaleCheckRetriggerService();
63295
65147
  stopRestartAnnouncer();
65148
+ await stopAllKnowledgeViewers().catch((err) => console.warn("[knowledge-viewer] shutdown failed:", err?.message ?? err));
63296
65149
  await stopDeaconChild().catch((err) => console.warn("[deacon-supervisor] child shutdown failed:", err?.message ?? err));
63297
65150
  try {
63298
- const { killAllGateProcessGroups } = await import("./validation-CIi6pnI2.js");
65151
+ const { killAllGateProcessGroups } = await import("./validation-CC9OPqJZ.js");
63299
65152
  const reaped = killAllGateProcessGroups();
63300
65153
  if (reaped > 0) console.log(`[overdeck] reaped ${reaped} in-flight gate process group(s)`);
63301
65154
  } catch (err) {
@@ -63350,7 +65203,7 @@ reconcileStaleGitHubBlockers().then((n) => {
63350
65203
  }
63351
65204
  }).catch((err) => console.warn(`[overdeck] Startup blocker reconciliation failed: ${err.message}`));
63352
65205
  try {
63353
- const { resetProcessingToQueued } = await import("./merge-sync-SSv3E-pl.js");
65206
+ const { resetProcessingToQueued } = await import("./merge-sync-BJYeOODr.js");
63354
65207
  const resetCount = resetProcessingToQueued();
63355
65208
  if (resetCount > 0) {
63356
65209
  console.log(`[overdeck] Reset ${resetCount} stuck merge queue entries to queued`);
@@ -63372,7 +65225,7 @@ else {
63372
65225
  console.log("[overdeck] Auto-merge executor started");
63373
65226
  }
63374
65227
  try {
63375
- const { reconcileInterruptedVerifications } = await import("./verification-runner-CDj4lD4t.js");
65228
+ const { reconcileInterruptedVerifications } = await import("./verification-runner-BW4HOKAz.js");
63376
65229
  const interrupted = reconcileInterruptedVerifications();
63377
65230
  if (interrupted > 0) console.log(`[overdeck] recovered ${interrupted} orphaned verification worker(s)`);
63378
65231
  } catch (err) {