@overdeck/desktop 0.45.15 → 0.45.18

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 (372) hide show
  1. package/dist-electron/main.js +149 -158
  2. package/dist-electron/main.js.map +1 -1
  3. package/dist-electron/preload.js +17 -2
  4. package/dist-electron/preload.js.map +1 -1
  5. package/package.json +5 -4
  6. package/server/acceptance-criteria-aQFKQf-J.js +62 -0
  7. package/server/{advancing-selfheal-CSuZ31bB.js → advancing-selfheal-DgwQgm4D.js} +6 -5
  8. package/server/{agent-gc-D_DxfBHR.js → agent-gc-kpzxqT7P.js} +3 -3
  9. package/server/agent-state-C_6TG-Ad.js +3 -0
  10. package/server/{agent-state-service-C_2ZAQRP.js → agent-state-service-BUfovFfB.js} +1 -1
  11. package/server/{agent-state-service-BZkvgQf4.js → agent-state-service-nUD3qfob.js} +9 -52
  12. package/server/agents-BA15AQqo.js +3 -0
  13. package/server/{briefing-freshness-Kh5V8RTh.js → agents-BHBxr8c9.js} +5 -131
  14. package/server/{archive-planning-DkivCk1A.js → archive-planning-CzCW9Ifl.js} +5 -10
  15. package/server/{archive-planning-CTILQRnV.js → archive-planning-D-QsBufn.js} +1 -1
  16. package/server/{artifact-index-jobs-CmsvQ1ey.js → artifact-index-jobs-qqa51B2Z.js} +2 -2
  17. package/server/{backlog-auto-trigger-ueRaT8Dy.js → backlog-auto-trigger-B7Bi0bvY.js} +3 -3
  18. package/server/behavior-CWqNMqE5.js +10 -0
  19. package/server/briefing-freshness-DuxIE1yr.js +131 -0
  20. package/server/{checkpoint-manager-fu9oVsR-.js → checkpoint-manager-DF6hb9Jw.js} +3 -3
  21. package/server/{checkpoint-manager-CAFos8e1.js → checkpoint-manager-DixkLus7.js} +1 -1
  22. package/server/checkpoint-worker.js +1 -1
  23. package/server/{checkpoints-DvhGi8P_.js → checkpoints-B1Z42tJE.js} +1 -1
  24. package/server/{checkpoints-1BqOlS4q.js → checkpoints-BiviJqei.js} +2 -2
  25. package/server/claude-hooks-provision-BeMGi4ty.js +3 -0
  26. package/server/{claude-hooks-provision-s_wdpeVj.js → claude-hooks-provision-Du_PkMsp.js} +132 -114
  27. package/server/{claude-permissions-CaWqysff.js → claude-permissions-BB6agcOZ.js} +2 -2
  28. package/server/{claude-settings-overlay-CcTf0xzG.js → claude-settings-overlay-CAq2oFSK.js} +2 -2
  29. package/server/{claude-settings-overlay-BbA4FbVI.js → claude-settings-overlay-DUWWLd6M.js} +1 -1
  30. package/server/cli-BFgrSWKV.js +3 -0
  31. package/server/{cli-BwCvCUBK.js → cli-C33xPZNm.js} +9 -9
  32. package/server/{cliproxy-C2xC-3vH.js → cliproxy-BQX1TL6N.js} +1 -1
  33. package/server/{cliproxy-BsoNNDAj.js → cliproxy-CGBA1GzA.js} +2 -2
  34. package/server/{close-issue-BleIwP3f.js → close-issue-DNv8npc1.js} +5 -5
  35. package/server/{closed-issue-reaper-BwUUvjEW.js → closed-issue-reaper-DrqgBJlr.js} +1 -1
  36. package/server/{closed-issue-reaper-mC5pujeb.js → closed-issue-reaper-LoMnnjtJ.js} +9 -9
  37. package/server/codex-DxLivxri.js +3 -0
  38. package/server/{behavior-Cpj03N4v.js → codex-parser-DboQnEXN.js} +3 -9
  39. package/server/{codex-DW60_5j2.js → codex-sgWVCGUd.js} +43 -17
  40. package/server/{config-BRNQJXhA.js → config-6MCHOZ2N.js} +1 -1
  41. package/server/{config-ZNnMpIlh.js → config-DfaUXr6r.js} +2 -2
  42. package/server/{config-yaml-Dcz-8uit.js → config-yaml-CqaAyn8y.js} +149 -80
  43. package/server/{conflict-gate-DTje2Ll7.js → conflict-gate-BF_zhcmb.js} +3 -3
  44. package/server/{conflict-gate-DGT8jCLp.js → conflict-gate-BubJprtD.js} +1 -1
  45. package/server/{context-layers-BdUCQ-cl.js → context-layers-BFrxfl0l.js} +17 -3
  46. package/server/{context-layers-ByOWUjUg.js → context-layers-DWL_8HhY.js} +2 -2
  47. package/server/{control-settings-DwkAeooY.js → control-settings-BguNQ1F_.js} +4 -4
  48. package/server/{conversation-compaction-WYQZUVDm.js → conversation-compaction-CRKAf2qP.js} +1 -1
  49. package/server/{conversation-compaction-OTYgd6eg.js → conversation-compaction-DxSXl0pT.js} +8 -8
  50. package/server/{conversation-service-C_kNZPLx.js → conversation-service-DzuY9qoH.js} +1 -1
  51. package/server/{conversation-service-BR1OgvxO.js → conversation-service-mFVFdDQK.js} +6 -5
  52. package/server/{conversations-DG2M8WnT.js → conversations-BX5aD-6F.js} +4 -4
  53. package/server/{conversations-izHvSoAR.js → conversations-BajHQ60c.js} +1 -1
  54. package/server/{cost-DQ2ajr_m.js → cost-BoqD1Pxz.js} +2 -2
  55. package/server/{cost-B2mj17iG.js → cost-DuZ5vlv-.js} +3 -3
  56. package/server/{cost-sync-gTayEuWP.js → cost-sync-BYnmnMkY.js} +3 -3
  57. package/server/{dag-CqTehWpY.js → dag-C6kYyF17.js} +7 -243
  58. package/server/{dangerous-git-ops-DDWQlPC3.js → dangerous-git-ops-q5OPtXMd.js} +1 -1
  59. package/server/dashboard-db-worker.js +6 -6
  60. package/server/{deacon-BqW9HMew.js → deacon-CwCiNuEZ.js} +3 -3
  61. package/server/{deacon-DrKDBeJL.js → deacon-Dru5onpk.js} +258 -167
  62. package/server/{deacon-nudge-log-D1wEK6zF.js → deacon-nudge-log-ilDfxrhK.js} +1 -1
  63. package/server/{deacon-swarm-CO_A7xyd.js → deacon-swarm-BPmBmSoU.js} +298 -72
  64. package/server/deacon-swarm-CKyGJng1.js +2 -0
  65. package/server/deacon.js +14 -7
  66. package/server/{devcontainer-renderer-BQolp_qZ.js → devcontainer-renderer-BqGNCzvN.js} +3 -3
  67. package/server/{dist-Bc32rWJB.js → dist-BwlEiLCU.js} +1 -1
  68. package/server/dist-Bx4KkgYL.js +3 -0
  69. package/server/{dist-src-Byxt1ifL.js → dist-src-BE0Denfs.js} +1 -1
  70. package/server/{docker-s-esqZ__.js → docker-CNjXS72x.js} +2 -2
  71. package/server/{ensure-devcontainer-DA4-jF6R.js → ensure-devcontainer-5e9xOve4.js} +4 -4
  72. package/server/{ensure-devcontainer-pUVaT0h3.js → ensure-devcontainer-C6gyUQdE.js} +1 -1
  73. package/server/{esm-shims-CJHy8CZY.js → esm-shims-Cso7IGBC.js} +1 -1
  74. package/server/{event-store-CcJAhKCl.js → event-store-D9UhQyMS.js} +1 -1
  75. package/server/{event-store-DRte2Rwt.js → event-store-KZnWUKWh.js} +3 -3
  76. package/server/{events-Bej1w_k8.js → events-2eFUPdqz.js} +3 -3
  77. package/server/{events-CtsLScn8.js → events-BYbvqZky.js} +1 -1
  78. package/server/{factory-FN727tWr.js → factory-BtaRsHFC.js} +20 -17
  79. package/server/{feature-registry-population-ie-yBcQC.js → feature-registry-population-Ca2UaV0U.js} +4 -4
  80. package/server/{feature-registry-storage-CkZTFSsn.js → feature-registry-storage-DaP-bQxO.js} +2 -2
  81. package/server/{features-Dtm9ABuz.js → features-DqvaoQoa.js} +2 -2
  82. package/server/{feedback-target-BYtpyt1i.js → feedback-target-BXWdOiYI.js} +9 -7
  83. package/server/{feedback-target-DVJQDiE4.js → feedback-target-BblmMe9P.js} +1 -1
  84. package/server/{feedback-writer-DOUhyIW2.js → feedback-writer-CULeOOY4.js} +1 -1
  85. package/server/{feedback-writer-fdE1BzeL.js → feedback-writer-Dn8o9ZyE.js} +4 -4
  86. package/server/{flywheel-Bi82iiNl.js → flywheel-BUWdcfhq.js} +1 -1
  87. package/server/{flywheel-Bv3wv2S6.js → flywheel-CqkO3cDj.js} +15 -28
  88. package/server/{flywheel-CUErLAyN.js → flywheel-D9r1mw2U.js} +13 -13
  89. package/server/{flywheel-merge-order-DXjeBnJ1.js → flywheel-merge-order-LDzQDwSg.js} +1 -1
  90. package/server/{flywheel-merge-order-BaEN3iyN.js → flywheel-merge-order-VtjUweEb.js} +7 -7
  91. package/server/forge-DJy3Zx4s.js +2 -0
  92. package/server/{forge-ButEdJ31.js → forge-wEollMCi.js} +22 -12
  93. package/server/{from-CbtTxftl.js → from-B2tOYhYV.js} +1 -1
  94. package/server/{fts-db-CBgBLZcL.js → fts-db-Bgzn2RO7.js} +2 -2
  95. package/server/{fts-operations-CI9Xuo_1.js → fts-operations-Bj8yutnR.js} +2 -2
  96. package/server/{git-utils-ClfpP47N.js → git-utils-GxlL0tmt.js} +2 -2
  97. package/server/{git-utils-BCLRWQ-y.js → git-utils-q8jNoBts.js} +1 -1
  98. package/server/{github-app-DRD2woO0.js → github-app-BrYwK_Gb.js} +1 -1
  99. package/server/{github-app-DscZ0_B6.js → github-app-tUbb8Ldr.js} +8 -3
  100. package/server/{github-client-DpiZnxGH.js → github-client-BwBU41jK.js} +3 -3
  101. package/server/{github-client-iFRw8f7e.js → github-client-D6CNsftm.js} +1 -1
  102. package/server/{github-pr-lookup-D-EBexxC.js → github-pr-lookup-BS5PqkJb.js} +2 -2
  103. package/server/{harness-resolve-iMjyNUJ2.js → harness-resolve-Dx8hUsvC.js} +3 -3
  104. package/server/{health-events-CRdxDFN2.js → health-events-2DLp-5Xp.js} +2 -2
  105. package/server/{health-events-B_WsQyYm.js → health-events-B0mj6Iae.js} +1 -1
  106. package/server/{hooks-C1ScyVxP.js → hooks-BDcQJDUe.js} +1 -1
  107. package/server/{hooks-C9b7Vqpw.js → hooks-BS_JrvYP.js} +3 -3
  108. package/server/hume-B4seN95Y.js +3 -0
  109. package/server/{hume-TQ5pvOZ_.js → hume-BRhNKyXQ.js} +2 -2
  110. package/server/{idle-stack-reaper-B1kG7B_X.js → idle-stack-reaper-BCITXNW5.js} +2 -2
  111. package/server/{idle-stack-reaper-iFVOAoJy.js → idle-stack-reaper-C1ymihno.js} +1 -1
  112. package/server/{infra-bpq1MHKU.js → infra-_Kx1m9pm.js} +9 -4
  113. package/server/{injection-BLWfwTVZ.js → injection-Bvhyg_MV.js} +1 -1
  114. package/server/{injection-DJqWld1v.js → injection-CCaYkofq.js} +7 -7
  115. package/server/{inspect-agent-DytCsltn.js → inspect-agent-BqyZ4pCo.js} +35 -67
  116. package/server/inspect-agent-DCJQm9Wu.js +2 -0
  117. package/server/{internal-token-CjlhdufS.js → internal-token-Cl-1IxaE.js} +2 -2
  118. package/server/{internal-token-CCaWaTwE.js → internal-token-D-t28de5.js} +1 -1
  119. package/server/{io-BiQ2Cs3k.js → io-DkC4sFSy.js} +42 -56
  120. package/server/{issue-closed-FApNiOOs.js → issue-closed-Cpl4VDUM.js} +41 -6
  121. package/server/{issue-lifecycle-C-K53ASY.js → issue-lifecycle-CFR8TJ22.js} +22 -37
  122. package/server/{issue-lifecycle-BkFWNjlD.js → issue-lifecycle-YNTy3OT3.js} +1 -1
  123. package/server/{issue-service-singleton-bG1WdSdQ.js → issue-service-singleton-D81mCts_.js} +1 -1
  124. package/server/{issue-service-singleton-CuHGpJJP.js → issue-service-singleton-ldvUUXi3.js} +29 -29
  125. package/server/{issues-CwQMphDH.js → issues-DIEHt9sq.js} +2 -2
  126. package/server/{jsonl-parser-dNIjHgym.js → jsonl-parser-Cd5jIqh7.js} +3 -3
  127. package/server/{label-cleanup-DYvAZknd.js → label-cleanup-Btny6Gyo.js} +3 -3
  128. package/server/{state-home-CRowbXqU.js → launcher-generator-BXLM9f4b.js} +7 -127
  129. package/server/{layers-CD6FysRU.js → layers-gCJlK62m.js} +2 -2
  130. package/server/lifecycle-D7aQUnTO.js +12 -0
  131. package/server/{lifecycle-io-C_Wu0_i-.js → lifecycle-io-DQBF-GHO.js} +1 -1
  132. package/server/{lifecycle-io-CeYxP3cE.js → lifecycle-io-FfPUtz-y.js} +36 -47
  133. package/server/{linear-client-EtVyblVz.js → linear-client-CDH2D6Qy.js} +3 -3
  134. package/server/{linear-client-4qoKnuQu.js → linear-client-WrYrUIAH.js} +1 -1
  135. package/server/memory-fts-worker.js +1 -1
  136. package/server/{merge-7rqkTUm2.js → merge-BsDgUxFz.js} +3 -3
  137. package/server/{merge-brm721Es.js → merge-Dervs4BF.js} +1 -1
  138. package/server/{merge-agent-4Zhlgvqp.js → merge-agent-D6DNhe9j.js} +64 -51
  139. package/server/{merge-agent-36wfYm2u.js → merge-agent-DMQTJMP0.js} +1 -1
  140. package/server/{merge-batch-itfnwdsT.js → merge-batch-Bv6Z5K2H.js} +1 -1
  141. package/server/{merge-blockers-Bto_Oe_o.js → merge-blockers-WWWi6Ur2.js} +2 -2
  142. package/server/merge-ops-h9OCnIVz.js +2 -0
  143. package/server/{merge-rebase-Czfqfe4q.js → merge-rebase-Czth9ggm.js} +2 -2
  144. package/server/{merge-set-BIkGQL9j.js → merge-set-DNc4zBqd.js} +3 -3
  145. package/server/{merge-set-G1RHcu3D.js → merge-set-vuE3MEVt.js} +1 -1
  146. package/server/{merge-sync-B43Dybea.js → merge-sync-B2KSk54U.js} +2 -2
  147. package/server/{merge-sync-DIrmlZUr.js → merge-sync-B9nHdUGx.js} +1 -1
  148. package/server/{merge-train-DGqVuNZV.js → merge-train-DJgr81tF.js} +3 -3
  149. package/server/{merge-train-deps-q15XLnAS.js → merge-train-deps-B2OWS0k9.js} +4 -4
  150. package/server/{merge-verification-Cqfxx6bE.js → merge-verification-BBIXUEqa.js} +4 -4
  151. package/server/{multipart-parser-CiPxxfUH.js → multipart-parser-9DhuAkPd.js} +2 -2
  152. package/server/{no-resume-mode-yrPEQ_pC.js → no-resume-mode-Gh5R_YLF.js} +1 -1
  153. package/server/node_modules/.package-lock.json +11 -11
  154. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +3 -3
  155. package/server/node_modules/toml/README.md +54 -0
  156. package/server/node_modules/toml/index.d.ts +42 -1
  157. package/server/node_modules/toml/index.js +3 -3
  158. package/server/node_modules/toml/lib/compiler.js +35 -3
  159. package/server/node_modules/toml/lib/parser.js +224 -143
  160. package/server/node_modules/toml/package.json +3 -1
  161. package/server/node_modules/ws/lib/receiver.js +15 -32
  162. package/server/node_modules/ws/lib/websocket-server.js +4 -4
  163. package/server/node_modules/ws/lib/websocket.js +4 -4
  164. package/server/node_modules/ws/package.json +5 -1
  165. package/server/{orphan-proposed-reconciler-BWWHn4Lr.js → orphan-proposed-reconciler-B8H41C4a.js} +14 -24
  166. package/server/{orphan-proposed-reconciler-DAD9FJtQ.js → orphan-proposed-reconciler-DbTmT7qy.js} +1 -1
  167. package/server/package-lock.json +12 -12
  168. package/server/package.json +1 -1
  169. package/server/{pan-dir-Bj7Hy8iu.js → pan-dir-BTw4MdSe.js} +4 -4
  170. package/server/{paths-C9DkhIOT.js → paths-Btkc8mzp.js} +2 -2
  171. package/server/{pickup-CKRuGDsB.js → pickup-BtvRBbvI.js} +1 -1
  172. package/server/{pipeline-notifier-BkKbQ8ji.js → pipeline-notifier-3frIvSi3.js} +1 -1
  173. package/server/{pipeline-notifier-CAurUste.js → pipeline-notifier-DTd19f18.js} +2 -2
  174. package/server/{project-pipelines-BRWaGmI4.js → project-pipelines-B95fcAek.js} +2 -2
  175. package/server/projects-Dc9aoVoG.js +3 -0
  176. package/server/{prompts-DfI5qbTW.js → prompts-CIVmjHxn.js} +2 -2
  177. package/server/{providers-D-5txBRc.js → providers-BLLk5IIb.js} +1 -1
  178. package/server/{providers-CWDXoaMA.js → providers-C-yWibCk.js} +7 -7
  179. package/server/public/assets/chunk-BO2N2NFS-DzKZyoKY.js +103 -0
  180. package/server/public/assets/{diagram-OG6HWLK6-Avtvq2qI.js → diagram-OG6HWLK6-Cx8mWUb8.js} +1 -1
  181. package/server/public/assets/{dist-BEHQuasD.js → dist-BqccLhaw.js} +3 -3
  182. package/server/public/assets/{dist-BvmY-qb1.js → dist-rC3nAs_O.js} +1 -1
  183. package/server/public/assets/{ganttDiagram-6RSMTGT7-7KhCd0fH.js → ganttDiagram-6RSMTGT7-DLYPLf5T.js} +1 -1
  184. package/server/public/assets/{highlighted-body-OFNGDK62-iQoBMTf0.js → highlighted-body-OFNGDK62-D4DqixbV.js} +1 -1
  185. package/server/public/assets/index-CPcysUHk.js +796 -0
  186. package/server/public/assets/index-H5M0yhM4.css +1 -0
  187. package/server/public/assets/{linear-CiJHW9g5.js → linear-yqcXkDfj.js} +1 -1
  188. package/server/public/assets/mermaid-GHXKKRXX-CWdZ_heB.js +1 -0
  189. package/server/public/assets/{pieDiagram-4H26LBE5-BOhmvUhW.js → pieDiagram-4H26LBE5-DhraIOaV.js} +1 -1
  190. package/server/public/assets/{prod-DmLBBqat.js → prod-DKUunUdN.js} +4 -4
  191. package/server/public/assets/{quadrantDiagram-W4KKPZXB-Cjku660G.js → quadrantDiagram-W4KKPZXB-DPiRcToa.js} +1 -1
  192. package/server/public/assets/{sankeyDiagram-5OEKKPKP-D52w5oPh.js → sankeyDiagram-5OEKKPKP-3An5HNkZ.js} +1 -1
  193. package/server/public/assets/{xychartDiagram-2RQKCTM6-BTO07_Iv.js → xychartDiagram-2RQKCTM6-lbEOjfqQ.js} +1 -1
  194. package/server/public/index.html +2 -2
  195. package/server/{pull-requests-CKZPWhjD.js → pull-requests-D7AL5woD.js} +1 -1
  196. package/server/{pull-requests-Bmre-Xlz.js → pull-requests-NDDNtqNq.js} +3 -3
  197. package/server/{agents-CsOzAmRg.js → queries-C0LCGG21.js} +743 -399
  198. package/server/{rally-BBd9tQ__.js → rally-4oKvnxLG.js} +3 -3
  199. package/server/rally-DF5a3ioP.js +3 -0
  200. package/server/{rally-api-DxZFObI_.js → rally-api-41tT6ikZ.js} +2 -2
  201. package/server/{rally-api-DDc85HIz.js → rally-api-BsaQ8Vnz.js} +1 -1
  202. package/server/{rally-client-DvvLiAQP.js → rally-client-Bo4hNcCZ.js} +5 -5
  203. package/server/{rally-client-BADHn0m_.js → rally-client-b5PT1x5L.js} +1 -1
  204. package/server/{reap-terminal-sessions-D_xvy-Mk.js → reap-terminal-sessions-BR39qflC.js} +1 -1
  205. package/server/{reap-terminal-sessions-D6JDJsqF.js → reap-terminal-sessions-CFkuquQj.js} +1 -1
  206. package/server/{rebuild-stack-GOsWqXi3.js → rebuild-stack-C7JPUom6.js} +1 -1
  207. package/server/{rebuild-stack-D19i080j.js → rebuild-stack-Ddv6W017.js} +6 -6
  208. package/server/{reconstruct-cache-lQrG4xGg.js → reconstruct-cache-Gqhm---K.js} +6 -6
  209. package/server/record-DLOqfbkI.js +3 -0
  210. package/server/record-update-BltEmPge.js +168 -0
  211. package/server/record-update-CDp7aTaT.js +3 -0
  212. package/server/recovery-trip-Cn7KJVkS.js +44 -0
  213. package/server/{release-engine-DxcMWRuK.js → release-engine-BYzmIBf9.js} +5 -5
  214. package/server/{release-set-BYsgX7o6.js → release-set-7pnxFOWR.js} +3 -3
  215. package/server/{remote-DmeL21dF.js → remote-Cvu4CSDk.js} +3 -3
  216. package/server/{remote-agents-BfQBE6MN.js → remote-agents-C2C6z9tj.js} +6 -33
  217. package/server/{remote-agents-DlvbzO7m.js → remote-agents-DYY5fFpd.js} +1 -1
  218. package/server/{remote-completion-BgkiSQmx.js → remote-completion-2Kb4IDg_.js} +13 -13
  219. package/server/{remote-8W2Yhygw.js → remote-rN0ecjHE.js} +3 -3
  220. package/server/resume-BFLl-yLn.js +3 -0
  221. package/server/{review-agent-D025Wt7w.js → review-agent-BZvk0N5G.js} +31 -23
  222. package/server/{review-agent-Rub0OpZc.js → review-agent-CpSHLzed.js} +1 -1
  223. package/server/{review-artifacts-CX951jTU.js → review-artifacts-PCo53YMn.js} +5 -19
  224. package/server/{review-context-DGGGR_w5.js → review-context-M7QtJlJq.js} +8 -8
  225. package/server/{review-monitor-0_qqMcnS.js → review-monitor-BLC5mTTg.js} +2 -2
  226. package/server/{review-status-Br6lAFGO.js → review-status-77N3PoZr.js} +1 -1
  227. package/server/{review-status-4qqLkRMu.js → review-status-DANr0t-v.js} +33 -59
  228. package/server/{review-status-enrichment-Cr8m3uVL.js → review-status-enrichment-DwOg4UfL.js} +3 -3
  229. package/server/{review-status-sync-D3KUhsdA.js → review-status-sync-Bd08OOFA.js} +1 -1
  230. package/server/{review-status-sync-OC-l1lNt.js → review-status-sync-BjTUJ5fx.js} +2 -2
  231. package/server/{review-verdict-feedback-YOzmsq9G.js → review-verdict-feedback-BsFLjN_6.js} +1 -1
  232. package/server/{review-verdict-feedback-DrWMuRaj.js → review-verdict-feedback-CBf-J_wS.js} +8 -8
  233. package/server/{rollup-CnxbwaLH.js → rollup-Bu0f2EyN.js} +8 -8
  234. package/server/{rollup-DmazRY0j.js → rollup-DTCCdEy4.js} +1 -1
  235. package/server/{scanner-DE1MqAaF.js → scanner-BlZ2vB7j.js} +7 -7
  236. package/server/{sequence-io-C0uoqfGx.js → sequence-io-ylyDtz2J.js} +4 -4
  237. package/server/{sequencer-agent-i-b2u4SJ.js → sequencer-agent-DsWQ-87H.js} +6 -17
  238. package/server/server.js +5670 -6392
  239. package/server/{service-D0_gh2tl.js → service-CLVBC_1Y.js} +116 -90
  240. package/server/{session-fork-DZ12vipL.js → session-fork-DlEIAhRy.js} +2 -2
  241. package/server/session-history-bnOFKMwf.js +168 -0
  242. package/server/settings-CP3GGon2.js +2 -0
  243. package/server/{settings-ByqjPtFO.js → settings-Cqa-8nyj.js} +2 -2
  244. package/server/{settings-DCC4BAqj.js → settings-gJrdLZy2.js} +3 -3
  245. package/server/{shadow-engineering-BhnmtW5m.js → shadow-engineering-fq1YEKV3.js} +3 -3
  246. package/server/{shadow-state-ByXZehsy.js → shadow-state-BqeFAygK.js} +1 -1
  247. package/server/{shadow-state-CKm8xWX9.js → shadow-state-RptE9Cau.js} +2 -2
  248. package/server/shadow-utils-BMWr5tRT.js +39 -0
  249. package/server/{ship-log-DE_0Cv_i.js → ship-log-BRQQi2lU.js} +1 -1
  250. package/server/{smart-compaction-D5Zen3AA.js → smart-compaction-CmoXpjeU.js} +7 -7
  251. package/server/{smart-compaction-h4_ca6Uk.js → smart-compaction-DldUel4B.js} +1 -1
  252. package/server/{spawn-planning-session-Dueit4WX.js → spawn-planning-session-CoS6LTc6.js} +16 -16
  253. package/server/{spawn-planning-session-Bgi7Ub02.js → spawn-planning-session-DT2tSMxo.js} +1 -1
  254. package/server/{specialist-completion-BZ8M-WZ0.js → specialist-completion-pJtESo7m.js} +1 -1
  255. package/server/{specialist-context-BMq83C58.js → specialist-context-CspI4Eog.js} +5 -5
  256. package/server/{specialist-handoff-logger-BxX1YefH.js → specialist-handoff-logger-Duz9RGvk.js} +2 -2
  257. package/server/{specialist-logs-BWZYcJ6P.js → specialist-logs-DtSkPJZK.js} +3 -3
  258. package/server/{specialists-ZkW4Mb7U.js → specialists-CywEMwxk.js} +1 -1
  259. package/server/{specialists-8ZAguXef.js → specialists-D9-dMUtI.js} +1 -1
  260. package/server/{specialists-BudKrjOu.js → specialists-Dax7tqXC.js} +1817 -560
  261. package/server/{specialists-DrPrC9Y9.js → specialists-GF42OOqd.js} +18 -18
  262. package/server/specs-VwcFtEDi.js +3 -0
  263. package/server/{src-DHn4Rd2F.js → src-By3D85Ry.js} +77 -1
  264. package/server/{src-Dv6L03vW.js → src-CqyFg52C.js} +5 -5
  265. package/server/{src-DNUUqkec.js → src-DhxM-eCb.js} +6 -6
  266. package/server/{stack-health-Dclm7_tu.js → stack-health-BsEVrJZ6.js} +1 -1
  267. package/server/{stack-health-DxsTx7II.js → stack-health-C-SnpRHh.js} +2 -2
  268. package/server/stale-task-claims-vTxmRzLi.js +69 -0
  269. package/server/state-home-Bur1y4oH.js +213 -0
  270. package/server/{state-mapping-BvAgFK8n.js → state-mapping-Ci0pkac4.js} +1 -1
  271. package/server/state-migrate-D3VveYfO.js +362 -0
  272. package/server/{stuck-remediation-CFWUP8_I.js → stuck-remediation-B699-p8v.js} +63 -46
  273. package/server/{stuck-remediation-CLHd-lrF.js → stuck-remediation-CaFYYTQW.js} +1 -1
  274. package/server/{summary-fork-CKc01Our.js → summary-fork-BxnF8Xh0.js} +2 -2
  275. package/server/{summary-fork-CtCwBJ2Z.js → summary-fork-COqYpVa3.js} +8 -8
  276. package/server/supervisor/{paths-3R6b989k.js → paths-Bk6hJRH9.js} +4 -3
  277. package/server/supervisor/pty-supervisor.js +2 -2
  278. package/server/supervisor/{pty-token-CScQ32Rj.js → pty-token-BZS5GYdG.js} +2 -2
  279. package/server/supervisor-eWAAmXKu.js +2 -0
  280. package/server/{supervisor-BA5D72Qa.js → supervisor-liMgIPDF.js} +2 -2
  281. package/server/{swarm-readiness-CL5sM9B1.js → swarm-readiness-sXB1vhzo.js} +3 -3
  282. package/server/{system-prerequisites-DmFSXIE5.js → system-prerequisites-Bz6KdkFJ.js} +1 -13
  283. package/server/{teardown-workspace-DWmFJzTw.js → teardown-workspace-DvzqnmUF.js} +14 -71
  284. package/server/{test-agent-queue-DjsQoV5X.js → test-agent-queue-hAU1Ah08.js} +6 -6
  285. package/server/{test-verdict-BSqsQp3G.js → test-verdict-CRsPpByy.js} +1 -1
  286. package/server/{test-verdict-D1AmZ2c0.js → test-verdict-CXMLATGc.js} +1 -1
  287. package/server/{tldr-daemon-C-MGomL8.js → tldr-daemon-Bam7Xhoo.js} +2 -2
  288. package/server/{tldr-daemon-DD9rI5gA.js → tldr-daemon-DhGwd88s.js} +1 -1
  289. package/server/tmux-C-rgxRDA.js +3 -0
  290. package/server/{tmux-C_d-lSIq.js → tmux-U55cNGFG.js} +92 -4
  291. package/server/{token-DfBf1bsd.js → token-Dsa-i36o.js} +2 -2
  292. package/server/{token-util-CROoF5ic.js → token-util-BWNpH96m.js} +1 -1
  293. package/server/token-util-DRt0j2nQ.js +3 -0
  294. package/server/{tracker-config-CNODpd11.js → tracker-config-OkdbaUCm.js} +2 -2
  295. package/server/{tracker-utils-Ch2_5GGf.js → tracker-utils-CghXMF3q.js} +2 -2
  296. package/server/{tracker-utils-B9ZoVA9b.js → tracker-utils-DdzUiPNU.js} +1 -1
  297. package/server/{traefik-connect-BF4x_LUQ.js → traefik-connect-CZYB3dlm.js} +1 -1
  298. package/server/{tunnel-r_5nHAI6.js → tunnel-D1YxesBL.js} +3 -3
  299. package/server/{tunnel-YD80_IHr.js → tunnel-DjlzgTl3.js} +1 -1
  300. package/server/typed-errors-CH4roFIj.js +3 -0
  301. package/server/{typed-errors-BEJhbjJg.js → typed-errors-n_Tnb4Fh.js} +3 -4
  302. package/server/{types-CE1m_daD.js → types-DOjWNv3Z.js} +1 -1
  303. package/server/{types-33JEP4LZ.js → types-DXBMm4mX.js} +1 -1
  304. package/server/{uat-train-DDI00aqD.js → uat-train-CaaWs9Rp.js} +1 -1
  305. package/server/{uat-train-DjkFWXge.js → uat-train-CqN34zFx.js} +24 -25
  306. package/server/{validation-DUTiJnyz.js → validation-4-z2Cw4z.js} +70 -23
  307. package/server/validation-DpTNakM6.js +3 -0
  308. package/server/verification-artifact-DK1xb1zG.js +56 -0
  309. package/server/verification-artifact-JD_edpZ9.js +2 -0
  310. package/server/{verification-runner-inLgeQux.js → verification-runner-BjHN80pJ.js} +338 -58
  311. package/server/verification-runner-ShYu5Ph3.js +2 -0
  312. package/server/{work-agent-prompt-fZljjA1_.js → work-agent-prompt-BiJ43Der.js} +12 -88
  313. package/server/workflows-B4C3lY9E.js +2 -0
  314. package/server/{workflows-oBnJ7Tm0.js → workflows-DkTotz_m.js} +17 -24
  315. package/server/{workspace-CNuW2j41.js → workspace-CuN0ev4Z.js} +3 -3
  316. package/server/{workspace-B2WOW9Hw.js → workspace-DQ4vVivd.js} +1 -1
  317. package/server/{workspace-config-CBgMGhWs.js → workspace-config-C77NKnsV.js} +1 -1
  318. package/server/{workspace-manager-DjUAJCSs.js → workspace-manager-B1mYn0lN.js} +1 -1
  319. package/server/{workspace-manager-CB-R07R3.js → workspace-manager-Beeo2aKF.js} +23 -48
  320. package/server/{workspace-metadata-9Nn5kgRl.js → workspace-metadata-BZC5BmoP.js} +2 -2
  321. package/server/{workspace-metadata-Fd58uUQG.js → workspace-metadata-Cy7_ZACL.js} +1 -1
  322. package/server/{workspaces-BjWXntty.js → workspaces-CGuzW1Ia.js} +191 -153
  323. package/sync-sources/hooks/ask-user-question-hook +7 -1
  324. package/sync-sources/hooks/codex-notify-hook +64 -8
  325. package/sync-sources/hooks/record-cost-event.js +1109 -36
  326. package/sync-sources/hooks/record-cost-event.js.map +1 -1
  327. package/sync-sources/hooks/statusline.sh +2 -2
  328. package/sync-sources/hooks/work-agent-stop-hook +1 -2
  329. package/server/acceptance-criteria-DHZk2ceV.js +0 -33
  330. package/server/agent-runtime-mirror-DrWxopNA.js +0 -37
  331. package/server/agent-state-EP2QFV9n.js +0 -3
  332. package/server/agents-DCvyTXNU.js +0 -3
  333. package/server/auto-commit-QAfsu3Sb.js +0 -3
  334. package/server/bd-process-lock-D3S4T4o-.js +0 -390
  335. package/server/beads-BGGxrkZ5.js +0 -649
  336. package/server/beads-CYsLiyIM.js +0 -2
  337. package/server/beads-query-B1DlJVp9.js +0 -95
  338. package/server/beads-restore-CyygSmmn.js +0 -23
  339. package/server/cli-ClIQwgMI.js +0 -3
  340. package/server/codex-B7DTpwEw.js +0 -3
  341. package/server/compact-beads-CK_hHEnB.js +0 -3
  342. package/server/compact-beads-DKL54y6j.js +0 -94
  343. package/server/deacon-swarm-BY5hKNaU.js +0 -2
  344. package/server/dist-DGTwcZhI.js +0 -3
  345. package/server/export-Dx_qJ3h8.js +0 -87
  346. package/server/forge-XlDgPQWs.js +0 -2
  347. package/server/hume-K1pi8jC4.js +0 -3
  348. package/server/inspect-agent-477VxQim.js +0 -2
  349. package/server/lifecycle-C_73gi-C.js +0 -14
  350. package/server/merge-ops-PzqsW69V.js +0 -2
  351. package/server/projects-KJ94e50I.js +0 -3
  352. package/server/public/assets/chunk-BO2N2NFS-ClukPsZQ.js +0 -103
  353. package/server/public/assets/index-DUFDmvmH.css +0 -1
  354. package/server/public/assets/index-DnTZ2QeN.js +0 -796
  355. package/server/public/assets/mermaid-GHXKKRXX-DZJOwgBG.js +0 -1
  356. package/server/rally-Dc2Wnxw2.js +0 -3
  357. package/server/record-pyB6VA32.js +0 -3
  358. package/server/recovery-trip-Dfh1tNHn.js +0 -98
  359. package/server/resolver-dTpSSzaH.js +0 -158
  360. package/server/resume-DhcIqsTm.js +0 -3
  361. package/server/settings-yydgaqhv.js +0 -2
  362. package/server/specs-DwoAEGrW.js +0 -3
  363. package/server/supervisor-DHjumXlL.js +0 -2
  364. package/server/tmux-x291Gjjb.js +0 -3
  365. package/server/token-util-xNaV-00f.js +0 -3
  366. package/server/tracker-config-DItsdelv.js +0 -3
  367. package/server/typed-errors-DSPn_xWP.js +0 -3
  368. package/server/validation-ict8hnXk.js +0 -3
  369. package/server/verification-runner-ATaLbpr5.js +0 -2
  370. package/server/workflows-tU7KKxQi.js +0 -2
  371. package/server/writer-CQMGzEkw.js +0 -3
  372. package/server/writer-fe1-8iGc.js +0 -251
@@ -1,40 +1,41 @@
1
1
  import { n as __esmMin, o as __toESM } from "./rolldown-runtime-DNCzzKnI.js";
2
- import { Ar as OVERDECK_HOME, C as init_tier_table, Dn as getProjectSwarmHotspots, F as getBuiltInDefaultHarness, H as setupCredentialFileAuthSync, It as resolveProjectForIssue, Kn as resolveProjectFromIssueSync, Kr as getOverdeckHome, L as getProviderEnvSync, Nt as readIssueRecordForWorkspaceSync, On as getProjectSync, P as clearCredentialFileAuthSync, Pn as init_projects, Pt as readIssueRecordSync, R as getProviderForModelSync, Rt as writeAgentHarnessModelSync, T as resolveTieredExecutionEnabledForIssue, Tn as getIssuePrefix, U as ensureOpenAICompatibleProxyRunning, W as init_openai_compatible_proxy, X as init_roles, Xr as resolveOhmypiExtensionPath, Yr as packageRoot, Z as resolveModel, Zr as sessionFilePath, at as resolveModelIdSync, b as DEFAULT_TIERED_EXECUTION_CONFIG, br as init_errors, cr as ClaudeCredentialParseError, ct as init_percent, et as getModelCapabilitySync, f as loadConfigSync, hn as shouldCommitLegacyWorkspaceArtifacts, ir as resolveBareNumericIdSync, kt as init_record, l as isClaudeCodeChannelsMcpEnabled, lr as ConfigError, nt as hasModelCapabilitySync, or as require_dist, ot as fmix32, pn as init_state_read_home, qr as init_paths, rt as init_model_capabilities, st as fnv1a32, t as init_config_yaml, tr as init_issue_id, u as isTldrEnabledSync, ur as FsError, w as resolveTieredExecutionEnabled, x as TIERED_EXECUTION_DIFFICULTIES, xn as findProjectByPathSync, xr as AGENTS_DIR, z as init_providers, zr as encodeClaudeProjectDir } from "./config-yaml-Dcz-8uit.js";
2
+ import { $r as sessionFilePath, C as init_tier_table, Cr as AGENTS_DIR, En as getIssuePrefix, F as getBuiltInDefaultHarness, Fn as init_projects, H as setupCredentialFileAuthSync, It as resolveProjectForIssue, Jr as getOverdeckHome, L as getProviderEnvSync, Mr as OVERDECK_HOME, Nt as readIssueRecordForWorkspaceSync, On as getProjectSwarmHotspots, P as clearCredentialFileAuthSync, Pt as readIssueRecordSync, Qr as resolveOhmypiExtensionPath, R as getProviderForModelSync, Rt as writeAgentHarnessModelSync, Sn as findProjectByPathSync, Sr as init_errors, T as resolveTieredExecutionEnabledForIssue, U as ensureOpenAICompatibleProxyRunning, Vr as encodeClaudeProjectDir, W as init_openai_compatible_proxy, X as init_roles, Yr as init_paths, Z as resolveModel, Zr as packageRoot, at as resolveModelIdSync, b as DEFAULT_TIERED_EXECUTION_CONFIG, cr as require_dist, ct as init_percent, dr as ConfigError, et as getModelCapabilitySync, f as loadConfigSync, fr as FsError, hn as shouldCommitLegacyWorkspaceArtifacts, kn as getProjectSync, kt as init_record, l as isClaudeCodeChannelsMcpEnabled, nt as hasModelCapabilitySync, or as resolveBareNumericIdSync, ot as fmix32, pn as init_state_read_home, qn as resolveProjectFromIssueSync, rr as init_issue_id, rt as init_model_capabilities, st as fnv1a32, t as init_config_yaml, u as isTldrEnabledSync, ur as ClaudeCredentialParseError, w as resolveTieredExecutionEnabled, x as TIERED_EXECUTION_DIFFICULTIES, z as init_providers } from "./config-yaml-CqaAyn8y.js";
3
3
  import { t as require_toml } from "./toml-CeLDATih.js";
4
4
  import { a as init_activity_logger, n as emitActivityEntrySync, r as emitActivityTtsSync } from "./activity-logger-pcbf-e30.js";
5
- import { d as getOverdeckDatabaseSync, f as init_infra } from "./infra-bpq1MHKU.js";
6
- import { A as listSessionsSync, C as isPaneDead, E as listPaneValues, I as sendRawKeystroke, L as sessionExists, N as sendEscapeKeyAsync, P as sendKeys, R as sessionExistsSync, T as killSessionSync, W as BLANKED_PROVIDER_ENV, a as capturePaneSync, d as exactPaneTarget, i as capturePane, k as listSessions, o as createSession, q as init_child_env, s as createSessionSync, w as killSession, x as init_tmux, z as setOption } from "./tmux-C_d-lSIq.js";
7
- import { a as init_event_store, i as initEventStore } from "./event-store-DRte2Rwt.js";
8
- import { a as getHarnessBehavior, i as OHMYPI_BEHAVIOR } from "./src-DHn4Rd2F.js";
9
- import { A as listOverdeckAgentStatesSync, E as readReviewStatusMap, O as getOverdeckAgentStateSync, T as init_review_status_source, c as init_review_status, j as saveOverdeckAgentStateSync, k as init_agent_state_sync, m as resetPipelineVerdictsForWorkStartSync } from "./review-status-4qqLkRMu.js";
10
- import { d as init_agents$1, l as countAgentsByStatus, n as ensureSessionContextBriefingFile, r as init_briefing_freshness } from "./briefing-freshness-Kh5V8RTh.js";
11
- import { o as getPricingSync, s as init_cost } from "./cost-DQ2ajr_m.js";
12
- import { t as init_behavior } from "./behavior-Cpj03N4v.js";
13
- import { _ as init_tier_metrics, g as estimateFeedDeliveryTokens, v as recordTierFeedDelivery } from "./cost-sync-gTayEuWP.js";
14
- import { n as init_agent_runtime_mirror, r as isAgentStateServiceInProcess, t as getRuntimeSnapshot } from "./agent-runtime-mirror-DrWxopNA.js";
15
- import { i as ensureInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-CjlhdufS.js";
16
- import { m as readWorkspacePlanSync, o as init_io } from "./io-BiQ2Cs3k.js";
17
- import { c as bridgeGeminiAuthToCliproxy, p as getCliproxyClientEnv, s as bridgeCodexAuthToCliproxySync, v as init_cliproxy } from "./cliproxy-BsoNNDAj.js";
18
- import { f as init_config$1, m as loadConfigSync$1 } from "./config-ZNnMpIlh.js";
19
- import { L as normalizeHarness, R as reactivateConversationForSpawn, S as getConversationByName, k as init_conversations, y as createConversation } from "./conversations-DG2M8WnT.js";
20
- import { n as recordFeatureRegistryLifecycle, t as init_feature_registry_population } from "./feature-registry-population-ie-yBcQC.js";
21
- import { a as readCavemanVariant, n as init_workspace } from "./workspace-CNuW2j41.js";
22
- import { a as init_launcher_generator, c as requireModelOverrideSync, i as generateLauncherScriptSync, l as shellQuoteModelIdSync, n as init_state_home, o as init_model_validation, r as isStateMigrated, s as normalizeModelOverrideSync } from "./state-home-CRowbXqU.js";
23
- import { a as init_claude_permissions, r as getClaudePermissionFlagsStringSync } from "./claude-permissions-CaWqysff.js";
24
- import { h as workspaceContextFile, o as init_layers } from "./layers-CD6FysRU.js";
25
- import { a as extractThreadIdFromRollout, c as initCodexHome, l as init_codex, o as findLatestRollout } from "./codex-DW60_5j2.js";
26
- import { a as getFlywheelActiveRunIdSync, s as init_control_settings } from "./control-settings-DwkAeooY.js";
27
- import { n as createTrackerFromConfig, r as init_factory, t as createTracker } from "./factory-FN727tWr.js";
28
- import { a as init_stack_health, i as getWorkspaceStackHealth } from "./stack-health-DxsTx7II.js";
29
- import { a as createActiveSlice, c as groupItemsByWave, s as getDispatchableItems, u as init_dag } from "./dag-CqTehWpY.js";
30
- import { n as init_bd_process_lock, t as BdTransientFailure } from "./bd-process-lock-D3S4T4o-.js";
31
- import { n as assertIssueHasBeads, r as init_beads_query, t as BeadsMissingError } from "./beads-query-B1DlJVp9.js";
32
- import { c as generateFixedPointPromptSync, f as initHookSync, n as checkHookSync, p as init_hooks } from "./hooks-C9b7Vqpw.js";
33
- import { n as resolveHarness, t as init_harness_resolve } from "./harness-resolve-iMjyNUJ2.js";
34
- import { r as isRoleTerminal, t as init_reap_terminal_sessions } from "./reap-terminal-sessions-D6JDJsqF.js";
35
- import { a as init_lifecycle_io, t as appendContinueSessionEntryForIssue } from "./lifecycle-io-CeYxP3cE.js";
36
- import { r as init_swarm_readiness, t as analyzeSwarmReadiness } from "./swarm-readiness-CL5sM9B1.js";
37
- import { delimiter, dirname, join, relative } from "node:path";
5
+ import { d as getOverdeckDatabaseSync, f as init_infra } from "./infra-_Kx1m9pm.js";
6
+ import { A as listSessions, B as setOption, D as listPaneValues, E as killSessionSync, F as sendKeys, G as BLANKED_PROVIDER_ENV, J as init_child_env, L as sendRawKeystroke, P as sendEscapeKeyAsync, R as sessionExists, S as init_tmux, T as killSession, a as capturePaneSync, f as exactPaneTarget, i as capturePane, j as listSessionsSync, o as createSession, s as createSessionSync, w as isPaneDead, z as sessionExistsSync } from "./tmux-U55cNGFG.js";
7
+ import { a as init_event_store, i as initEventStore } from "./event-store-KZnWUKWh.js";
8
+ import { a as getHarnessBehavior, i as OHMYPI_BEHAVIOR } from "./src-By3D85Ry.js";
9
+ import { C as init_review_status_source, D as init_agent_state_sync, E as getOverdeckAgentStateSync, O as listOverdeckAgentStatesSync, c as init_review_status, k as saveOverdeckAgentStateSync, m as resetPipelineVerdictsForWorkStartSync, w as readReviewStatusMap } from "./review-status-DANr0t-v.js";
10
+ import { i as countAgentsByStatus, o as init_agents$1 } from "./agents-BHBxr8c9.js";
11
+ import { n as ensureSessionContextBriefingFile, r as init_briefing_freshness } from "./briefing-freshness-DuxIE1yr.js";
12
+ import { o as getPricingSync, s as init_cost } from "./cost-BoqD1Pxz.js";
13
+ import { _ as init_tier_metrics, g as estimateFeedDeliveryTokens, v as recordTierFeedDelivery } from "./cost-sync-BYnmnMkY.js";
14
+ import { a as persistCurrentSessionId, d as isAgentStateServiceInProcess, i as logLauncherSessionPinned, l as getRuntimeSnapshot, n as createFreshSessionIdentity, o as init_persistent_logger, r as init_session_history, s as logAgentLifecycleSync, u as init_agent_runtime_mirror } from "./session-history-bnOFKMwf.js";
15
+ import { t as init_behavior } from "./behavior-CWqNMqE5.js";
16
+ import { i as ensureInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-Cl-1IxaE.js";
17
+ import { m as readWorkspacePlanSync, o as init_io } from "./io-DkC4sFSy.js";
18
+ import { c as bridgeGeminiAuthToCliproxy, d as getCliproxyAuthDir, g as getCliproxyLogPath, l as decodeJwtPayload$1, p as getCliproxyClientEnv, s as bridgeCodexAuthToCliproxySync, v as init_cliproxy } from "./cliproxy-CGBA1GzA.js";
19
+ import { L as normalizeHarness, R as reactivateConversationForSpawn, S as getConversationByName, k as init_conversations, y as createConversation } from "./conversations-BX5aD-6F.js";
20
+ import { n as recordFeatureRegistryLifecycle, t as init_feature_registry_population } from "./feature-registry-population-Ca2UaV0U.js";
21
+ import { a as readCavemanVariant, n as init_workspace } from "./workspace-CuN0ev4Z.js";
22
+ import { a as requireModelOverrideSync, i as normalizeModelOverrideSync, n as init_launcher_generator, o as shellQuoteModelIdSync, r as init_model_validation, t as generateLauncherScriptSync } from "./launcher-generator-BXLM9f4b.js";
23
+ import { a as init_claude_permissions, r as getClaudePermissionFlagsStringSync } from "./claude-permissions-BB6agcOZ.js";
24
+ import { h as workspaceContextFile, o as init_layers } from "./layers-gCJlK62m.js";
25
+ import { a as extractThreadIdFromRollout, c as initCodexHome, l as init_codex, o as findLatestRollout } from "./codex-sgWVCGUd.js";
26
+ import { f as init_config$1, m as loadConfigSync$1 } from "./config-DfaUXr6r.js";
27
+ import { a as getFlywheelActiveRunIdSync, s as init_control_settings } from "./control-settings-BguNQ1F_.js";
28
+ import { n as createTrackerFromConfig, r as init_factory, t as createTracker } from "./factory-BtaRsHFC.js";
29
+ import { a as init_stack_health, i as getWorkspaceStackHealth } from "./stack-health-C-SnpRHh.js";
30
+ import { i as createActiveSlice, l as init_dag, o as getDispatchableItems, s as groupItemsByWave } from "./dag-C6kYyF17.js";
31
+ import { c as generateFixedPointPromptSync, f as initHookSync, n as checkHookSync, p as init_hooks } from "./hooks-BS_JrvYP.js";
32
+ import { n as resolveHarness, t as init_harness_resolve } from "./harness-resolve-Dx8hUsvC.js";
33
+ import { r as isRoleTerminal, t as init_reap_terminal_sessions } from "./reap-terminal-sessions-CFkuquQj.js";
34
+ import { c as isStateMigrated, o as init_state_home } from "./state-home-Bur1y4oH.js";
35
+ import { n as provisionClaudeHooks, t as init_claude_hooks_provision } from "./claude-hooks-provision-Du_PkMsp.js";
36
+ import { a as init_lifecycle_io, t as appendContinueSessionEntryForIssue } from "./lifecycle-io-FfPUtz-y.js";
37
+ import { r as init_swarm_readiness, t as analyzeSwarmReadiness } from "./swarm-readiness-sXB1vhzo.js";
38
+ import { dirname, join, relative } from "node:path";
38
39
  import { Data, Duration, Effect, FileSystem } from "effect";
39
40
  import { appendFileSync, existsSync, mkdirSync, readFileSync, statSync, statfsSync, unlinkSync, writeFileSync } from "fs";
40
41
  import { basename as basename$1, dirname as dirname$1, join as join$1, resolve as resolve$1 } from "path";
@@ -44,11 +45,11 @@ import { chmodSync as chmodSync$1, closeSync as closeSync$1, constants, cpSync,
44
45
  import { chmod, mkdir, readFile, stat as stat$1, writeFile } from "node:fs/promises";
45
46
  import { randomUUID } from "crypto";
46
47
  import { ChildProcess } from "effect/unstable/process";
47
- import { mkdir as mkdir$1, readFile as readFile$1, readdir as readdir$1, rename as rename$1, rm as rm$1, stat as stat$2, writeFile as writeFile$1 } from "fs/promises";
48
+ import { mkdir as mkdir$1, open as open$1, readFile as readFile$1, readdir as readdir$1, rename as rename$1, rm as rm$1, stat as stat$2, writeFile as writeFile$1 } from "fs/promises";
48
49
  import { platform as platform$2 } from "process";
49
50
  import { exec, execFile } from "node:child_process";
50
51
  import { promisify } from "node:util";
51
- import { exec as exec$1, execSync as execSync$1 } from "child_process";
52
+ import { exec as exec$1, execSync } from "child_process";
52
53
  import { promisify as promisify$1 } from "util";
53
54
  import { createHash as createHash$1, randomBytes, randomUUID as randomUUID$1 } from "node:crypto";
54
55
  import { fileURLToPath } from "node:url";
@@ -356,6 +357,402 @@ var init_ohmypi_parser = __esmMin((() => {
356
357
  ]);
357
358
  }));
358
359
  //#endregion
360
+ //#region ../../lib/codex-auth.ts
361
+ /** Absolute path to the codex CLI's own global credential file. */
362
+ function getNativeCodexAuthPath() {
363
+ return join$1(homedir(), ".codex", "auth.json");
364
+ }
365
+ /**
366
+ * Pure classifier for the native store's raw JSON (PAN-2285). Decodes the
367
+ * access_token JWT `exp` to decide valid/expired; reports missing when the file
368
+ * is absent (raw === null) and unknown when it is malformed. API-key mode
369
+ * (OPENAI_API_KEY set, no OAuth tokens) is a valid auth state. Exported for
370
+ * testing with fabricated JWTs.
371
+ */
372
+ function classifyNativeCodexAuth(raw, now = Date.now()) {
373
+ if (raw === null) return { status: "missing" };
374
+ let parsed;
375
+ try {
376
+ parsed = JSON.parse(raw);
377
+ } catch {
378
+ return { status: "unknown" };
379
+ }
380
+ const lastRefresh = typeof parsed.last_refresh === "string" ? parsed.last_refresh : void 0;
381
+ const accessToken = typeof parsed.tokens?.access_token === "string" ? parsed.tokens.access_token : null;
382
+ if (!accessToken) {
383
+ if (typeof parsed.OPENAI_API_KEY === "string" && parsed.OPENAI_API_KEY) return {
384
+ status: "valid",
385
+ lastRefresh
386
+ };
387
+ return {
388
+ status: "unknown",
389
+ lastRefresh
390
+ };
391
+ }
392
+ const idToken = typeof parsed.tokens?.id_token === "string" ? parsed.tokens.id_token : null;
393
+ const idClaims = idToken ? decodeJwtPayload$1(idToken) : null;
394
+ const email = idClaims && typeof idClaims.email === "string" ? idClaims.email : void 0;
395
+ const accessClaims = decodeJwtPayload$1(accessToken);
396
+ const expSec = accessClaims && typeof accessClaims.exp === "number" ? accessClaims.exp : null;
397
+ if (expSec === null) return {
398
+ status: "unknown",
399
+ email,
400
+ lastRefresh
401
+ };
402
+ const expiresAt = (/* @__PURE__ */ new Date(expSec * 1e3)).toISOString();
403
+ if (expSec * 1e3 <= now) return {
404
+ status: "expired",
405
+ email,
406
+ expiresAt,
407
+ lastRefresh
408
+ };
409
+ return {
410
+ status: "valid",
411
+ email,
412
+ expiresAt,
413
+ lastRefresh
414
+ };
415
+ }
416
+ /** Async native-store probe used by the dashboard status endpoint. */
417
+ async function probeNativeCodexAuth(now = Date.now()) {
418
+ const path = getNativeCodexAuthPath();
419
+ let raw;
420
+ let mtimeMs = 0;
421
+ try {
422
+ raw = await readFile$1(path, "utf8");
423
+ mtimeMs = (await stat$2(path)).mtimeMs;
424
+ } catch {
425
+ raw = null;
426
+ }
427
+ return {
428
+ ...classifyNativeCodexAuth(raw, now),
429
+ mtimeMs
430
+ };
431
+ }
432
+ /** Sync native-store probe used by the spawn gate. */
433
+ function probeNativeCodexAuthSync(now = Date.now()) {
434
+ let raw;
435
+ try {
436
+ raw = readFileSync(getNativeCodexAuthPath(), "utf8");
437
+ } catch {
438
+ raw = null;
439
+ }
440
+ return classifyNativeCodexAuth(raw, now);
441
+ }
442
+ function nativeCodexAuthMtimeSync() {
443
+ try {
444
+ return statSync(getNativeCodexAuthPath()).mtimeMs;
445
+ } catch {
446
+ return 0;
447
+ }
448
+ }
449
+ /**
450
+ * Pure classifier over a codex agent's pane tail (PAN-2285). True when the pane
451
+ * shows the revoked/invalidated refresh-token error. Exported so it is testable
452
+ * without tmux.
453
+ */
454
+ function paneShowsCodexAuthBurn(paneText) {
455
+ return CODEX_AUTH_BURN_MARKERS.some((marker) => paneText.includes(marker));
456
+ }
457
+ /**
458
+ * Mark an agent state as codex-auth-burned (PAN-2285). Pure mutation — the
459
+ * caller persists via the agent-state write door (saveAgentStateSync), which
460
+ * mirrors into the shared agents table so the flag crosses the deacon/server
461
+ * process boundary. Returns true only when the state was newly flagged
462
+ * (idempotent: an already-flagged state is left untouched), so callers can emit
463
+ * a single operator notice instead of one per patrol tick. The flag time is
464
+ * embedded in the reason (`codex-auth-burned[<ISO>]`) because the agents table
465
+ * has no dedicated column for it and `troubledAt` may predate the burn when the
466
+ * agent was already troubled for another reason.
467
+ */
468
+ function applyCodexAuthBurnFlag(state, nowMs = Date.now()) {
469
+ if (state.troubled && state.lastFailureReason?.startsWith("codex-auth-burned")) return false;
470
+ const nowIso = new Date(nowMs).toISOString();
471
+ state.troubled = true;
472
+ if (!state.troubledAt) state.troubledAt = nowIso;
473
+ state.lastFailureReason = `${CODEX_AUTH_BURNED_REASON_PREFIX}[${nowIso}]: Codex refresh token was revoked — re-authenticate (dashboard Codex-auth banner has a Re-authenticate button, or run \`codex login\`)`;
474
+ state.lastFailureAt = nowIso;
475
+ return true;
476
+ }
477
+ /**
478
+ * When (epoch ms) a state was flagged codex-auth-burned, or null if it is not
479
+ * currently flagged. Requires the troubled gate to still be set — `pan
480
+ * untroubled` / resume clears troubled and the failure fields, which retires the
481
+ * flag. Parses the ISO stamp embedded in the reason; falls back to `troubledAt`
482
+ * for flags written by builds that predate the embedded stamp.
483
+ */
484
+ function codexAuthBurnFlaggedAtMs(state) {
485
+ if (!state.troubled) return null;
486
+ const reason = state.lastFailureReason;
487
+ if (!reason?.startsWith("codex-auth-burned")) return null;
488
+ const embedded = reason.match(/^codex-auth-burned\[([^\]]+)\]/)?.[1];
489
+ const fromReason = embedded ? Date.parse(embedded) : NaN;
490
+ if (Number.isFinite(fromReason)) return fromReason;
491
+ const fromTroubledAt = state.troubledAt ? Date.parse(state.troubledAt) : NaN;
492
+ return Number.isFinite(fromTroubledAt) ? fromTroubledAt : 0;
493
+ }
494
+ /**
495
+ * Pure filter: which of these agent states are burned AND still current? Flags
496
+ * recorded strictly before the native store's last write are stale: a global
497
+ * `codex login` rewrites ~/.codex/auth.json (bumping its mtime) and heals every
498
+ * agent through the shared symlink, so those burns no longer apply (the flag
499
+ * itself is retired when the agent is untroubled/resumed).
500
+ */
501
+ function filterCodexAuthBurnedAgentIds(states, nativeMtimeMs) {
502
+ const active = [];
503
+ for (const state of states) {
504
+ const flaggedAt = codexAuthBurnFlaggedAtMs(state);
505
+ if (flaggedAt !== null && flaggedAt >= nativeMtimeMs) active.push(state.id);
506
+ }
507
+ return active;
508
+ }
509
+ /**
510
+ * Agents currently flagged codex-auth-burned. Callers supply states read through
511
+ * the agent resolver so this pure auth module does not create a spawn-time cycle.
512
+ */
513
+ function listCodexAuthBurnedAgentsSync(nativeMtimeMs, states) {
514
+ return filterCodexAuthBurnedAgentIds(states, nativeMtimeMs);
515
+ }
516
+ /** Sync convenience for the spawn gate: are any agents still burned right now? */
517
+ function hasActiveBurnedCodexAgentsSync(states) {
518
+ return listCodexAuthBurnedAgentsSync(nativeCodexAuthMtimeSync(), states).length > 0;
519
+ }
520
+ function nativeToStatus(native) {
521
+ switch (native.status) {
522
+ case "valid": return {
523
+ status: "valid",
524
+ email: native.email ?? "",
525
+ expiresAt: native.expiresAt ?? "",
526
+ source: "native"
527
+ };
528
+ case "expired": return {
529
+ status: "expired",
530
+ email: native.email ?? "",
531
+ expiresAt: native.expiresAt ?? "",
532
+ source: "native"
533
+ };
534
+ case "missing": return {
535
+ status: "missing",
536
+ source: "native"
537
+ };
538
+ case "unknown": return {
539
+ status: "unknown",
540
+ source: "native"
541
+ };
542
+ }
543
+ }
544
+ function withSource(status, source) {
545
+ return {
546
+ ...status,
547
+ source
548
+ };
549
+ }
550
+ /**
551
+ * Merge the native and cliproxy statuses into the single worst state the banner
552
+ * should react to (burned > expired > valid > missing > unknown). Both stores
553
+ * are healed by the same `codex login`, so surfacing the more severe one is
554
+ * correct and its remedy is identical. Exported for testing.
555
+ */
556
+ function combineCodexAuthStatuses(native, cliproxy) {
557
+ const nativeSev = CODEX_AUTH_SEVERITY[native.status];
558
+ return CODEX_AUTH_SEVERITY[cliproxy.status] > nativeSev ? withSource(cliproxy, "cliproxy") : native;
559
+ }
560
+ async function checkCodexAuthStatusPromise(options = {}) {
561
+ const native = await probeNativeCodexAuth(Date.now());
562
+ const cliproxy = await checkCliproxyCodexAuthStatusPromise(options);
563
+ const activeBurned = listCodexAuthBurnedAgentsSync(native.mtimeMs, options.agentStates ?? []);
564
+ if (activeBurned.length > 0) return {
565
+ status: "burned",
566
+ email: native.email ?? "",
567
+ expiresAt: native.expiresAt ?? "",
568
+ source: "native",
569
+ affectedAgents: activeBurned
570
+ };
571
+ return combineCodexAuthStatuses(nativeToStatus(native), cliproxy);
572
+ }
573
+ /**
574
+ * Spawn gate (PAN-2285): refuse to launch a NEW codex-harness agent while the
575
+ * native codex auth is unusable — missing/expired file or any agent currently
576
+ * burned (revoked refresh token shared across the family). Resumes are exempt:
577
+ * the symlink migration in initCodexHome heals a stale home on relaunch. Throws
578
+ * a clear, remedy-naming error, mirroring the harness-policy ToS gate.
579
+ */
580
+ function assertCodexNativeAuthForSpawn(harness, agentStates) {
581
+ if (harness !== "codex") return;
582
+ const native = probeNativeCodexAuthSync();
583
+ const reason = native.status === "missing" ? "not signed in (~/.codex/auth.json is missing)" : native.status === "expired" ? "expired (~/.codex/auth.json access token has lapsed)" : hasActiveBurnedCodexAgentsSync(agentStates) ? "revoked (a running codex agent hit a revoked refresh token — the shared token family is dead)" : null;
584
+ if (reason === null) return;
585
+ throw new Error(`Cannot spawn a Codex agent: native Codex authentication is ${reason}. Run \`codex login\` on the host (or click Re-authenticate in the dashboard Codex-auth banner), then retry.`);
586
+ }
587
+ async function checkCliproxyCodexAuthStatusPromise(options = {}) {
588
+ const credPath = join$1(getCliproxyAuthDir(), "codex-primary.json");
589
+ let raw;
590
+ let credMtimeMs = null;
591
+ try {
592
+ raw = await readFile$1(credPath, "utf8");
593
+ credMtimeMs = (await stat$2(credPath)).mtimeMs;
594
+ } catch {
595
+ return { status: "missing" };
596
+ }
597
+ let creds;
598
+ try {
599
+ creds = JSON.parse(raw);
600
+ } catch {
601
+ return {
602
+ status: "unknown",
603
+ message: "Malformed credential file"
604
+ };
605
+ }
606
+ const accessToken = typeof creds.access_token === "string" ? creds.access_token : null;
607
+ if (!accessToken) return {
608
+ status: "unknown",
609
+ message: "Missing access_token in credential file"
610
+ };
611
+ const claims = decodeJwtPayload$1(accessToken);
612
+ if (!claims) return {
613
+ status: "unknown",
614
+ message: "Unable to decode access_token"
615
+ };
616
+ const expSec = typeof claims.exp === "number" ? claims.exp : null;
617
+ if (expSec === null) return {
618
+ status: "unknown",
619
+ message: "Missing exp claim in access_token"
620
+ };
621
+ const email = typeof creds.email === "string" ? creds.email : "";
622
+ const expiresAt = (/* @__PURE__ */ new Date(expSec * 1e3)).toISOString();
623
+ if (expSec * 1e3 <= Date.now()) return {
624
+ status: "expired",
625
+ email,
626
+ expiresAt
627
+ };
628
+ return await applyBurnedTokenOverride({
629
+ status: "valid",
630
+ email,
631
+ expiresAt
632
+ }, email, expiresAt, { ignoreBurnBefore: options.ignoreBurnBefore ?? credMtimeMs ?? void 0 });
633
+ }
634
+ /** Read the trailing window of the cliproxy log for burn/failure analysis. */
635
+ async function readLogTail(path) {
636
+ const TAIL_BYTES = 128 * 1024;
637
+ const file = await open$1(path, "r");
638
+ try {
639
+ const stat = await file.stat();
640
+ const length = Math.min(stat.size, TAIL_BYTES);
641
+ const buffer = Buffer.alloc(length);
642
+ await file.read(buffer, 0, length, stat.size - length);
643
+ return buffer.toString("utf8");
644
+ } finally {
645
+ await file.close();
646
+ }
647
+ }
648
+ async function applyBurnedTokenOverride(baseStatus, email, expiresAt, options) {
649
+ let logRaw;
650
+ try {
651
+ logRaw = await readLogTail(getCliproxyLogPath());
652
+ } catch {
653
+ return baseStatus;
654
+ }
655
+ return evaluateBurnedFromLog(logRaw, baseStatus, email, expiresAt, options);
656
+ }
657
+ /**
658
+ * Pure decision: given the cliproxy log tail, decide whether a JWT-valid token
659
+ * is actually burned. Exported for regression testing (PAN-1584).
660
+ *
661
+ * "Auth failure" evidence = either a refresh-token burn line
662
+ * (`refresh token has already been used`) OR a `503` on `/v1/messages` /
663
+ * `/v1/chat/completions` (the live symptom the agent hits once cliproxy disables
664
+ * the provider — and which keeps appearing after the burn line stops, since a
665
+ * disabled provider no longer attempts refreshes). "Success" = a `200` on those
666
+ * same paths (proves the auth path works right now).
667
+ *
668
+ * Decision:
669
+ * - No failure evidence → trust base status.
670
+ * - Success AFTER the last failure → trust base status (recovered).
671
+ * - Failure AFTER the credential's last write (ignoreBurnBefore) → BURNED,
672
+ * regardless of age. The credential write time is when you last logged in;
673
+ * a failure after it means the current token is dead. This is authoritative
674
+ * and is the fix for the bug where a >1h-stale burn line was dismissed as
675
+ * "valid" during a quiet period even though the token was dead (PAN-1584).
676
+ * - Failure BEFORE that cutoff → trust base status (re-authed since).
677
+ * - No cutoff available → fall back to the staleness backstop:
678
+ * burned only if the last failure is within BURN_STALENESS_MS.
679
+ *
680
+ * We intentionally don't probe cliproxy with HTTP — `GET /v1/models` always
681
+ * 401s (it needs real OAuth, not the local key) and would generate spurious log
682
+ * lines on every dashboard load.
683
+ */
684
+ function evaluateBurnedFromLog(logRaw, baseStatus, email, expiresAt, options = {}) {
685
+ const now = options.now ?? Date.now();
686
+ const lines = logRaw.split("\n").slice(-500);
687
+ const isBurnLine = (l) => l.includes("refresh token has already been used") || l.includes("refresh_token_reused");
688
+ const isAuthFailure503 = (l) => /\b503 \|/.test(l) && /POST\s+"\/v1\/(messages|chat\/completions)/.test(l);
689
+ const isSuccess = (l) => /\b200 \|/.test(l) && /POST\s+"\/v1\/(messages|chat\/completions)/.test(l);
690
+ const timestampAt = (idx) => {
691
+ for (let j = idx; j >= Math.max(0, idx - 10); j--) {
692
+ const m = lines[j]?.match(/^\[(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})\]/);
693
+ if (m) {
694
+ const t = Date.parse(`${m[1]}T${m[2]}Z`);
695
+ if (Number.isFinite(t)) return t;
696
+ }
697
+ }
698
+ return null;
699
+ };
700
+ let lastFailureIdx = -1;
701
+ let lastFailureTimestamp = null;
702
+ let lastSuccessIdx = -1;
703
+ for (let i = lines.length - 1; i >= 0; i--) {
704
+ const line = lines[i] ?? "";
705
+ if (lastFailureIdx < 0 && (isBurnLine(line) || isAuthFailure503(line))) {
706
+ lastFailureIdx = i;
707
+ lastFailureTimestamp = timestampAt(i);
708
+ }
709
+ if (lastSuccessIdx < 0 && isSuccess(line)) lastSuccessIdx = i;
710
+ if (lastFailureIdx >= 0 && lastSuccessIdx >= 0) break;
711
+ }
712
+ if (lastFailureIdx < 0) return baseStatus;
713
+ if (lastSuccessIdx > lastFailureIdx) return baseStatus;
714
+ if (options.ignoreBurnBefore !== void 0) {
715
+ if (lastFailureTimestamp !== null && lastFailureTimestamp + 1e3 <= options.ignoreBurnBefore) return baseStatus;
716
+ return {
717
+ status: "burned",
718
+ email,
719
+ expiresAt
720
+ };
721
+ }
722
+ if (lastFailureTimestamp !== null && now - lastFailureTimestamp > BURN_STALENESS_MS) return baseStatus;
723
+ return {
724
+ status: "burned",
725
+ email,
726
+ expiresAt
727
+ };
728
+ }
729
+ var CodexAuthCheckError, CODEX_AUTH_BURN_MARKERS, CODEX_AUTH_BURNED_REASON_PREFIX, CODEX_AUTH_SEVERITY, BURN_STALENESS_MS, checkCodexAuthStatus;
730
+ var init_codex_auth = __esmMin((() => {
731
+ init_cliproxy();
732
+ CodexAuthCheckError = class extends Data.TaggedError("CodexAuthCheckError") {};
733
+ CODEX_AUTH_BURN_MARKERS = [
734
+ "could not be refreshed because your refresh token was revoked",
735
+ "token_invalidated",
736
+ "token_revoked"
737
+ ];
738
+ CODEX_AUTH_BURNED_REASON_PREFIX = "codex-auth-burned";
739
+ CODEX_AUTH_SEVERITY = {
740
+ burned: 4,
741
+ expired: 3,
742
+ valid: 2,
743
+ missing: 1,
744
+ unknown: 0
745
+ };
746
+ BURN_STALENESS_MS = 3600 * 1e3;
747
+ checkCodexAuthStatus = (options = {}) => Effect.tryPromise({
748
+ try: () => checkCodexAuthStatusPromise(options),
749
+ catch: (cause) => new CodexAuthCheckError({
750
+ message: cause instanceof Error ? cause.message : String(cause),
751
+ cause
752
+ })
753
+ });
754
+ }));
755
+ //#endregion
359
756
  //#region ../../lib/overdeck/agent-rollback-state.ts
360
757
  function getRollbackAgentStatePath(agentId) {
361
758
  return join(getOverdeckHome(), "agents", agentId, AGENT_STATE_ROLLBACK_FILE);
@@ -889,54 +1286,6 @@ var init_agent_record_sync = __esmMin((() => {
889
1286
  init_record();
890
1287
  }));
891
1288
  //#endregion
892
- //#region ../../lib/persistent-logger.ts
893
- /**
894
- * Append-only persistent logger for forensic audit trails.
895
- *
896
- * Complements the SQLite event store (activity-logger.ts) with flat-file logs
897
- * that survive event-store resets and are greppable from the shell.
898
- *
899
- * Files:
900
- * ~/.overdeck/logs/deacon.log — deacon startup recovery actions
901
- * ~/.overdeck/agents/<id>/lifecycle.log — per-agent state transitions
902
- */
903
- function logsDir() {
904
- return join$1(getOverdeckHome(), "logs");
905
- }
906
- function agentDir(agentId) {
907
- return join$1(getOverdeckHome(), "agents", agentId);
908
- }
909
- function ensureLogsDir() {
910
- try {
911
- mkdirSync(logsDir(), { recursive: true });
912
- } catch {}
913
- }
914
- function ensureAgentDir(agentId) {
915
- try {
916
- mkdirSync(agentDir(agentId), { recursive: true });
917
- } catch {}
918
- }
919
- function timestamp() {
920
- return (/* @__PURE__ */ new Date()).toISOString();
921
- }
922
- /** Append a line to ~/.overdeck/logs/deacon.log */
923
- function logDeaconEventSync(message) {
924
- ensureLogsDir();
925
- try {
926
- appendFileSync(join$1(logsDir(), "deacon.log"), `[${timestamp()}] ${message}\n`);
927
- } catch {}
928
- }
929
- /** Append a line to ~/.overdeck/agents/<agentId>/lifecycle.log */
930
- function logAgentLifecycleSync(agentId, message) {
931
- ensureAgentDir(agentId);
932
- try {
933
- appendFileSync(join$1(agentDir(agentId), "lifecycle.log"), `[${timestamp()}] ${message}\n`);
934
- } catch {}
935
- }
936
- var init_persistent_logger = __esmMin((() => {
937
- init_paths();
938
- }));
939
- //#endregion
940
1289
  //#region ../../lib/agents/agent-state.ts
941
1290
  function getAgentDir(agentId) {
942
1291
  return join$1(getOverdeckHome(), "agents", agentId);
@@ -1308,10 +1657,16 @@ function getAgentResumeGateBlockReason(state) {
1308
1657
  /** Intent-aware policy over a classified gate. This function never mutates agent state. */
1309
1658
  function decideResumeGate(block, intent, context = {}) {
1310
1659
  if (!block) return { decision: "proceed" };
1311
- if (intent === "message-delivery") return {
1312
- decision: "queue-message",
1313
- reason: block.reason
1314
- };
1660
+ if (intent === "message-delivery") {
1661
+ if (block.gate === "stopped-by-user" && context.hasCompletedHandoff === true && context.owesRework === true) return {
1662
+ decision: "proceed",
1663
+ clearStoppedByUser: true
1664
+ };
1665
+ return {
1666
+ decision: "queue-message",
1667
+ reason: block.reason
1668
+ };
1669
+ }
1315
1670
  if (intent === "operator-start") {
1316
1671
  if (block.gate === "paused") return {
1317
1672
  decision: "block",
@@ -2324,7 +2679,7 @@ async function createOhmypiFifoPromise(agentId, home) {
2324
2679
  mode: 448
2325
2680
  });
2326
2681
  if (existsSync$1(paths.fifoPath)) unlinkSync$1(paths.fifoPath);
2327
- await execAsync$7(`mkfifo -m 600 ${shellQuote$2(paths.fifoPath)}`);
2682
+ await execAsync$6(`mkfifo -m 600 ${shellQuote$1(paths.fifoPath)}`);
2328
2683
  return paths.fifoPath;
2329
2684
  }
2330
2685
  /**
@@ -2362,14 +2717,14 @@ function writeOhmypiCommandSync(agentId, command, home) {
2362
2717
  closeSync$1(fd);
2363
2718
  }
2364
2719
  }
2365
- function shellQuote$2(s) {
2720
+ function shellQuote$1(s) {
2366
2721
  if (/^[A-Za-z0-9._/-]+$/.test(s)) return s;
2367
2722
  return `'${s.replace(/'/g, `'\\''`)}'`;
2368
2723
  }
2369
- var execAsync$7, OhmypiNotReady, OhmypiFifoError, createOhmypiFifo;
2724
+ var execAsync$6, OhmypiNotReady, OhmypiFifoError, createOhmypiFifo;
2370
2725
  var init_ohmypi_fifo = __esmMin((() => {
2371
2726
  init_paths();
2372
- execAsync$7 = promisify(exec);
2727
+ execAsync$6 = promisify(exec);
2373
2728
  OhmypiNotReady = class extends Error {
2374
2729
  code = "OHMYPI_NOT_READY";
2375
2730
  constructor(message) {
@@ -2429,12 +2784,12 @@ async function claudeSystemPromptFiles(workspace, harness) {
2429
2784
  files.push(await ensureSessionContextBriefingFile());
2430
2785
  const behavior = getHarnessBehavior(harness);
2431
2786
  if (behavior.contextLayerKind === "pi") {
2432
- const { piGlobalContextFile } = await import("./context-layers-ByOWUjUg.js");
2787
+ const { piGlobalContextFile } = await import("./context-layers-DWL_8HhY.js");
2433
2788
  const globalFile = piGlobalContextFile();
2434
2789
  if (existsSync(globalFile)) files.unshift(globalFile);
2435
2790
  }
2436
2791
  if (behavior.contextLayerKind === "codex") {
2437
- const { codexGlobalContextFile } = await import("./context-layers-ByOWUjUg.js");
2792
+ const { codexGlobalContextFile } = await import("./context-layers-DWL_8HhY.js");
2438
2793
  const globalFile = codexGlobalContextFile();
2439
2794
  if (existsSync(globalFile)) files.unshift(globalFile);
2440
2795
  }
@@ -2461,14 +2816,14 @@ async function hasAgentRuntimeInSubtree(rootPid, harness = "claude-code") {
2461
2816
  if (seen.has(pid) || !/^\d+$/.test(pid)) continue;
2462
2817
  seen.add(pid);
2463
2818
  try {
2464
- const { stdout: comm } = await execAsync$5(`ps -p ${pid} -o comm=`);
2819
+ const { stdout: comm } = await execAsync$4(`ps -p ${pid} -o comm=`);
2465
2820
  const name = comm.trim();
2466
2821
  if (expectedProcessNames.has(name)) return true;
2467
2822
  } catch {
2468
2823
  continue;
2469
2824
  }
2470
2825
  try {
2471
- const { stdout: kids } = await execAsync$5(`pgrep -P ${pid}`);
2826
+ const { stdout: kids } = await execAsync$4(`pgrep -P ${pid}`);
2472
2827
  for (const kid of kids.trim().split("\n").filter(Boolean)) queue.push(kid);
2473
2828
  } catch {}
2474
2829
  }
@@ -2587,7 +2942,7 @@ async function injectPiPromptTimeMemory(agentId, prompt) {
2587
2942
  agentRole: agentState.role ?? "work",
2588
2943
  agentHarness: agentState.harness ?? "claude-code"
2589
2944
  };
2590
- const { injectPromptTimeMemory } = await import("./injection-BLWfwTVZ.js");
2945
+ const { injectPromptTimeMemory } = await import("./injection-Bvhyg_MV.js");
2591
2946
  const result = await injectPromptTimeMemory({
2592
2947
  prompt,
2593
2948
  identity,
@@ -2621,7 +2976,7 @@ async function injectPiConversationMemory(opts, prompt) {
2621
2976
  agentRole: "work",
2622
2977
  agentHarness: "ohmypi"
2623
2978
  };
2624
- const { injectPromptTimeMemory } = await import("./injection-BLWfwTVZ.js");
2979
+ const { injectPromptTimeMemory } = await import("./injection-Bvhyg_MV.js");
2625
2980
  const result = await injectPromptTimeMemory({
2626
2981
  prompt,
2627
2982
  identity,
@@ -2797,7 +3152,7 @@ async function getRoleRuntimeBaseCommand(model, agentName, role, harness = "clau
2797
3152
  if (provider.name === "openai" && await getProviderAuthMode(validatedModel) === "subscription") return `claude${printFlag}${roleInject}${permissionFlags} --model ${shellQuoteModelIdSync(CLI_PROXY_MODEL_ALIASES[validatedModel] ?? validatedModel)}${effortFlag}${nameFlag}`;
2798
3153
  return `claude${printFlag}${roleInject}${permissionFlags} --model ${quotedModel}${effortFlag}${nameFlag}`;
2799
3154
  }
2800
- var import_dist, execAsync$5, missingRoleDefinitionWarnings, OHMYPI_AGENT_READY_TIMEOUT_SECONDS;
3155
+ var import_dist, execAsync$4, missingRoleDefinitionWarnings, OHMYPI_AGENT_READY_TIMEOUT_SECONDS;
2801
3156
  var init_runtime_command = __esmMin((() => {
2802
3157
  import_dist = /* @__PURE__ */ __toESM(require_dist(), 1);
2803
3158
  init_claude_permissions();
@@ -2817,7 +3172,7 @@ var init_runtime_command = __esmMin((() => {
2817
3172
  init_agent_state();
2818
3173
  init_identity();
2819
3174
  init_provider_env();
2820
- execAsync$5 = promisify$1(exec$1);
3175
+ execAsync$4 = promisify$1(exec$1);
2821
3176
  missingRoleDefinitionWarnings = /* @__PURE__ */ new Set();
2822
3177
  OHMYPI_AGENT_READY_TIMEOUT_SECONDS = 120;
2823
3178
  }));
@@ -2876,6 +3231,14 @@ var init_resolve_tier = __esmMin((() => {
2876
3231
  }));
2877
3232
  //#endregion
2878
3233
  //#region ../../lib/agents/staffing.ts
3234
+ /** Per-issue work-model override from the issue record, or undefined. */
3235
+ function resolveIssueWorkModel(issueId) {
3236
+ const resolved = resolveProjectFromIssueSync(issueId);
3237
+ if (!resolved) return void 0;
3238
+ const project = getProjectSync(resolved.projectKey);
3239
+ if (!project) return void 0;
3240
+ return readIssueRecordSync(project, issueId)?.workModel || void 0;
3241
+ }
2879
3242
  /** Provider-default harness for a model (PAN-1984: harness is derived from the
2880
3243
  * model's provider — per-provider setting else built-in default). */
2881
3244
  function providerDefaultHarnessSync(model, config) {
@@ -2900,6 +3263,16 @@ function resolveImplicitStaffing(config, spawnKey) {
2900
3263
  */
2901
3264
  function resolveStaffing(item, options = {}) {
2902
3265
  const config = options.config ?? loadConfigSync().config;
3266
+ const issueModel = options.issueId ? resolveIssueWorkModel(options.issueId) : void 0;
3267
+ if (issueModel) {
3268
+ const model = requireModelOverrideSync(issueModel);
3269
+ return {
3270
+ tierName: "issue-override",
3271
+ model,
3272
+ harness: providerDefaultHarnessSync(model, config),
3273
+ implicit: false
3274
+ };
3275
+ }
2903
3276
  const tiered = config.tieredExecution;
2904
3277
  if (tiered && resolveTieredExecutionEnabled(tiered, options.planMetadata)) try {
2905
3278
  const tier = resolveTier(item, tiered);
@@ -2939,7 +3312,9 @@ var init_staffing = __esmMin((() => {
2939
3312
  init_config_yaml();
2940
3313
  init_roles();
2941
3314
  init_model_validation();
3315
+ init_record();
2942
3316
  init_providers();
3317
+ init_projects();
2943
3318
  init_percent();
2944
3319
  init_resolve_tier();
2945
3320
  init_tier_table();
@@ -3011,7 +3386,8 @@ function resolveSlotTierSpawnParams(baseWorkspace, slotItemId, explicitModel, sp
3011
3386
  const staffing = resolveStaffing(item, {
3012
3387
  planMetadata,
3013
3388
  spawnKey,
3014
- config
3389
+ config,
3390
+ issueId: issueId ?? void 0
3015
3391
  });
3016
3392
  return {
3017
3393
  model: staffing.model,
@@ -3043,6 +3419,7 @@ function resolveSingleWorkTierSpawnParams(workspace, explicitModel, spawnKey) {
3043
3419
  const staffing = resolveStaffing(item, {
3044
3420
  planMetadata,
3045
3421
  spawnKey,
3422
+ issueId: issueId ?? void 0,
3046
3423
  config: {
3047
3424
  ...config,
3048
3425
  tieredExecution: {
@@ -3125,7 +3502,7 @@ async function transitionIssueToInReview(issueId, workspacePath) {
3125
3502
  async function buildAgentLaunchConfig(opts) {
3126
3503
  const model = requireModelOverrideSync(opts.model);
3127
3504
  try {
3128
- const { injectOverdeckInfraDeny } = await import("./claude-settings-overlay-BbA4FbVI.js");
3505
+ const { injectOverdeckInfraDeny } = await import("./claude-settings-overlay-DUWWLd6M.js");
3129
3506
  await Effect.runPromise(injectOverdeckInfraDeny(opts.workspace));
3130
3507
  } catch (err) {
3131
3508
  console.warn(`[agents] injectOverdeckInfraDeny failed for ${opts.agentId} (non-fatal): ${err instanceof Error ? err.message : err}`);
@@ -3206,7 +3583,7 @@ async function retrieveSpawnTimeMemoryContext(input) {
3206
3583
  agentRole: input.role,
3207
3584
  agentHarness: input.harness
3208
3585
  };
3209
- const { injectPromptTimeMemory } = await import("./injection-BLWfwTVZ.js");
3586
+ const { injectPromptTimeMemory } = await import("./injection-Bvhyg_MV.js");
3210
3587
  return (await injectPromptTimeMemory({
3211
3588
  prompt: input.prompt,
3212
3589
  identity,
@@ -3297,7 +3674,7 @@ async function assertWorkspaceStackHealthyForSpawn(issueId, role, allowHost = fa
3297
3674
  record.attempts += 1;
3298
3675
  spawnStackRebuildState.set(normalizedIssue, record);
3299
3676
  console.log(`[agents] Workspace stack for ${normalizedIssue} unhealthy (${details}) — rebuilding before spawn (attempt ${record.attempts}/${SPAWN_STACK_REBUILD_MAX_ATTEMPTS})`);
3300
- const { rebuildWorkspaceStack } = await import("./rebuild-stack-GOsWqXi3.js");
3677
+ const { rebuildWorkspaceStack } = await import("./rebuild-stack-C7JPUom6.js");
3301
3678
  const result = await Effect.runPromise(rebuildWorkspaceStack(issueId, { onProgress: (m) => console.log(`[agents] ${normalizedIssue} stack rebuild: ${m}`) })).catch((err) => ({
3302
3679
  success: false,
3303
3680
  error: err instanceof Error ? err.message : String(err)
@@ -4196,12 +4573,6 @@ var init_config = __esmMin((() => {
4196
4573
  120
4197
4574
  ]
4198
4575
  },
4199
- cost_limits: {
4200
- per_agent_usd: 10,
4201
- per_issue_usd: 25,
4202
- daily_total_usd: 100,
4203
- alert_threshold: .8
4204
- },
4205
4576
  retention: {
4206
4577
  agent_state_days: 7,
4207
4578
  reviewer_state_days: 1,
@@ -4523,151 +4894,6 @@ var init_concurrency = __esmMin((() => {
4523
4894
  swarmReservedThisPatrol = 0;
4524
4895
  }));
4525
4896
  //#endregion
4526
- //#region ../../lib/agents/queries.ts
4527
- function listRunningAgentsSync() {
4528
- const tmuxSessions = listSessionsSync();
4529
- const tmuxNames = new Set(tmuxSessions.map((s) => s.name));
4530
- return listOverdeckAgentStatesSync().map((state) => {
4531
- const normalizedId = normalizeAgentId(state.id);
4532
- return {
4533
- ...state,
4534
- id: normalizedId,
4535
- tmuxActive: tmuxNames.has(normalizedId)
4536
- };
4537
- });
4538
- }
4539
- /**
4540
- * PAN-1908: list all agents in the SQLite registry with optional filtering.
4541
- * This is the replacement for enumerating ~/.overdeck/agents/ directories.
4542
- */
4543
- function listAgentStates(options) {
4544
- return listOverdeckAgentStatesSync().filter((state) => {
4545
- if (options?.status && state.status !== options.status) return false;
4546
- if (options?.role && state.role !== options.role) return false;
4547
- return true;
4548
- });
4549
- }
4550
- /**
4551
- * PAN-1048 P2: async startup migration.
4552
- *
4553
- * The previous synchronous version used readdirSync, readFileSync,
4554
- * killSession (sync tmux subprocess), and rmSync — all on the Node
4555
- * event loop. Called from warnOnBareNumericIssueIds() during dashboard
4556
- * read-model bootstrap, this blocked all HTTP/WebSocket/PTY traffic on
4557
- * server startup while it scanned every agent dir, killed stale tmux
4558
- * sessions, and recursively deleted directories.
4559
- *
4560
- * This async variant does the same work using fs/promises and the
4561
- * already-async killSessionAsync() so the bootstrap path no longer
4562
- * stalls the event loop.
4563
- */
4564
- async function dropLegacyAgentStatesMissingRoleAsync() {
4565
- if (!existsSync(AGENTS_DIR)) return 0;
4566
- const fsp = await import("fs/promises");
4567
- let entries;
4568
- try {
4569
- entries = await fsp.readdir(AGENTS_DIR);
4570
- } catch {
4571
- return 0;
4572
- }
4573
- let dropped = 0;
4574
- await Promise.all(entries.map(async (entry) => {
4575
- const dirPath = join$1(AGENTS_DIR, entry);
4576
- let stat;
4577
- try {
4578
- stat = await fsp.stat(dirPath);
4579
- } catch {
4580
- return;
4581
- }
4582
- if (!stat.isDirectory()) return;
4583
- const agentId = normalizeAgentId(entry);
4584
- const stateFile = getRollbackAgentStatePath(agentId);
4585
- let raw;
4586
- try {
4587
- const contents = await fsp.readFile(stateFile, "utf8");
4588
- raw = JSON.parse(contents);
4589
- } catch {
4590
- return;
4591
- }
4592
- if (isRole(raw.role)) return;
4593
- try {
4594
- await Effect.runPromise(killSession(agentId));
4595
- } catch {}
4596
- try {
4597
- await fsp.rm(dirPath, {
4598
- recursive: true,
4599
- force: true
4600
- });
4601
- dropped++;
4602
- } catch (err) {
4603
- const msg = err instanceof Error ? err.message : String(err);
4604
- console.warn(`[agents] Failed to drop legacy agent state ${agentId}: ${msg}`);
4605
- }
4606
- }));
4607
- return dropped;
4608
- }
4609
- /**
4610
- * Scan ~/.overdeck/agents/ for state files with bare numeric issueIds
4611
- * (e.g. "484" instead of "PAN-484") and log warnings to stderr.
4612
- *
4613
- * These workspaces were created before the pan- prefix convention and may
4614
- * cause cross-tracker pollution if their in_review transition is triggered.
4615
- * Called once at server startup to surface legacy state files.
4616
- */
4617
- /**
4618
- * PAN-1048 P2: bootstrap-path migration is async.
4619
- *
4620
- * Sweeps legacy state files missing a `role` field and warns on bare
4621
- * numeric issueIds. Both passes used to be synchronous (readdirSync,
4622
- * readFileSync, killSession, rmSync), which blocked the dashboard
4623
- * server's event loop on startup. The async version scans the same
4624
- * directory once per concern and uses fs/promises throughout.
4625
- */
4626
- async function warnOnBareNumericIssueIds() {
4627
- const droppedLegacyAgents = await dropLegacyAgentStatesMissingRoleAsync();
4628
- if (droppedLegacyAgents > 0) console.warn(`[agents] Dropped ${droppedLegacyAgents} legacy agent state file(s) missing role`);
4629
- if (!existsSync(AGENTS_DIR)) return;
4630
- const fsp = await import("fs/promises");
4631
- let entries;
4632
- try {
4633
- entries = await fsp.readdir(AGENTS_DIR);
4634
- } catch {
4635
- return;
4636
- }
4637
- const legacy = [];
4638
- await Promise.all(entries.map(async (entry) => {
4639
- const dirPath = join$1(AGENTS_DIR, entry);
4640
- try {
4641
- if (!(await fsp.stat(dirPath)).isDirectory()) return;
4642
- } catch {
4643
- return;
4644
- }
4645
- const state = await Effect.runPromise(getAgentState(entry));
4646
- if (state?.issueId && /^\d+$/.test(state.issueId)) legacy.push(`${entry} (issueId: "${state.issueId}")`);
4647
- }));
4648
- if (legacy.length > 0) console.warn(`[agents] WARNING: ${legacy.length} agent state file(s) have bare numeric issueIds (created before the pan- prefix convention). These agents will not be able to transition tracker state. Consider removing or updating them:\n` + legacy.map((l) => ` ~/.overdeck/agents/${l}`).join("\n"));
4649
- }
4650
- var listRunningAgents;
4651
- var init_queries = __esmMin((() => {
4652
- init_agents();
4653
- init_tmux();
4654
- init_paths();
4655
- init_agent_rollback_state();
4656
- init_agent_state_sync();
4657
- listRunningAgents = () => Effect.gen(function* () {
4658
- const tmuxSessions = yield* listSessions();
4659
- const tmuxNames = new Set(tmuxSessions.map((s) => s.name));
4660
- return listOverdeckAgentStatesSync().map((state) => {
4661
- const normalizedId = normalizeAgentId(state.id);
4662
- return {
4663
- ...state,
4664
- id: normalizedId,
4665
- tmuxActive: tmuxNames.has(normalizedId)
4666
- };
4667
- });
4668
- });
4669
- }));
4670
- //#endregion
4671
4897
  //#region ../../lib/agents/termination.ts
4672
4898
  /**
4673
4899
  * True when the PID is a tmux process (client or server). Used to keep the
@@ -4701,7 +4927,7 @@ function killLauncherProcessSync(agentId) {
4701
4927
  const launcherPath = join$1(AGENTS_DIR, agentId, "launcher.sh");
4702
4928
  let pidsOut;
4703
4929
  try {
4704
- pidsOut = execSync$1(`pgrep -f ${JSON.stringify(launcherPath)}`, {
4930
+ pidsOut = execSync(`pgrep -f ${JSON.stringify(launcherPath)}`, {
4705
4931
  encoding: "utf-8",
4706
4932
  stdio: [
4707
4933
  "ignore",
@@ -4718,7 +4944,7 @@ function killLauncherProcessSync(agentId) {
4718
4944
  process.kill(pid, "SIGTERM");
4719
4945
  } catch {}
4720
4946
  try {
4721
- execSync$1("sleep 0.5", { stdio: "ignore" });
4947
+ execSync("sleep 0.5", { stdio: "ignore" });
4722
4948
  } catch {}
4723
4949
  const survivors = [];
4724
4950
  for (const pid of pids) try {
@@ -4733,7 +4959,7 @@ async function killLauncherProcessAsync(agentId) {
4733
4959
  const launcherPath = join$1(AGENTS_DIR, agentId, "launcher.sh");
4734
4960
  let pidsOut;
4735
4961
  try {
4736
- const { stdout } = await execAsync$4(`pgrep -f ${JSON.stringify(launcherPath)}`);
4962
+ const { stdout } = await execAsync$3(`pgrep -f ${JSON.stringify(launcherPath)}`);
4737
4963
  pidsOut = stdout.trim();
4738
4964
  } catch {
4739
4965
  return;
@@ -4777,14 +5003,14 @@ function stopAgentSync(agentId) {
4777
5003
  lastActivity: (/* @__PURE__ */ new Date()).toISOString()
4778
5004
  });
4779
5005
  }
4780
- var execAsync$4, stopAgent;
5006
+ var execAsync$3, stopAgent;
4781
5007
  var init_termination = __esmMin((() => {
4782
5008
  init_agents();
4783
5009
  init_agent_runtime();
4784
5010
  init_paths();
4785
5011
  init_tmux();
4786
5012
  init_errors();
4787
- execAsync$4 = promisify$1(exec$1);
5013
+ execAsync$3 = promisify$1(exec$1);
4788
5014
  stopAgent = (agentId) => {
4789
5015
  const normalizedId = normalizeAgentId(agentId);
4790
5016
  return Effect.gen(function* () {
@@ -4835,44 +5061,25 @@ var init_termination = __esmMin((() => {
4835
5061
  };
4836
5062
  }));
4837
5063
  //#endregion
4838
- //#region ../../lib/beads/bd-shim.ts
4839
- function shellQuote$1(value) {
4840
- return `'${value.replace(/'/g, `'"'"'`)}'`;
4841
- }
4842
- function installBdAgentShim(agentDir, realBdPath) {
4843
- const binDir = join(agentDir, "bin");
4844
- mkdirSync$1(binDir, { recursive: true });
4845
- const path = join(binDir, "bd");
4846
- writeFileSync$1(path, `#!/usr/bin/env bash
4847
- set -euo pipefail
4848
- verb="\${1:-}"
4849
- subverb="\${2:-}"
4850
- case "$verb:$subverb" in
4851
- create:*|update:*|close:*|delete:*|import:*|init:*|migrate:*|batch:*|dep:add|dep:remove|dolt:push|dolt:commit|dolt:reset|config:set|config:unset|comments:add|comments:delete|admin:compact)
4852
- echo "Raw mutating bd commands are blocked in agent sessions. Use pan beads claim|update|close|create|dep|delete so the canonical writer pulls, validates, exports, and pushes durably." >&2
4853
- exit 64
4854
- ;;
4855
- esac
4856
- exec ${shellQuote$1(realBdPath)} "$@"
4857
- `, { mode: 493 });
4858
- chmodSync$1(path, 493);
4859
- return {
4860
- binDir,
4861
- pathPrefix: `${binDir}${delimiter}${process.env.PATH ?? ""}`
4862
- };
4863
- }
4864
- async function resolveBdAgentShimPath(agentDir) {
4865
- try {
4866
- const { stdout } = await execAsync$3("command -v bd", { encoding: "utf8" });
4867
- const realBd = stdout.trim();
4868
- return realBd ? installBdAgentShim(agentDir, realBd).pathPrefix : void 0;
4869
- } catch {
4870
- return;
4871
- }
4872
- }
4873
- var execAsync$3;
4874
- var init_bd_shim = __esmMin((() => {
4875
- execAsync$3 = promisify(exec);
5064
+ //#region ../../lib/agents/hook-readiness.ts
5065
+ /**
5066
+ * Ensure Claude's global lifecycle hooks are registered before the process can
5067
+ * emit SessionStart. This must be awaited: provisioning after launch races the
5068
+ * one event that writes ready.json and acknowledges kickoff delivery.
5069
+ */
5070
+ async function ensureLifecycleHooksBeforeLaunch(agentId, harness) {
5071
+ if (harness !== "claude-code") return;
5072
+ const result = await provisionClaudeHooks();
5073
+ if (!result.ok) {
5074
+ const reason = result.reason ?? "unknown provisioning failure";
5075
+ logAgentLifecycleSync(agentId, `hook provisioning: failed harness=${harness} reason=${reason}`);
5076
+ throw new Error(`Claude Code lifecycle hooks are unavailable: ${reason}. Run \`pan up\` to install host prerequisites, then \`pan sync\` and retry.`);
5077
+ }
5078
+ logAgentLifecycleSync(agentId, `hook provisioning: ready harness=${harness} changed=${result.changed} binariesSynced=${result.binariesSynced} registered=${result.registered.length} pruned=${result.pruned.length}`);
5079
+ }
5080
+ var init_hook_readiness = __esmMin((() => {
5081
+ init_claude_hooks_provision();
5082
+ init_persistent_logger();
4876
5083
  }));
4877
5084
  //#endregion
4878
5085
  //#region ../../lib/agents/spawn.ts
@@ -4923,18 +5130,18 @@ async function spawnRun(issueId, role, options = {}) {
4923
5130
  let reapWarmIdle = false;
4924
5131
  const advancing = role === "review" || role === "test" || role === "ship";
4925
5132
  try {
4926
- const { isPaneDead } = await import("./tmux-x291Gjjb.js");
5133
+ const { isPaneDead } = await import("./tmux-C-rgxRDA.js");
4927
5134
  if (await Effect.runPromise(isPaneDead(agentId))) reapWarmIdle = true;
4928
5135
  else if (advancing) {
4929
- const { getReviewStatusSync } = await import("./review-status-Br6lAFGO.js");
4930
- const { isRoleTerminal } = await import("./reap-terminal-sessions-D_xvy-Mk.js");
5136
+ const { getReviewStatusSync } = await import("./review-status-77N3PoZr.js");
5137
+ const { isRoleTerminal } = await import("./reap-terminal-sessions-BR39qflC.js");
4931
5138
  const status = getReviewStatusSync(issueId);
4932
5139
  reapWarmIdle = !!status && isRoleTerminal(role, status);
4933
5140
  }
4934
5141
  } catch {}
4935
5142
  if (!reapWarmIdle) throw new Error(`Role run ${agentId} already running. Use 'pan tell' to message it.`);
4936
5143
  console.log(`[spawn] ${agentId} is warm-idle from the previous cycle — reaping it for the new ${role} dispatch (PAN-2579)`);
4937
- const { killSession } = await import("./tmux-x291Gjjb.js");
5144
+ const { killSession } = await import("./tmux-C-rgxRDA.js");
4938
5145
  await Effect.runPromise(killSession(agentId)).catch(() => {});
4939
5146
  }
4940
5147
  await assertWorkspaceStackHealthyForSpawn(issueId, role, options.allowHost, workspace);
@@ -4944,8 +5151,10 @@ async function spawnRun(issueId, role, options = {}) {
4944
5151
  role,
4945
5152
  model: selectedModel
4946
5153
  });
5154
+ assertCodexNativeAuthForSpawn(resolvedHarness, listAgentStates());
5155
+ await ensureLifecycleHooksBeforeLaunch(agentId, resolvedHarness);
4947
5156
  if (getProviderForModelSync(selectedModel).name === "openai" && await getProviderAuthMode(selectedModel) === "subscription") {
4948
- const { isCliproxyRunning } = await import("./cliproxy-C2xC-3vH.js");
5157
+ const { isCliproxyRunning } = await import("./cliproxy-BQX1TL6N.js");
4949
5158
  if (!await Effect.runPromise(isCliproxyRunning())) throw new Error("CLIProxyAPI sidecar is not running. GPT subscription role runs route through a local cliproxy process managed by `pan up`. Run `pan up` (or restart the dashboard) before spawning a GPT role run.");
4950
5159
  }
4951
5160
  const state = {
@@ -4986,7 +5195,6 @@ async function spawnRun(issueId, role, options = {}) {
4986
5195
  await Effect.runPromise(saveAgentState(state));
4987
5196
  }
4988
5197
  }
4989
- checkAndSetupHooks();
4990
5198
  const provider = getProviderForModelSync(selectedModel);
4991
5199
  if (provider.authType === "credential-file") setupCredentialFileAuthSync(provider, workspace);
4992
5200
  else clearCredentialFileAuthSync(workspace);
@@ -5054,7 +5262,7 @@ async function spawnRun(issueId, role, options = {}) {
5054
5262
  const claudeCmd = `bash ${launcherScript}`;
5055
5263
  console.log(`[claude-invoke] purpose=role-run | role=${role} | model=${state.model} | source=agents.ts:spawnRun | session=${agentId} | command="${claudeCmd}"`);
5056
5264
  try {
5057
- const { preTrustDirectory } = await import("./workspace-manager-DjUAJCSs.js");
5265
+ const { preTrustDirectory } = await import("./workspace-manager-B1mYn0lN.js");
5058
5266
  preTrustDirectory(workspace);
5059
5267
  } catch {}
5060
5268
  clearReadySignal(agentId);
@@ -5124,15 +5332,7 @@ async function spawnAgent(options) {
5124
5332
  if (await Effect.runPromise(sessionExists(agentId))) throw new Error(`Agent ${agentId} already running. Use 'pan tell' to message it.`);
5125
5333
  await assertWorkspaceStackHealthyForSpawn(options.issueId, role, options.allowHost, options.workspace);
5126
5334
  initHookSync(agentId);
5127
- if (role !== "strike" && role !== "knowledge" && options.slotItemId === void 0) try {
5128
- await Effect.runPromise(assertIssueHasBeads(options.workspace, options.issueId, { acquisitionTimeoutMs: 500 }));
5129
- } catch (error) {
5130
- if (error instanceof BeadsMissingError && error.transientFailure !== void 0) {
5131
- const attempts = error.transientFailure instanceof BdTransientFailure ? ` after ${error.transientFailure.attempts} attempts` : "";
5132
- throw new Error(`Beads database was temporarily locked while checking ${options.issueId}${attempts}; re-run shortly.`);
5133
- }
5134
- throw error;
5135
- }
5335
+ if (role !== "strike" && role !== "knowledge" && options.slotItemId === void 0 && !readWorkspacePlanSync(options.workspace)) throw new Error(`The required vBRIEF checklist for ${options.issueId} is missing or unreadable. Run planning before spawning a work agent.`);
5136
5336
  const modelSpawnKey = `${role}:${options.issueId}`;
5137
5337
  const singleTierParams = role === "work" && options.slotItemId === void 0 && options.slotIndex === void 0 ? resolveSingleWorkTierSpawnParams(options.workspace, options.model, modelSpawnKey) : {};
5138
5338
  const selectedModel = determineModel({
@@ -5142,7 +5342,7 @@ async function spawnAgent(options) {
5142
5342
  });
5143
5343
  console.log(`[DEBUG] Selected model: ${selectedModel}`);
5144
5344
  if (getProviderForModelSync(selectedModel).name === "openai" && await getProviderAuthMode(selectedModel) === "subscription") {
5145
- const { isCliproxyRunning } = await import("./cliproxy-C2xC-3vH.js");
5345
+ const { isCliproxyRunning } = await import("./cliproxy-BQX1TL6N.js");
5146
5346
  if (!await Effect.runPromise(isCliproxyRunning())) throw new Error("CLIProxyAPI sidecar is not running. GPT subscription agents route through a local cliproxy process managed by `pan up`. Run `pan up` (or restart the dashboard) before spawning a GPT agent.");
5147
5347
  }
5148
5348
  const resolvedHarness = await resolveHarness({
@@ -5150,6 +5350,8 @@ async function spawnAgent(options) {
5150
5350
  role,
5151
5351
  model: selectedModel
5152
5352
  });
5353
+ assertCodexNativeAuthForSpawn(resolvedHarness, listAgentStates());
5354
+ await ensureLifecycleHooksBeforeLaunch(agentId, resolvedHarness);
5153
5355
  const state = {
5154
5356
  id: agentId,
5155
5357
  issueId: options.issueId,
@@ -5161,14 +5363,15 @@ async function spawnAgent(options) {
5161
5363
  status: "starting",
5162
5364
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
5163
5365
  costSoFar: 0,
5164
- hostOverride: options.allowHost || void 0
5366
+ hostOverride: options.allowHost || void 0,
5367
+ sessionId: createFreshSessionIdentity(agentId, resolvedHarness)
5165
5368
  };
5166
5369
  const supervisorLaunch = await prepareSupervisorForFreshLaunch(agentId, options, state);
5167
5370
  saveAgentStateSync(state);
5168
5371
  if (role === "work") {
5169
5372
  try {
5170
5373
  if (resetPipelineVerdictsForWorkStartSync(options.issueId)) {
5171
- const { resetPostMergeState } = await import("./merge-agent-36wfYm2u.js");
5374
+ const { resetPostMergeState } = await import("./merge-agent-DMQTJMP0.js");
5172
5375
  resetPostMergeState(options.issueId);
5173
5376
  }
5174
5377
  } catch (err) {
@@ -5179,7 +5382,7 @@ async function spawnAgent(options) {
5179
5382
  });
5180
5383
  }
5181
5384
  if (role === "work") try {
5182
- const { writeStoryFeatureContext } = await import("./work-agent-prompt-fZljjA1_.js");
5385
+ const { writeStoryFeatureContext } = await import("./work-agent-prompt-BiJ43Der.js");
5183
5386
  await writeStoryFeatureContext(options.workspace, options.issueId);
5184
5387
  } catch (ctxErr) {
5185
5388
  console.warn(`[agents] Could not write story feature context for ${options.issueId}: ${ctxErr.message}`);
@@ -5225,11 +5428,10 @@ async function spawnAgent(options) {
5225
5428
  saveAgentStateSync(state);
5226
5429
  }
5227
5430
  }
5228
- checkAndSetupHooks();
5229
5431
  try {
5230
5432
  const venvPath = join$1(options.workspace, ".venv");
5231
5433
  if (isTldrEnabledSync() && existsSync(venvPath)) {
5232
- const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DD9rI5gA.js");
5434
+ const { getTldrDaemonServiceSync } = await import("./tldr-daemon-DhGwd88s.js");
5233
5435
  const tldrService = getTldrDaemonServiceSync(options.workspace, venvPath);
5234
5436
  if (!(await tldrService.getStatus()).running) {
5235
5437
  await tldrService.start(true);
@@ -5259,21 +5461,23 @@ async function spawnAgent(options) {
5259
5461
  useSupervisor: supervisorLaunch.useSupervisor,
5260
5462
  supervisorScriptPath: supervisorLaunch.supervisorScriptPath,
5261
5463
  harness: state.harness ?? "claude-code",
5464
+ sessionId: state.sessionId,
5262
5465
  extraEnvExports: flywheelEnvExports(flywheelEnv),
5263
5466
  effort: options.effort
5264
5467
  });
5265
5468
  const launcherScript = join$1(getAgentDir(agentId), "launcher.sh");
5266
5469
  await writeLauncherScriptAtomic(launcherScript, launcherContent);
5470
+ if (state.sessionId) logLauncherSessionPinned(agentId, state.sessionId, launcherScript);
5267
5471
  const claudeCmd = `bash ${launcherScript}`;
5268
5472
  console.log(`[claude-invoke] purpose=work-agent | model=${state.model} | source=agents.ts:spawnAgent | session=${agentId} | command="${claudeCmd}"`);
5269
5473
  try {
5270
- const { preTrustDirectory } = await import("./workspace-manager-DjUAJCSs.js");
5474
+ const { preTrustDirectory } = await import("./workspace-manager-B1mYn0lN.js");
5271
5475
  preTrustDirectory(options.workspace);
5272
5476
  } catch {}
5273
5477
  try {
5274
- const { isGitHubAppConfigured, generateInstallationToken, configureWorkspaceForBot } = await import("./github-app-DRD2woO0.js");
5478
+ const { isGitHubAppConfigured, generateInstallationToken, configureWorkspaceForBot } = await import("./github-app-BrYwK_Gb.js");
5275
5479
  if (isGitHubAppConfigured()) {
5276
- const { findProjectByPathSync } = await import("./projects-KJ94e50I.js");
5480
+ const { findProjectByPathSync } = await import("./projects-Dc9aoVoG.js");
5277
5481
  const ghRepo = findProjectByPathSync(resolve$1(options.workspace, "..", ".."))?.github_repo;
5278
5482
  if (ghRepo) {
5279
5483
  const [owner, repo] = ghRepo.split("/");
@@ -5286,7 +5490,6 @@ async function spawnAgent(options) {
5286
5490
  console.warn(`[${agentId}] GitHub App config failed (falling back to SSH): ${err.message}`);
5287
5491
  }
5288
5492
  clearReadySignal(agentId);
5289
- const bdShimPath = role === "work" ? await resolveBdAgentShimPath(getAgentDir(agentId)) : void 0;
5290
5493
  await Effect.runPromise(createSession(agentId, options.workspace, claudeCmd, { env: {
5291
5494
  ...BLANKED_PROVIDER_ENV,
5292
5495
  TERM: "xterm-256color",
@@ -5295,11 +5498,11 @@ async function spawnAgent(options) {
5295
5498
  OVERDECK_SESSION_TYPE: role,
5296
5499
  CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION: "false",
5297
5500
  GIT_SEQUENCE_EDITOR: "false",
5298
- ...bdShimPath ? { PATH: bdShimPath } : {},
5299
5501
  ...flywheelEnv,
5300
5502
  ...providerEnv
5301
5503
  } }));
5302
5504
  await saveAgentRuntimeState(agentId, {
5505
+ claudeSessionId: state.sessionId,
5303
5506
  sessionModel: selectedModel,
5304
5507
  sessionHarness: resolvedHarness
5305
5508
  });
@@ -5343,7 +5546,7 @@ async function spawnAgent(options) {
5343
5546
  const codexHomeForAgent = join$1(homedir(), ".overdeck", "agents", agentId, "codex-home");
5344
5547
  (async () => {
5345
5548
  try {
5346
- const { waitForCodexRollout, extractThreadIdFromRollout, writeThreadId } = await import("./codex-B7DTpwEw.js");
5549
+ const { waitForCodexRollout, extractThreadIdFromRollout, writeThreadId } = await import("./codex-DxLivxri.js");
5347
5550
  const rollout = await waitForCodexRollout(codexHomeForAgent, 12e4);
5348
5551
  if (rollout) {
5349
5552
  const threadId = extractThreadIdFromRollout(rollout);
@@ -5423,26 +5626,6 @@ function escapeRegExp$1(value) {
5423
5626
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5424
5627
  }
5425
5628
  /**
5426
- * Check if Overdeck hooks are configured, and auto-setup if not
5427
- */
5428
- function checkAndSetupHooks() {
5429
- const settingsPath = join$1(homedir(), ".claude", "settings.json");
5430
- const hookPath = join$1(homedir(), ".overdeck", "bin", "heartbeat-hook");
5431
- if (existsSync(settingsPath)) try {
5432
- const settingsContent = readFileSync(settingsPath, "utf-8");
5433
- if ((JSON.parse(settingsContent)?.hooks?.PostToolUse || []).some((hookConfig) => hookConfig.hooks?.some((hook) => hook.command === hookPath || hook.command?.includes("overdeck") || hook.command?.includes("heartbeat-hook")))) return;
5434
- } catch {}
5435
- try {
5436
- console.log("Configuring Overdeck heartbeat hooks...");
5437
- exec$1("pan admin hooks install", (error) => {
5438
- if (error) console.warn("⚠ Failed to auto-configure hooks. Run `pan admin hooks install` manually.");
5439
- else console.log("✓ Heartbeat hooks configured");
5440
- });
5441
- } catch (error) {
5442
- console.warn("⚠ Failed to auto-configure hooks. Run `pan admin hooks install` manually.");
5443
- }
5444
- }
5445
- /**
5446
5629
  * Write task cache for heartbeat hook to use
5447
5630
  */
5448
5631
  function writeTaskCache(agentId, issueId) {
@@ -5457,8 +5640,6 @@ function writeTaskCache(agentId, issueId) {
5457
5640
  var execAsync$2;
5458
5641
  var init_spawn = __esmMin((() => {
5459
5642
  init_activity_logger();
5460
- init_beads_query();
5461
- init_bd_process_lock();
5462
5643
  init_child_env();
5463
5644
  init_config_yaml();
5464
5645
  init_conversations();
@@ -5468,6 +5649,7 @@ var init_spawn = __esmMin((() => {
5468
5649
  init_providers();
5469
5650
  init_review_status();
5470
5651
  init_harness_resolve();
5652
+ init_codex_auth();
5471
5653
  init_bridge_token();
5472
5654
  init_tmux();
5473
5655
  init_dag();
@@ -5486,7 +5668,8 @@ var init_spawn = __esmMin((() => {
5486
5668
  init_state_read_home();
5487
5669
  init_supervisor_channels();
5488
5670
  init_termination();
5489
- init_bd_shim();
5671
+ init_session_history();
5672
+ init_hook_readiness();
5490
5673
  execAsync$2 = promisify$1(exec$1);
5491
5674
  }));
5492
5675
  //#endregion
@@ -5917,9 +6100,7 @@ function getActivity(agentId, limit = 100) {
5917
6100
  * Save Claude session ID for later resume
5918
6101
  */
5919
6102
  function saveSessionId(agentId, sessionId) {
5920
- const dir = getAgentDir(agentId);
5921
- mkdirSync(dir, { recursive: true });
5922
- writeFileSync(join$1(dir, "session.id"), sessionId);
6103
+ persistCurrentSessionId(agentId, sessionId);
5923
6104
  }
5924
6105
  /**
5925
6106
  * Get saved Claude session ID
@@ -6024,6 +6205,7 @@ var init_activity = __esmMin((() => {
6024
6205
  init_ohmypi();
6025
6206
  init_behavior();
6026
6207
  init_errors();
6208
+ init_session_history();
6027
6209
  getLatestSessionId = (agentId) => {
6028
6210
  const agentDir = getAgentDir(agentId);
6029
6211
  const sessionFile = join$1(agentDir, "session.id");
@@ -6102,9 +6284,24 @@ async function appendTellInterventionForUserSource(normalizedId, caller) {
6102
6284
  source: caller
6103
6285
  });
6104
6286
  }
6105
- async function messageAgent(agentId, message, caller = "internal") {
6287
+ async function messageAgent(agentId, message, caller = "internal", opts = {}) {
6106
6288
  const normalizedId = normalizeAgentId(agentId);
6107
6289
  const agentState = getAgentStateSync(normalizedId);
6290
+ const decideMessageGate = () => {
6291
+ const block = agentState ? getAgentResumeGateBlockReason(agentState) : void 0;
6292
+ const agentDir = getAgentDir(normalizedId);
6293
+ const decision = decideResumeGate(block, "message-delivery", {
6294
+ hasCompletedHandoff: existsSync(join$1(agentDir, "completed")) || existsSync(join$1(agentDir, "completed.processed")),
6295
+ owesRework: opts.owesRework === true
6296
+ });
6297
+ if (decision.decision === "proceed" && decision.clearStoppedByUser && agentState) {
6298
+ console.log(`[agents] ${normalizedId} was operator-stopped but owes rework after a completed handoff — clearing stop gate to deliver feedback (PAN-2668)`);
6299
+ logAgentLifecycleSync(normalizedId, "stoppedByUser cleared: completed handoff owes rework; delivering pipeline feedback (PAN-2668)");
6300
+ delete agentState.stoppedByUser;
6301
+ saveAgentStateSync(agentState);
6302
+ }
6303
+ return decision;
6304
+ };
6108
6305
  if (agentState?.paused === true) {
6109
6306
  const gateBlockReason = getAgentResumeGateBlockReason(agentState)?.reason ?? "agent is paused";
6110
6307
  queueAgentMail(normalizedId, message);
@@ -6113,15 +6310,16 @@ async function messageAgent(agentId, message, caller = "internal") {
6113
6310
  return;
6114
6311
  }
6115
6312
  if (getAgentRuntimeStateSync(normalizedId)?.state === "suspended") {
6116
- const gateBlockReason = agentState ? getAgentResumeGateBlockReason(agentState)?.reason : void 0;
6117
- if (gateBlockReason) {
6313
+ const suspendedGate = decideMessageGate();
6314
+ if (suspendedGate.decision !== "proceed") {
6315
+ const gateBlockReason = suspendedGate.reason ?? "agent is gated";
6118
6316
  queueAgentMail(normalizedId, message);
6119
6317
  logAgentLifecycleSync(normalizedId, `messageAgent queued mail without resume: ${gateBlockReason}`);
6120
6318
  console.log(`[agents] Queued message for ${normalizedId}; ${gateBlockReason}`);
6121
6319
  return;
6122
6320
  }
6123
6321
  console.log(`[agents] Auto-resuming suspended agent ${normalizedId} to deliver message`);
6124
- const { resumeAgent } = await import("./agents-DCvyTXNU.js");
6322
+ const { resumeAgent } = await import("./agents-BA15AQqo.js");
6125
6323
  const result = await resumeAgent(normalizedId, message);
6126
6324
  if (!result.success) throw new Error(`Failed to auto-resume agent: ${result.error}`);
6127
6325
  if (result.messageDelivered === false) throw new Error(`Agent resumed but ready signal did not fire — message not delivered. Feedback is in the mail queue.`);
@@ -6129,15 +6327,16 @@ async function messageAgent(agentId, message, caller = "internal") {
6129
6327
  return;
6130
6328
  }
6131
6329
  if (agentState && agentState.status === "stopped") {
6132
- const gateBlockReason = getAgentResumeGateBlockReason(agentState)?.reason;
6133
- if (gateBlockReason) {
6330
+ const stoppedGate = decideMessageGate();
6331
+ if (stoppedGate.decision !== "proceed") {
6332
+ const gateBlockReason = stoppedGate.reason ?? "agent is gated";
6134
6333
  queueAgentMail(normalizedId, message);
6135
6334
  logAgentLifecycleSync(normalizedId, `messageAgent queued mail without resume: ${gateBlockReason}`);
6136
6335
  console.log(`[agents] Queued message for ${normalizedId}; ${gateBlockReason}`);
6137
6336
  return;
6138
6337
  }
6139
6338
  console.log(`[agents] Auto-resuming stopped agent ${normalizedId} to deliver feedback (session exists: ${await Effect.runPromise(sessionExists(normalizedId))})`);
6140
- const { resumeAgent } = await import("./agents-DCvyTXNU.js");
6339
+ const { resumeAgent } = await import("./agents-BA15AQqo.js");
6141
6340
  const resumeResult = await resumeAgent(normalizedId, message);
6142
6341
  queueAgentMail(normalizedId, message);
6143
6342
  if (resumeResult.success && resumeResult.messageDelivered !== false) {
@@ -6173,7 +6372,7 @@ async function messageAgent(agentId, message, caller = "internal") {
6173
6372
  const resumeRole = agentState.role ?? "work";
6174
6373
  const resumeModel = agentState.model || "claude-sonnet-4-6";
6175
6374
  const fallbackHarness = agentState.harness ?? "claude-code";
6176
- const { assertWorkspaceStackHealthyForSpawn } = await import("./agents-DCvyTXNU.js");
6375
+ const { assertWorkspaceStackHealthyForSpawn } = await import("./agents-BA15AQqo.js");
6177
6376
  await assertWorkspaceStackHealthyForSpawn(agentState.issueId || normalizedId.replace(/^agent-/, "").toUpperCase(), resumeRole, agentState.hostOverride === true, agentState.workspace);
6178
6377
  const fallbackPiFields = fallbackHarness === "ohmypi" ? await getOhmypiLauncherFields(normalizedId, resumeModel) : {};
6179
6378
  const fallbackCodexFields = fallbackHarness === "codex" ? getCodexLauncherFields(normalizedId, resumeModel, agentState.workspace) : {};
@@ -6236,7 +6435,7 @@ async function messageAgent(agentId, message, caller = "internal") {
6236
6435
  } else console.warn(`[agents] Fallback-restarted ${normalizedId} but ready signal not detected — feedback in mail queue`);
6237
6436
  return;
6238
6437
  }
6239
- const { loadRemoteAgentState, sendToRemoteAgent } = await import("./remote-agents-DlvbzO7m.js");
6438
+ const { loadRemoteAgentState, sendToRemoteAgent } = await import("./remote-agents-DYY5fFpd.js");
6240
6439
  const remoteState = loadRemoteAgentState(normalizedId);
6241
6440
  if (remoteState && remoteState.vmName) {
6242
6441
  console.log(`[agents] Sending message to remote agent ${normalizedId} on ${remoteState.vmName}`);
@@ -6250,7 +6449,7 @@ async function messageAgent(agentId, message, caller = "internal") {
6250
6449
  const expectedHarness = agentState?.harness ?? "claude-code";
6251
6450
  if (panePids.length > 0 && !await hasAgentRuntimeInSubtree(panePids[0], expectedHarness)) {
6252
6451
  console.warn(`[agents] ${normalizedId} tmux session is a zombie (no ${expectedHarness} runtime) — attempting resume`);
6253
- const { resumeAgent } = await import("./agents-DCvyTXNU.js");
6452
+ const { resumeAgent } = await import("./agents-BA15AQqo.js");
6254
6453
  const resumeResult = await resumeAgent(normalizedId, message);
6255
6454
  if (resumeResult.success) {
6256
6455
  if (resumeResult.messageDelivered !== false) await appendTellInterventionForUserSource(normalizedId, caller);
@@ -6318,7 +6517,7 @@ function buildCompactRecoverySeedMessage(issueId, summary) {
6318
6517
  const lines = [`Your previous session for ${issueId} hit the model's context-window limit, so you are starting a fresh session. This freed tokens; it did not reset your filesystem work.`, "Do NOT start over and do NOT expect the prior conversation to be available."];
6319
6518
  if (summary) lines.push("", "Summary of the archived session:", "", summary, "");
6320
6519
  else lines.push("");
6321
- lines.push("Reconstruct your exact work-in-progress from durable artifacts:", "1. Read .pan/continue.json for resumePoint, decisions, hazards, feedback, and sessionHistory.", "2. Run `bd ready` for your open beads and `bd show <id>` for the bead you are working on.", "3. Inspect `git status` and `git diff` for uncommitted work already on disk.", "Then continue from that reconstructed state and complete the next required bead — do not wait for further instructions.");
6520
+ lines.push("Reconstruct your exact work-in-progress from durable artifacts:", "1. Read .pan/continue.json for resumePoint, decisions, hazards, feedback, and sessionHistory.", "2. Run `pan task next` for the next open item and `pan task show <issue> <item>` for its current state.", "3. Inspect `git status` and `git diff` for uncommitted work already on disk.", "Then continue from that reconstructed state and complete the next required bead — do not wait for further instructions.");
6322
6521
  return lines.join("\n");
6323
6522
  }
6324
6523
  var CONTEXT_OVERFLOW_PATTERNS;
@@ -6362,7 +6561,7 @@ async function buildCompactRecoverySeed(agentId) {
6362
6561
  if (agentState?.workspace && sessionId) {
6363
6562
  const sessionFile = sessionFilePath(agentState.workspace, sessionId);
6364
6563
  try {
6365
- const [{ getConversationCompactionSettings }, { generateSmartSummary }] = await Promise.all([import("./conversation-compaction-WYQZUVDm.js"), import("./smart-compaction-h4_ca6Uk.js")]);
6564
+ const [{ getConversationCompactionSettings }, { generateSmartSummary }] = await Promise.all([import("./conversation-compaction-CRKAf2qP.js"), import("./smart-compaction-DldUel4B.js")]);
6366
6565
  const settings = getConversationCompactionSettings();
6367
6566
  summary = (await Effect.runPromise(generateSmartSummary({
6368
6567
  jsonlPath: sessionFile,
@@ -6373,7 +6572,7 @@ async function buildCompactRecoverySeed(agentId) {
6373
6572
  } catch (err) {
6374
6573
  logAgentLifecycleSync(normalizedId, `compact-recovery smart summary failed (${err instanceof Error ? err.message : String(err)}); trying heuristic fallback`);
6375
6574
  try {
6376
- const { generateFallbackSummary } = await import("./summary-fork-CKc01Our.js");
6575
+ const { generateFallbackSummary } = await import("./summary-fork-BxnF8Xh0.js");
6377
6576
  summary = await Effect.runPromise(generateFallbackSummary(sessionFile));
6378
6577
  } catch (fallbackErr) {
6379
6578
  logAgentLifecycleSync(normalizedId, `compact-recovery fallback summary failed (${fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr)}); seeding with reseed instructions only`);
@@ -6990,7 +7189,7 @@ function generateRecoveryPrompt(state) {
6990
7189
  `- Started: ${state.startedAt}`,
6991
7190
  "",
6992
7191
  "## Recovery Steps",
6993
- "1. Check beads for context: `bd show " + state.issueId + "`",
7192
+ "1. Check the vBRIEF task state: `pan task show " + state.issueId + " <item-id>`",
6994
7193
  "2. Review recent git commits: `git log --oneline -10`",
6995
7194
  "3. Check hook for pending work: `pan admin fpp check`",
6996
7195
  "4. Resume from last known state",
@@ -7192,10 +7391,10 @@ function computeTierRunSchedule(doc, config) {
7192
7391
  if (!item) continue;
7193
7392
  const tier = resolveTier(item, config);
7194
7393
  const currentRun = runs[runs.length - 1];
7195
- if (currentRun && currentRun.tierName === tier.tierName) currentRun.beadIds.push(item.id);
7394
+ if (currentRun && currentRun.tierName === tier.tierName) currentRun.itemIds.push(item.id);
7196
7395
  else runs.push({
7197
7396
  tierName: tier.tierName,
7198
- beadIds: [item.id]
7397
+ itemIds: [item.id]
7199
7398
  });
7200
7399
  }
7201
7400
  return runs;
@@ -7229,20 +7428,20 @@ function applyEffectiveDifficulty(item, overrides) {
7229
7428
  * retry event persistence, tier promotion writes, dispatch, and notifications.
7230
7429
  */
7231
7430
  function decideEscalation(trigger, bead, config, overrides) {
7232
- const beadId = trigger.beadId || bead.id;
7431
+ const itemId = trigger.itemId || bead.id;
7233
7432
  const override = overrides[bead.id];
7234
7433
  const currentDifficulty = override?.effectiveDifficulty ?? bead.metadata?.difficulty;
7235
7434
  if (!currentDifficulty) return {
7236
7435
  action: "block",
7237
- reason: `bead ${beadId} has no effective difficulty`
7436
+ reason: `task ${itemId} has no effective difficulty`
7238
7437
  };
7239
7438
  if ((override?.promotions ?? 0) >= config.max_promotions) return {
7240
7439
  action: "block",
7241
- reason: `max promotions reached for ${beadId} at ${currentDifficulty}`
7440
+ reason: `max promotions reached for ${itemId} at ${currentDifficulty}`
7242
7441
  };
7243
7442
  if (currentDifficulty === "expert") return {
7244
7443
  action: "block",
7245
- reason: `expert bead ${beadId} cannot promote beyond expert`
7444
+ reason: `expert task ${itemId} cannot promote beyond expert`
7246
7445
  };
7247
7446
  const attemptsAtCurrentTier = trigger.attemptsAtCurrentTier ?? 0;
7248
7447
  if (attemptsAtCurrentTier < config.retries_at_tier) return {
@@ -7252,7 +7451,7 @@ function decideEscalation(trigger, bead, config, overrides) {
7252
7451
  const to = TIERED_EXECUTION_DIFFICULTIES[TIERED_EXECUTION_DIFFICULTIES.indexOf(currentDifficulty) + 1];
7253
7452
  if (!to) return {
7254
7453
  action: "block",
7255
- reason: `bead ${beadId} cannot promote beyond ${currentDifficulty}`
7454
+ reason: `task ${itemId} cannot promote beyond ${currentDifficulty}`
7256
7455
  };
7257
7456
  return {
7258
7457
  action: "promote",
@@ -7324,20 +7523,20 @@ function resolveFeedApiUrl(env = process.env) {
7324
7523
  }
7325
7524
  /**
7326
7525
  * Compose the ingestion-only feed message for one commit. Deterministic over
7327
- * (sha, beadTitle, diff) so replay reconstructs byte-identical messages.
7526
+ * (sha, itemTitle, diff) so replay reconstructs byte-identical messages.
7328
7527
  */
7329
- function composeCommitFeedMessage(sha, beadTitle, diff, callout) {
7528
+ function composeCommitFeedMessage(sha, itemTitle, diff, callout) {
7330
7529
  const lines = [
7331
7530
  `# Commit feed (ingestion-only): ${sha}`,
7332
7531
  "",
7333
- `Bead: ${beadTitle}`,
7532
+ `Bead: ${itemTitle}`,
7334
7533
  ""
7335
7534
  ];
7336
7535
  if (callout) {
7337
7536
  const body = JSON.stringify({
7338
7537
  issueId: callout.issueId,
7339
7538
  sha,
7340
- beadId: callout.beadId,
7539
+ itemId: callout.itemId,
7341
7540
  tierName: callout.tierName,
7342
7541
  agentId: callout.agentId,
7343
7542
  claim: "<one sentence: what is wrong and where>"
@@ -7354,22 +7553,22 @@ function composeCommitFeedMessage(sha, beadTitle, diff, callout) {
7354
7553
  */
7355
7554
  async function broadcastCommit(options) {
7356
7555
  const feedConfig = options.feedConfig ?? DEFAULT_FEED_CONFIG;
7357
- if (shouldSkipFeedSubject(options.commitSubject ?? options.beadTitle, feedConfig)) return [];
7556
+ if (shouldSkipFeedSubject(options.commitSubject ?? options.itemTitle, feedConfig)) return [];
7358
7557
  const renderDiff = options.renderDiff ?? (options.gitShow ? (workspace, sha) => options.gitShow(workspace, sha) : renderCommitFeedDiff);
7359
7558
  const deliver = options.deliver ?? deliverAgentMessage;
7360
7559
  const recordDelivery = options.recordDelivery ?? recordTierFeedDelivery;
7361
7560
  const now = options.now ?? (() => /* @__PURE__ */ new Date());
7362
7561
  const diff = await renderDiff(options.workspace, options.sha, feedConfig);
7363
- const baseMessage = composeCommitFeedMessage(options.sha, options.beadTitle, diff);
7562
+ const baseMessage = composeCommitFeedMessage(options.sha, options.itemTitle, diff);
7364
7563
  const baseTokenCount = estimateFeedDeliveryTokens(baseMessage);
7365
- const includeCallout = feedConfig.callouts !== "off" && options.issueId !== void 0 && options.beadId !== void 0;
7564
+ const includeCallout = feedConfig.callouts !== "off" && options.issueId !== void 0 && options.itemId !== void 0;
7366
7565
  const apiUrl = options.apiUrl ?? resolveFeedApiUrl();
7367
7566
  const deliveries = [];
7368
7567
  for (const tier of options.tiers) {
7369
- const message = includeCallout ? composeCommitFeedMessage(options.sha, options.beadTitle, diff, {
7568
+ const message = includeCallout ? composeCommitFeedMessage(options.sha, options.itemTitle, diff, {
7370
7569
  apiUrl,
7371
7570
  issueId: options.issueId,
7372
- beadId: options.beadId,
7571
+ itemId: options.itemId,
7373
7572
  tierName: tier.tierName,
7374
7573
  agentId: tier.agentId
7375
7574
  }) : baseMessage;
@@ -7388,7 +7587,7 @@ async function broadcastCommit(options) {
7388
7587
  ts: now().toISOString(),
7389
7588
  issueId: options.issueId,
7390
7589
  sha: options.sha,
7391
- beadTitle: options.beadTitle,
7590
+ itemTitle: options.itemTitle,
7392
7591
  tierName: tier.tierName,
7393
7592
  agentId: tier.agentId,
7394
7593
  tokenCount,
@@ -7467,10 +7666,10 @@ function shouldSupervise(bead, policy, options = {}) {
7467
7666
  * is stable across the live commit feed, replay re-delivery (tier-replay),
7468
7667
  * and tests.
7469
7668
  */
7470
- function sampleFraction(beadId) {
7669
+ function sampleFraction(itemId) {
7471
7670
  let hash = 2166136261;
7472
- for (let i = 0; i < beadId.length; i++) {
7473
- hash ^= beadId.charCodeAt(i);
7671
+ for (let i = 0; i < itemId.length; i++) {
7672
+ hash ^= itemId.charCodeAt(i);
7474
7673
  hash = Math.imul(hash, 16777619);
7475
7674
  }
7476
7675
  return (hash >>> 0) / 4294967296;
@@ -7587,7 +7786,7 @@ You are the standing supervisor for ${event.issueId}. Review this commit against
7587
7786
  ## Bead under review
7588
7787
 
7589
7788
  - Issue: ${event.issueId}
7590
- - Bead: ${event.beadId} — ${event.beadTitle}
7789
+ - Bead: ${event.itemId} — ${event.itemTitle}
7591
7790
  - Commit: ${event.sha}
7592
7791
 
7593
7792
  ## Acceptance criteria
@@ -7602,14 +7801,14 @@ ${event.diff}
7602
7801
 
7603
7802
  ## Verdict (REQUIRED — post exactly one)
7604
7803
 
7605
- Land your verdict on the existing inspect-status surface. Your notes MUST begin with "Bead ${event.beadId}" — the server extracts the bead id from that prefix.
7804
+ Land your verdict on the existing inspect-status surface. Your notes MUST begin with "Item ${event.itemId}" — the server extracts the bead id from that prefix.
7606
7805
 
7607
7806
  If the diff satisfies the acceptance criteria, post an ack (this persists inspectStatus and saves the bead checkpoint):
7608
7807
 
7609
7808
  \`\`\`bash
7610
7809
  curl -X POST ${event.apiUrl}/api/specialists/done \\
7611
7810
  -H "Content-Type: application/json" \\
7612
- -d '{"specialist":"inspect","issueId":"${event.issueId}","status":"passed","notes":"Bead ${event.beadId} ack: <one-line summary>"}'
7811
+ -d '{"specialist":"inspect","issueId":"${event.issueId}","status":"passed","notes":"Item ${event.itemId} ack: <one-line summary>"}'
7613
7812
  \`\`\`
7614
7813
 
7615
7814
  If any acceptance criterion is not met, post a blocking finding with specific, actionable violations ([file:line] + what is wrong):
@@ -7617,7 +7816,7 @@ If any acceptance criterion is not met, post a blocking finding with specific, a
7617
7816
  \`\`\`bash
7618
7817
  curl -X POST ${event.apiUrl}/api/specialists/done \\
7619
7818
  -H "Content-Type: application/json" \\
7620
- -d '{"specialist":"inspect","issueId":"${event.issueId}","status":"failed","notes":"Bead ${event.beadId} BLOCKED: <specific violations and required fixes>"}'
7819
+ -d '{"specialist":"inspect","issueId":"${event.issueId}","status":"failed","notes":"Item ${event.itemId} BLOCKED: <specific violations and required fixes>"}'
7621
7820
  \`\`\`
7622
7821
 
7623
7822
  Rules:
@@ -7646,8 +7845,8 @@ async function deliverCommitForReview(options) {
7646
7845
  const frText = options.prdMarkdown && traces.length > 0 ? extractTracedFrText(options.prdMarkdown, traces) : void 0;
7647
7846
  const message = buildSupervisorReviewMessage({
7648
7847
  issueId: options.issueId,
7649
- beadId: options.beadId ?? options.item.id,
7650
- beadTitle: options.item.title,
7848
+ itemId: options.itemId ?? options.item.id,
7849
+ itemTitle: options.item.title,
7651
7850
  sha: options.sha,
7652
7851
  diff,
7653
7852
  acceptanceCriteria: extractAcceptanceCriteria(options.item),
@@ -7784,11 +7983,11 @@ async function replayTierFeed(agentId, target, commits, deps) {
7784
7983
  const includeCallout = (target.feedConfig ?? DEFAULT_TIERED_EXECUTION_CONFIG.feed).callouts !== "off";
7785
7984
  const apiUrl = target.apiUrl ?? resolveFeedApiUrl();
7786
7985
  for (const commit of commits) {
7787
- const beadId = commit.beadId;
7788
- const message = composeCommitFeedMessage(commit.sha, commit.subject, commit.diff, includeCallout && beadId ? {
7986
+ const itemId = commit.itemId;
7987
+ const message = composeCommitFeedMessage(commit.sha, commit.subject, commit.diff, includeCallout && itemId ? {
7789
7988
  apiUrl,
7790
7989
  issueId: target.issueId,
7791
- beadId,
7990
+ itemId,
7792
7991
  tierName: target.tierName,
7793
7992
  agentId
7794
7993
  } : void 0);
@@ -7808,8 +8007,8 @@ async function replaySupervisorFeed(agentId, target, commits, deps) {
7808
8007
  const frText = target.prdMarkdown && traces.length > 0 ? extractTracedFrText(target.prdMarkdown, traces) : void 0;
7809
8008
  const message = buildSupervisorReviewMessage({
7810
8009
  issueId: target.issueId,
7811
- beadId: item.id,
7812
- beadTitle: item.title,
8010
+ itemId: item.id,
8011
+ itemTitle: item.title,
7813
8012
  sha: commit.sha,
7814
8013
  diff: commit.diff,
7815
8014
  acceptanceCriteria: extractAcceptanceCriteria(item),
@@ -7915,6 +8114,151 @@ var init_agents = __esmMin((() => {
7915
8114
  init_tier_replay();
7916
8115
  }));
7917
8116
  //#endregion
7918
- export { warnOnBareNumericIssueIds as $, writeAgentStateJsonSync as $n, waitForPromptReady as $t, init_messaging as A, getAgentDir as An, init_bridge_token as At, createOhmypiRuntimeSync as B, markAgentRunningState as Bn, resolveStaffing as Bt, restartAgent as C, __testInternals as Cn, deliverAgentPermissionDecision as Ct, init_context_overflow as D, clearAgentTroubledSync as Dn, captureTranscriptUserRecordSnapshot as Dt, resumeAgent as E, clearAgentTroubled as En, setAgentDeliveryMethod as Et, getActivity as F, init_agent_state as Fn, init_spawn_prep as Ft, init_termination as G, recordStartupSessionExit as Gn, getAgentRuntimeBaseCommand as Gt, init_spawn as H, markAgentTroubled as Hn, resolveTier as Ht, getLatestSessionId as I, isAgentPaused as In, retrieveSpawnTimeMemoryContext as It, dropLegacyAgentStatesMissingRoleAsync as J, saveAgentStateSync as Jn, getProviderAuthMode as Jt, stopAgent as K, resetAgentFailureCount as Kn, getCodexLauncherFields as Kt, getLatestSessionIdSync as L, isAgentTroubled as Ln, transitionIssueToInProgress as Lt, init_operator_interventions as M, getAgentState as Mn, assertWorkspaceStackHealthyForSpawn as Mt, operatorInterventionEvent as N, getAgentStateFilePath as Nn, buildAgentLaunchConfig as Nt, isContextOverflowError as O, clearYieldForResumeSync as On, init_transcript_landing as Ot, appendActivity as P, getAgentStateSync as Pn, defaultRunWorkspace as Pt, listRunningAgentsSync as Q, wipeAgentStateDirs as Qn, roleAgentDefinitionPath as Qt, getSessionId as R, isRole as Rn, transitionIssueToInReview as Rt, recoverAgent as S, SESSION_EXITED_BEFORE_KICKOFF as Sn, parseOhmypiSessionCostResultSync as Sr, deliverAgentMessage as St, init_resume as T, clearAgentPausedSync as Tn, deliverResumeMessageWithTranscriptConfirmation as Tt, spawnAgent as U, recordAgentFailure as Un, OHMYPI_AGENT_READY_TIMEOUT_SECONDS as Ut, init_ohmypi as V, markAgentStoppedState as Vn, init_resolve_tier as Vt, spawnRun as W, recordAgentFailureSync as Wn, describeOhmypiSpawnFailure as Wt, listAgentStates as X, setAgentPausedSync as Xn, init_runtime_command as Xt, init_queries as Y, setAgentPaused as Yn, getRoleRuntimeBaseCommand as Yt, listRunningAgents as Z, setAgentYieldedSync as Zn, injectPiConversationMemory as Zt, init_slot_reconcile as _, decideChannelsForWorkAgent as _n, init_runtime_state as _r, init_config as _t, replayStandingAgent as a, init_claude_auth as an, init_pty_token as ar, init_concurrency as at, autoRecoverAgents as b, writeChannelsBridgeMcpConfig as bn, init_agent_runtime as br, saveCloisterConfigSync as bt, init_tier_supervisor as c, determineModel as cn, resolvePtySupervisorScriptPath as cr, resetPatrolDispatchBudget as ct, spawnTierSupervisor as d, getProviderTmuxFlags as dn, normalizeAgentId as dr, workResumeSlotsAvailable as dt, init_pi_fifo as en, init_persistent_logger as er, countRunningAgents as et, supervisorAgentId as f, init_provider_health as fn, resolveAgentTargetSync as fr, getCachedMemoryVerdict as ft, init_tier_escalation as g, buildDefaultResumeContinueMessage as gn, getAgentRuntimeStateSync as gr, getHealthThresholdsMs as gt, decideEscalation as h, init_openai_auth as hn, getAgentRuntimeState as hr, DEFAULT_CLOISTER_CONFIG as ht, replayCrashedStandingAgent as i, getClaudeAuthStatus as in, readAgentHarnessModelRecordSync as ir, getConcurrencyLimits as it, messageAgent as j, getAgentResumeGateBlockReason as jn, writeBridgeTokenSync as jt, isContextOverflowTail as k, decideResumeGate as kn, probeTranscriptSince as kt, loadPrdDraft as l, getProviderEnvForModel as ln, clearReadySignal as lr, tryReserveAdvancingSlot as lt, init_tier_feed as m, getOpenAIAuthStatus as mn, waitForReadySignal as mr, setCachedMemoryVerdict as mt, compactAtTierRunBoundary as n, init_ohmypi_fifo as nn, logDeaconEventSync as nr, describeRunningAgents as nt, shouldReplayCompactAtTierRunBoundary as o, buildCavemanExports as on, writePtyToken as or, releaseAdvancingSlot as ot, broadcastCommit as p, validateProviderHealth as pn, waitForAgentIdle as pr, init_memory_verdict_cache as pt, stopAgentSync as q, saveAgentState as qn, getOhmypiLauncherFields as qt, contextWindowForModel as r, ohmypiFifoPaths as rn, init_agent_record_sync as rr, emergencyBrake as rt, deliverCommitForReview as s, buildSpawnEnvForModel as sn, init_pty_supervisor_locate as sr, releaseSwarmSlot as st, init_agents as t, piFifoPaths as tn, logAgentLifecycleSync as tr, countRunningSwarmSlotsForIssue as tt, shouldSupervise as u, getProviderExportsForModel as un, isQualifiedAgentId as ur, tryReserveSwarmSlot as ut, listSlotAssignments as v, decideSupervisorForWorkAgent as vn, saveAgentRuntimeState as vr, loadCloisterConfig as vt, buildCompactRecoverySeed as w, clearAgentPaused as wn, deliverInitialPromptWithRetry as wt, detectCrashedAgents as x, GOVERNOR_SLOT_PAUSE_REASON_PREFIX as xn, init_ohmypi_parser as xr, shouldAutoStart as xt, reconcileSlotState as y, dismissDevChannelsDialog as yn, getAgentRuntimeSnapshot as yr, loadCloisterConfigSync as yt, saveSessionId as z, markAgentRunning as zn, init_staffing as zt };
8117
+ //#region ../../lib/agents/queries.ts
8118
+ function listRunningAgentsSync() {
8119
+ const tmuxSessions = listSessionsSync();
8120
+ const tmuxNames = new Set(tmuxSessions.map((s) => s.name));
8121
+ return listOverdeckAgentStatesSync().map((state) => {
8122
+ const normalizedId = normalizeAgentId(state.id);
8123
+ return {
8124
+ ...state,
8125
+ id: normalizedId,
8126
+ tmuxActive: tmuxNames.has(normalizedId)
8127
+ };
8128
+ });
8129
+ }
8130
+ /**
8131
+ * PAN-1908: list all agents in the SQLite registry with optional filtering.
8132
+ * This is the replacement for enumerating ~/.overdeck/agents/ directories.
8133
+ */
8134
+ function listAgentStates(options) {
8135
+ return listOverdeckAgentStatesSync().filter((state) => {
8136
+ if (options?.status && state.status !== options.status) return false;
8137
+ if (options?.role && state.role !== options.role) return false;
8138
+ return true;
8139
+ });
8140
+ }
8141
+ /**
8142
+ * PAN-1048 P2: async startup migration.
8143
+ *
8144
+ * The previous synchronous version used readdirSync, readFileSync,
8145
+ * killSession (sync tmux subprocess), and rmSync — all on the Node
8146
+ * event loop. Called from warnOnBareNumericIssueIds() during dashboard
8147
+ * read-model bootstrap, this blocked all HTTP/WebSocket/PTY traffic on
8148
+ * server startup while it scanned every agent dir, killed stale tmux
8149
+ * sessions, and recursively deleted directories.
8150
+ *
8151
+ * This async variant does the same work using fs/promises and the
8152
+ * already-async killSessionAsync() so the bootstrap path no longer
8153
+ * stalls the event loop.
8154
+ */
8155
+ async function dropLegacyAgentStatesMissingRoleAsync() {
8156
+ if (!existsSync(AGENTS_DIR)) return 0;
8157
+ const fsp = await import("fs/promises");
8158
+ let entries;
8159
+ try {
8160
+ entries = await fsp.readdir(AGENTS_DIR);
8161
+ } catch {
8162
+ return 0;
8163
+ }
8164
+ let dropped = 0;
8165
+ await Promise.all(entries.map(async (entry) => {
8166
+ const dirPath = join$1(AGENTS_DIR, entry);
8167
+ let stat;
8168
+ try {
8169
+ stat = await fsp.stat(dirPath);
8170
+ } catch {
8171
+ return;
8172
+ }
8173
+ if (!stat.isDirectory()) return;
8174
+ const agentId = normalizeAgentId(entry);
8175
+ const stateFile = getRollbackAgentStatePath(agentId);
8176
+ let raw;
8177
+ try {
8178
+ const contents = await fsp.readFile(stateFile, "utf8");
8179
+ raw = JSON.parse(contents);
8180
+ } catch {
8181
+ return;
8182
+ }
8183
+ if (isRole(raw.role)) return;
8184
+ try {
8185
+ await Effect.runPromise(killSession(agentId));
8186
+ } catch {}
8187
+ try {
8188
+ await fsp.rm(dirPath, {
8189
+ recursive: true,
8190
+ force: true
8191
+ });
8192
+ dropped++;
8193
+ } catch (err) {
8194
+ const msg = err instanceof Error ? err.message : String(err);
8195
+ console.warn(`[agents] Failed to drop legacy agent state ${agentId}: ${msg}`);
8196
+ }
8197
+ }));
8198
+ return dropped;
8199
+ }
8200
+ /**
8201
+ * Scan ~/.overdeck/agents/ for state files with bare numeric issueIds
8202
+ * (e.g. "484" instead of "PAN-484") and log warnings to stderr.
8203
+ *
8204
+ * These workspaces were created before the pan- prefix convention and may
8205
+ * cause cross-tracker pollution if their in_review transition is triggered.
8206
+ * Called once at server startup to surface legacy state files.
8207
+ */
8208
+ /**
8209
+ * PAN-1048 P2: bootstrap-path migration is async.
8210
+ *
8211
+ * Sweeps legacy state files missing a `role` field and warns on bare
8212
+ * numeric issueIds. Both passes used to be synchronous (readdirSync,
8213
+ * readFileSync, killSession, rmSync), which blocked the dashboard
8214
+ * server's event loop on startup. The async version scans the same
8215
+ * directory once per concern and uses fs/promises throughout.
8216
+ */
8217
+ async function warnOnBareNumericIssueIds() {
8218
+ const droppedLegacyAgents = await dropLegacyAgentStatesMissingRoleAsync();
8219
+ if (droppedLegacyAgents > 0) console.warn(`[agents] Dropped ${droppedLegacyAgents} legacy agent state file(s) missing role`);
8220
+ if (!existsSync(AGENTS_DIR)) return;
8221
+ const fsp = await import("fs/promises");
8222
+ let entries;
8223
+ try {
8224
+ entries = await fsp.readdir(AGENTS_DIR);
8225
+ } catch {
8226
+ return;
8227
+ }
8228
+ const legacy = [];
8229
+ await Promise.all(entries.map(async (entry) => {
8230
+ const dirPath = join$1(AGENTS_DIR, entry);
8231
+ try {
8232
+ if (!(await fsp.stat(dirPath)).isDirectory()) return;
8233
+ } catch {
8234
+ return;
8235
+ }
8236
+ const state = await Effect.runPromise(getAgentState(entry));
8237
+ if (state?.issueId && /^\d+$/.test(state.issueId)) legacy.push(`${entry} (issueId: "${state.issueId}")`);
8238
+ }));
8239
+ if (legacy.length > 0) console.warn(`[agents] WARNING: ${legacy.length} agent state file(s) have bare numeric issueIds (created before the pan- prefix convention). These agents will not be able to transition tracker state. Consider removing or updating them:\n` + legacy.map((l) => ` ~/.overdeck/agents/${l}`).join("\n"));
8240
+ }
8241
+ var listRunningAgents;
8242
+ var init_queries = __esmMin((() => {
8243
+ init_agents();
8244
+ init_tmux();
8245
+ init_paths();
8246
+ init_agent_rollback_state();
8247
+ init_agent_state_sync();
8248
+ listRunningAgents = () => Effect.gen(function* () {
8249
+ const tmuxSessions = yield* listSessions();
8250
+ const tmuxNames = new Set(tmuxSessions.map((s) => s.name));
8251
+ return listOverdeckAgentStatesSync().map((state) => {
8252
+ const normalizedId = normalizeAgentId(state.id);
8253
+ return {
8254
+ ...state,
8255
+ id: normalizedId,
8256
+ tmuxActive: tmuxNames.has(normalizedId)
8257
+ };
8258
+ });
8259
+ });
8260
+ }));
8261
+ //#endregion
8262
+ export { stopAgentSync as $, wipeAgentStateDirs as $n, roleAgentDefinitionPath as $t, buildCompactRecoverySeed as A, decideResumeGate as An, init_bridge_token as At, appendActivity as B, markAgentRunning as Bn, resolveImplicitStaffing as Bt, init_slot_reconcile as C, SESSION_EXITED_BEFORE_KICKOFF as Cn, init_ohmypi_parser as Cr, deliverAgentPermissionDecision as Ct, detectCrashedAgents as D, clearAgentTroubled as Dn, captureTranscriptUserRecordSnapshot as Dt, autoRecoverAgents as E, clearAgentPausedSync as En, setAgentDeliveryMethod as Et, isContextOverflowTail as F, getAgentStateSync as Fn, init_spawn_prep as Ft, saveSessionId as G, recordAgentFailureSync as Gn, describeOhmypiSpawnFailure as Gt, getLatestSessionId as H, markAgentStoppedState as Hn, init_resolve_tier as Ht, init_messaging as I, init_agent_state as In, retrieveSpawnTimeMemoryContext as It, init_spawn as J, saveAgentState as Jn, getOhmypiLauncherFields as Jt, createOhmypiRuntimeSync as K, recordStartupSessionExit as Kn, getAgentRuntimeBaseCommand as Kt, messageAgent as L, isAgentPaused as Ln, transitionIssueToInProgress as Lt, resumeAgent as M, getAgentResumeGateBlockReason as Mn, assertWorkspaceStackHealthyForSpawn as Mt, init_context_overflow as N, getAgentState as Nn, buildAgentLaunchConfig as Nt, recoverAgent as O, clearAgentTroubledSync as On, init_transcript_landing as Ot, isContextOverflowError as P, getAgentStateFilePath as Pn, defaultRunWorkspace as Pt, stopAgent as Q, setAgentYieldedSync as Qn, injectPiConversationMemory as Qt, init_operator_interventions as R, isAgentTroubled as Rn, transitionIssueToInReview as Rt, init_tier_escalation as S, GOVERNOR_SLOT_PAUSE_REASON_PREFIX as Sn, paneShowsCodexAuthBurn as Sr, deliverAgentMessage as St, reconcileSlotState as T, clearAgentPaused as Tn, deliverResumeMessageWithTranscriptConfirmation as Tt, getLatestSessionIdSync as U, markAgentTroubled as Un, resolveTier as Ut, getActivity as V, markAgentRunningState as Vn, resolveStaffing as Vt, getSessionId as W, recordAgentFailure as Wn, OHMYPI_AGENT_READY_TIMEOUT_SECONDS as Wt, spawnRun as X, setAgentPaused as Xn, getRoleRuntimeBaseCommand as Xt, spawnAgent as Y, saveAgentStateSync as Yn, getProviderAuthMode as Yt, init_termination as Z, setAgentPausedSync as Zn, init_runtime_command as Zt, spawnTierSupervisor as _, buildDefaultResumeContinueMessage as _n, getAgentRuntimeSnapshot as _r, init_config as _t, listRunningAgentsSync as a, getClaudeAuthStatus as an, init_pty_supervisor_locate as ar, init_concurrency as at, init_tier_feed as b, dismissDevChannelsDialog as bn, checkCodexAuthStatus as br, saveCloisterConfigSync as bt, compactAtTierRunBoundary as c, buildSpawnEnvForModel as cn, isQualifiedAgentId as cr, resetPatrolDispatchBudget as ct, replayStandingAgent as d, getProviderExportsForModel as dn, waitForAgentIdle as dr, workResumeSlotsAvailable as dt, waitForPromptReady as en, writeAgentStateJsonSync as er, countRunningAgents as et, shouldReplayCompactAtTierRunBoundary as f, getProviderTmuxFlags as fn, waitForReadySignal as fr, getCachedMemoryVerdict as ft, shouldSupervise as g, init_openai_auth as gn, saveAgentRuntimeState as gr, getHealthThresholdsMs as gt, loadPrdDraft as h, getOpenAIAuthStatus as hn, init_runtime_state as hr, DEFAULT_CLOISTER_CONFIG as ht, listRunningAgents as i, ohmypiFifoPaths as in, writePtyToken as ir, getConcurrencyLimits as it, init_resume as j, getAgentDir as jn, writeBridgeTokenSync as jt, restartAgent as k, clearYieldForResumeSync as kn, probeTranscriptSince as kt, contextWindowForModel as l, determineModel as ln, normalizeAgentId as lr, tryReserveAdvancingSlot as lt, init_tier_supervisor as m, validateProviderHealth as mn, getAgentRuntimeStateSync as mr, setCachedMemoryVerdict as mt, init_queries as n, piFifoPaths as nn, readAgentHarnessModelRecordSync as nr, describeRunningAgents as nt, warnOnBareNumericIssueIds as o, init_claude_auth as on, resolvePtySupervisorScriptPath as or, releaseAdvancingSlot as ot, deliverCommitForReview as p, init_provider_health as pn, getAgentRuntimeState as pr, init_memory_verdict_cache as pt, init_ohmypi as q, resetAgentFailureCount as qn, getCodexLauncherFields as qt, listAgentStates as r, init_ohmypi_fifo as rn, init_pty_token as rr, emergencyBrake as rt, init_agents as s, buildCavemanExports as sn, clearReadySignal as sr, releaseSwarmSlot as st, dropLegacyAgentStatesMissingRoleAsync as t, init_pi_fifo as tn, init_agent_record_sync as tr, countRunningSwarmSlotsForIssue as tt, replayCrashedStandingAgent as u, getProviderEnvForModel as un, resolveAgentTargetSync as ur, tryReserveSwarmSlot as ut, supervisorAgentId as v, decideChannelsForWorkAgent as vn, init_agent_runtime as vr, loadCloisterConfig as vt, listSlotAssignments as w, __testInternals as wn, parseOhmypiSessionCostResultSync as wr, deliverInitialPromptWithRetry as wt, decideEscalation as x, writeChannelsBridgeMcpConfig as xn, init_codex_auth as xr, shouldAutoStart as xt, broadcastCommit as y, decideSupervisorForWorkAgent as yn, applyCodexAuthBurnFlag as yr, loadCloisterConfigSync as yt, operatorInterventionEvent as z, isRole as zn, init_staffing as zt };
7919
8263
 
7920
- //# sourceMappingURL=agents-CsOzAmRg.js.map
8264
+ //# sourceMappingURL=queries-C0LCGG21.js.map