@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,267 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Record cost events from Claude Code transcript data
4
+ * Called by heartbeat-hook with PostToolUse JSON on stdin
5
+ *
6
+ * Claude Code's PostToolUse events do NOT include token usage.
7
+ * Instead, we read usage from the transcript JSONL file
8
+ * (available via the transcript_path field in the event).
9
+ *
10
+ * Uses byte-offset tracking to efficiently process only new
11
+ * transcript entries on each invocation.
12
+ */
13
+
14
+ import { readFileSync, existsSync, writeFileSync, mkdirSync, openSync, readSync, fstatSync, closeSync } from 'fs';
15
+ import { execFileSync } from 'child_process';
16
+ import { join } from 'path';
17
+ import { homedir } from 'os';
18
+ import { calculateCostSync, getPricingSync, AIProvider } from '../../src/lib/cost.js';
19
+ import { appendCostEventSync } from '../../src/lib/costs/events.js';
20
+ import { captureTldrMetricsSync, type TldrSessionMetrics } from '../../src/lib/tldr-daemon.js';
21
+
22
+ // ============== Types ==============
23
+
24
+ interface PostToolUseEvent {
25
+ session_id?: string;
26
+ transcript_path?: string;
27
+ tool_name?: string;
28
+ tool_use_id?: string;
29
+ }
30
+
31
+ interface TranscriptUsage {
32
+ input_tokens?: number;
33
+ output_tokens?: number;
34
+ cache_read_input_tokens?: number;
35
+ cache_creation_input_tokens?: number;
36
+ }
37
+
38
+ interface TranscriptEntry {
39
+ type?: string;
40
+ message?: {
41
+ model?: string;
42
+ usage?: TranscriptUsage;
43
+ };
44
+ requestId?: string;
45
+ }
46
+
47
+ // ============== Main ==============
48
+
49
+ // Read PostToolUse event from stdin
50
+ let event: PostToolUseEvent;
51
+ try {
52
+ const input = readFileSync(0, 'utf-8');
53
+ event = JSON.parse(input) as PostToolUseEvent;
54
+ } catch {
55
+ process.exit(0);
56
+ }
57
+
58
+ // Need transcript path to read usage data
59
+ const transcriptPath = event?.transcript_path;
60
+ if (!transcriptPath || !existsSync(transcriptPath)) {
61
+ process.exit(0);
62
+ }
63
+
64
+ const sessionId = event?.session_id || 'unknown';
65
+
66
+ // State tracking: byte offset per session to avoid re-processing
67
+ const stateDir = join(process.env.HOME || homedir(), '.overdeck', 'costs', 'state');
68
+ mkdirSync(stateDir, { recursive: true });
69
+ const stateFile = join(stateDir, `${sessionId}.offset`);
70
+
71
+ let lastOffset = 0;
72
+ if (existsSync(stateFile)) {
73
+ try {
74
+ lastOffset = parseInt(readFileSync(stateFile, 'utf-8').trim(), 10) || 0;
75
+ } catch { /* start from 0 */ }
76
+ }
77
+
78
+ // Load persisted seen requestIds to guard against crash-before-write duplicates (PAN-238)
79
+ // Claude Code's transcript can have multiple entries per requestId — we emit exactly one event per requestId.
80
+ const seenFile = join(stateDir, `${sessionId}.seen`);
81
+ const seenRequestIds = new Set<string>();
82
+ if (existsSync(seenFile)) {
83
+ try {
84
+ const seenContent = readFileSync(seenFile, 'utf-8').trim();
85
+ if (seenContent) {
86
+ for (const id of seenContent.split('\n')) {
87
+ if (id.trim()) seenRequestIds.add(id.trim());
88
+ }
89
+ }
90
+ } catch { /* start fresh */ }
91
+ }
92
+
93
+ // Read only NEW content from the transcript (efficient for large files)
94
+ let fd: number;
95
+ try {
96
+ fd = openSync(transcriptPath, 'r');
97
+ } catch {
98
+ process.exit(0);
99
+ }
100
+
101
+ const stat = fstatSync(fd);
102
+ if (stat.size <= lastOffset) {
103
+ closeSync(fd);
104
+ // Save current size even if no new content (handles file truncation)
105
+ writeFileSync(stateFile, String(stat.size), 'utf-8');
106
+ process.exit(0);
107
+ }
108
+
109
+ const bytesToRead = stat.size - lastOffset;
110
+ const buffer = Buffer.alloc(bytesToRead);
111
+ readSync(fd, buffer, 0, bytesToRead, lastOffset);
112
+ closeSync(fd);
113
+
114
+ const newContent = buffer.toString('utf-8');
115
+ const lines = newContent.split('\n');
116
+
117
+ // Get agent/issue context from environment, with git branch fallback
118
+ const agentId: string = process.env.OVERDECK_AGENT_ID || 'unattributed';
119
+ let issueId: string = process.env.OVERDECK_ISSUE_ID || '';
120
+ const sessionType: string = process.env.OVERDECK_SESSION_TYPE || 'implementation';
121
+ // Caveman A/B test variant — set by agent launcher when agents.caveman.ab_test is active (PAN-611)
122
+ const cavemanVariant = process.env.OVERDECK_CAVEMAN_VARIANT as 'enabled' | 'disabled' | 'off' | undefined;
123
+
124
+ // Infer issue ID from git branch if not set (covers ad-hoc Claude sessions)
125
+ if (!issueId || issueId === 'UNKNOWN') {
126
+ try {
127
+ const branch = execFileSync('git', ['branch', '--show-current'], {
128
+ encoding: 'utf-8',
129
+ timeout: 2000,
130
+ stdio: ['pipe', 'pipe', 'pipe'],
131
+ }).trim();
132
+ const branchMatch = branch.match(/(pan|min|aud|krux|cli)[-](\d+)/i);
133
+ if (branchMatch) {
134
+ issueId = `${branchMatch[1].toUpperCase()}-${branchMatch[2]}`;
135
+ }
136
+ } catch {
137
+ // Git not available or not in a repo — that's fine
138
+ }
139
+ }
140
+
141
+ // Final fallback
142
+ if (!issueId) {
143
+ issueId = 'UNKNOWN';
144
+ }
145
+
146
+ // Capture TLDR metrics for this batch (PAN-236)
147
+ // Find workspace root via git (same process already used for branch detection above)
148
+ let tldrMetrics: TldrSessionMetrics | null = null;
149
+ try {
150
+ const workspaceRoot = execFileSync('git', ['rev-parse', '--show-toplevel'], {
151
+ encoding: 'utf-8',
152
+ timeout: 2000,
153
+ stdio: ['pipe', 'pipe', 'pipe'],
154
+ }).trim();
155
+ if (workspaceRoot) {
156
+ tldrMetrics = captureTldrMetricsSync(workspaceRoot);
157
+ }
158
+ } catch { /* git not available or no workspace — skip TLDR metrics */ }
159
+
160
+ // Process new transcript lines looking for assistant messages with usage
161
+ let tldrAttachedToFirstEvent = false;
162
+ for (const line of lines) {
163
+ if (!line.trim()) continue;
164
+
165
+ try {
166
+ const entry = JSON.parse(line) as TranscriptEntry;
167
+
168
+ // Only process assistant messages that have usage data
169
+ if (entry.type !== 'assistant' || !entry.message?.usage) {
170
+ continue;
171
+ }
172
+
173
+ // Skip already-seen requestIds — transcript has multiple entries per API request (PAN-238)
174
+ const requestId = entry.requestId;
175
+ if (requestId) {
176
+ if (seenRequestIds.has(requestId)) {
177
+ continue; // Duplicate entry for this request — already emitted a cost event
178
+ }
179
+ seenRequestIds.add(requestId);
180
+ }
181
+
182
+ const usage = entry.message.usage;
183
+ const model: string = entry.message.model || 'claude-sonnet-4';
184
+
185
+ const inputTokens = usage.input_tokens || 0;
186
+ const outputTokens = usage.output_tokens || 0;
187
+ const cacheReadTokens = usage.cache_read_input_tokens || 0;
188
+ const cacheWriteTokens = usage.cache_creation_input_tokens || 0;
189
+
190
+ // Skip entries with zero tokens
191
+ if (inputTokens === 0 && outputTokens === 0 && cacheReadTokens === 0 && cacheWriteTokens === 0) {
192
+ continue;
193
+ }
194
+
195
+ // Determine provider from model name
196
+ let provider: AIProvider = 'anthropic';
197
+ if (model.includes('gpt')) {
198
+ provider = 'openai';
199
+ } else if (model.includes('gemini')) {
200
+ provider = 'google';
201
+ } else if (model.includes('kimi') || model.toLowerCase().startsWith('minimax')) {
202
+ provider = 'custom';
203
+ }
204
+
205
+ // Get pricing and calculate cost (Sync variants — the Effect-returning
206
+ // getPricing/calculateCost are lazy and silently broke recording, PAN-1570)
207
+ const pricing = getPricingSync(provider, model);
208
+ if (!pricing) continue;
209
+
210
+ const cost = calculateCostSync({
211
+ inputTokens,
212
+ outputTokens,
213
+ cacheReadTokens,
214
+ cacheWriteTokens,
215
+ cacheTTL: '5m',
216
+ }, pricing);
217
+
218
+ // Attach TLDR metrics to the first event in each batch (delta since last batch)
219
+ const tldrFields = tldrMetrics && !tldrAttachedToFirstEvent && tldrMetrics.interceptions + tldrMetrics.bypasses > 0
220
+ ? {
221
+ tldrInterceptions: tldrMetrics.interceptions,
222
+ tldrBypasses: tldrMetrics.bypasses,
223
+ tldrTokensSaved: tldrMetrics.estimatedTokensSaved,
224
+ tldrBypassReasons: Object.keys(tldrMetrics.bypassReasons).length > 0
225
+ ? tldrMetrics.bypassReasons
226
+ : undefined,
227
+ }
228
+ : {};
229
+
230
+ if (tldrMetrics && !tldrAttachedToFirstEvent) {
231
+ tldrAttachedToFirstEvent = true;
232
+ }
233
+
234
+ // Record the cost event.
235
+ // NOTE: appendCostEventSync (not the Effect-returning appendCostEvent) — the
236
+ // latter is a lazy Effect that does nothing unless run, which silently dropped
237
+ // every cost event after the PAN-1249 Effect migration (PAN-1570).
238
+ appendCostEventSync({
239
+ ts: new Date().toISOString(),
240
+ type: 'cost',
241
+ agentId,
242
+ issueId,
243
+ sessionType,
244
+ provider,
245
+ model,
246
+ input: inputTokens,
247
+ output: outputTokens,
248
+ cacheRead: cacheReadTokens,
249
+ cacheWrite: cacheWriteTokens,
250
+ cost,
251
+ ...(requestId ? { requestId } : {}),
252
+ sessionId,
253
+ ...tldrFields,
254
+ ...(cavemanVariant ? { cavemanVariant } : {}),
255
+ });
256
+ } catch {
257
+ // Skip malformed lines silently
258
+ }
259
+ }
260
+
261
+ // Save new byte offset and seen requestIds for next invocation
262
+ writeFileSync(stateFile, String(stat.size), 'utf-8');
263
+ if (seenRequestIds.size > 0) {
264
+ writeFileSync(seenFile, Array.from(seenRequestIds).join('\n') + '\n', 'utf-8');
265
+ }
266
+
267
+ process.exit(0);
@@ -0,0 +1,152 @@
1
+ #!/bin/bash
2
+ # ~/.overdeck/bin/rtk-bash-filter
3
+ # PreToolUse hook on Bash — delegates command rewriting to rtk-ai/rtk so
4
+ # expensive command output can be filtered before Claude Code runs the command.
5
+ #
6
+ # Bypasses (allows normal Bash execution):
7
+ # - Non-Bash tool_name
8
+ # - jq unavailable or malformed PreToolUse JSON
9
+ # - OVERDECK_RTK_ENABLED is unset/false and agents.rtk.enabled is absent/false
10
+ # - ~/.overdeck/bin/rtk is missing or not executable
11
+ # - rtk exits non-zero, emits no output, or emits an invalid PreToolUse response
12
+ # - rtk chooses not to rewrite a command, including commands whose output it
13
+ # expects to be too small to benefit from filtering
14
+ #
15
+ # Don't use set -e — hooks must never break Claude Code execution.
16
+ set +e
17
+
18
+ rtk_truthy() {
19
+ case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in
20
+ 1|true|yes|on|enabled) return 0 ;;
21
+ *) return 1 ;;
22
+ esac
23
+ }
24
+
25
+ rtk_project_root() {
26
+ local current
27
+ current="$PWD"
28
+ while [ "$current" != "/" ]; do
29
+ if [ -e "$current/.git" ]; then
30
+ printf '%s\n' "$current"
31
+ return 0
32
+ fi
33
+ current=$(dirname "$current")
34
+ done
35
+ }
36
+
37
+ rtk_read_config_enabled() {
38
+ local config_path
39
+ config_path="$1"
40
+ [ -z "$config_path" ] && return 0
41
+ [ ! -f "$config_path" ] && return 0
42
+
43
+ awk '
44
+ function trim(s) { sub(/^[ \t\r\n]+/, "", s); sub(/[ \t\r\n]+$/, "", s); return s }
45
+ BEGIN { in_agents = 0; in_rtk = 0; agents_indent = -1; rtk_indent = -1 }
46
+ {
47
+ line = $0
48
+ sub(/#.*/, "", line)
49
+ if (line ~ /^[[:space:]]*$/) next
50
+ match(line, /^[ ]*/)
51
+ indent = RLENGTH
52
+ key = line
53
+ sub(/^[[:space:]]*/, "", key)
54
+
55
+ if (key ~ /^agents:[[:space:]]*$/) {
56
+ in_agents = 1
57
+ in_rtk = 0
58
+ agents_indent = indent
59
+ next
60
+ }
61
+ if (in_agents && indent <= agents_indent) {
62
+ in_agents = 0
63
+ in_rtk = 0
64
+ }
65
+ if (in_agents && key ~ /^rtk:[[:space:]]*$/) {
66
+ in_rtk = 1
67
+ rtk_indent = indent
68
+ next
69
+ }
70
+ if (in_rtk && indent <= rtk_indent) {
71
+ in_rtk = 0
72
+ }
73
+ if (in_rtk && key ~ /^enabled:[[:space:]]*/) {
74
+ sub(/^enabled:[[:space:]]*/, "", key)
75
+ gsub(/"/, "", key)
76
+ gsub(/\047/, "", key)
77
+ print trim(key)
78
+ exit
79
+ }
80
+ }
81
+ ' "$config_path" 2>/dev/null
82
+ }
83
+
84
+ rtk_config_enabled_value() {
85
+ local config_path project_root value result
86
+
87
+ if [ -n "${OVERDECK_CONFIG:-}" ]; then
88
+ value=$(rtk_read_config_enabled "$OVERDECK_CONFIG")
89
+ else
90
+ value=$(rtk_read_config_enabled "$HOME/.overdeck/config.yaml")
91
+ fi
92
+ [ -n "$value" ] && result="$value"
93
+
94
+ project_root=$(rtk_project_root)
95
+ if [ -n "$project_root" ]; then
96
+ if [ -f "$project_root/.pan.yaml" ]; then
97
+ config_path="$project_root/.pan.yaml"
98
+ elif [ -f "$project_root/.overdeck.yaml" ]; then
99
+ config_path="$project_root/.overdeck.yaml"
100
+ else
101
+ config_path=""
102
+ fi
103
+
104
+ value=$(rtk_read_config_enabled "$config_path")
105
+ [ -n "$value" ] && result="$value"
106
+ fi
107
+
108
+ printf '%s\n' "$result"
109
+ }
110
+
111
+ RTK_BIN="$HOME/.overdeck/bin/rtk"
112
+
113
+ if [ -n "${OVERDECK_RTK_ENABLED+x}" ]; then
114
+ if ! rtk_truthy "$OVERDECK_RTK_ENABLED"; then
115
+ exit 0
116
+ fi
117
+ else
118
+ CONFIG_VALUE=$(rtk_config_enabled_value)
119
+ if ! rtk_truthy "$CONFIG_VALUE"; then
120
+ exit 0
121
+ fi
122
+ fi
123
+
124
+ if [ ! -x "$RTK_BIN" ]; then
125
+ exit 0
126
+ fi
127
+
128
+ if ! command -v jq >/dev/null 2>&1; then
129
+ exit 0
130
+ fi
131
+
132
+ INPUT=$(cat 2>/dev/null || echo '{}')
133
+ TOOL_NAME=$(printf '%s' "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null)
134
+ if [ "$TOOL_NAME" != "Bash" ]; then
135
+ exit 0
136
+ fi
137
+
138
+ RTK_OUTPUT=$(printf '%s' "$INPUT" | "$RTK_BIN" hook claude 2>/dev/null)
139
+ RTK_STATUS=$?
140
+ if [ $RTK_STATUS -ne 0 ] || [ -z "$RTK_OUTPUT" ]; then
141
+ exit 0
142
+ fi
143
+
144
+ if ! printf '%s' "$RTK_OUTPUT" | jq -e '
145
+ .hookSpecificOutput.hookEventName == "PreToolUse"
146
+ and (.hookSpecificOutput.updatedInput.command | type == "string")
147
+ ' >/dev/null 2>&1; then
148
+ exit 0
149
+ fi
150
+
151
+ printf '%s\n' "$RTK_OUTPUT"
152
+ exit 0
@@ -0,0 +1,80 @@
1
+ #!/bin/bash
2
+ # ~/.overdeck/bin/session-start-hook (PAN-800)
3
+ #
4
+ # Fires on Claude Code SessionStart. Emits agent.activity_changed(idle) so the
5
+ # runtime snapshot is current before the first tool fires, and emits
6
+ # agent.model_set when the model is inferable from the payload or env.
7
+ #
8
+ # This hook replaces the waitForReadySignal tmux fallback referenced in
9
+ # PAN-759 — the hook that was supposed to exist from the start but was never
10
+ # registered in ~/.claude/settings.json by the installer.
11
+
12
+ set +e
13
+
14
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
15
+ # shellcheck source=pan-hook-lib.sh
16
+ . "$SCRIPT_DIR/pan-hook-lib.sh" 2>/dev/null || exit 0
17
+
18
+ pan_resolve_agent_id || exit 0
19
+
20
+ INPUT=$(cat 2>/dev/null || echo '{}')
21
+
22
+ CLAUDE_SESSION_ID=""
23
+ MODEL=""
24
+ if command -v jq >/dev/null 2>&1; then
25
+ CLAUDE_SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // ""' 2>/dev/null)
26
+ MODEL=$(echo "$INPUT" | jq -r '.model // .model_name // ""' 2>/dev/null)
27
+ fi
28
+ [ -z "$MODEL" ] && MODEL="${ANTHROPIC_MODEL:-}"
29
+
30
+ TS=$(date -Iseconds)
31
+
32
+ pan_emit_event "$AGENT_ID" "{\"kind\":\"activity\",\"activity\":\"idle\",\"timestamp\":\"$TS\"}"
33
+
34
+ # PAN-1594: write the ready.json readiness signal that waitForReadySignal()
35
+ # consumes. Claude-side counterpart to the Pi extension's handleSessionStart
36
+ # writer (packages/pi-extension/src/index.ts). Closes the PAN-759 gap where the
37
+ # hook emitted the idle event but never wrote the file, which forced
38
+ # waitForReadySignal onto a tmux pane-scrape fallback coupled to permission-mode
39
+ # footer text. clearReadySignal() removes this file before every (re)launch, so
40
+ # its presence means "this session reached the prompt".
41
+ READY_DIR="${OVERDECK_HOME:-$HOME/.overdeck}/agents/$AGENT_ID"
42
+ mkdir -p "$READY_DIR" 2>/dev/null
43
+ if command -v jq >/dev/null 2>&1; then
44
+ jq -n --arg agentId "$AGENT_ID" --arg sid "$CLAUDE_SESSION_ID" --arg ts "$TS" \
45
+ '{ready: true, agentId: $agentId, sessionId: (if $sid == "" then null else $sid end), reason: "session-start", timestamp: $ts}' \
46
+ > "$READY_DIR/ready.json" 2>/dev/null || true
47
+ else
48
+ printf '{"ready":true,"agentId":"%s","sessionId":"%s","reason":"session-start","timestamp":"%s"}\n' \
49
+ "$AGENT_ID" "$CLAUDE_SESSION_ID" "$TS" > "$READY_DIR/ready.json" 2>/dev/null || true
50
+ fi
51
+
52
+ if [ -n "$MODEL" ]; then
53
+ if command -v jq >/dev/null 2>&1; then
54
+ BODY=$(jq -n --arg model "$MODEL" --arg sid "$CLAUDE_SESSION_ID" --arg ts "$TS" \
55
+ 'if $sid == "" then {kind: "model_set", model: $model, timestamp: $ts}
56
+ else {kind: "model_set", model: $model, claudeSessionId: $sid, timestamp: $ts} end')
57
+ elif [ -n "$CLAUDE_SESSION_ID" ]; then
58
+ BODY="{\"kind\":\"model_set\",\"model\":\"$MODEL\",\"claudeSessionId\":\"$CLAUDE_SESSION_ID\",\"timestamp\":\"$TS\"}"
59
+ else
60
+ BODY="{\"kind\":\"model_set\",\"model\":\"$MODEL\",\"timestamp\":\"$TS\"}"
61
+ fi
62
+ pan_emit_event "$AGENT_ID" "$BODY"
63
+ fi
64
+
65
+ INTERNAL_TOKEN="${OVERDECK_INTERNAL_TOKEN:-}"
66
+ if [ -z "$INTERNAL_TOKEN" ]; then
67
+ TOKEN_PATH="${OVERDECK_HOME:-$HOME/.overdeck}/internal-token"
68
+ if [ -f "$TOKEN_PATH" ]; then
69
+ INTERNAL_TOKEN=$(cat "$TOKEN_PATH" 2>/dev/null || true)
70
+ fi
71
+ fi
72
+
73
+ if command -v jq >/dev/null 2>&1; then
74
+ SESSION_BODY=$(printf '%s' "$INPUT" | jq -c --arg agentId "$AGENT_ID" '. + {agentId: $agentId}' 2>/dev/null)
75
+ if [ -n "$SESSION_BODY" ]; then
76
+ curl -s -m 0.5 -o /dev/null -X POST -H 'Content-Type: application/json' -H "x-overdeck-internal-token: $INTERNAL_TOKEN" --data "$SESSION_BODY" "$PAN_DASHBOARD_URL/api/memory/session/start" 2>/dev/null || true
77
+ fi
78
+ fi
79
+
80
+ exit 0
@@ -0,0 +1,106 @@
1
+ #!/bin/bash
2
+ # ~/.overdeck/bin/specialist-stop-hook
3
+ # Called when a specialist agent goes idle - detects completion patterns
4
+ #
5
+ # This hook is chained from stop-hook and only runs for specialist agents.
6
+ # It captures the last 50 lines of terminal output and looks for completion
7
+ # patterns to auto-trigger status updates.
8
+
9
+ # Don't use set -e - we want the hook to be resilient to failures
10
+ # and never break Claude Code execution
11
+
12
+ # Get agent ID from env or tmux session name
13
+ if [ -n "$OVERDECK_AGENT_ID" ]; then
14
+ AGENT_ID="$OVERDECK_AGENT_ID"
15
+ elif [ -n "$TMUX" ]; then
16
+ AGENT_ID=$(tmux display-message -p '#S' 2>/dev/null)
17
+ else
18
+ exit 0 # Not in a tracked session
19
+ fi
20
+
21
+ # Check if this is a specialist agent
22
+ case "$AGENT_ID" in
23
+ specialist-review-agent|specialist-test-agent|specialist-merge-agent)
24
+ ;;
25
+ *)
26
+ exit 0 # Not a specialist, skip
27
+ ;;
28
+ esac
29
+
30
+ # Get the specialist type from agent ID
31
+ SPECIALIST_TYPE="${AGENT_ID#specialist-}"
32
+
33
+ # Capture the last 50 lines of terminal output
34
+ OUTPUT=$(tmux capture-pane -t "$AGENT_ID" -p -S -50 2>/dev/null || echo "")
35
+
36
+ if [ -z "$OUTPUT" ]; then
37
+ exit 0 # No output to analyze
38
+ fi
39
+
40
+ # Define completion patterns for each specialist (case-insensitive grep -E patterns)
41
+ case "$SPECIALIST_TYPE" in
42
+ review-agent)
43
+ # Patterns that indicate review passed
44
+ PASS_PATTERN="[Rr]eview (passed|complete|PASSED|COMPLETE)|LGTM|[Nn]o issues found|[Cc]ode review complete|✓.*[Pp]assed"
45
+ # Patterns that indicate review failed/blocked
46
+ FAIL_PATTERN="[Rr]eview (failed|blocked|FAILED|BLOCKED)|[Ii]ssues found|[Nn]eeds changes|[Bb]locked"
47
+ STATUS_FIELD="reviewStatus"
48
+ ;;
49
+ test-agent)
50
+ # Patterns that indicate tests passed
51
+ PASS_PATTERN="(all )?[Tt]ests? passed|test suite passed|0 failed|✓.*[Pp]assed|Tests PASSED"
52
+ # Patterns that indicate tests failed
53
+ FAIL_PATTERN="[Tt]ests? failed|test failures|[0-9]+ failed|✗.*[Ff]ailed|Tests FAILED"
54
+ STATUS_FIELD="testStatus"
55
+ ;;
56
+ merge-agent)
57
+ # Patterns that indicate merge complete
58
+ PASS_PATTERN="[Mm]erge (complete|successful)|[Pp]ushed to|[Mm]erged to main|[Mm]erged successfully"
59
+ # Patterns that indicate merge failed
60
+ FAIL_PATTERN="[Mm]erge conflict|[Cc]annot merge|[Mm]erge failed"
61
+ STATUS_FIELD="mergeStatus"
62
+ ;;
63
+ *)
64
+ exit 0
65
+ ;;
66
+ esac
67
+
68
+ # Check for completion patterns (look at output)
69
+ STATUS=""
70
+ if echo "$OUTPUT" | grep -qE "$PASS_PATTERN"; then
71
+ STATUS="passed"
72
+ elif echo "$OUTPUT" | grep -qE "$FAIL_PATTERN"; then
73
+ STATUS="failed"
74
+ fi
75
+
76
+ if [ -z "$STATUS" ]; then
77
+ exit 0 # No recognized completion pattern - specialist is just idle
78
+ fi
79
+
80
+ # Get current issue from specialist state file
81
+ STATE_FILE="$HOME/.overdeck/agents/$AGENT_ID/state.json"
82
+ ISSUE_ID=""
83
+
84
+ if [ -f "$STATE_FILE" ] && command -v jq &> /dev/null; then
85
+ ISSUE_ID=$(jq -r '.currentIssue // ""' "$STATE_FILE" 2>/dev/null || echo "")
86
+ fi
87
+
88
+ if [ -z "$ISSUE_ID" ] || [ "$ISSUE_ID" = "null" ]; then
89
+ # No issue ID - cannot report completion
90
+ exit 0
91
+ fi
92
+
93
+ # Report completion to dashboard API (non-blocking background process)
94
+ # Only if dashboard is running
95
+ if curl -s -f --max-time 0.5 "http://localhost:3011/health" > /dev/null 2>&1; then
96
+ curl -s -X POST "http://localhost:3011/api/specialists/$SPECIALIST_TYPE/auto-complete" \
97
+ -H "Content-Type: application/json" \
98
+ -d "{\"issueId\":\"$ISSUE_ID\",\"status\":\"$STATUS\"}" \
99
+ > /dev/null 2>&1 &
100
+
101
+ # Log the completion detection
102
+ echo "[specialist-stop-hook] Detected completion: $SPECIALIST_TYPE -> $ISSUE_ID -> $STATUS" \
103
+ >> "$HOME/.overdeck/logs/hooks.log" 2>/dev/null || true
104
+ fi
105
+
106
+ exit 0