@overdeck/desktop 0.45.12 → 0.45.13

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 (323) 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-CfujPRrz.js} +2 -2
  4. package/server/{advancing-selfheal-BqsLWqEM.js → advancing-selfheal-Bn5QiLtn.js} +4 -4
  5. package/server/{agent-gc-CUb52n7s.js → agent-gc-Cl9Nm0Zu.js} +3 -3
  6. package/server/{agent-state-D-moNwhA.js → agent-state-C6Rm6FPR.js} +1 -1
  7. package/server/{agent-state-service-BzESvLOf.js → agent-state-service-JhFzYCP_.js} +5 -5
  8. package/server/{agent-state-service-BaZH7sXJ.js → agent-state-service-U8feBf8t.js} +1 -1
  9. package/server/{agents-C4kZ8a2r.js → agents-CxbuBjID.js} +1 -1
  10. package/server/{agents-B5LfpLPv.js → agents-DqQa4Dq_.js} +88 -64
  11. package/server/{archive-planning-oX1pj6nY.js → archive-planning-CPitEZo4.js} +3 -3
  12. package/server/{archive-planning-BbZe-8IK.js → archive-planning-DmpT1_14.js} +1 -1
  13. package/server/{artifact-index-jobs-DGr6bxev.js → artifact-index-jobs-sMnNtPhy.js} +2 -2
  14. package/server/{auto-commit-CGQlb4rV.js → auto-commit-wZ9X7Isd.js} +1 -1
  15. package/server/{backlog-auto-trigger-BlJHikOm.js → backlog-auto-trigger-Cf9C8fwD.js} +2 -2
  16. package/server/{bd-process-lock-i3CYMS-B.js → bd-process-lock-D1aJxeYv.js} +2 -2
  17. package/server/{beads-BNU-fb48.js → beads-CivpXztb.js} +1 -1
  18. package/server/{beads-DD7fYCl5.js → beads-DRoj6-e1.js} +4 -4
  19. package/server/{beads-query-e6oku4P5.js → beads-query-tOsAYP5h.js} +2 -2
  20. package/server/{behavior-CPf0pbOt.js → behavior-D3d2mVyD.js} +3 -3
  21. package/server/{briefing-freshness-B2FdLwIv.js → briefing-freshness-BL3Q6p7R.js} +4 -4
  22. package/server/{checkpoint-manager-JryW6MpM.js → checkpoint-manager-DCxjQvP_.js} +2 -2
  23. package/server/{checkpoint-manager-eFgaMMu4.js → checkpoint-manager-j5URlFY7.js} +1 -1
  24. package/server/checkpoint-worker.js +1 -1
  25. package/server/{checkpoints-qvOqvMuC.js → checkpoints-BoX1H2Hf.js} +2 -2
  26. package/server/{checkpoints-BK17oicz.js → checkpoints-Bu_M_Q9W.js} +1 -1
  27. package/server/claude-hooks-provision-D-jGXmu1.js +360 -0
  28. package/server/{claude-permissions-B6bWGh9d.js → claude-permissions-DxIjkOVl.js} +2 -2
  29. package/server/{claude-settings-overlay-BPdhTPjo.js → claude-settings-overlay-5b9X2S0C.js} +1 -1
  30. package/server/{claude-settings-overlay-CRyyKKXQ.js → claude-settings-overlay-BPDS6GfE.js} +2 -2
  31. package/server/cli-CqgiSAU8.js +3 -0
  32. package/server/{cli-B75AieAM.js → cli-s7bPWy-E.js} +9 -9
  33. package/server/{cliproxy-CCzwuSNe.js → cliproxy-BituqWtR.js} +2 -2
  34. package/server/{cliproxy-DOQf66G9.js → cliproxy-D3sHB0sI.js} +1 -1
  35. package/server/{close-issue-_X3MXJyG.js → close-issue-CrBE7voz.js} +4 -4
  36. package/server/{closed-issue-reaper-CLR7ClsO.js → closed-issue-reaper-BRQBc7Xa.js} +1 -1
  37. package/server/{closed-issue-reaper-BsUfBSjM.js → closed-issue-reaper-DX9mYUji.js} +9 -9
  38. package/server/{codex-CY-QRuU9.js → codex-Bi1ITSOo.js} +1 -1
  39. package/server/{codex-B4KEpX5V.js → codex-CO0HrK3j.js} +5 -5
  40. package/server/{compact-beads-cZds2MTr.js → compact-beads-CrA8-k10.js} +1 -1
  41. package/server/{compact-beads-uEDccC76.js → compact-beads-DUkCUFxA.js} +3 -3
  42. package/server/{config-DARrpYWA.js → config-B4_d7z7z.js} +1 -1
  43. package/server/{config-8sjaU6jZ.js → config-DsCxzjXK.js} +2 -2
  44. package/server/{config-yaml-ClpGgrf6.js → config-yaml-C_djSurJ.js} +2 -2
  45. package/server/{conflict-gate-Ds9_2yjd.js → conflict-gate-CpOn9KC-.js} +1 -1
  46. package/server/{conflict-gate-BtB_o-Vi.js → conflict-gate-D47Kl78u.js} +3 -3
  47. package/server/{context-layers-r2ywnQYA.js → context-layers-BNhUBTkf.js} +3 -3
  48. package/server/{context-layers-CRCk1QG7.js → context-layers-CHl3Nroz.js} +2 -2
  49. package/server/{control-settings-D1B3u6HP.js → control-settings-KyYNXZLv.js} +4 -4
  50. package/server/{conversation-compaction-D86Zo2Ci.js → conversation-compaction-D3aS5PnS.js} +8 -8
  51. package/server/{conversation-compaction-CZRVk4hg.js → conversation-compaction-D4Wed1BJ.js} +1 -1
  52. package/server/{conversation-service-CuTVU8dV.js → conversation-service-CFZIjs-M.js} +5 -5
  53. package/server/{conversation-service-CkL-6MuG.js → conversation-service-DcDB5usR.js} +1 -1
  54. package/server/{conversations-DfJKBDwB.js → conversations-BSOU5qnu.js} +4 -4
  55. package/server/{conversations-BmWEluPL.js → conversations-BbDPrz89.js} +1 -1
  56. package/server/{cost-DAPYN6iA.js → cost-BE_ulOrw.js} +3 -3
  57. package/server/{cost-CCnqa5xK.js → cost-CaiG63FG.js} +2 -2
  58. package/server/{cost-sync-BDL10Nwu.js → cost-sync-D6AX8jv-.js} +3 -3
  59. package/server/{dag-Dv2r5bVD.js → dag-BQFtXOuJ.js} +3 -3
  60. package/server/{dangerous-git-ops-Dcw7PbYo.js → dangerous-git-ops-04Ba-Qu3.js} +1 -1
  61. package/server/dashboard-db-worker.js +6 -6
  62. package/server/{deacon-CM0MxbS8.js → deacon-2EvA9Ci3.js} +97 -97
  63. package/server/{deacon-DYnZH7kC.js → deacon-Bz-6Wjmn.js} +3 -3
  64. package/server/deacon-swarm-B8pgK2a7.js +2 -0
  65. package/server/{deacon-swarm-BstYoz8Q.js → deacon-swarm-DYYOzHRH.js} +10 -10
  66. package/server/deacon.js +7 -7
  67. package/server/{devcontainer-renderer-CaYOG9JN.js → devcontainer-renderer-Dx0C7VWJ.js} +2 -2
  68. package/server/dist-BYSj075e.js +3 -0
  69. package/server/{dist-BIC8spJ0.js → dist-ya66D9ze.js} +1 -1
  70. package/server/{docker-DDI1shu3.js → docker-D2TbXDO6.js} +2 -2
  71. package/server/{ensure-devcontainer-CbSXvN9W.js → ensure-devcontainer-BIShzs3M.js} +1 -1
  72. package/server/{ensure-devcontainer-DCAg3ksz.js → ensure-devcontainer-BTiMfFp5.js} +3 -3
  73. package/server/{event-store-DU3HkZlN.js → event-store-C02Gprug.js} +1 -1
  74. package/server/{event-store-DCMqyI07.js → event-store-C71x6h0i.js} +3 -3
  75. package/server/{events-BfiosVAn.js → events-BFDuPV6n.js} +3 -3
  76. package/server/{events-DLRxpSuV.js → events-D2gP2-Yv.js} +1 -1
  77. package/server/{factory-BMtWV9iv.js → factory-ByfbrCab.js} +4 -4
  78. package/server/{feature-registry-population-DA7bO6Zn.js → feature-registry-population-CSH66UO8.js} +4 -4
  79. package/server/{feature-registry-storage-nAY1fbBt.js → feature-registry-storage-DW7dUefc.js} +2 -2
  80. package/server/{features-DMu7eGmU.js → features-x_aLR7U9.js} +2 -2
  81. package/server/{feedback-target-DHqcw3cN.js → feedback-target-BFo9fScH.js} +6 -6
  82. package/server/{feedback-target-B2SEai8-.js → feedback-target-C4VMPTZu.js} +1 -1
  83. package/server/{feedback-writer-qvm7UON7.js → feedback-writer-B9ZqnnX3.js} +4 -4
  84. package/server/{feedback-writer-DMBdS_jL.js → feedback-writer-DCyd75yJ.js} +1 -1
  85. package/server/{flywheel-Dfpx4bIV.js → flywheel-D9NKvWqb.js} +11 -11
  86. package/server/{flywheel-k4FPtCQ_.js → flywheel-DB48X7Nn.js} +1 -1
  87. package/server/{flywheel-D2LdPSic.js → flywheel-DwQCoZQG.js} +13 -13
  88. package/server/{flywheel-merge-order-CB4lbXeJ.js → flywheel-merge-order-DrjmFXg4.js} +6 -6
  89. package/server/{flywheel-merge-order-CttTazRY.js → flywheel-merge-order-f1bi5XIf.js} +1 -1
  90. package/server/{forge-CoPFXFyl.js → forge-C-SoKy8U.js} +2 -2
  91. package/server/forge-CUCYK7h_.js +2 -0
  92. package/server/{from-B0YoJl9-.js → from-fu7ZumnY.js} +1 -1
  93. package/server/{fts-db-DAHW1yA_.js → fts-db-CL-YzSRG.js} +2 -2
  94. package/server/{fts-operations-DDXDBi0d.js → fts-operations-Bylu5NjM.js} +2 -2
  95. package/server/{git-utils-B90Zjzfl.js → git-utils-C8koBs8j.js} +2 -2
  96. package/server/{git-utils-DbfC0zls.js → git-utils-Ym380hJZ.js} +1 -1
  97. package/server/{github-app-C7lftMNj.js → github-app-DIr70YLg.js} +1 -1
  98. package/server/{github-app-BecAnXRX.js → github-app-DhycHVLF.js} +2 -2
  99. package/server/{github-client-D21rCIXk.js → github-client-7gkcXcBS.js} +2 -2
  100. package/server/{github-client-BwtKZtM0.js → github-client-Ji9lUTNF.js} +1 -1
  101. package/server/{github-pr-lookup-CzVWuysl.js → github-pr-lookup-rt7T9FwA.js} +2 -2
  102. package/server/{harness-resolve-SkRJm4a7.js → harness-resolve-CvGXUnAF.js} +3 -3
  103. package/server/{health-events-BT0aAfeA.js → health-events-D4E1DLN-.js} +2 -2
  104. package/server/{health-events-DA_JLpgZ.js → health-events-DDfkoO5a.js} +1 -1
  105. package/server/{hooks-DxEn2BoY.js → hooks-D_6pAbuJ.js} +2 -2
  106. package/server/{hooks-BQxRXtRb.js → hooks-DvdnCVv6.js} +1 -1
  107. package/server/{idle-stack-reaper-C7fJL8jH.js → idle-stack-reaper-DNbV9-fj.js} +1 -1
  108. package/server/{idle-stack-reaper-DGy7tvC9.js → idle-stack-reaper-cDRXDpgE.js} +2 -2
  109. package/server/{infra-DE3C4PMr.js → infra-Clew3DpF.js} +50 -3
  110. package/server/{injection-Dt22tGvS.js → injection-QCIHOpk6.js} +1 -1
  111. package/server/{injection-Cc4Qt8LZ.js → injection-ql0Nddcn.js} +7 -7
  112. package/server/inspect-agent-D8UBDgfR.js +2 -0
  113. package/server/{inspect-agent-DOaCDkCF.js → inspect-agent-DY18KEx4.js} +9 -9
  114. package/server/{internal-token-B_1YLWLI.js → internal-token-BeXjPLKy.js} +2 -2
  115. package/server/{internal-token-nobT6FhA.js → internal-token-C90jBp-y.js} +1 -1
  116. package/server/{io-A7ZuOBkz.js → io-CbAFXQge.js} +2 -2
  117. package/server/{issue-closed-Da3DeomA.js → issue-closed-BYC2TCk-.js} +4 -4
  118. package/server/{issue-lifecycle-543pQX9D.js → issue-lifecycle-BoJa6qIt.js} +21 -21
  119. package/server/{issue-lifecycle-Bd9XBJAQ.js → issue-lifecycle-CLHbj8RS.js} +1 -1
  120. package/server/{issue-service-singleton-BC2JLZi7.js → issue-service-singleton-3g_CCY-1.js} +1 -1
  121. package/server/{issue-service-singleton-Brc3t0SV.js → issue-service-singleton-BS9NENuR.js} +8 -8
  122. package/server/{issues-D3kt9UWE.js → issues-BPcqPqfV.js} +2 -2
  123. package/server/{label-cleanup-w9X_T3AQ.js → label-cleanup-CwiCSZrb.js} +2 -2
  124. package/server/{layers-Cwe1J-9o.js → layers-OHHLphl0.js} +2 -2
  125. package/server/{lifecycle-f1GbDK33.js → lifecycle-B8IdvUbt.js} +6 -6
  126. package/server/{lifecycle-io-D56q8zlO.js → lifecycle-io-BMCH1Bxg.js} +1 -1
  127. package/server/{lifecycle-io-Bqvj0m3i.js → lifecycle-io-C73m5e6R.js} +4 -4
  128. package/server/{linear-client-Bh4T4S-c.js → linear-client-BMxgycoy.js} +1 -1
  129. package/server/{linear-client-CfJMTAYd.js → linear-client-CgQlM4aT.js} +2 -2
  130. package/server/memory-fts-worker.js +1 -1
  131. package/server/{merge-ZrXFM3jv.js → merge-B7Oi-g6k.js} +3 -3
  132. package/server/{merge-DRMPa8CQ.js → merge-BRkVaIx-.js} +1 -1
  133. package/server/merge-agent-Bwm34MZ5.js +3 -0
  134. package/server/{merge-agent-CHHs5S_0.js → merge-agent-DNFFsiEm.js} +61 -26
  135. package/server/{merge-batch-BwhGdlh4.js → merge-batch-BpYXUaqJ.js} +1 -1
  136. package/server/{merge-blockers-BMhDpMl_.js → merge-blockers-DIOZmqdK.js} +2 -2
  137. package/server/merge-ops-B7m-hBEZ.js +2 -0
  138. package/server/{merge-rebase-R7MfqpiE.js → merge-rebase-C8WH39MB.js} +2 -2
  139. package/server/{merge-set-B3Breacq.js → merge-set-CsEE2CyQ.js} +9 -5
  140. package/server/{merge-set-D-iXNP0I.js → merge-set-DOsBTBQc.js} +1 -1
  141. package/server/{merge-sync-DHWbGtjR.js → merge-sync-C2B322Ot.js} +2 -2
  142. package/server/{merge-sync-bOOtfeXR.js → merge-sync-CcLM2vwW.js} +1 -1
  143. package/server/{merge-train-98ptZrPT.js → merge-train-BIm7-7cy.js} +3 -3
  144. package/server/{merge-train-deps-B5FWJTE2.js → merge-train-deps-DG1oQ2DT.js} +4 -4
  145. package/server/{merge-verification-BGiuiXAK.js → merge-verification-BAbjxEd5.js} +4 -4
  146. package/server/{multipart-parser-D7mzNNDm.js → multipart-parser-jKtKAXtl.js} +2 -2
  147. package/server/node_modules/.package-lock.json +1 -1
  148. package/server/{orphan-proposed-reconciler-CSuxivr9.js → orphan-proposed-reconciler-BqVGaOIj.js} +1 -1
  149. package/server/{orphan-proposed-reconciler-BSGCNJ6X.js → orphan-proposed-reconciler-zHrwJ3xr.js} +9 -9
  150. package/server/package-lock.json +2 -2
  151. package/server/package.json +1 -1
  152. package/server/{pan-dir-DoPtdHrp.js → pan-dir-BlNrLzW7.js} +3 -3
  153. package/server/{paths-CVDLPxXp.js → paths-CiVeo4N_.js} +2 -2
  154. package/server/{pipeline-notifier-WD2dnOsR.js → pipeline-notifier-DBF6dHxH.js} +2 -2
  155. package/server/{pipeline-notifier-BtYHbBPl.js → pipeline-notifier-nkWCe042.js} +1 -1
  156. package/server/{projects-Bqfwuqet.js → projects-BqRMlDOv.js} +1 -1
  157. package/server/{prompts-Cg7e9FPb.js → prompts-CXbQvevY.js} +2 -2
  158. package/server/{providers-fLduChnX.js → providers-CUdAb5Qu.js} +7 -7
  159. package/server/{providers-JjK6izqX.js → providers-gZ0cUgQM.js} +1 -1
  160. package/server/public/assets/{chunk-BO2N2NFS-aNlsGDCu.js → chunk-BO2N2NFS-C-6y8VFI.js} +4 -4
  161. package/server/public/assets/{diagram-OG6HWLK6-CnjkrvT8.js → diagram-OG6HWLK6-NACO1xW5.js} +1 -1
  162. package/server/public/assets/{dist-CGKBCieA.js → dist-D1FjqGgm.js} +1 -1
  163. package/server/public/assets/{dist-Bg3Sbsx4.js → dist-DQD-ZjQY.js} +3 -3
  164. package/server/public/assets/{ganttDiagram-6RSMTGT7-C8LLKj23.js → ganttDiagram-6RSMTGT7-CEMAKgmE.js} +1 -1
  165. package/server/public/assets/{highlighted-body-OFNGDK62-BSDEUvhW.js → highlighted-body-OFNGDK62-D5lC7FW8.js} +1 -1
  166. package/server/public/assets/{index-LQIfhmgI.js → index-BDqWyuZQ.js} +140 -140
  167. package/server/public/assets/{linear-DEbYZoxg.js → linear-DDHAMRPB.js} +1 -1
  168. package/server/public/assets/mermaid-GHXKKRXX-DRM2ANcR.js +1 -0
  169. package/server/public/assets/{pieDiagram-4H26LBE5-BtZL5pXE.js → pieDiagram-4H26LBE5-DwBdeKBb.js} +1 -1
  170. package/server/public/assets/{prod-DYVvIyuh.js → prod-DAZt0c4G.js} +4 -4
  171. package/server/public/assets/{quadrantDiagram-W4KKPZXB-a7vS8Jc8.js → quadrantDiagram-W4KKPZXB-CNDLp-_m.js} +1 -1
  172. package/server/public/assets/{sankeyDiagram-5OEKKPKP-Ckbq2SWH.js → sankeyDiagram-5OEKKPKP-oIUL_uO1.js} +1 -1
  173. package/server/public/assets/{xychartDiagram-2RQKCTM6-DJyeNa99.js → xychartDiagram-2RQKCTM6-B-IM6Cck.js} +1 -1
  174. package/server/public/index.html +1 -1
  175. package/server/{pull-requests-D2SjJIwY.js → pull-requests-DZ-V7_LB.js} +1 -1
  176. package/server/{pull-requests-1WXmTBlo.js → pull-requests-kTRl7cWC.js} +3 -3
  177. package/server/rally-CRteqXe0.js +3 -0
  178. package/server/{rally-api-H5I2CBO0.js → rally-api-DpZo3WwF.js} +2 -2
  179. package/server/{rally-api-BtvwdX6d.js → rally-api-jOk4vit_.js} +1 -1
  180. package/server/{rally-client-Bt-qHiOh.js → rally-client-BQjm3aaq.js} +1 -1
  181. package/server/{rally-client-33CYZYYu.js → rally-client-CoWZeVEj.js} +4 -4
  182. package/server/{rally-8aQlLLVj.js → rally-xCTZ-UcI.js} +3 -3
  183. package/server/{rebuild-stack-KHkkrGjx.js → rebuild-stack-BZ7j27xY.js} +5 -5
  184. package/server/{rebuild-stack-CXSgAGPR.js → rebuild-stack-r-cxcr26.js} +1 -1
  185. package/server/{reconstruct-cache-D_Ml65_6.js → reconstruct-cache-13EkMg_i.js} +6 -6
  186. package/server/{record-De2syxNB.js → record-CJsjvRO4.js} +1 -1
  187. package/server/release-engine-YLTnEO_K.js +306 -0
  188. package/server/release-set-DwvT_Opu.js +125 -0
  189. package/server/{remote-CGuognN3.js → remote-9u9WL0NJ.js} +3 -3
  190. package/server/{remote-D0Old0Cv.js → remote-B062S1Kc.js} +3 -3
  191. package/server/{remote-agents-UHoi4oGr.js → remote-agents-B4eWgwNd.js} +1 -1
  192. package/server/{remote-agents-DfhMq6kQ.js → remote-agents-BBTg-vLT.js} +5 -5
  193. package/server/{remote-completion-RZYePR_0.js → remote-completion-B0rmBnbL.js} +12 -12
  194. package/server/resume-R7xkSmLW.js +3 -0
  195. package/server/{review-agent-uwVftH98.js → review-agent-Bf9XjLnl.js} +1 -1
  196. package/server/{review-agent-sZBCpEVv.js → review-agent-tfR5RDzG.js} +22 -22
  197. package/server/{review-artifacts-C7a45b1_.js → review-artifacts-D0_IE6DQ.js} +6 -6
  198. package/server/{review-context-CErbQpKL.js → review-context-CXO5ml5D.js} +7 -7
  199. package/server/{review-monitor-DHD9m_kh.js → review-monitor-DfFUSx0J.js} +2 -2
  200. package/server/{review-status-JhQ3qlDS.js → review-status-B0Axo-Ma.js} +1 -1
  201. package/server/{review-status-gPndPUBc.js → review-status-BcfwcAcO.js} +23 -16
  202. package/server/{review-status-enrichment-qWvWckYN.js → review-status-enrichment-Cp5kFTGl.js} +3 -3
  203. package/server/{review-status-sync-B_GrEke8.js → review-status-sync-Bc0c_u12.js} +1 -1
  204. package/server/{review-status-sync-D3A9KX95.js → review-status-sync-CEFty1pW.js} +9 -5
  205. package/server/{review-verdict-feedback-4WZ5ZdbC.js → review-verdict-feedback-BOKRLLDf.js} +6 -6
  206. package/server/{review-verdict-feedback-Zo0r_z4m.js → review-verdict-feedback-BnGtT0vN.js} +1 -1
  207. package/server/{rollup-Bmhn80tB.js → rollup-BVqFuiS9.js} +1 -1
  208. package/server/{rollup-BrUIKMv_.js → rollup-C22QDVxh.js} +8 -8
  209. package/server/{scanner-BIGumel_.js → scanner-BLCnuXqY.js} +7 -7
  210. package/server/{sequence-io-DA0akEQN.js → sequence-io-BozlUb6f.js} +4 -4
  211. package/server/{sequencer-agent-DeflKafB.js → sequencer-agent-BEDEHfd2.js} +5 -5
  212. package/server/server.js +251 -160
  213. package/server/{service-V0sUK-OR.js → service-C8jKYZ0w.js} +42 -42
  214. package/server/{session-fork-Yx3UcAQf.js → session-fork-BDGksK4e.js} +2 -2
  215. package/server/{settings-CFEeQRj2.js → settings-CSLhh6qR.js} +2 -2
  216. package/server/settings-CSaXtkoA.js +2 -0
  217. package/server/{settings-CxVate0h.js → settings-DrRQCren.js} +3 -3
  218. package/server/{shadow-engineering-BRxnVSDk.js → shadow-engineering-BMcBN-Of.js} +2 -2
  219. package/server/{shadow-state-BiMwdyl1.js → shadow-state-B4ayC7nx.js} +2 -2
  220. package/server/{shadow-state-1aS8FijU.js → shadow-state-CHqWHD3T.js} +1 -1
  221. package/server/{ship-log-CMWH3H5-.js → ship-log-CDVmOlZP.js} +1 -1
  222. package/server/{smart-compaction-Bw1K_Sbl.js → smart-compaction-C-F5sP9P.js} +7 -7
  223. package/server/{smart-compaction-xblMyVpT.js → smart-compaction-V9DBrGcr.js} +1 -1
  224. package/server/{spawn-planning-session-CzDFSKAQ.js → spawn-planning-session-Bz4_JES2.js} +1 -1
  225. package/server/{spawn-planning-session-DxLxcM7m.js → spawn-planning-session-dSpOU0lP.js} +15 -15
  226. package/server/{specialist-completion-BiEXUHfD.js → specialist-completion-Coz3eTSr.js} +1 -1
  227. package/server/{specialist-context-BfkTA81h.js → specialist-context-fmb03vXQ.js} +5 -5
  228. package/server/{specialist-handoff-logger-BiKuLtNm.js → specialist-handoff-logger-B9HK_lRu.js} +2 -2
  229. package/server/{specialist-logs-CFJjGsLC.js → specialist-logs-B24R2B9Y.js} +3 -3
  230. package/server/{specialists-BLIreoE7.js → specialists-B6f5-5nG.js} +1 -1
  231. package/server/{specialists-DjHbwQ_p.js → specialists-BGNZ0_ZW.js} +18 -18
  232. package/server/{specialists-B4byf18k.js → specialists-CL7E8yUg.js} +75 -75
  233. package/server/{specialists-DdvpFNt1.js → specialists-Chvvwf5z.js} +1 -1
  234. package/server/specs-oaaYaA5c.js +3 -0
  235. package/server/{src-CALBEUMX.js → src-BVxZuHMg.js} +3 -3
  236. package/server/{src-mK_M_ZIj.js → src-D-VXCC9C.js} +5 -5
  237. package/server/{src-fgbU-jJ-.js → src-DGAEtABV.js} +13 -2
  238. package/server/{stack-health-BFM8YlHw.js → stack-health-BKbTTOT2.js} +1 -1
  239. package/server/{stack-health-Qd7rPiVe.js → stack-health-C-le5erA.js} +2 -2
  240. package/server/{state-home-C2Bicw9N.js → state-home-CoyWsECg.js} +6 -6
  241. package/server/{summary-fork-EWWBvzgE.js → summary-fork-BF_0vxrq.js} +2 -2
  242. package/server/{summary-fork-DezPkJSm.js → summary-fork-BlE30Q-I.js} +8 -8
  243. package/server/supervisor-03Tj_Wra.js +2 -0
  244. package/server/{supervisor-D5GC5jUM.js → supervisor-BSeML_p0.js} +2 -2
  245. package/server/{swarm-readiness-Cf9mommA.js → swarm-readiness-CQ4sjrXc.js} +3 -3
  246. package/server/{system-prerequisites-BsI9hxh9.js → system-prerequisites-DnmLYOnU.js} +13 -1
  247. package/server/{teardown-workspace-CWz1pbEK.js → teardown-workspace-CpcjDrZ4.js} +12 -12
  248. package/server/{test-agent-queue-TiVXe3ZT.js → test-agent-queue-Bq298zZl.js} +5 -5
  249. package/server/{tldr-daemon-C_1frSDj.js → tldr-daemon-CaSUXd9r.js} +2 -2
  250. package/server/{tldr-daemon-Big5IZ_M.js → tldr-daemon-Rn1Zue0P.js} +1 -1
  251. package/server/{tmux-D57f-XNv.js → tmux-BVc-NeKM.js} +2 -2
  252. package/server/{tmux-DClqWwb8.js → tmux-CbcrkUx5.js} +1 -1
  253. package/server/{token-_qujO3JZ.js → token-D2OC_9ms.js} +1 -1
  254. package/server/{tracker-config-BmdJU_w6.js → tracker-config-C1Y_2CIo.js} +2 -2
  255. package/server/{tracker-config-B_Ubts1Z.js → tracker-config-EsBoOWEy.js} +1 -1
  256. package/server/{tracker-utils-Bg-Sevcv.js → tracker-utils-DSb9cfrF.js} +1 -1
  257. package/server/{tracker-utils-CWFt6jjV.js → tracker-utils-lph9C3Pw.js} +2 -2
  258. package/server/{tunnel-UBf2vyAL.js → tunnel-BFBCeo97.js} +2 -2
  259. package/server/{tunnel-hOBNQbmF.js → tunnel-DDe-ATFF.js} +1 -1
  260. package/server/{uat-train-DGkIkLxu.js → uat-train-8T24rPzc.js} +1 -1
  261. package/server/{uat-train-qNanv5hN.js → uat-train-DtKHHy1U.js} +23 -23
  262. package/server/{validation-B0QaLIHP.js → validation-COOXwNXU.js} +1 -1
  263. package/server/{validation-C4wegCvH.js → validation-lyudzPvD.js} +3 -3
  264. package/server/{verification-runner-CntudBes.js → verification-runner-DO0nYTJx.js} +11 -11
  265. package/server/{verification-runner-DdleMNLq.js → verification-runner-Dd1FX8Qk.js} +1 -1
  266. package/server/{vtt-parser-CKc-smWM.js → vtt-parser-C57tEF7-.js} +1 -1
  267. package/server/{work-agent-prompt-CG5jFV9A.js → work-agent-prompt-B2F3ZwKm.js} +11 -11
  268. package/server/workflows-B4fIN8VP.js +2 -0
  269. package/server/{workflows-BK2xs_a8.js → workflows-Clz_AFwR.js} +13 -13
  270. package/server/{workspace-CLrSIRCx.js → workspace-CY_2-Ddv.js} +3 -3
  271. package/server/{workspace-C9lC5o3E.js → workspace-D0rCFemz.js} +1 -1
  272. package/server/{workspace-manager-Cb2a7bg9.js → workspace-manager-BIfpzqdU.js} +1 -1
  273. package/server/{workspace-manager-BJhW2sky.js → workspace-manager-D6NgGkiF.js} +10 -10
  274. package/server/{workspace-metadata-QQmo_Z0l.js → workspace-metadata-C8yn8kAH.js} +2 -2
  275. package/server/{workspace-metadata-CTRnr323.js → workspace-metadata-DfgR40YU.js} +1 -1
  276. package/server/{workspaces-Ca4zZs12.js → workspaces-DOeHyKmA.js} +104 -92
  277. package/sync-sources/hooks/ask-user-question-hook +87 -0
  278. package/sync-sources/hooks/auto-approve-hook +96 -0
  279. package/sync-sources/hooks/codex-notify-hook +62 -0
  280. package/sync-sources/hooks/gh-issue-trailer-hook +4 -0
  281. package/sync-sources/hooks/gh-issue-trailer-hook.d.ts +7 -0
  282. package/sync-sources/hooks/gh-issue-trailer-hook.d.ts.map +1 -0
  283. package/sync-sources/hooks/gh-issue-trailer-hook.js +239 -0
  284. package/sync-sources/hooks/gh-issue-trailer-hook.js.map +1 -0
  285. package/sync-sources/hooks/gh-issue-trailer-hook.ts +296 -0
  286. package/sync-sources/hooks/git-hooks/post-checkout +109 -0
  287. package/sync-sources/hooks/heartbeat-hook +113 -0
  288. package/sync-sources/hooks/notification-hook +70 -0
  289. package/sync-sources/hooks/notify-complete +79 -0
  290. package/sync-sources/hooks/pan-hook-lib.sh +153 -0
  291. package/sync-sources/hooks/permission-event-hook +24 -0
  292. package/sync-sources/hooks/post-compact-hook +25 -0
  293. package/sync-sources/hooks/pre-compact-hook +26 -0
  294. package/sync-sources/hooks/pre-tool-hook +35 -0
  295. package/sync-sources/hooks/record-cost-event.d.ts +1 -0
  296. package/sync-sources/hooks/record-cost-event.js +31858 -0
  297. package/sync-sources/hooks/record-cost-event.js.map +1 -0
  298. package/sync-sources/hooks/record-cost-event.ts +267 -0
  299. package/sync-sources/hooks/rtk-bash-filter +152 -0
  300. package/sync-sources/hooks/session-start-hook +80 -0
  301. package/sync-sources/hooks/specialist-stop-hook +106 -0
  302. package/sync-sources/hooks/statusline.sh +169 -0
  303. package/sync-sources/hooks/stop-hook +217 -0
  304. package/sync-sources/hooks/tldr-post-edit +72 -0
  305. package/sync-sources/hooks/tldr-read-enforcer +340 -0
  306. package/sync-sources/hooks/tmux-send-keys-guard +87 -0
  307. package/sync-sources/hooks/tsdown.config.ts +14 -0
  308. package/sync-sources/hooks/user-prompt-submit-hook +57 -0
  309. package/sync-sources/hooks/work-agent-stop-hook +424 -0
  310. package/server/cli-Ch_BWJB2.js +0 -3
  311. package/server/deacon-swarm-CSWGRfzr.js +0 -2
  312. package/server/dist-BUplB3Od.js +0 -3
  313. package/server/forge-IgLR0Ist.js +0 -2
  314. package/server/inspect-agent-CYoWAeeB.js +0 -2
  315. package/server/merge-agent-CfohxFWM.js +0 -3
  316. package/server/merge-ops-Czke6UAp.js +0 -2
  317. package/server/public/assets/mermaid-GHXKKRXX-CZOsRYoT.js +0 -1
  318. package/server/rally-Ba9QoNYc.js +0 -3
  319. package/server/resume-CmxF3Kjz.js +0 -3
  320. package/server/settings-DEhYpW0k.js +0 -2
  321. package/server/specs-CVH1kvz3.js +0 -3
  322. package/server/supervisor-DQMK2e3I.js +0 -2
  323. 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 { 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,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 +0,0 @@
1
- import{C as e}from"./chunk-BO2N2NFS-aNlsGDCu.js";export{e as Mermaid};
@@ -1,3 +0,0 @@
1
- import { n as init_rally, t as RallyTracker } from "./rally-8aQlLLVj.js";
2
- init_rally();
3
- export { RallyTracker };
@@ -1,3 +0,0 @@
1
- import { E as resumeAgent, T as init_resume } from "./agents-B5LfpLPv.js";
2
- init_resume();
3
- export { resumeAgent };
@@ -1,2 +0,0 @@
1
- import { t as getAgentCommandSync } from "./settings-CFEeQRj2.js";
2
- export { getAgentCommandSync };
@@ -1,3 +0,0 @@
1
- import { C as findSpecByIssue, T as init_specs } from "./io-A7ZuOBkz.js";
2
- init_specs();
3
- export { findSpecByIssue };
@@ -1,2 +0,0 @@
1
- import { n as getSupervisorUrlSync } from "./supervisor-D5GC5jUM.js";
2
- export { getSupervisorUrlSync };
@@ -1,2 +0,0 @@
1
- import { a as deepWipe, i as closeOut } from "./workflows-BK2xs_a8.js";
2
- export { closeOut, deepWipe };