@overdeck/desktop 0.45.12 → 0.45.15

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 (355) hide show
  1. package/drizzle/overdeck/0000_overdeck_init.sql +33 -0
  2. package/package.json +7 -2
  3. package/server/{acceptance-criteria-1LHgD9vg.js → acceptance-criteria-DHZk2ceV.js} +2 -2
  4. package/server/{advancing-selfheal-BqsLWqEM.js → advancing-selfheal-CSuZ31bB.js} +5 -5
  5. package/server/{agent-gc-CUb52n7s.js → agent-gc-D_DxfBHR.js} +3 -3
  6. package/server/{agent-state-D-moNwhA.js → agent-state-EP2QFV9n.js} +1 -1
  7. package/server/{agent-state-service-BzESvLOf.js → agent-state-service-BZkvgQf4.js} +5 -5
  8. package/server/{agent-state-service-BaZH7sXJ.js → agent-state-service-C_2ZAQRP.js} +1 -1
  9. package/server/{agents-B5LfpLPv.js → agents-CsOzAmRg.js} +145 -78
  10. package/server/{agents-C4kZ8a2r.js → agents-DCvyTXNU.js} +1 -1
  11. package/server/{archive-planning-BbZe-8IK.js → archive-planning-CTILQRnV.js} +1 -1
  12. package/server/{archive-planning-oX1pj6nY.js → archive-planning-DkivCk1A.js} +4 -4
  13. package/server/{artifact-index-jobs-DGr6bxev.js → artifact-index-jobs-CmsvQ1ey.js} +2 -2
  14. package/server/auto-commit-QAfsu3Sb.js +3 -0
  15. package/server/{backlog-auto-trigger-BlJHikOm.js → backlog-auto-trigger-ueRaT8Dy.js} +2 -2
  16. package/server/{bd-process-lock-i3CYMS-B.js → bd-process-lock-D3S4T4o-.js} +32 -11
  17. package/server/{beads-DD7fYCl5.js → beads-BGGxrkZ5.js} +96 -196
  18. package/server/{beads-BNU-fb48.js → beads-CYsLiyIM.js} +1 -1
  19. package/server/{beads-query-e6oku4P5.js → beads-query-B1DlJVp9.js} +24 -99
  20. package/server/beads-restore-CyygSmmn.js +23 -0
  21. package/server/{behavior-CPf0pbOt.js → behavior-Cpj03N4v.js} +3 -3
  22. package/server/{briefing-freshness-B2FdLwIv.js → briefing-freshness-Kh5V8RTh.js} +4 -4
  23. package/server/{checkpoint-manager-eFgaMMu4.js → checkpoint-manager-CAFos8e1.js} +1 -1
  24. package/server/{checkpoint-manager-JryW6MpM.js → checkpoint-manager-fu9oVsR-.js} +2 -2
  25. package/server/checkpoint-worker.js +1 -1
  26. package/server/{checkpoints-qvOqvMuC.js → checkpoints-1BqOlS4q.js} +2 -2
  27. package/server/{checkpoints-BK17oicz.js → checkpoints-DvhGi8P_.js} +1 -1
  28. package/server/claude-hooks-provision-s_wdpeVj.js +360 -0
  29. package/server/{claude-permissions-B6bWGh9d.js → claude-permissions-CaWqysff.js} +2 -2
  30. package/server/{claude-settings-overlay-BPdhTPjo.js → claude-settings-overlay-BbA4FbVI.js} +1 -1
  31. package/server/{claude-settings-overlay-CRyyKKXQ.js → claude-settings-overlay-CcTf0xzG.js} +2 -2
  32. package/server/{cli-B75AieAM.js → cli-BwCvCUBK.js} +9 -9
  33. package/server/cli-ClIQwgMI.js +3 -0
  34. package/server/{cliproxy-CCzwuSNe.js → cliproxy-BsoNNDAj.js} +2 -2
  35. package/server/{cliproxy-DOQf66G9.js → cliproxy-C2xC-3vH.js} +1 -1
  36. package/server/{close-issue-_X3MXJyG.js → close-issue-BleIwP3f.js} +5 -5
  37. package/server/{closed-issue-reaper-CLR7ClsO.js → closed-issue-reaper-BwUUvjEW.js} +1 -1
  38. package/server/{closed-issue-reaper-BsUfBSjM.js → closed-issue-reaper-mC5pujeb.js} +102 -30
  39. package/server/{codex-CY-QRuU9.js → codex-B7DTpwEw.js} +1 -1
  40. package/server/{codex-B4KEpX5V.js → codex-DW60_5j2.js} +5 -5
  41. package/server/{compact-beads-cZds2MTr.js → compact-beads-CK_hHEnB.js} +1 -1
  42. package/server/{compact-beads-uEDccC76.js → compact-beads-DKL54y6j.js} +15 -8
  43. package/server/{config-DARrpYWA.js → config-BRNQJXhA.js} +1 -1
  44. package/server/{config-8sjaU6jZ.js → config-ZNnMpIlh.js} +2 -2
  45. package/server/{config-yaml-ClpGgrf6.js → config-yaml-Dcz-8uit.js} +29 -3
  46. package/server/{conflict-gate-Ds9_2yjd.js → conflict-gate-DGT8jCLp.js} +1 -1
  47. package/server/{conflict-gate-BtB_o-Vi.js → conflict-gate-DTje2Ll7.js} +3 -3
  48. package/server/{context-layers-r2ywnQYA.js → context-layers-BdUCQ-cl.js} +3 -3
  49. package/server/{context-layers-CRCk1QG7.js → context-layers-ByOWUjUg.js} +2 -2
  50. package/server/{control-settings-D1B3u6HP.js → control-settings-DwkAeooY.js} +4 -4
  51. package/server/{conversation-compaction-D86Zo2Ci.js → conversation-compaction-OTYgd6eg.js} +8 -8
  52. package/server/{conversation-compaction-CZRVk4hg.js → conversation-compaction-WYQZUVDm.js} +1 -1
  53. package/server/{conversation-service-CuTVU8dV.js → conversation-service-BR1OgvxO.js} +5 -5
  54. package/server/{conversation-service-CkL-6MuG.js → conversation-service-C_kNZPLx.js} +1 -1
  55. package/server/{conversations-DfJKBDwB.js → conversations-DG2M8WnT.js} +4 -4
  56. package/server/{conversations-BmWEluPL.js → conversations-izHvSoAR.js} +1 -1
  57. package/server/{cost-DAPYN6iA.js → cost-B2mj17iG.js} +3 -3
  58. package/server/{cost-CCnqa5xK.js → cost-DQ2ajr_m.js} +2 -2
  59. package/server/{cost-sync-BDL10Nwu.js → cost-sync-gTayEuWP.js} +3 -3
  60. package/server/{dag-Dv2r5bVD.js → dag-CqTehWpY.js} +3 -3
  61. package/server/{dangerous-git-ops-Dcw7PbYo.js → dangerous-git-ops-DDWQlPC3.js} +1 -1
  62. package/server/dashboard-db-worker.js +6 -6
  63. package/server/{deacon-DYnZH7kC.js → deacon-BqW9HMew.js} +3 -3
  64. package/server/{deacon-CM0MxbS8.js → deacon-DrKDBeJL.js} +161 -1594
  65. package/server/{deacon-nudge-log-B-naf89q.js → deacon-nudge-log-D1wEK6zF.js} +1 -1
  66. package/server/deacon-swarm-BY5hKNaU.js +2 -0
  67. package/server/{deacon-swarm-BstYoz8Q.js → deacon-swarm-CO_A7xyd.js} +12 -105
  68. package/server/deacon.js +7 -7
  69. package/server/{devcontainer-renderer-CaYOG9JN.js → devcontainer-renderer-BQolp_qZ.js} +3 -3
  70. package/server/{dist-BIC8spJ0.js → dist-Bc32rWJB.js} +1 -1
  71. package/server/dist-DGTwcZhI.js +3 -0
  72. package/server/{docker-DDI1shu3.js → docker-s-esqZ__.js} +67 -28
  73. package/server/{ensure-devcontainer-DCAg3ksz.js → ensure-devcontainer-DA4-jF6R.js} +4 -4
  74. package/server/{ensure-devcontainer-CbSXvN9W.js → ensure-devcontainer-pUVaT0h3.js} +1 -1
  75. package/server/{esm-shims-DiV9jHa_.js → esm-shims-CJHy8CZY.js} +1 -1
  76. package/server/{event-store-DU3HkZlN.js → event-store-CcJAhKCl.js} +1 -1
  77. package/server/{event-store-DCMqyI07.js → event-store-DRte2Rwt.js} +3 -3
  78. package/server/{events-BfiosVAn.js → events-Bej1w_k8.js} +3 -3
  79. package/server/{events-DLRxpSuV.js → events-CtsLScn8.js} +1 -1
  80. package/server/export-Dx_qJ3h8.js +87 -0
  81. package/server/{factory-BMtWV9iv.js → factory-FN727tWr.js} +4 -4
  82. package/server/{feature-registry-population-DA7bO6Zn.js → feature-registry-population-ie-yBcQC.js} +4 -4
  83. package/server/{feature-registry-storage-nAY1fbBt.js → feature-registry-storage-CkZTFSsn.js} +2 -2
  84. package/server/{features-DMu7eGmU.js → features-Dtm9ABuz.js} +2 -2
  85. package/server/{feedback-target-DHqcw3cN.js → feedback-target-BYtpyt1i.js} +6 -6
  86. package/server/{feedback-target-B2SEai8-.js → feedback-target-DVJQDiE4.js} +1 -1
  87. package/server/{feedback-writer-DMBdS_jL.js → feedback-writer-DOUhyIW2.js} +1 -1
  88. package/server/{feedback-writer-qvm7UON7.js → feedback-writer-fdE1BzeL.js} +4 -4
  89. package/server/{flywheel-k4FPtCQ_.js → flywheel-Bi82iiNl.js} +1 -1
  90. package/server/{flywheel-Dfpx4bIV.js → flywheel-Bv3wv2S6.js} +23 -15
  91. package/server/{flywheel-D2LdPSic.js → flywheel-CUErLAyN.js} +13 -13
  92. package/server/{flywheel-merge-order-CB4lbXeJ.js → flywheel-merge-order-BaEN3iyN.js} +7 -7
  93. package/server/{flywheel-merge-order-CttTazRY.js → flywheel-merge-order-DXjeBnJ1.js} +1 -1
  94. package/server/{forge-CoPFXFyl.js → forge-ButEdJ31.js} +2 -2
  95. package/server/forge-XlDgPQWs.js +2 -0
  96. package/server/{from-B0YoJl9-.js → from-CbtTxftl.js} +1 -1
  97. package/server/{fts-db-DAHW1yA_.js → fts-db-CBgBLZcL.js} +2 -2
  98. package/server/{fts-operations-DDXDBi0d.js → fts-operations-CI9Xuo_1.js} +2 -2
  99. package/server/{git-utils-DbfC0zls.js → git-utils-BCLRWQ-y.js} +1 -1
  100. package/server/{git-utils-B90Zjzfl.js → git-utils-ClfpP47N.js} +2 -2
  101. package/server/{github-app-C7lftMNj.js → github-app-DRD2woO0.js} +1 -1
  102. package/server/{github-app-BecAnXRX.js → github-app-DscZ0_B6.js} +2 -2
  103. package/server/{github-client-D21rCIXk.js → github-client-DpiZnxGH.js} +2 -2
  104. package/server/{github-client-BwtKZtM0.js → github-client-iFRw8f7e.js} +1 -1
  105. package/server/{github-pr-lookup-CzVWuysl.js → github-pr-lookup-D-EBexxC.js} +2 -2
  106. package/server/{harness-resolve-SkRJm4a7.js → harness-resolve-iMjyNUJ2.js} +3 -3
  107. package/server/{health-events-DA_JLpgZ.js → health-events-B_WsQyYm.js} +1 -1
  108. package/server/{health-events-BT0aAfeA.js → health-events-CRdxDFN2.js} +2 -2
  109. package/server/{hooks-BQxRXtRb.js → hooks-C1ScyVxP.js} +1 -1
  110. package/server/{hooks-DxEn2BoY.js → hooks-C9b7Vqpw.js} +2 -2
  111. package/server/hume-K1pi8jC4.js +3 -0
  112. package/server/{hume-DkVOs1Qi.js → hume-TQ5pvOZ_.js} +2 -2
  113. package/server/{idle-stack-reaper-DGy7tvC9.js → idle-stack-reaper-B1kG7B_X.js} +2 -2
  114. package/server/{idle-stack-reaper-C7fJL8jH.js → idle-stack-reaper-iFVOAoJy.js} +1 -1
  115. package/server/{infra-DE3C4PMr.js → infra-bpq1MHKU.js} +50 -3
  116. package/server/{injection-Dt22tGvS.js → injection-BLWfwTVZ.js} +1 -1
  117. package/server/{injection-Cc4Qt8LZ.js → injection-DJqWld1v.js} +7 -7
  118. package/server/inspect-agent-477VxQim.js +2 -0
  119. package/server/{inspect-agent-DOaCDkCF.js → inspect-agent-DytCsltn.js} +9 -9
  120. package/server/{internal-token-nobT6FhA.js → internal-token-CCaWaTwE.js} +1 -1
  121. package/server/{internal-token-B_1YLWLI.js → internal-token-CjlhdufS.js} +2 -2
  122. package/server/{io-A7ZuOBkz.js → io-BiQ2Cs3k.js} +2 -2
  123. package/server/{issue-closed-Da3DeomA.js → issue-closed-FApNiOOs.js} +4 -4
  124. package/server/{issue-lifecycle-Bd9XBJAQ.js → issue-lifecycle-BkFWNjlD.js} +1 -1
  125. package/server/{issue-lifecycle-543pQX9D.js → issue-lifecycle-C-K53ASY.js} +21 -21
  126. package/server/{issue-service-singleton-Brc3t0SV.js → issue-service-singleton-CuHGpJJP.js} +8 -8
  127. package/server/{issue-service-singleton-BC2JLZi7.js → issue-service-singleton-bG1WdSdQ.js} +1 -1
  128. package/server/{issues-D3kt9UWE.js → issues-CwQMphDH.js} +2 -2
  129. package/server/jsonl-parser-dNIjHgym.js +245 -0
  130. package/server/{label-cleanup-w9X_T3AQ.js → label-cleanup-DYvAZknd.js} +3 -3
  131. package/server/{layers-Cwe1J-9o.js → layers-CD6FysRU.js} +2 -2
  132. package/server/{lifecycle-f1GbDK33.js → lifecycle-C_73gi-C.js} +7 -7
  133. package/server/{lifecycle-io-D56q8zlO.js → lifecycle-io-C_Wu0_i-.js} +1 -1
  134. package/server/{lifecycle-io-Bqvj0m3i.js → lifecycle-io-CeYxP3cE.js} +4 -4
  135. package/server/{linear-client-Bh4T4S-c.js → linear-client-4qoKnuQu.js} +1 -1
  136. package/server/{linear-client-CfJMTAYd.js → linear-client-EtVyblVz.js} +2 -2
  137. package/server/memory-fts-worker.js +1 -1
  138. package/server/{merge-ZrXFM3jv.js → merge-7rqkTUm2.js} +3 -3
  139. package/server/merge-agent-36wfYm2u.js +3 -0
  140. package/server/{merge-agent-CHHs5S_0.js → merge-agent-4Zhlgvqp.js} +62 -27
  141. package/server/{merge-batch-BwhGdlh4.js → merge-batch-itfnwdsT.js} +1 -1
  142. package/server/{merge-blockers-BMhDpMl_.js → merge-blockers-Bto_Oe_o.js} +2 -2
  143. package/server/{merge-DRMPa8CQ.js → merge-brm721Es.js} +1 -1
  144. package/server/merge-ops-PzqsW69V.js +2 -0
  145. package/server/{merge-rebase-R7MfqpiE.js → merge-rebase-Czfqfe4q.js} +2 -2
  146. package/server/{merge-set-B3Breacq.js → merge-set-BIkGQL9j.js} +9 -5
  147. package/server/{merge-set-D-iXNP0I.js → merge-set-G1RHcu3D.js} +1 -1
  148. package/server/{merge-sync-DHWbGtjR.js → merge-sync-B43Dybea.js} +2 -2
  149. package/server/{merge-sync-bOOtfeXR.js → merge-sync-DIrmlZUr.js} +1 -1
  150. package/server/{merge-train-98ptZrPT.js → merge-train-DGqVuNZV.js} +3 -3
  151. package/server/{merge-train-deps-B5FWJTE2.js → merge-train-deps-q15XLnAS.js} +4 -4
  152. package/server/{merge-verification-BGiuiXAK.js → merge-verification-Cqfxx6bE.js} +4 -4
  153. package/server/{multipart-parser-D7mzNNDm.js → multipart-parser-CiPxxfUH.js} +2 -2
  154. package/server/node_modules/.package-lock.json +1 -1
  155. package/server/{orphan-proposed-reconciler-BSGCNJ6X.js → orphan-proposed-reconciler-BWWHn4Lr.js} +15 -39
  156. package/server/{orphan-proposed-reconciler-CSuxivr9.js → orphan-proposed-reconciler-DAD9FJtQ.js} +1 -1
  157. package/server/package-lock.json +2 -2
  158. package/server/package.json +1 -1
  159. package/server/{pan-dir-DoPtdHrp.js → pan-dir-Bj7Hy8iu.js} +3 -3
  160. package/server/{paths-CVDLPxXp.js → paths-C9DkhIOT.js} +2 -2
  161. package/server/{pickup-KLRUhThD.js → pickup-CKRuGDsB.js} +1 -1
  162. package/server/{pipeline-notifier-BtYHbBPl.js → pipeline-notifier-BkKbQ8ji.js} +1 -1
  163. package/server/{pipeline-notifier-WD2dnOsR.js → pipeline-notifier-CAurUste.js} +2 -2
  164. package/server/project-pipelines-BRWaGmI4.js +162 -0
  165. package/server/projects-KJ94e50I.js +3 -0
  166. package/server/{prompts-Cg7e9FPb.js → prompts-DfI5qbTW.js} +2 -2
  167. package/server/{providers-fLduChnX.js → providers-CWDXoaMA.js} +7 -7
  168. package/server/providers-D-5txBRc.js +3 -0
  169. package/server/public/assets/{chunk-BO2N2NFS-aNlsGDCu.js → chunk-BO2N2NFS-ClukPsZQ.js} +4 -4
  170. package/server/public/assets/{diagram-OG6HWLK6-CnjkrvT8.js → diagram-OG6HWLK6-Avtvq2qI.js} +1 -1
  171. package/server/public/assets/{dist-Bg3Sbsx4.js → dist-BEHQuasD.js} +3 -3
  172. package/server/public/assets/{dist-CGKBCieA.js → dist-BvmY-qb1.js} +1 -1
  173. package/server/public/assets/{ganttDiagram-6RSMTGT7-C8LLKj23.js → ganttDiagram-6RSMTGT7-7KhCd0fH.js} +1 -1
  174. package/server/public/assets/{highlighted-body-OFNGDK62-BSDEUvhW.js → highlighted-body-OFNGDK62-iQoBMTf0.js} +1 -1
  175. package/server/public/assets/index-DUFDmvmH.css +1 -0
  176. package/server/public/assets/index-DnTZ2QeN.js +796 -0
  177. package/server/public/assets/{linear-DEbYZoxg.js → linear-CiJHW9g5.js} +1 -1
  178. package/server/public/assets/mermaid-GHXKKRXX-DZJOwgBG.js +1 -0
  179. package/server/public/assets/{pieDiagram-4H26LBE5-BtZL5pXE.js → pieDiagram-4H26LBE5-BOhmvUhW.js} +1 -1
  180. package/server/public/assets/{prod-DYVvIyuh.js → prod-DmLBBqat.js} +4 -4
  181. package/server/public/assets/{quadrantDiagram-W4KKPZXB-a7vS8Jc8.js → quadrantDiagram-W4KKPZXB-Cjku660G.js} +1 -1
  182. package/server/public/assets/{sankeyDiagram-5OEKKPKP-Ckbq2SWH.js → sankeyDiagram-5OEKKPKP-D52w5oPh.js} +1 -1
  183. package/server/public/assets/{xychartDiagram-2RQKCTM6-DJyeNa99.js → xychartDiagram-2RQKCTM6-BTO07_Iv.js} +1 -1
  184. package/server/public/index.html +2 -2
  185. package/server/{pull-requests-1WXmTBlo.js → pull-requests-Bmre-Xlz.js} +3 -3
  186. package/server/{pull-requests-D2SjJIwY.js → pull-requests-CKZPWhjD.js} +1 -1
  187. package/server/{rally-8aQlLLVj.js → rally-BBd9tQ__.js} +3 -3
  188. package/server/rally-Dc2Wnxw2.js +3 -0
  189. package/server/{rally-api-BtvwdX6d.js → rally-api-DDc85HIz.js} +1 -1
  190. package/server/{rally-api-H5I2CBO0.js → rally-api-DxZFObI_.js} +2 -2
  191. package/server/{rally-client-Bt-qHiOh.js → rally-client-BADHn0m_.js} +1 -1
  192. package/server/{rally-client-33CYZYYu.js → rally-client-DvvLiAQP.js} +4 -4
  193. package/server/{reap-terminal-sessions-CAmURC2h.js → reap-terminal-sessions-D6JDJsqF.js} +1 -1
  194. package/server/{reap-terminal-sessions-BwJb2DLJ.js → reap-terminal-sessions-D_xvy-Mk.js} +1 -1
  195. package/server/{rebuild-stack-KHkkrGjx.js → rebuild-stack-D19i080j.js} +6 -6
  196. package/server/{rebuild-stack-CXSgAGPR.js → rebuild-stack-GOsWqXi3.js} +1 -1
  197. package/server/{reconstruct-cache-D_Ml65_6.js → reconstruct-cache-lQrG4xGg.js} +6 -6
  198. package/server/record-pyB6VA32.js +3 -0
  199. package/server/recovery-trip-Dfh1tNHn.js +98 -0
  200. package/server/release-engine-DxcMWRuK.js +306 -0
  201. package/server/release-set-BYsgX7o6.js +125 -0
  202. package/server/{remote-CGuognN3.js → remote-8W2Yhygw.js} +3 -3
  203. package/server/{remote-D0Old0Cv.js → remote-DmeL21dF.js} +3 -3
  204. package/server/{remote-agents-DfhMq6kQ.js → remote-agents-BfQBE6MN.js} +5 -5
  205. package/server/{remote-agents-UHoi4oGr.js → remote-agents-DlvbzO7m.js} +1 -1
  206. package/server/{remote-completion-RZYePR_0.js → remote-completion-BgkiSQmx.js} +12 -12
  207. package/server/resolver-dTpSSzaH.js +158 -0
  208. package/server/resume-DhcIqsTm.js +3 -0
  209. package/server/{review-agent-sZBCpEVv.js → review-agent-D025Wt7w.js} +22 -22
  210. package/server/{review-agent-uwVftH98.js → review-agent-Rub0OpZc.js} +1 -1
  211. package/server/{review-artifacts-C7a45b1_.js → review-artifacts-CX951jTU.js} +6 -6
  212. package/server/{review-context-CErbQpKL.js → review-context-DGGGR_w5.js} +7 -7
  213. package/server/{review-monitor-DHD9m_kh.js → review-monitor-0_qqMcnS.js} +2 -2
  214. package/server/{review-status-gPndPUBc.js → review-status-4qqLkRMu.js} +24 -17
  215. package/server/{review-status-JhQ3qlDS.js → review-status-Br6lAFGO.js} +1 -1
  216. package/server/{review-status-enrichment-qWvWckYN.js → review-status-enrichment-Cr8m3uVL.js} +3 -3
  217. package/server/{review-status-sync-B_GrEke8.js → review-status-sync-D3KUhsdA.js} +1 -1
  218. package/server/{review-status-sync-D3A9KX95.js → review-status-sync-OC-l1lNt.js} +9 -5
  219. package/server/{review-verdict-feedback-4WZ5ZdbC.js → review-verdict-feedback-DrWMuRaj.js} +6 -6
  220. package/server/{review-verdict-feedback-Zo0r_z4m.js → review-verdict-feedback-YOzmsq9G.js} +1 -1
  221. package/server/{rollup-BrUIKMv_.js → rollup-CnxbwaLH.js} +8 -8
  222. package/server/{rollup-Bmhn80tB.js → rollup-DmazRY0j.js} +1 -1
  223. package/server/{scanner-BIGumel_.js → scanner-DE1MqAaF.js} +7 -7
  224. package/server/{sequence-io-DA0akEQN.js → sequence-io-C0uoqfGx.js} +4 -4
  225. package/server/{sequencer-agent-DeflKafB.js → sequencer-agent-i-b2u4SJ.js} +10 -6
  226. package/server/server.js +1115 -297
  227. package/server/{service-V0sUK-OR.js → service-D0_gh2tl.js} +1668 -1408
  228. package/server/{session-fork-Yx3UcAQf.js → session-fork-DZ12vipL.js} +2 -2
  229. package/server/{settings-CFEeQRj2.js → settings-ByqjPtFO.js} +2 -2
  230. package/server/{settings-CxVate0h.js → settings-DCC4BAqj.js} +3 -3
  231. package/server/settings-yydgaqhv.js +2 -0
  232. package/server/{shadow-engineering-BRxnVSDk.js → shadow-engineering-BhnmtW5m.js} +2 -2
  233. package/server/{shadow-state-1aS8FijU.js → shadow-state-ByXZehsy.js} +1 -1
  234. package/server/{shadow-state-BiMwdyl1.js → shadow-state-CKm8xWX9.js} +2 -2
  235. package/server/{ship-log-CMWH3H5-.js → ship-log-DE_0Cv_i.js} +1 -1
  236. package/server/{smart-compaction-Bw1K_Sbl.js → smart-compaction-D5Zen3AA.js} +7 -7
  237. package/server/{smart-compaction-xblMyVpT.js → smart-compaction-h4_ca6Uk.js} +1 -1
  238. package/server/{spawn-planning-session-CzDFSKAQ.js → spawn-planning-session-Bgi7Ub02.js} +1 -1
  239. package/server/{spawn-planning-session-DxLxcM7m.js → spawn-planning-session-Dueit4WX.js} +15 -15
  240. package/server/{specialist-completion-BiEXUHfD.js → specialist-completion-BZ8M-WZ0.js} +1 -1
  241. package/server/{specialist-context-BfkTA81h.js → specialist-context-BMq83C58.js} +5 -5
  242. package/server/{specialist-handoff-logger-BiKuLtNm.js → specialist-handoff-logger-BxX1YefH.js} +2 -2
  243. package/server/{specialist-logs-CFJjGsLC.js → specialist-logs-BWZYcJ6P.js} +3 -3
  244. package/server/{specialists-DdvpFNt1.js → specialists-8ZAguXef.js} +1 -1
  245. package/server/{specialists-B4byf18k.js → specialists-BudKrjOu.js} +76 -76
  246. package/server/{specialists-DjHbwQ_p.js → specialists-DrPrC9Y9.js} +20 -256
  247. package/server/{specialists-BLIreoE7.js → specialists-ZkW4Mb7U.js} +1 -1
  248. package/server/specs-DwoAEGrW.js +3 -0
  249. package/server/{src-fgbU-jJ-.js → src-DHn4Rd2F.js} +25 -3
  250. package/server/{src-mK_M_ZIj.js → src-DNUUqkec.js} +6 -6
  251. package/server/{src-CALBEUMX.js → src-Dv6L03vW.js} +3 -3
  252. package/server/{stack-health-BFM8YlHw.js → stack-health-Dclm7_tu.js} +1 -1
  253. package/server/{stack-health-Qd7rPiVe.js → stack-health-DxsTx7II.js} +2 -2
  254. package/server/{state-home-C2Bicw9N.js → state-home-CRowbXqU.js} +6 -6
  255. package/server/stuck-remediation-CFWUP8_I.js +1491 -0
  256. package/server/stuck-remediation-CLHd-lrF.js +2 -0
  257. package/server/{summary-fork-EWWBvzgE.js → summary-fork-CKc01Our.js} +2 -2
  258. package/server/{summary-fork-DezPkJSm.js → summary-fork-CtCwBJ2Z.js} +8 -8
  259. package/server/{supervisor-D5GC5jUM.js → supervisor-BA5D72Qa.js} +2 -2
  260. package/server/supervisor-DHjumXlL.js +2 -0
  261. package/server/{swarm-readiness-Cf9mommA.js → swarm-readiness-CL5sM9B1.js} +3 -3
  262. package/server/{system-prerequisites-BsI9hxh9.js → system-prerequisites-DmFSXIE5.js} +13 -1
  263. package/server/{teardown-workspace-CWz1pbEK.js → teardown-workspace-DWmFJzTw.js} +37 -68
  264. package/server/{test-agent-queue-TiVXe3ZT.js → test-agent-queue-DjsQoV5X.js} +6 -6
  265. package/server/{test-verdict-CCDd25uN.js → test-verdict-BSqsQp3G.js} +1 -1
  266. package/server/{test-verdict-Bm4uv_AA.js → test-verdict-D1AmZ2c0.js} +1 -1
  267. package/server/{tldr-daemon-C_1frSDj.js → tldr-daemon-C-MGomL8.js} +2 -2
  268. package/server/{tldr-daemon-Big5IZ_M.js → tldr-daemon-DD9rI5gA.js} +1 -1
  269. package/server/{tmux-D57f-XNv.js → tmux-C_d-lSIq.js} +2 -2
  270. package/server/{tmux-DClqWwb8.js → tmux-x291Gjjb.js} +1 -1
  271. package/server/{token-_qujO3JZ.js → token-DfBf1bsd.js} +1 -1
  272. package/server/{tracker-config-BmdJU_w6.js → tracker-config-CNODpd11.js} +2 -2
  273. package/server/{tracker-config-B_Ubts1Z.js → tracker-config-DItsdelv.js} +1 -1
  274. package/server/{tracker-utils-Bg-Sevcv.js → tracker-utils-B9ZoVA9b.js} +1 -1
  275. package/server/{tracker-utils-CWFt6jjV.js → tracker-utils-Ch2_5GGf.js} +2 -2
  276. package/server/{traefik-connect-5EP1WS_Z.js → traefik-connect-BF4x_LUQ.js} +1 -1
  277. package/server/{tunnel-hOBNQbmF.js → tunnel-YD80_IHr.js} +1 -1
  278. package/server/{tunnel-UBf2vyAL.js → tunnel-r_5nHAI6.js} +3 -3
  279. package/server/{types-B5u3NxMl.js → types-33JEP4LZ.js} +1 -1
  280. package/server/{uat-train-DGkIkLxu.js → uat-train-DDI00aqD.js} +1 -1
  281. package/server/{uat-train-qNanv5hN.js → uat-train-DjkFWXge.js} +25 -25
  282. package/server/{validation-C4wegCvH.js → validation-DUTiJnyz.js} +4 -4
  283. package/server/{validation-B0QaLIHP.js → validation-ict8hnXk.js} +1 -1
  284. package/server/{verification-runner-DdleMNLq.js → verification-runner-ATaLbpr5.js} +1 -1
  285. package/server/{verification-runner-CntudBes.js → verification-runner-inLgeQux.js} +12 -12
  286. package/server/{vtt-parser-CKc-smWM.js → vtt-parser-QnRfcjiU.js} +1 -1
  287. package/server/{work-agent-prompt-CG5jFV9A.js → work-agent-prompt-fZljjA1_.js} +12 -12
  288. package/server/{workflows-BK2xs_a8.js → workflows-oBnJ7Tm0.js} +14 -14
  289. package/server/workflows-tU7KKxQi.js +2 -0
  290. package/server/{workspace-C9lC5o3E.js → workspace-B2WOW9Hw.js} +1 -1
  291. package/server/{workspace-CLrSIRCx.js → workspace-CNuW2j41.js} +3 -3
  292. package/server/{workspace-config-DA8U97k9.js → workspace-config-CBgMGhWs.js} +1 -1
  293. package/server/{workspace-manager-BJhW2sky.js → workspace-manager-CB-R07R3.js} +12 -12
  294. package/server/{workspace-manager-Cb2a7bg9.js → workspace-manager-DjUAJCSs.js} +1 -1
  295. package/server/{workspace-metadata-QQmo_Z0l.js → workspace-metadata-9Nn5kgRl.js} +2 -2
  296. package/server/{workspace-metadata-CTRnr323.js → workspace-metadata-Fd58uUQG.js} +1 -1
  297. package/server/{workspaces-Ca4zZs12.js → workspaces-BjWXntty.js} +106 -120
  298. package/server/writer-CQMGzEkw.js +3 -0
  299. package/server/writer-fe1-8iGc.js +251 -0
  300. package/sync-sources/hooks/ask-user-question-hook +87 -0
  301. package/sync-sources/hooks/auto-approve-hook +96 -0
  302. package/sync-sources/hooks/codex-notify-hook +62 -0
  303. package/sync-sources/hooks/gh-issue-trailer-hook +4 -0
  304. package/sync-sources/hooks/gh-issue-trailer-hook.d.ts +7 -0
  305. package/sync-sources/hooks/gh-issue-trailer-hook.d.ts.map +1 -0
  306. package/sync-sources/hooks/gh-issue-trailer-hook.js +239 -0
  307. package/sync-sources/hooks/gh-issue-trailer-hook.js.map +1 -0
  308. package/sync-sources/hooks/gh-issue-trailer-hook.ts +296 -0
  309. package/sync-sources/hooks/git-hooks/post-checkout +109 -0
  310. package/sync-sources/hooks/heartbeat-hook +113 -0
  311. package/sync-sources/hooks/notification-hook +70 -0
  312. package/sync-sources/hooks/notify-complete +79 -0
  313. package/sync-sources/hooks/pan-hook-lib.sh +153 -0
  314. package/sync-sources/hooks/permission-event-hook +24 -0
  315. package/sync-sources/hooks/post-compact-hook +25 -0
  316. package/sync-sources/hooks/pre-compact-hook +26 -0
  317. package/sync-sources/hooks/pre-tool-hook +35 -0
  318. package/sync-sources/hooks/record-cost-event.d.ts +1 -0
  319. package/sync-sources/hooks/record-cost-event.js +31859 -0
  320. package/sync-sources/hooks/record-cost-event.js.map +1 -0
  321. package/sync-sources/hooks/record-cost-event.ts +267 -0
  322. package/sync-sources/hooks/rtk-bash-filter +152 -0
  323. package/sync-sources/hooks/session-start-hook +80 -0
  324. package/sync-sources/hooks/specialist-stop-hook +106 -0
  325. package/sync-sources/hooks/statusline.sh +169 -0
  326. package/sync-sources/hooks/stop-hook +217 -0
  327. package/sync-sources/hooks/tldr-post-edit +72 -0
  328. package/sync-sources/hooks/tldr-read-enforcer +340 -0
  329. package/sync-sources/hooks/tmux-send-keys-guard +87 -0
  330. package/sync-sources/hooks/tsdown.config.ts +14 -0
  331. package/sync-sources/hooks/user-prompt-submit-hook +57 -0
  332. package/sync-sources/hooks/work-agent-stop-hook +424 -0
  333. package/server/auto-commit-CGQlb4rV.js +0 -3
  334. package/server/bd-mutex-BItGvLQ8.js +0 -35
  335. package/server/beads-restore-CMbDSB5R.js +0 -60
  336. package/server/cli-Ch_BWJB2.js +0 -3
  337. package/server/deacon-swarm-CSWGRfzr.js +0 -2
  338. package/server/dist-BUplB3Od.js +0 -3
  339. package/server/forge-IgLR0Ist.js +0 -2
  340. package/server/hume-x9voULey.js +0 -3
  341. package/server/inspect-agent-CYoWAeeB.js +0 -2
  342. package/server/merge-agent-CfohxFWM.js +0 -3
  343. package/server/merge-ops-Czke6UAp.js +0 -2
  344. package/server/projects-Bqfwuqet.js +0 -3
  345. package/server/providers-JjK6izqX.js +0 -3
  346. package/server/public/assets/index-CZiADHcL.css +0 -1
  347. package/server/public/assets/index-LQIfhmgI.js +0 -796
  348. package/server/public/assets/mermaid-GHXKKRXX-CZOsRYoT.js +0 -1
  349. package/server/rally-Ba9QoNYc.js +0 -3
  350. package/server/record-De2syxNB.js +0 -3
  351. package/server/resume-CmxF3Kjz.js +0 -3
  352. package/server/settings-DEhYpW0k.js +0 -2
  353. package/server/specs-CVH1kvz3.js +0 -3
  354. package/server/supervisor-DQMK2e3I.js +0 -2
  355. package/server/workflows-pKw9yRSV.js +0 -2
@@ -0,0 +1,424 @@
1
+ #!/bin/bash
2
+ # ~/.overdeck/bin/work-agent-stop-hook (PAN-800)
3
+ #
4
+ # Detects work agents that forgot to call `pan work done` after finishing their
5
+ # implementation, and nudges them via tmux. Writes the lifecycle resolution
6
+ # signal through POST /api/agents/:id/heartbeat (kind=resolution_set) —
7
+ # runtime.json is no longer touched.
8
+ #
9
+ # Escalation tiers:
10
+ # working — default while tool activity is recent
11
+ # done — STATE.md marked complete AND branch pushed
12
+ # api_error — transient provider error detected (auto-retry nudge)
13
+ # needs_input — LLM verdict STOPPED_FOR_INPUT
14
+ # stuck — 2+ consecutive UNCLEAR LLM verdicts
15
+ #
16
+ # The model used for the completion-check LLM is configurable via
17
+ # OVERDECK_COMPLETION_CHECK_MODEL or the completion-check-hook override
18
+ # in ~/.overdeck/config.yaml.
19
+
20
+ set +e
21
+
22
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
23
+ # shellcheck source=pan-hook-lib.sh
24
+ . "$SCRIPT_DIR/pan-hook-lib.sh" 2>/dev/null || exit 0
25
+
26
+ pan_resolve_agent_id || exit 0
27
+
28
+ # Only run for work agents (agent-*, excluding specialists).
29
+ case "$AGENT_ID" in
30
+ agent-*)
31
+ case "$AGENT_ID" in
32
+ specialist-*) exit 0 ;;
33
+ esac
34
+ ;;
35
+ *)
36
+ exit 0
37
+ ;;
38
+ esac
39
+
40
+ ISSUE_ID=$(echo "$AGENT_ID" | sed 's/^agent-//' | tr '[:lower:]' '[:upper:]')
41
+
42
+ AGENT_STATE_DIR="$HOME/.overdeck/agents/$AGENT_ID"
43
+ LOG_DIR="$HOME/.overdeck/logs"
44
+ mkdir -p "$LOG_DIR"
45
+
46
+ COMPLETED_FILE="$AGENT_STATE_DIR/completed"
47
+ [ -f "$COMPLETED_FILE" ] && exit 0
48
+
49
+ # Skip if the issue is actively flowing through the specialist pipeline.
50
+ # Read through the dashboard's SQLite-backed review-status API; review-status.json
51
+ # is legacy and can be empty or stale.
52
+ PIPELINE_STATUS_JSON=$(curl -s -m "$PAN_CURL_TIMEOUT" \
53
+ -H "x-overdeck-internal-token: $PAN_INTERNAL_TOKEN" \
54
+ "$PAN_DASHBOARD_URL/api/review/$ISSUE_ID/status" 2>/dev/null || echo "")
55
+ if [ -n "$PIPELINE_STATUS_JSON" ]; then
56
+ IN_ACTIVE_PIPELINE=$(printf '%s' "$PIPELINE_STATUS_JSON" | python3 -c "
57
+ import json, sys
58
+ try:
59
+ status = json.load(sys.stdin)
60
+ review = status.get('reviewStatus', '')
61
+ test = status.get('testStatus', '')
62
+ merge = status.get('mergeStatus', '')
63
+ ready = status.get('readyForMerge', False)
64
+ verification = status.get('verificationStatus', '')
65
+ is_active = (
66
+ review in ('reviewing', 'passed') and
67
+ test in ('passed', 'reviewing', 'pending') and
68
+ (ready or merge in ('queued', 'merging', 'verifying'))
69
+ )
70
+ needs_action = (
71
+ review in ('blocked', 'failed') or
72
+ verification == 'failed'
73
+ )
74
+ print('yes' if (is_active and not needs_action) else 'no')
75
+ except Exception:
76
+ print('no')
77
+ " 2>/dev/null || echo "no")
78
+ if [ "$IN_ACTIVE_PIPELINE" = "yes" ]; then
79
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID skipped — actively in specialist pipeline" \
80
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
81
+ exit 0
82
+ fi
83
+ fi
84
+
85
+ # Cooldown: don't nudge more than once per 10 minutes.
86
+ NUDGE_FILE="$AGENT_STATE_DIR/.last-completion-nudge"
87
+ if [ -f "$NUDGE_FILE" ]; then
88
+ LAST_NUDGE=$(cat "$NUDGE_FILE" 2>/dev/null || echo "0")
89
+ NOW=$(date +%s)
90
+ if [ $(( NOW - LAST_NUDGE )) -lt 600 ]; then
91
+ exit 0
92
+ fi
93
+ fi
94
+
95
+ # Local cache of the last resolution THIS HOOK emitted for this agent.
96
+ # Authoritative for "what did I say last time" — avoids dashboard round-trips
97
+ # that can silently fail under load and reset the ratchet to count=1.
98
+ RESOLUTION_CACHE="$AGENT_STATE_DIR/last-resolution.tsv"
99
+ RESOLUTION_LOCK="$AGENT_STATE_DIR/last-resolution.lock"
100
+ MAX_CHANNEL_REPLY_SUMMARY_LENGTH=4096
101
+
102
+ normalize_log_text() {
103
+ python3 - "$1" "$MAX_CHANNEL_REPLY_SUMMARY_LENGTH" <<'PY'
104
+ import re
105
+ import sys
106
+
107
+ text = sys.argv[1]
108
+ limit = int(sys.argv[2])
109
+ text = text.replace("\r", " ").replace("\n", " ").replace("\t", " ")
110
+ text = re.sub(r'\x1B\[[0-?]*[ -/]*[@-~]', '', text)
111
+ text = ''.join(ch for ch in text if ch >= ' ')
112
+ text = re.sub(r'\s+', ' ', text).strip()
113
+ print(text[:limit], end='')
114
+ PY
115
+ }
116
+
117
+ # Read last-emitted resolution from local cache. Echoes "resolution count"
118
+ # (space-separated) or empty string if cache missing/unreadable.
119
+ read_cached_resolution() {
120
+ [ -f "$RESOLUTION_CACHE" ] || return 0
121
+ local line
122
+ line=$(flock -s -w 1 "$RESOLUTION_LOCK" -c "cat '$RESOLUTION_CACHE'" 2>/dev/null || echo "")
123
+ [ -z "$line" ] && return 0
124
+ local res count
125
+ res=$(echo "$line" | awk -F'\t' '{print $1}')
126
+ count=$(echo "$line" | awk -F'\t' '{print $2}')
127
+ # Sanity: count must be numeric
128
+ case "$count" in
129
+ ''|*[!0-9]*) return 0 ;;
130
+ esac
131
+ echo "$res $count"
132
+ }
133
+
134
+ # Write last-emitted resolution to local cache (flock-guarded).
135
+ write_cached_resolution() {
136
+ local res="$1" count="$2"
137
+ local tmp="$RESOLUTION_CACHE.tmp.$$"
138
+ printf '%s\t%s\t%s\n' "$res" "$count" "$(date -Iseconds)" > "$tmp" 2>/dev/null || return 0
139
+ flock -x -w 1 "$RESOLUTION_LOCK" -c "mv '$tmp' '$RESOLUTION_CACHE'" 2>/dev/null || rm -f "$tmp"
140
+ }
141
+
142
+ # Emit a resolution event via the heartbeat endpoint.
143
+ # Uses the local cache as the source of truth for prev resolution/count
144
+ # (the dashboard snapshot is unreliable under load); falls back to the
145
+ # dashboard only if no local cache exists (first emit for this agent).
146
+ emit_resolution() {
147
+ local resolution="$1"
148
+ local bootstrap_snapshot="${2:-}"
149
+ local prev_resolution="" prev_count=0 prev_source=""
150
+ local cached
151
+ cached=$(read_cached_resolution)
152
+ if [ -n "$cached" ]; then
153
+ prev_resolution=$(echo "$cached" | awk '{print $1}')
154
+ prev_count=$(echo "$cached" | awk '{print $2}')
155
+ prev_source="cache"
156
+ else
157
+ # No local cache — bootstrap from structured reply snapshot when available,
158
+ # otherwise fall back to the dashboard snapshot.
159
+ local snap="$bootstrap_snapshot"
160
+ if [ -z "$snap" ]; then
161
+ snap=$(curl -s -m 0.5 "$PAN_DASHBOARD_URL/api/agents/$AGENT_ID/runtime" 2>/dev/null || echo "")
162
+ prev_source="dashboard"
163
+ else
164
+ prev_source="structured_snapshot"
165
+ fi
166
+ if [ -n "$snap" ] && command -v jq >/dev/null 2>&1; then
167
+ prev_resolution=$(echo "$snap" | jq -r '.snapshot.resolution // ""' 2>/dev/null || echo "")
168
+ prev_count=$(echo "$snap" | jq -r '.snapshot.resolutionCount // 0' 2>/dev/null || echo "0")
169
+ else
170
+ prev_source="none"
171
+ fi
172
+ fi
173
+ local new_count
174
+ if [ "$prev_resolution" = "$resolution" ]; then
175
+ new_count=$(( prev_count + 1 ))
176
+ else
177
+ new_count=1
178
+ fi
179
+
180
+ local body="{\"kind\":\"resolution_set\",\"resolution\":\"$resolution\",\"resolutionCount\":$new_count}"
181
+ pan_emit_event "$AGENT_ID" "$body"
182
+
183
+ write_cached_resolution "$resolution" "$new_count"
184
+
185
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID resolution=$resolution count=$new_count (prev=$prev_resolution/$prev_count src=$prev_source)" \
186
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
187
+ }
188
+
189
+ # ── Phase 1: evidence-based completion detection ─────────────────────────
190
+ WORKSPACE=""
191
+ STATE_FILE="$AGENT_STATE_DIR/state.json"
192
+ if [ -f "$STATE_FILE" ]; then
193
+ WORKSPACE=$(python3 -c "import json; d=json.load(open('$STATE_FILE')); print(d.get('workspace',''))" 2>/dev/null || echo "")
194
+ fi
195
+
196
+ STATE_MD_COMPLETE=false
197
+ BRANCH_PUSHED=false
198
+
199
+ if [ -n "$WORKSPACE" ] && [ -f "$WORKSPACE/.planning/STATE.md" ]; then
200
+ if grep -qiE '(^##?\s*(Status|Current Status).*:.*\b(COMPLETE|DONE|FINISHED)\b|^Status:\s*(COMPLETE|DONE|FINISHED)|implementation[[:space:]]+complete|all[[:space:]]+tasks[[:space:]]+complete)' "$WORKSPACE/.planning/STATE.md" 2>/dev/null; then
201
+ STATE_MD_COMPLETE=true
202
+ fi
203
+ fi
204
+
205
+ if [ -n "$WORKSPACE" ] && git -C "$WORKSPACE" rev-parse --git-dir >/dev/null 2>&1; then
206
+ BRANCH=$(git -C "$WORKSPACE" branch --show-current 2>/dev/null || echo "")
207
+ if [ -n "$BRANCH" ]; then
208
+ UNPUSHED=$(git -C "$WORKSPACE" log "origin/$BRANCH..HEAD" --oneline 2>/dev/null || echo "no-remote")
209
+ [ "$UNPUSHED" = "" ] && BRANCH_PUSHED=true
210
+ fi
211
+ fi
212
+
213
+ nudge_agent() {
214
+ local msg="$1"
215
+ local tmpfile
216
+ tmpfile=$(mktemp)
217
+ echo "$msg" > "$tmpfile"
218
+ tmux load-buffer "$tmpfile" 2>/dev/null
219
+ tmux paste-buffer -t "$AGENT_ID" 2>/dev/null
220
+ sleep 0.3
221
+ tmux send-keys -t "$AGENT_ID" C-m 2>/dev/null
222
+ rm -f "$tmpfile"
223
+ }
224
+
225
+ if [ "$STATE_MD_COMPLETE" = "true" ] && [ "$BRANCH_PUSHED" = "true" ]; then
226
+ emit_resolution "done"
227
+ date +%s > "$NUDGE_FILE" 2>/dev/null || true
228
+ nudge_agent "Your STATE.md indicates work is complete and your branch is pushed. You MUST run this command now:
229
+
230
+ pan work done $ISSUE_ID -c \"Implementation complete\"
231
+
232
+ If you still have remaining tasks, continue working on them. Do NOT stop until all work is done AND you have called pan work done."
233
+ exit 0
234
+ fi
235
+
236
+ if [ "$STATE_MD_COMPLETE" = "true" ] && [ "$BRANCH_PUSHED" = "false" ]; then
237
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID still_working (STATE.md=complete, branch=not-pushed)" \
238
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
239
+ exit 0
240
+ fi
241
+
242
+ handle_structured_channel_reply() {
243
+ command -v jq >/dev/null 2>&1 || return 1
244
+ local snap
245
+ snap=$(curl -s -m 0.5 "$PAN_DASHBOARD_URL/api/agents/$AGENT_ID/runtime" 2>/dev/null || echo "")
246
+ [ -z "$snap" ] && return 1
247
+
248
+ local reply_kind reply_summary normalized_reply_summary
249
+ reply_kind=$(echo "$snap" | jq -r '.snapshot.channelReply.kind // ""' 2>/dev/null || echo "")
250
+ [ -z "$reply_kind" ] && return 1
251
+ reply_summary=$(echo "$snap" | jq -r '.snapshot.channelReply.summary // ""' 2>/dev/null || echo "")
252
+ normalized_reply_summary=$(normalize_log_text "$reply_summary")
253
+
254
+ case "$reply_kind" in
255
+ done)
256
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID using structured channel_reply kind=done summary=$normalized_reply_summary" \
257
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
258
+ emit_resolution "done" "$snap"
259
+ date +%s > "$NUDGE_FILE" 2>/dev/null || true
260
+ nudge_agent "You reported completion via channel_reply. If your implementation is complete, you MUST run this command now:
261
+
262
+ pan work done $ISSUE_ID -c \"Implementation complete\"
263
+
264
+ If you still have remaining tasks, continue working on them. Do NOT stop until all work is done AND you have called pan work done."
265
+ return 0
266
+ ;;
267
+ needs_input)
268
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID using structured channel_reply kind=needs_input summary=$normalized_reply_summary" \
269
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
270
+ emit_resolution "needs_input" "$snap"
271
+ return 0
272
+ ;;
273
+ *)
274
+ return 1
275
+ ;;
276
+ esac
277
+ }
278
+
279
+ if handle_structured_channel_reply; then
280
+ exit 0
281
+ fi
282
+
283
+ # ── Phase 2: pane heuristic before the LLM call ──────────────────────────
284
+ # Capture 200 lines to give the LLM enough context (a short summary in the
285
+ # final chunk alongside earlier tool output is often the key disambiguator).
286
+ # Prompt-indicator regex covers Claude Code (Worked for) and non-Claude runtimes
287
+ # routed through Claude Code (Sautéed/Cooking/Thinking) that share the `❯` prompt.
288
+ OUTPUT=$(tmux capture-pane -t "$AGENT_ID" -p -S -200 2>/dev/null || echo "")
289
+ [ -z "$OUTPUT" ] && exit 0
290
+ echo "$OUTPUT" | tail -20 | grep -qE '(^❯|Worked for|Sautéed|Cooking|Thinking for)' || exit 0
291
+
292
+ # ── Phase 2.5: API error detection (auto-retry) ─────────────────────────
293
+ # If the agent stopped because of a transient API error, nudge it to retry
294
+ # instead of burning an LLM call on completion analysis. The agent was doing
295
+ # work and got cut off by infrastructure — it should just continue.
296
+ API_ERROR_PATTERNS=(
297
+ "API Error: The server had an error while processing your request"
298
+ "API Error: Overloaded"
299
+ "API Error: Rate limit"
300
+ "API Error: Request was aborted"
301
+ "API Error: Timed out"
302
+ "529 Overloaded"
303
+ "502 Bad Gateway"
304
+ "503 Service Unavailable"
305
+ )
306
+
307
+ API_ERROR_DETECTED=false
308
+ for pattern in "${API_ERROR_PATTERNS[@]}"; do
309
+ if echo "$OUTPUT" | grep -qF "$pattern"; then
310
+ API_ERROR_DETECTED=true
311
+ break
312
+ fi
313
+ done
314
+
315
+ if [ "$API_ERROR_DETECTED" = "true" ]; then
316
+ # Cooldown: don't retry more than once per 5 minutes for API errors.
317
+ API_ERROR_NUDGE_FILE="$AGENT_STATE_DIR/.last-api-error-nudge"
318
+ if [ -f "$API_ERROR_NUDGE_FILE" ]; then
319
+ LAST_API_NUDGE=$(cat "$API_ERROR_NUDGE_FILE" 2>/dev/null || echo "0")
320
+ NOW=$(date +%s)
321
+ if [ $(( NOW - LAST_API_NUDGE )) -lt 300 ]; then
322
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID api_error detected but cooldown active" \
323
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
324
+ exit 0
325
+ fi
326
+ fi
327
+
328
+ emit_resolution "api_error"
329
+ date +%s > "$API_ERROR_NUDGE_FILE" 2>/dev/null || true
330
+
331
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID api_error detected — nudging retry" \
332
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
333
+
334
+ nudge_agent "You stopped due to a transient API error. This is a temporary server issue, not a problem with your code. Continue your work from where you left off. Do NOT start over — pick up exactly where you stopped."
335
+ exit 0
336
+ fi
337
+
338
+ # ── Phase 3: LLM fallback ────────────────────────────────────────────────
339
+ COMPLETION_MODEL="${OVERDECK_COMPLETION_CHECK_MODEL:-}"
340
+ if [ -z "$COMPLETION_MODEL" ]; then
341
+ CONFIG_FILE="$HOME/.overdeck/config.yaml"
342
+ if [ -f "$CONFIG_FILE" ]; then
343
+ COMPLETION_MODEL=$(grep 'completion-check-hook:' "$CONFIG_FILE" 2>/dev/null | awk '{print $2}' | tr -d '"' || echo "")
344
+ fi
345
+ fi
346
+ COMPLETION_MODEL="${COMPLETION_MODEL:-claude-haiku-4-5}"
347
+
348
+ ANALYSIS_PROMPT="You are analyzing a work agent's terminal output to determine whether it finished its implementation but failed to call 'pan work done' as its final action.
349
+
350
+ The agent was working on issue $ISSUE_ID. The contract is: once every task is complete, the agent MUST run \`pan work done <ISSUE_ID>\` as a Bash command. Finishing work without running that command is a failure — the pipeline stalls.
351
+
352
+ Here is the last 200 lines of its terminal output:
353
+
354
+ <terminal_output>
355
+ $OUTPUT
356
+ </terminal_output>
357
+
358
+ Decide FORGOT_COMPLETION if ANY of these are true AND the transcript does NOT show a 'pan work done' Bash invocation in the tail:
359
+ - the agent wrote a summary/wrap-up message ('all tests pass', 'implementation complete', 'all beads closed', 'ready for review', etc.) and then stopped
360
+ - the agent closed beads or ran 'bd close' and finished with a prompt
361
+ - the agent committed + pushed and the last message is a status summary instead of a pan-work-done command
362
+
363
+ Decide STILL_WORKING only if the tail clearly shows an in-progress task (mid-edit, running tests, reading files) with no wrap-up summary.
364
+ Decide STOPPED_FOR_INPUT only if the agent explicitly asked the human a question or flagged a blocker.
365
+ Use UNCLEAR only as a last resort when the tail is genuinely ambiguous (e.g. no summary and no active work).
366
+
367
+ Respond with EXACTLY one word, nothing else: FORGOT_COMPLETION | STILL_WORKING | STOPPED_FOR_INPUT | UNCLEAR"
368
+
369
+ CLAUDE_STDERR="$LOG_DIR/work-agent-stop-hook.claude-stderr.log"
370
+ RESULT=$(echo "$ANALYSIS_PROMPT" | claude -p --model "$COMPLETION_MODEL" 2>>"$CLAUDE_STDERR")
371
+ CLAUDE_RC=$?
372
+ if [ $CLAUDE_RC -ne 0 ] || [ -z "$RESULT" ]; then
373
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID claude -p failed rc=$CLAUDE_RC (see $CLAUDE_STDERR), fallback to UNCLEAR" \
374
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
375
+ RESULT="UNCLEAR"
376
+ fi
377
+ VERDICT=$(echo "$RESULT" | tr -d '[:space:]' | head -c 30)
378
+
379
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID ($ISSUE_ID) -> $VERDICT (model: $COMPLETION_MODEL, rc=$CLAUDE_RC)" \
380
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
381
+
382
+ case "$VERDICT" in
383
+ FORGOT_COMPLETION)
384
+ emit_resolution "done"
385
+ date +%s > "$NUDGE_FILE" 2>/dev/null || true
386
+ nudge_agent "You stopped without calling pan work done. If your implementation is complete, you MUST run this command now:
387
+
388
+ pan work done $ISSUE_ID -c \"Implementation complete\"
389
+
390
+ If you still have remaining tasks, continue working on them. Do NOT stop until all work is done AND you have called pan work done."
391
+ ;;
392
+ STOPPED_FOR_INPUT)
393
+ emit_resolution "needs_input"
394
+ ;;
395
+ UNCLEAR)
396
+ # Escalate to stuck after 2+ consecutive UNCLEAR — the hook has looked at
397
+ # this agent's tail twice and still can't tell what it's doing, which is
398
+ # itself signal. Uses the local resolution cache (not the dashboard) so
399
+ # this decision is deterministic even when the dashboard is unreachable.
400
+ escalate_to_stuck=false
401
+ esc_prev_resolution=""
402
+ esc_prev_count=0
403
+ esc_cached=$(read_cached_resolution)
404
+ if [ -n "$esc_cached" ]; then
405
+ esc_prev_resolution=$(echo "$esc_cached" | awk '{print $1}')
406
+ esc_prev_count=$(echo "$esc_cached" | awk '{print $2}')
407
+ # Stay stuck once escalated (don't ratchet back to unclear on subsequent
408
+ # UNCLEAR verdicts — deacon's poke logic counts consecutive stuck heartbeats).
409
+ if { [ "$esc_prev_resolution" = "unclear" ] && [ "$esc_prev_count" -ge 1 ]; } \
410
+ || [ "$esc_prev_resolution" = "stuck" ]; then
411
+ escalate_to_stuck=true
412
+ fi
413
+ fi
414
+ echo "[$(date -Iseconds)] work-agent-stop-hook: $AGENT_ID UNCLEAR gate prev=$esc_prev_resolution/$esc_prev_count escalate=$escalate_to_stuck" \
415
+ >> "$LOG_DIR/hooks.log" 2>/dev/null || true
416
+ if [ "$escalate_to_stuck" = "true" ]; then
417
+ emit_resolution "stuck"
418
+ else
419
+ emit_resolution "unclear"
420
+ fi
421
+ ;;
422
+ esac
423
+
424
+ exit 0
@@ -1,3 +0,0 @@
1
- import { an as queueBeadsAutoCommit, nn as flushAutoCommits, rn as init_auto_commit } from "./config-yaml-ClpGgrf6.js";
2
- init_auto_commit();
3
- export { flushAutoCommits, queueBeadsAutoCommit };
@@ -1,35 +0,0 @@
1
- import { t as init_beads_restore } from "./beads-restore-CMbDSB5R.js";
2
- import { Effect } from "effect";
3
- //#region ../../lib/bd-mutex.ts
4
- /**
5
- * Global mutex for bd (beads) CLI commands.
6
- *
7
- * Embedded Dolt uses file-based locking — only one process can hold the
8
- * database lock at a time. When the dashboard spawns concurrent `bd` commands
9
- * (e.g. planning-state queries for every kanban card), each process blocks
10
- * waiting for the lock, creating a cascade of hundreds of hung processes.
11
- *
12
- * This mutex serializes all bd operations so only one runs at a time,
13
- * preventing lock contention and process pile-up.
14
- */
15
- init_beads_restore();
16
- let pending = Promise.resolve();
17
- async function withBdMutexPromise(fn) {
18
- const result = pending.then(fn, fn);
19
- pending = result.then(() => {}, () => {});
20
- return result;
21
- }
22
- /**
23
- * Effect-native variant of withBdMutex over a thunk that returns a no-context
24
- * Effect. Serializes against all other bd-mutex callers via the Promise queue.
25
- * The wrapped Effect must be no-context (R = never) since it is launched from
26
- * inside a tryPromise — Layers cannot be threaded through the global mutex.
27
- */
28
- const withBdMutex = (fn) => Effect.tryPromise({
29
- try: () => withBdMutexPromise(() => Effect.runPromise(fn())),
30
- catch: (e) => e
31
- });
32
- //#endregion
33
- export { withBdMutexPromise as n, withBdMutex as t };
34
-
35
- //# sourceMappingURL=bd-mutex-BItGvLQ8.js.map
@@ -1,60 +0,0 @@
1
- import { n as __esmMin } from "./rolldown-runtime-DNCzzKnI.js";
2
- import { Effect, Layer, Stream } from "effect";
3
- import { ChildProcess } from "effect/unstable/process";
4
- import * as NodeChildProcessSpawner from "@effect/platform-node/NodeChildProcessSpawner";
5
- import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem";
6
- import * as NodePath from "@effect/platform-node/NodePath";
7
- //#region ../../lib/beads-restore.ts
8
- /**
9
- * Safety net for the workspace beads JSONL export.
10
- *
11
- * Workspace bd dolt databases occasionally lose state (see PAN-1158): a stale
12
- * dolt-server, port collision between sibling worktrees, or partial init can
13
- * leave `bd list` returning zero issues. The next `bd export` then faithfully
14
- * writes a zero-issue file (which bd v1.0.4 chooses not to materialise at all),
15
- * and git reports the previously-tracked `.beads/issues.jsonl` as deleted.
16
- *
17
- * That phantom deletion blocks every workspace path that checks `git status`
18
- * before doing real work (`pan review request`, `syncMainIntoWorkspace`'s
19
- * pre-flight auto-commit), and the worst case is the auto-commit catching it
20
- * and propagating the deletion onto the feature branch.
21
- *
22
- * `restoreTrackedBeadsExport()` is the recovery primitive: if the tracked
23
- * export is missing on disk, `git restore` it from the index. The real fix
24
- * lives in PAN-1158 (prevent the dolt DB from going empty in the first place
25
- * and refuse-empty in `bd export`). Until that lands, this primitive is the
26
- * safety net we wedge into the workspace flows that get hurt today.
27
- *
28
- * NOTE: PR #1155 introduces an inline copy of this helper in `bd-mutex.ts`.
29
- * Once both PRs land, the duplicate should be removed in favour of this file.
30
- */
31
- var spawnerLayer, runGit, restoreTrackedBeadsExport;
32
- var init_beads_restore = __esmMin((() => {
33
- spawnerLayer = NodeChildProcessSpawner.layer.pipe(Layer.provide(Layer.mergeAll(NodeFileSystem.layer, NodePath.layer)));
34
- runGit = (args, cwd) => Effect.gen(function* () {
35
- const handle = yield* ChildProcess.make("git", [...args], { cwd });
36
- const buf = yield* Stream.runFold(handle.stdout, () => Buffer.alloc(0), (acc, chunk) => Buffer.concat([acc, Buffer.from(chunk)]));
37
- yield* handle.exitCode;
38
- return buf.toString("utf-8");
39
- }).pipe(Effect.scoped, Effect.provide(spawnerLayer));
40
- restoreTrackedBeadsExport = (workspacePath) => Effect.gen(function* () {
41
- const xy = (yield* runGit([
42
- "status",
43
- "--porcelain",
44
- "--",
45
- ".beads/issues.jsonl"
46
- ], workspacePath)).split("\n").find((line) => line.endsWith(" .beads/issues.jsonl"));
47
- if (xy && (xy[0] === "D" || xy[1] === "D")) yield* runGit([
48
- "restore",
49
- "--source=HEAD",
50
- "--staged",
51
- "--worktree",
52
- "--",
53
- ".beads/issues.jsonl"
54
- ], workspacePath);
55
- }).pipe(Effect.catch(() => Effect.void));
56
- }));
57
- //#endregion
58
- export { restoreTrackedBeadsExport as n, init_beads_restore as t };
59
-
60
- //# sourceMappingURL=beads-restore-CMbDSB5R.js.map
@@ -1,3 +0,0 @@
1
- import { r as init_cli, t as createResetMarker } from "./cli-B75AieAM.js";
2
- init_cli();
3
- export { createResetMarker };
@@ -1,2 +0,0 @@
1
- import { r as coordinateSwarmSlots } from "./deacon-swarm-BstYoz8Q.js";
2
- export { coordinateSwarmSlots };
@@ -1,3 +0,0 @@
1
- import { t as require_dist } from "./dist-BIC8spJ0.js";
2
- export default require_dist();
3
- export {};
@@ -1,2 +0,0 @@
1
- import { n as getForgeAdapter } from "./forge-CoPFXFyl.js";
2
- export { getForgeAdapter };
@@ -1,3 +0,0 @@
1
- import { i as init_hume, r as deleteHumeConfig } from "./hume-DkVOs1Qi.js";
2
- init_hume();
3
- export { deleteHumeConfig };
@@ -1,2 +0,0 @@
1
- import { n as onInspectComplete } from "./inspect-agent-DOaCDkCF.js";
2
- export { onInspectComplete };
@@ -1,3 +0,0 @@
1
- import { _ as scanGitPatterns, a as init_merge_agent, c as isSyncMainMainPreferredPath, d as parseAgentOutput, f as postMergeLifecycle, g as scanForConflictMarkers, h as salvageStrandedMerge, i as captureTmuxOutput, l as logMergeHistory, m as runProjectQualityGates, n as GIT_PATTERNS, o as isAutoCommitExcludedPath, p as resetPostMergeState, r as autoCommitWorkspaceChangesBeforeSync, s as isMergeAgentRunning, t as AUTO_COMMIT_EXCLUDED_PATHS, u as notifyTldrDaemon, v as sendMessageToAgent, y as syncMainIntoWorkspace } from "./merge-agent-CHHs5S_0.js";
2
- init_merge_agent();
3
- export { AUTO_COMMIT_EXCLUDED_PATHS, GIT_PATTERNS, autoCommitWorkspaceChangesBeforeSync, captureTmuxOutput, isAutoCommitExcludedPath, isMergeAgentRunning, isSyncMainMainPreferredPath, logMergeHistory, notifyTldrDaemon, parseAgentOutput, postMergeLifecycle, resetPostMergeState, runProjectQualityGates, salvageStrandedMerge, scanForConflictMarkers, scanGitPatterns, sendMessageToAgent, syncMainIntoWorkspace };
@@ -1,2 +0,0 @@
1
- import { c as triggerMerge } from "./workspaces-Ca4zZs12.js";
2
- export { triggerMerge };
@@ -1,3 +0,0 @@
1
- import { An as getSpecialistRetention, Cn as findProjectsByRallyProject, Dn as getProjectSync, En as getProjectSwarmHotspots, Fn as initializeProjectsConfigSync, Gn as resolveProjectFromIssueSync, Hn as registerProjectSync, In as listProjects, Jn as saveProjectsConfigSync, Kn as resolveProjectPath, Ln as listProjectsSync, Mn as hasProjectsSync, Nn as init_projects, On as getSpecialistConfig, Pn as initializeProjectsConfig, Rn as loadProjectsConfig, Sn as findProjectByTeamSync, Tn as getProject, Un as resolveInfraRepo, Vn as registerProject, Wn as resolveProjectFromIssue, Xn as unregisterProject, Yn as setProjectAutoMergeDefaultSync, Zn as unregisterProjectSync, _n as createDefaultProjectsConfig, bn as findProjectByPathSync, gn as PROJECTS_CONFIG_FILE, jn as hasProjects, kn as getSpecialistPromptOverride, qn as saveProjectsConfig, vn as extractTeamPrefix, wn as getIssuePrefix, xn as findProjectByTeam, yn as findProjectByPath, zn as loadProjectsConfigSync } from "./config-yaml-ClpGgrf6.js";
2
- init_projects();
3
- export { PROJECTS_CONFIG_FILE, createDefaultProjectsConfig, extractTeamPrefix, findProjectByPath, findProjectByPathSync, findProjectByTeam, findProjectByTeamSync, findProjectsByRallyProject, getIssuePrefix, getProject, getProjectSwarmHotspots, getProjectSync, getSpecialistConfig, getSpecialistPromptOverride, getSpecialistRetention, hasProjects, hasProjectsSync, initializeProjectsConfig, initializeProjectsConfigSync, listProjects, listProjectsSync, loadProjectsConfig, loadProjectsConfigSync, registerProject, registerProjectSync, resolveInfraRepo, resolveProjectFromIssue, resolveProjectFromIssueSync, resolveProjectPath, saveProjectsConfig, saveProjectsConfigSync, setProjectAutoMergeDefaultSync, unregisterProject, unregisterProjectSync };
@@ -1,3 +0,0 @@
1
- import { I as getProviderEnvSync, L as getProviderForModelSync, R as init_providers } from "./config-yaml-ClpGgrf6.js";
2
- init_providers();
3
- export { getProviderEnvSync, getProviderForModelSync };