@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.
- package/drizzle/overdeck/0000_overdeck_init.sql +33 -0
- package/package.json +7 -2
- package/server/{acceptance-criteria-1LHgD9vg.js → acceptance-criteria-CfujPRrz.js} +2 -2
- package/server/{advancing-selfheal-BqsLWqEM.js → advancing-selfheal-Bn5QiLtn.js} +4 -4
- package/server/{agent-gc-CUb52n7s.js → agent-gc-Cl9Nm0Zu.js} +3 -3
- package/server/{agent-state-D-moNwhA.js → agent-state-C6Rm6FPR.js} +1 -1
- package/server/{agent-state-service-BzESvLOf.js → agent-state-service-JhFzYCP_.js} +5 -5
- package/server/{agent-state-service-BaZH7sXJ.js → agent-state-service-U8feBf8t.js} +1 -1
- package/server/{agents-C4kZ8a2r.js → agents-CxbuBjID.js} +1 -1
- package/server/{agents-B5LfpLPv.js → agents-DqQa4Dq_.js} +88 -64
- package/server/{archive-planning-oX1pj6nY.js → archive-planning-CPitEZo4.js} +3 -3
- package/server/{archive-planning-BbZe-8IK.js → archive-planning-DmpT1_14.js} +1 -1
- package/server/{artifact-index-jobs-DGr6bxev.js → artifact-index-jobs-sMnNtPhy.js} +2 -2
- package/server/{auto-commit-CGQlb4rV.js → auto-commit-wZ9X7Isd.js} +1 -1
- package/server/{backlog-auto-trigger-BlJHikOm.js → backlog-auto-trigger-Cf9C8fwD.js} +2 -2
- package/server/{bd-process-lock-i3CYMS-B.js → bd-process-lock-D1aJxeYv.js} +2 -2
- package/server/{beads-BNU-fb48.js → beads-CivpXztb.js} +1 -1
- package/server/{beads-DD7fYCl5.js → beads-DRoj6-e1.js} +4 -4
- package/server/{beads-query-e6oku4P5.js → beads-query-tOsAYP5h.js} +2 -2
- package/server/{behavior-CPf0pbOt.js → behavior-D3d2mVyD.js} +3 -3
- package/server/{briefing-freshness-B2FdLwIv.js → briefing-freshness-BL3Q6p7R.js} +4 -4
- package/server/{checkpoint-manager-JryW6MpM.js → checkpoint-manager-DCxjQvP_.js} +2 -2
- package/server/{checkpoint-manager-eFgaMMu4.js → checkpoint-manager-j5URlFY7.js} +1 -1
- package/server/checkpoint-worker.js +1 -1
- package/server/{checkpoints-qvOqvMuC.js → checkpoints-BoX1H2Hf.js} +2 -2
- package/server/{checkpoints-BK17oicz.js → checkpoints-Bu_M_Q9W.js} +1 -1
- package/server/claude-hooks-provision-D-jGXmu1.js +360 -0
- package/server/{claude-permissions-B6bWGh9d.js → claude-permissions-DxIjkOVl.js} +2 -2
- package/server/{claude-settings-overlay-BPdhTPjo.js → claude-settings-overlay-5b9X2S0C.js} +1 -1
- package/server/{claude-settings-overlay-CRyyKKXQ.js → claude-settings-overlay-BPDS6GfE.js} +2 -2
- package/server/cli-CqgiSAU8.js +3 -0
- package/server/{cli-B75AieAM.js → cli-s7bPWy-E.js} +9 -9
- package/server/{cliproxy-CCzwuSNe.js → cliproxy-BituqWtR.js} +2 -2
- package/server/{cliproxy-DOQf66G9.js → cliproxy-D3sHB0sI.js} +1 -1
- package/server/{close-issue-_X3MXJyG.js → close-issue-CrBE7voz.js} +4 -4
- package/server/{closed-issue-reaper-CLR7ClsO.js → closed-issue-reaper-BRQBc7Xa.js} +1 -1
- package/server/{closed-issue-reaper-BsUfBSjM.js → closed-issue-reaper-DX9mYUji.js} +9 -9
- package/server/{codex-CY-QRuU9.js → codex-Bi1ITSOo.js} +1 -1
- package/server/{codex-B4KEpX5V.js → codex-CO0HrK3j.js} +5 -5
- package/server/{compact-beads-cZds2MTr.js → compact-beads-CrA8-k10.js} +1 -1
- package/server/{compact-beads-uEDccC76.js → compact-beads-DUkCUFxA.js} +3 -3
- package/server/{config-DARrpYWA.js → config-B4_d7z7z.js} +1 -1
- package/server/{config-8sjaU6jZ.js → config-DsCxzjXK.js} +2 -2
- package/server/{config-yaml-ClpGgrf6.js → config-yaml-C_djSurJ.js} +2 -2
- package/server/{conflict-gate-Ds9_2yjd.js → conflict-gate-CpOn9KC-.js} +1 -1
- package/server/{conflict-gate-BtB_o-Vi.js → conflict-gate-D47Kl78u.js} +3 -3
- package/server/{context-layers-r2ywnQYA.js → context-layers-BNhUBTkf.js} +3 -3
- package/server/{context-layers-CRCk1QG7.js → context-layers-CHl3Nroz.js} +2 -2
- package/server/{control-settings-D1B3u6HP.js → control-settings-KyYNXZLv.js} +4 -4
- package/server/{conversation-compaction-D86Zo2Ci.js → conversation-compaction-D3aS5PnS.js} +8 -8
- package/server/{conversation-compaction-CZRVk4hg.js → conversation-compaction-D4Wed1BJ.js} +1 -1
- package/server/{conversation-service-CuTVU8dV.js → conversation-service-CFZIjs-M.js} +5 -5
- package/server/{conversation-service-CkL-6MuG.js → conversation-service-DcDB5usR.js} +1 -1
- package/server/{conversations-DfJKBDwB.js → conversations-BSOU5qnu.js} +4 -4
- package/server/{conversations-BmWEluPL.js → conversations-BbDPrz89.js} +1 -1
- package/server/{cost-DAPYN6iA.js → cost-BE_ulOrw.js} +3 -3
- package/server/{cost-CCnqa5xK.js → cost-CaiG63FG.js} +2 -2
- package/server/{cost-sync-BDL10Nwu.js → cost-sync-D6AX8jv-.js} +3 -3
- package/server/{dag-Dv2r5bVD.js → dag-BQFtXOuJ.js} +3 -3
- package/server/{dangerous-git-ops-Dcw7PbYo.js → dangerous-git-ops-04Ba-Qu3.js} +1 -1
- package/server/dashboard-db-worker.js +6 -6
- package/server/{deacon-CM0MxbS8.js → deacon-2EvA9Ci3.js} +97 -97
- package/server/{deacon-DYnZH7kC.js → deacon-Bz-6Wjmn.js} +3 -3
- package/server/deacon-swarm-B8pgK2a7.js +2 -0
- package/server/{deacon-swarm-BstYoz8Q.js → deacon-swarm-DYYOzHRH.js} +10 -10
- package/server/deacon.js +7 -7
- package/server/{devcontainer-renderer-CaYOG9JN.js → devcontainer-renderer-Dx0C7VWJ.js} +2 -2
- package/server/dist-BYSj075e.js +3 -0
- package/server/{dist-BIC8spJ0.js → dist-ya66D9ze.js} +1 -1
- package/server/{docker-DDI1shu3.js → docker-D2TbXDO6.js} +2 -2
- package/server/{ensure-devcontainer-CbSXvN9W.js → ensure-devcontainer-BIShzs3M.js} +1 -1
- package/server/{ensure-devcontainer-DCAg3ksz.js → ensure-devcontainer-BTiMfFp5.js} +3 -3
- package/server/{event-store-DU3HkZlN.js → event-store-C02Gprug.js} +1 -1
- package/server/{event-store-DCMqyI07.js → event-store-C71x6h0i.js} +3 -3
- package/server/{events-BfiosVAn.js → events-BFDuPV6n.js} +3 -3
- package/server/{events-DLRxpSuV.js → events-D2gP2-Yv.js} +1 -1
- package/server/{factory-BMtWV9iv.js → factory-ByfbrCab.js} +4 -4
- package/server/{feature-registry-population-DA7bO6Zn.js → feature-registry-population-CSH66UO8.js} +4 -4
- package/server/{feature-registry-storage-nAY1fbBt.js → feature-registry-storage-DW7dUefc.js} +2 -2
- package/server/{features-DMu7eGmU.js → features-x_aLR7U9.js} +2 -2
- package/server/{feedback-target-DHqcw3cN.js → feedback-target-BFo9fScH.js} +6 -6
- package/server/{feedback-target-B2SEai8-.js → feedback-target-C4VMPTZu.js} +1 -1
- package/server/{feedback-writer-qvm7UON7.js → feedback-writer-B9ZqnnX3.js} +4 -4
- package/server/{feedback-writer-DMBdS_jL.js → feedback-writer-DCyd75yJ.js} +1 -1
- package/server/{flywheel-Dfpx4bIV.js → flywheel-D9NKvWqb.js} +11 -11
- package/server/{flywheel-k4FPtCQ_.js → flywheel-DB48X7Nn.js} +1 -1
- package/server/{flywheel-D2LdPSic.js → flywheel-DwQCoZQG.js} +13 -13
- package/server/{flywheel-merge-order-CB4lbXeJ.js → flywheel-merge-order-DrjmFXg4.js} +6 -6
- package/server/{flywheel-merge-order-CttTazRY.js → flywheel-merge-order-f1bi5XIf.js} +1 -1
- package/server/{forge-CoPFXFyl.js → forge-C-SoKy8U.js} +2 -2
- package/server/forge-CUCYK7h_.js +2 -0
- package/server/{from-B0YoJl9-.js → from-fu7ZumnY.js} +1 -1
- package/server/{fts-db-DAHW1yA_.js → fts-db-CL-YzSRG.js} +2 -2
- package/server/{fts-operations-DDXDBi0d.js → fts-operations-Bylu5NjM.js} +2 -2
- package/server/{git-utils-B90Zjzfl.js → git-utils-C8koBs8j.js} +2 -2
- package/server/{git-utils-DbfC0zls.js → git-utils-Ym380hJZ.js} +1 -1
- package/server/{github-app-C7lftMNj.js → github-app-DIr70YLg.js} +1 -1
- package/server/{github-app-BecAnXRX.js → github-app-DhycHVLF.js} +2 -2
- package/server/{github-client-D21rCIXk.js → github-client-7gkcXcBS.js} +2 -2
- package/server/{github-client-BwtKZtM0.js → github-client-Ji9lUTNF.js} +1 -1
- package/server/{github-pr-lookup-CzVWuysl.js → github-pr-lookup-rt7T9FwA.js} +2 -2
- package/server/{harness-resolve-SkRJm4a7.js → harness-resolve-CvGXUnAF.js} +3 -3
- package/server/{health-events-BT0aAfeA.js → health-events-D4E1DLN-.js} +2 -2
- package/server/{health-events-DA_JLpgZ.js → health-events-DDfkoO5a.js} +1 -1
- package/server/{hooks-DxEn2BoY.js → hooks-D_6pAbuJ.js} +2 -2
- package/server/{hooks-BQxRXtRb.js → hooks-DvdnCVv6.js} +1 -1
- package/server/{idle-stack-reaper-C7fJL8jH.js → idle-stack-reaper-DNbV9-fj.js} +1 -1
- package/server/{idle-stack-reaper-DGy7tvC9.js → idle-stack-reaper-cDRXDpgE.js} +2 -2
- package/server/{infra-DE3C4PMr.js → infra-Clew3DpF.js} +50 -3
- package/server/{injection-Dt22tGvS.js → injection-QCIHOpk6.js} +1 -1
- package/server/{injection-Cc4Qt8LZ.js → injection-ql0Nddcn.js} +7 -7
- package/server/inspect-agent-D8UBDgfR.js +2 -0
- package/server/{inspect-agent-DOaCDkCF.js → inspect-agent-DY18KEx4.js} +9 -9
- package/server/{internal-token-B_1YLWLI.js → internal-token-BeXjPLKy.js} +2 -2
- package/server/{internal-token-nobT6FhA.js → internal-token-C90jBp-y.js} +1 -1
- package/server/{io-A7ZuOBkz.js → io-CbAFXQge.js} +2 -2
- package/server/{issue-closed-Da3DeomA.js → issue-closed-BYC2TCk-.js} +4 -4
- package/server/{issue-lifecycle-543pQX9D.js → issue-lifecycle-BoJa6qIt.js} +21 -21
- package/server/{issue-lifecycle-Bd9XBJAQ.js → issue-lifecycle-CLHbj8RS.js} +1 -1
- package/server/{issue-service-singleton-BC2JLZi7.js → issue-service-singleton-3g_CCY-1.js} +1 -1
- package/server/{issue-service-singleton-Brc3t0SV.js → issue-service-singleton-BS9NENuR.js} +8 -8
- package/server/{issues-D3kt9UWE.js → issues-BPcqPqfV.js} +2 -2
- package/server/{label-cleanup-w9X_T3AQ.js → label-cleanup-CwiCSZrb.js} +2 -2
- package/server/{layers-Cwe1J-9o.js → layers-OHHLphl0.js} +2 -2
- package/server/{lifecycle-f1GbDK33.js → lifecycle-B8IdvUbt.js} +6 -6
- package/server/{lifecycle-io-D56q8zlO.js → lifecycle-io-BMCH1Bxg.js} +1 -1
- package/server/{lifecycle-io-Bqvj0m3i.js → lifecycle-io-C73m5e6R.js} +4 -4
- package/server/{linear-client-Bh4T4S-c.js → linear-client-BMxgycoy.js} +1 -1
- package/server/{linear-client-CfJMTAYd.js → linear-client-CgQlM4aT.js} +2 -2
- package/server/memory-fts-worker.js +1 -1
- package/server/{merge-ZrXFM3jv.js → merge-B7Oi-g6k.js} +3 -3
- package/server/{merge-DRMPa8CQ.js → merge-BRkVaIx-.js} +1 -1
- package/server/merge-agent-Bwm34MZ5.js +3 -0
- package/server/{merge-agent-CHHs5S_0.js → merge-agent-DNFFsiEm.js} +61 -26
- package/server/{merge-batch-BwhGdlh4.js → merge-batch-BpYXUaqJ.js} +1 -1
- package/server/{merge-blockers-BMhDpMl_.js → merge-blockers-DIOZmqdK.js} +2 -2
- package/server/merge-ops-B7m-hBEZ.js +2 -0
- package/server/{merge-rebase-R7MfqpiE.js → merge-rebase-C8WH39MB.js} +2 -2
- package/server/{merge-set-B3Breacq.js → merge-set-CsEE2CyQ.js} +9 -5
- package/server/{merge-set-D-iXNP0I.js → merge-set-DOsBTBQc.js} +1 -1
- package/server/{merge-sync-DHWbGtjR.js → merge-sync-C2B322Ot.js} +2 -2
- package/server/{merge-sync-bOOtfeXR.js → merge-sync-CcLM2vwW.js} +1 -1
- package/server/{merge-train-98ptZrPT.js → merge-train-BIm7-7cy.js} +3 -3
- package/server/{merge-train-deps-B5FWJTE2.js → merge-train-deps-DG1oQ2DT.js} +4 -4
- package/server/{merge-verification-BGiuiXAK.js → merge-verification-BAbjxEd5.js} +4 -4
- package/server/{multipart-parser-D7mzNNDm.js → multipart-parser-jKtKAXtl.js} +2 -2
- package/server/node_modules/.package-lock.json +1 -1
- package/server/{orphan-proposed-reconciler-CSuxivr9.js → orphan-proposed-reconciler-BqVGaOIj.js} +1 -1
- package/server/{orphan-proposed-reconciler-BSGCNJ6X.js → orphan-proposed-reconciler-zHrwJ3xr.js} +9 -9
- package/server/package-lock.json +2 -2
- package/server/package.json +1 -1
- package/server/{pan-dir-DoPtdHrp.js → pan-dir-BlNrLzW7.js} +3 -3
- package/server/{paths-CVDLPxXp.js → paths-CiVeo4N_.js} +2 -2
- package/server/{pipeline-notifier-WD2dnOsR.js → pipeline-notifier-DBF6dHxH.js} +2 -2
- package/server/{pipeline-notifier-BtYHbBPl.js → pipeline-notifier-nkWCe042.js} +1 -1
- package/server/{projects-Bqfwuqet.js → projects-BqRMlDOv.js} +1 -1
- package/server/{prompts-Cg7e9FPb.js → prompts-CXbQvevY.js} +2 -2
- package/server/{providers-fLduChnX.js → providers-CUdAb5Qu.js} +7 -7
- package/server/{providers-JjK6izqX.js → providers-gZ0cUgQM.js} +1 -1
- package/server/public/assets/{chunk-BO2N2NFS-aNlsGDCu.js → chunk-BO2N2NFS-C-6y8VFI.js} +4 -4
- package/server/public/assets/{diagram-OG6HWLK6-CnjkrvT8.js → diagram-OG6HWLK6-NACO1xW5.js} +1 -1
- package/server/public/assets/{dist-CGKBCieA.js → dist-D1FjqGgm.js} +1 -1
- package/server/public/assets/{dist-Bg3Sbsx4.js → dist-DQD-ZjQY.js} +3 -3
- package/server/public/assets/{ganttDiagram-6RSMTGT7-C8LLKj23.js → ganttDiagram-6RSMTGT7-CEMAKgmE.js} +1 -1
- package/server/public/assets/{highlighted-body-OFNGDK62-BSDEUvhW.js → highlighted-body-OFNGDK62-D5lC7FW8.js} +1 -1
- package/server/public/assets/{index-LQIfhmgI.js → index-BDqWyuZQ.js} +140 -140
- package/server/public/assets/{linear-DEbYZoxg.js → linear-DDHAMRPB.js} +1 -1
- package/server/public/assets/mermaid-GHXKKRXX-DRM2ANcR.js +1 -0
- package/server/public/assets/{pieDiagram-4H26LBE5-BtZL5pXE.js → pieDiagram-4H26LBE5-DwBdeKBb.js} +1 -1
- package/server/public/assets/{prod-DYVvIyuh.js → prod-DAZt0c4G.js} +4 -4
- package/server/public/assets/{quadrantDiagram-W4KKPZXB-a7vS8Jc8.js → quadrantDiagram-W4KKPZXB-CNDLp-_m.js} +1 -1
- package/server/public/assets/{sankeyDiagram-5OEKKPKP-Ckbq2SWH.js → sankeyDiagram-5OEKKPKP-oIUL_uO1.js} +1 -1
- package/server/public/assets/{xychartDiagram-2RQKCTM6-DJyeNa99.js → xychartDiagram-2RQKCTM6-B-IM6Cck.js} +1 -1
- package/server/public/index.html +1 -1
- package/server/{pull-requests-D2SjJIwY.js → pull-requests-DZ-V7_LB.js} +1 -1
- package/server/{pull-requests-1WXmTBlo.js → pull-requests-kTRl7cWC.js} +3 -3
- package/server/rally-CRteqXe0.js +3 -0
- package/server/{rally-api-H5I2CBO0.js → rally-api-DpZo3WwF.js} +2 -2
- package/server/{rally-api-BtvwdX6d.js → rally-api-jOk4vit_.js} +1 -1
- package/server/{rally-client-Bt-qHiOh.js → rally-client-BQjm3aaq.js} +1 -1
- package/server/{rally-client-33CYZYYu.js → rally-client-CoWZeVEj.js} +4 -4
- package/server/{rally-8aQlLLVj.js → rally-xCTZ-UcI.js} +3 -3
- package/server/{rebuild-stack-KHkkrGjx.js → rebuild-stack-BZ7j27xY.js} +5 -5
- package/server/{rebuild-stack-CXSgAGPR.js → rebuild-stack-r-cxcr26.js} +1 -1
- package/server/{reconstruct-cache-D_Ml65_6.js → reconstruct-cache-13EkMg_i.js} +6 -6
- package/server/{record-De2syxNB.js → record-CJsjvRO4.js} +1 -1
- package/server/release-engine-YLTnEO_K.js +306 -0
- package/server/release-set-DwvT_Opu.js +125 -0
- package/server/{remote-CGuognN3.js → remote-9u9WL0NJ.js} +3 -3
- package/server/{remote-D0Old0Cv.js → remote-B062S1Kc.js} +3 -3
- package/server/{remote-agents-UHoi4oGr.js → remote-agents-B4eWgwNd.js} +1 -1
- package/server/{remote-agents-DfhMq6kQ.js → remote-agents-BBTg-vLT.js} +5 -5
- package/server/{remote-completion-RZYePR_0.js → remote-completion-B0rmBnbL.js} +12 -12
- package/server/resume-R7xkSmLW.js +3 -0
- package/server/{review-agent-uwVftH98.js → review-agent-Bf9XjLnl.js} +1 -1
- package/server/{review-agent-sZBCpEVv.js → review-agent-tfR5RDzG.js} +22 -22
- package/server/{review-artifacts-C7a45b1_.js → review-artifacts-D0_IE6DQ.js} +6 -6
- package/server/{review-context-CErbQpKL.js → review-context-CXO5ml5D.js} +7 -7
- package/server/{review-monitor-DHD9m_kh.js → review-monitor-DfFUSx0J.js} +2 -2
- package/server/{review-status-JhQ3qlDS.js → review-status-B0Axo-Ma.js} +1 -1
- package/server/{review-status-gPndPUBc.js → review-status-BcfwcAcO.js} +23 -16
- package/server/{review-status-enrichment-qWvWckYN.js → review-status-enrichment-Cp5kFTGl.js} +3 -3
- package/server/{review-status-sync-B_GrEke8.js → review-status-sync-Bc0c_u12.js} +1 -1
- package/server/{review-status-sync-D3A9KX95.js → review-status-sync-CEFty1pW.js} +9 -5
- package/server/{review-verdict-feedback-4WZ5ZdbC.js → review-verdict-feedback-BOKRLLDf.js} +6 -6
- package/server/{review-verdict-feedback-Zo0r_z4m.js → review-verdict-feedback-BnGtT0vN.js} +1 -1
- package/server/{rollup-Bmhn80tB.js → rollup-BVqFuiS9.js} +1 -1
- package/server/{rollup-BrUIKMv_.js → rollup-C22QDVxh.js} +8 -8
- package/server/{scanner-BIGumel_.js → scanner-BLCnuXqY.js} +7 -7
- package/server/{sequence-io-DA0akEQN.js → sequence-io-BozlUb6f.js} +4 -4
- package/server/{sequencer-agent-DeflKafB.js → sequencer-agent-BEDEHfd2.js} +5 -5
- package/server/server.js +251 -160
- package/server/{service-V0sUK-OR.js → service-C8jKYZ0w.js} +42 -42
- package/server/{session-fork-Yx3UcAQf.js → session-fork-BDGksK4e.js} +2 -2
- package/server/{settings-CFEeQRj2.js → settings-CSLhh6qR.js} +2 -2
- package/server/settings-CSaXtkoA.js +2 -0
- package/server/{settings-CxVate0h.js → settings-DrRQCren.js} +3 -3
- package/server/{shadow-engineering-BRxnVSDk.js → shadow-engineering-BMcBN-Of.js} +2 -2
- package/server/{shadow-state-BiMwdyl1.js → shadow-state-B4ayC7nx.js} +2 -2
- package/server/{shadow-state-1aS8FijU.js → shadow-state-CHqWHD3T.js} +1 -1
- package/server/{ship-log-CMWH3H5-.js → ship-log-CDVmOlZP.js} +1 -1
- package/server/{smart-compaction-Bw1K_Sbl.js → smart-compaction-C-F5sP9P.js} +7 -7
- package/server/{smart-compaction-xblMyVpT.js → smart-compaction-V9DBrGcr.js} +1 -1
- package/server/{spawn-planning-session-CzDFSKAQ.js → spawn-planning-session-Bz4_JES2.js} +1 -1
- package/server/{spawn-planning-session-DxLxcM7m.js → spawn-planning-session-dSpOU0lP.js} +15 -15
- package/server/{specialist-completion-BiEXUHfD.js → specialist-completion-Coz3eTSr.js} +1 -1
- package/server/{specialist-context-BfkTA81h.js → specialist-context-fmb03vXQ.js} +5 -5
- package/server/{specialist-handoff-logger-BiKuLtNm.js → specialist-handoff-logger-B9HK_lRu.js} +2 -2
- package/server/{specialist-logs-CFJjGsLC.js → specialist-logs-B24R2B9Y.js} +3 -3
- package/server/{specialists-BLIreoE7.js → specialists-B6f5-5nG.js} +1 -1
- package/server/{specialists-DjHbwQ_p.js → specialists-BGNZ0_ZW.js} +18 -18
- package/server/{specialists-B4byf18k.js → specialists-CL7E8yUg.js} +75 -75
- package/server/{specialists-DdvpFNt1.js → specialists-Chvvwf5z.js} +1 -1
- package/server/specs-oaaYaA5c.js +3 -0
- package/server/{src-CALBEUMX.js → src-BVxZuHMg.js} +3 -3
- package/server/{src-mK_M_ZIj.js → src-D-VXCC9C.js} +5 -5
- package/server/{src-fgbU-jJ-.js → src-DGAEtABV.js} +13 -2
- package/server/{stack-health-BFM8YlHw.js → stack-health-BKbTTOT2.js} +1 -1
- package/server/{stack-health-Qd7rPiVe.js → stack-health-C-le5erA.js} +2 -2
- package/server/{state-home-C2Bicw9N.js → state-home-CoyWsECg.js} +6 -6
- package/server/{summary-fork-EWWBvzgE.js → summary-fork-BF_0vxrq.js} +2 -2
- package/server/{summary-fork-DezPkJSm.js → summary-fork-BlE30Q-I.js} +8 -8
- package/server/supervisor-03Tj_Wra.js +2 -0
- package/server/{supervisor-D5GC5jUM.js → supervisor-BSeML_p0.js} +2 -2
- package/server/{swarm-readiness-Cf9mommA.js → swarm-readiness-CQ4sjrXc.js} +3 -3
- package/server/{system-prerequisites-BsI9hxh9.js → system-prerequisites-DnmLYOnU.js} +13 -1
- package/server/{teardown-workspace-CWz1pbEK.js → teardown-workspace-CpcjDrZ4.js} +12 -12
- package/server/{test-agent-queue-TiVXe3ZT.js → test-agent-queue-Bq298zZl.js} +5 -5
- package/server/{tldr-daemon-C_1frSDj.js → tldr-daemon-CaSUXd9r.js} +2 -2
- package/server/{tldr-daemon-Big5IZ_M.js → tldr-daemon-Rn1Zue0P.js} +1 -1
- package/server/{tmux-D57f-XNv.js → tmux-BVc-NeKM.js} +2 -2
- package/server/{tmux-DClqWwb8.js → tmux-CbcrkUx5.js} +1 -1
- package/server/{token-_qujO3JZ.js → token-D2OC_9ms.js} +1 -1
- package/server/{tracker-config-BmdJU_w6.js → tracker-config-C1Y_2CIo.js} +2 -2
- package/server/{tracker-config-B_Ubts1Z.js → tracker-config-EsBoOWEy.js} +1 -1
- package/server/{tracker-utils-Bg-Sevcv.js → tracker-utils-DSb9cfrF.js} +1 -1
- package/server/{tracker-utils-CWFt6jjV.js → tracker-utils-lph9C3Pw.js} +2 -2
- package/server/{tunnel-UBf2vyAL.js → tunnel-BFBCeo97.js} +2 -2
- package/server/{tunnel-hOBNQbmF.js → tunnel-DDe-ATFF.js} +1 -1
- package/server/{uat-train-DGkIkLxu.js → uat-train-8T24rPzc.js} +1 -1
- package/server/{uat-train-qNanv5hN.js → uat-train-DtKHHy1U.js} +23 -23
- package/server/{validation-B0QaLIHP.js → validation-COOXwNXU.js} +1 -1
- package/server/{validation-C4wegCvH.js → validation-lyudzPvD.js} +3 -3
- package/server/{verification-runner-CntudBes.js → verification-runner-DO0nYTJx.js} +11 -11
- package/server/{verification-runner-DdleMNLq.js → verification-runner-Dd1FX8Qk.js} +1 -1
- package/server/{vtt-parser-CKc-smWM.js → vtt-parser-C57tEF7-.js} +1 -1
- package/server/{work-agent-prompt-CG5jFV9A.js → work-agent-prompt-B2F3ZwKm.js} +11 -11
- package/server/workflows-B4fIN8VP.js +2 -0
- package/server/{workflows-BK2xs_a8.js → workflows-Clz_AFwR.js} +13 -13
- package/server/{workspace-CLrSIRCx.js → workspace-CY_2-Ddv.js} +3 -3
- package/server/{workspace-C9lC5o3E.js → workspace-D0rCFemz.js} +1 -1
- package/server/{workspace-manager-Cb2a7bg9.js → workspace-manager-BIfpzqdU.js} +1 -1
- package/server/{workspace-manager-BJhW2sky.js → workspace-manager-D6NgGkiF.js} +10 -10
- package/server/{workspace-metadata-QQmo_Z0l.js → workspace-metadata-C8yn8kAH.js} +2 -2
- package/server/{workspace-metadata-CTRnr323.js → workspace-metadata-DfgR40YU.js} +1 -1
- package/server/{workspaces-Ca4zZs12.js → workspaces-DOeHyKmA.js} +104 -92
- package/sync-sources/hooks/ask-user-question-hook +87 -0
- package/sync-sources/hooks/auto-approve-hook +96 -0
- package/sync-sources/hooks/codex-notify-hook +62 -0
- package/sync-sources/hooks/gh-issue-trailer-hook +4 -0
- package/sync-sources/hooks/gh-issue-trailer-hook.d.ts +7 -0
- package/sync-sources/hooks/gh-issue-trailer-hook.d.ts.map +1 -0
- package/sync-sources/hooks/gh-issue-trailer-hook.js +239 -0
- package/sync-sources/hooks/gh-issue-trailer-hook.js.map +1 -0
- package/sync-sources/hooks/gh-issue-trailer-hook.ts +296 -0
- package/sync-sources/hooks/git-hooks/post-checkout +109 -0
- package/sync-sources/hooks/heartbeat-hook +113 -0
- package/sync-sources/hooks/notification-hook +70 -0
- package/sync-sources/hooks/notify-complete +79 -0
- package/sync-sources/hooks/pan-hook-lib.sh +153 -0
- package/sync-sources/hooks/permission-event-hook +24 -0
- package/sync-sources/hooks/post-compact-hook +25 -0
- package/sync-sources/hooks/pre-compact-hook +26 -0
- package/sync-sources/hooks/pre-tool-hook +35 -0
- package/sync-sources/hooks/record-cost-event.d.ts +1 -0
- package/sync-sources/hooks/record-cost-event.js +31858 -0
- package/sync-sources/hooks/record-cost-event.js.map +1 -0
- package/sync-sources/hooks/record-cost-event.ts +267 -0
- package/sync-sources/hooks/rtk-bash-filter +152 -0
- package/sync-sources/hooks/session-start-hook +80 -0
- package/sync-sources/hooks/specialist-stop-hook +106 -0
- package/sync-sources/hooks/statusline.sh +169 -0
- package/sync-sources/hooks/stop-hook +217 -0
- package/sync-sources/hooks/tldr-post-edit +72 -0
- package/sync-sources/hooks/tldr-read-enforcer +340 -0
- package/sync-sources/hooks/tmux-send-keys-guard +87 -0
- package/sync-sources/hooks/tsdown.config.ts +14 -0
- package/sync-sources/hooks/user-prompt-submit-hook +57 -0
- package/sync-sources/hooks/work-agent-stop-hook +424 -0
- package/server/cli-Ch_BWJB2.js +0 -3
- package/server/deacon-swarm-CSWGRfzr.js +0 -2
- package/server/dist-BUplB3Od.js +0 -3
- package/server/forge-IgLR0Ist.js +0 -2
- package/server/inspect-agent-CYoWAeeB.js +0 -2
- package/server/merge-agent-CfohxFWM.js +0 -3
- package/server/merge-ops-Czke6UAp.js +0 -2
- package/server/public/assets/mermaid-GHXKKRXX-CZOsRYoT.js +0 -1
- package/server/rally-Ba9QoNYc.js +0 -3
- package/server/resume-CmxF3Kjz.js +0 -3
- package/server/settings-DEhYpW0k.js +0 -2
- package/server/specs-CVH1kvz3.js +0 -3
- package/server/supervisor-DQMK2e3I.js +0 -2
- package/server/workflows-pKw9yRSV.js +0 -2
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ~/.overdeck/bin/tldr-read-enforcer
|
|
3
|
+
# PreToolUse hook on Read — intercepts file reads and returns TLDR summaries
|
|
4
|
+
# for large code files, saving 90-95% of context tokens.
|
|
5
|
+
#
|
|
6
|
+
# Bypasses (allows normal read):
|
|
7
|
+
# - Files < 3KB (small enough to read directly)
|
|
8
|
+
# - Reads with offset/limit (targeted reads for editing)
|
|
9
|
+
# - Non-code files (configs, docs, json, etc.)
|
|
10
|
+
# - No .venv available (TLDR not installed)
|
|
11
|
+
# - TLDR disabled via OVERDECK_TLDR_ENABLED=0 or agents.tldr.enabled: false
|
|
12
|
+
# - TLDR command fails (graceful degradation)
|
|
13
|
+
# - Summary too sparse to be useful (< 100 tokens for file > 5KB)
|
|
14
|
+
# - Recently edited files (in .tldr/dirty-files — agent needs to verify changes)
|
|
15
|
+
|
|
16
|
+
# Don't use set -e — never break Claude Code execution
|
|
17
|
+
INPUT=$(cat 2>/dev/null || echo '{}')
|
|
18
|
+
|
|
19
|
+
# Only act on Read tool
|
|
20
|
+
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null)
|
|
21
|
+
if [ "$TOOL_NAME" != "Read" ]; then
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Bypass: TLDR disabled via env override or config (read live, so the Settings
|
|
26
|
+
# toggle takes effect on the very next Read — no agent restart required).
|
|
27
|
+
# TLDR defaults ON: only an explicit falsy value (0/false/no/off/disabled)
|
|
28
|
+
# disables it; an absent/empty value means "enabled".
|
|
29
|
+
tldr_falsy() {
|
|
30
|
+
case "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" in
|
|
31
|
+
0|false|no|off|disabled) return 0 ;;
|
|
32
|
+
*) return 1 ;;
|
|
33
|
+
esac
|
|
34
|
+
}
|
|
35
|
+
tldr_read_config_enabled() {
|
|
36
|
+
local config_path="$1"
|
|
37
|
+
[ -z "$config_path" ] && return 0
|
|
38
|
+
[ ! -f "$config_path" ] && return 0
|
|
39
|
+
awk '
|
|
40
|
+
function trim(s) { sub(/^[ \t\r\n]+/, "", s); sub(/[ \t\r\n]+$/, "", s); return s }
|
|
41
|
+
BEGIN { in_agents = 0; in_tldr = 0; agents_indent = -1; tldr_indent = -1 }
|
|
42
|
+
{
|
|
43
|
+
line = $0
|
|
44
|
+
sub(/#.*/, "", line)
|
|
45
|
+
if (line ~ /^[[:space:]]*$/) next
|
|
46
|
+
match(line, /^[ ]*/)
|
|
47
|
+
indent = RLENGTH
|
|
48
|
+
key = line
|
|
49
|
+
sub(/^[[:space:]]*/, "", key)
|
|
50
|
+
if (key ~ /^agents:[[:space:]]*$/) { in_agents = 1; in_tldr = 0; agents_indent = indent; next }
|
|
51
|
+
if (in_agents && indent <= agents_indent) { in_agents = 0; in_tldr = 0 }
|
|
52
|
+
if (in_agents && key ~ /^tldr:[[:space:]]*$/) { in_tldr = 1; tldr_indent = indent; next }
|
|
53
|
+
if (in_tldr && indent <= tldr_indent) { in_tldr = 0 }
|
|
54
|
+
if (in_tldr && key ~ /^enabled:[[:space:]]*/) {
|
|
55
|
+
sub(/^enabled:[[:space:]]*/, "", key)
|
|
56
|
+
gsub(/"/, "", key); gsub(/\047/, "", key)
|
|
57
|
+
print trim(key); exit
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
' "$config_path" 2>/dev/null
|
|
61
|
+
}
|
|
62
|
+
tldr_config_enabled_value() {
|
|
63
|
+
if [ -n "${OVERDECK_CONFIG:-}" ]; then
|
|
64
|
+
tldr_read_config_enabled "$OVERDECK_CONFIG"
|
|
65
|
+
else
|
|
66
|
+
tldr_read_config_enabled "$HOME/.overdeck/config.yaml"
|
|
67
|
+
fi
|
|
68
|
+
}
|
|
69
|
+
if [ -n "${OVERDECK_TLDR_ENABLED+x}" ]; then
|
|
70
|
+
tldr_falsy "$OVERDECK_TLDR_ENABLED" && exit 0
|
|
71
|
+
else
|
|
72
|
+
tldr_falsy "$(tldr_config_enabled_value)" && exit 0
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# Extract Read parameters
|
|
76
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""' 2>/dev/null)
|
|
77
|
+
OFFSET=$(echo "$INPUT" | jq -r '.tool_input.offset // empty' 2>/dev/null)
|
|
78
|
+
LIMIT=$(echo "$INPUT" | jq -r '.tool_input.limit // empty' 2>/dev/null)
|
|
79
|
+
|
|
80
|
+
# Bypass: targeted reads (offset or limit specified — agent is reading for editing)
|
|
81
|
+
if [ -n "$OFFSET" ] || [ -n "$LIMIT" ]; then
|
|
82
|
+
exit 0
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Bypass: file doesn't exist
|
|
86
|
+
if [ ! -f "$FILE_PATH" ]; then
|
|
87
|
+
exit 0
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Bypass: small files (< 3KB)
|
|
91
|
+
FILE_SIZE=$(stat -c%s "$FILE_PATH" 2>/dev/null || echo 0)
|
|
92
|
+
if [ "$FILE_SIZE" -lt 3072 ]; then
|
|
93
|
+
exit 0
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Bypass: non-code files
|
|
97
|
+
EXT="${FILE_PATH##*.}"
|
|
98
|
+
EXT_LOWER=$(echo "$EXT" | tr '[:upper:]' '[:lower:]')
|
|
99
|
+
case "$EXT_LOWER" in
|
|
100
|
+
ts|tsx|js|jsx|py|java|go|rs|cpp|c|h|hpp|rb|php|kt|swift|cs|scala|lua|ex|exs)
|
|
101
|
+
# Code file — continue to TLDR
|
|
102
|
+
;;
|
|
103
|
+
*)
|
|
104
|
+
# Non-code — allow normal read
|
|
105
|
+
exit 0
|
|
106
|
+
;;
|
|
107
|
+
esac
|
|
108
|
+
|
|
109
|
+
# Find the .venv/bin/tldr binary
|
|
110
|
+
# Check workspace first, then project root
|
|
111
|
+
TLDR_BIN=""
|
|
112
|
+
DIR="$(dirname "$FILE_PATH")"
|
|
113
|
+
while [ "$DIR" != "/" ]; do
|
|
114
|
+
if [ -x "$DIR/.venv/bin/tldr" ]; then
|
|
115
|
+
TLDR_BIN="$DIR/.venv/bin/tldr"
|
|
116
|
+
PROJECT_DIR="$DIR"
|
|
117
|
+
break
|
|
118
|
+
fi
|
|
119
|
+
DIR=$(dirname "$DIR")
|
|
120
|
+
done
|
|
121
|
+
|
|
122
|
+
# Bypass: no TLDR binary found
|
|
123
|
+
if [ -z "$TLDR_BIN" ]; then
|
|
124
|
+
exit 0
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
# Get relative path from project root
|
|
128
|
+
REL_PATH="${FILE_PATH#$PROJECT_DIR/}"
|
|
129
|
+
|
|
130
|
+
# Bypass: recently edited files (agent needs to verify its own changes)
|
|
131
|
+
# The post-edit hook tracks edits in .tldr/dirty-files
|
|
132
|
+
DIRTY_FILE="$PROJECT_DIR/.tldr/dirty-files"
|
|
133
|
+
if [ -f "$DIRTY_FILE" ] && grep -qxF "$REL_PATH" "$DIRTY_FILE" 2>/dev/null; then
|
|
134
|
+
exit 0
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# Detect language from extension for tldr --lang flag
|
|
138
|
+
case "$EXT_LOWER" in
|
|
139
|
+
ts|tsx) TLDR_LANG="typescript" ;;
|
|
140
|
+
js|jsx) TLDR_LANG="javascript" ;;
|
|
141
|
+
py) TLDR_LANG="python" ;;
|
|
142
|
+
go) TLDR_LANG="go" ;;
|
|
143
|
+
rs) TLDR_LANG="rust" ;;
|
|
144
|
+
java|kt) TLDR_LANG="java" ;;
|
|
145
|
+
rb) TLDR_LANG="ruby" ;;
|
|
146
|
+
*) TLDR_LANG="python" ;;
|
|
147
|
+
esac
|
|
148
|
+
|
|
149
|
+
# Strip file extension — tldr context expects module paths without extension
|
|
150
|
+
# e.g., "src/lib/agents" not "src/lib/agents.ts"
|
|
151
|
+
MODULE_PATH="${REL_PATH%.*}"
|
|
152
|
+
|
|
153
|
+
# Try to get TLDR context for this file (module path mode)
|
|
154
|
+
TLDR_OUTPUT=$("$TLDR_BIN" context "$MODULE_PATH" --lang "$TLDR_LANG" 2>/dev/null)
|
|
155
|
+
TLDR_EXIT=$?
|
|
156
|
+
|
|
157
|
+
# Quality gate: check if context output is too sparse to be useful.
|
|
158
|
+
# Pattern: "~XX tokens" where XX < 100 means the summary captured almost nothing.
|
|
159
|
+
# This happens with test files (describe/it blocks) and type-only files.
|
|
160
|
+
CONTEXT_SPARSE=false
|
|
161
|
+
if [ $TLDR_EXIT -eq 0 ] && [ -n "$TLDR_OUTPUT" ]; then
|
|
162
|
+
CTX_TOKENS=$(echo "$TLDR_OUTPUT" | grep -oP '\~\K\d+(?= tokens)' || echo "0")
|
|
163
|
+
if [ "$CTX_TOKENS" -lt 100 ] && [ "$FILE_SIZE" -gt 5120 ]; then
|
|
164
|
+
CONTEXT_SPARSE=true
|
|
165
|
+
fi
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
# Fallback: if context failed, was sparse, or empty — try extract command
|
|
169
|
+
# extract works on actual file paths (including .tsx) and returns structured JSON
|
|
170
|
+
if [ $TLDR_EXIT -ne 0 ] || [ -z "$TLDR_OUTPUT" ] || [ "$CONTEXT_SPARSE" = true ]; then
|
|
171
|
+
EXTRACT_JSON=$("$TLDR_BIN" extract "$REL_PATH" 2>/dev/null)
|
|
172
|
+
EXTRACT_EXIT=$?
|
|
173
|
+
if [ $EXTRACT_EXIT -eq 0 ] && [ -n "$EXTRACT_JSON" ]; then
|
|
174
|
+
# Check if extract found any real content
|
|
175
|
+
EXTRACT_COUNTS=$(echo "$EXTRACT_JSON" | python3 -c "
|
|
176
|
+
import json, sys
|
|
177
|
+
try:
|
|
178
|
+
d = json.load(sys.stdin)
|
|
179
|
+
nf = len(d.get('functions', []))
|
|
180
|
+
nc = len(d.get('classes', []))
|
|
181
|
+
print(f'{nf} {nc}')
|
|
182
|
+
except:
|
|
183
|
+
print('0 0')
|
|
184
|
+
" 2>/dev/null)
|
|
185
|
+
EXTRACT_FUNCS=$(echo "$EXTRACT_COUNTS" | cut -d' ' -f1)
|
|
186
|
+
EXTRACT_CLASSES=$(echo "$EXTRACT_COUNTS" | cut -d' ' -f2)
|
|
187
|
+
|
|
188
|
+
# If extract also found nothing useful, bypass entirely
|
|
189
|
+
if [ "${EXTRACT_FUNCS:-0}" -eq 0 ] && [ "${EXTRACT_CLASSES:-0}" -eq 0 ]; then
|
|
190
|
+
# Neither context nor extract found useful content — let the agent read the file
|
|
191
|
+
exit 0
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
# Convert extract JSON to a readable summary with language-appropriate syntax
|
|
195
|
+
TLDR_OUTPUT=$(echo "$EXTRACT_JSON" | python3 -c "
|
|
196
|
+
import json, sys
|
|
197
|
+
try:
|
|
198
|
+
data = json.load(sys.stdin)
|
|
199
|
+
lang = '$TLDR_LANG'
|
|
200
|
+
lines = []
|
|
201
|
+
fname = data.get('file_path', '$REL_PATH')
|
|
202
|
+
short = fname.split('/')[-1]
|
|
203
|
+
lines.append(f'## Code Context: {fname}')
|
|
204
|
+
lines.append('')
|
|
205
|
+
|
|
206
|
+
# Language-appropriate function keyword
|
|
207
|
+
fn_kw = {'typescript': 'function', 'javascript': 'function', 'python': 'def',
|
|
208
|
+
'go': 'func', 'rust': 'fn', 'java': '', 'ruby': 'def'}.get(lang, 'function')
|
|
209
|
+
|
|
210
|
+
for func in data.get('functions', []):
|
|
211
|
+
name = func.get('name', '?')
|
|
212
|
+
params = ', '.join(
|
|
213
|
+
p.get('name','') + (': ' + p.get('type','') if p.get('type') else '')
|
|
214
|
+
for p in func.get('parameters', [])
|
|
215
|
+
)
|
|
216
|
+
ret = func.get('return_type', '')
|
|
217
|
+
doc = (func.get('docstring') or '')[:80]
|
|
218
|
+
line = func.get('start_line') or '?'
|
|
219
|
+
sig = f'{fn_kw} {name}({params})'.strip()
|
|
220
|
+
if ret:
|
|
221
|
+
if lang in ('typescript', 'javascript', 'go', 'rust'):
|
|
222
|
+
sig += f': {ret}'
|
|
223
|
+
else:
|
|
224
|
+
sig += f' -> {ret}'
|
|
225
|
+
lines.append(f'{name} ({short}:{line})')
|
|
226
|
+
lines.append(f' {sig}')
|
|
227
|
+
if doc:
|
|
228
|
+
lines.append(f' // {doc}')
|
|
229
|
+
lines.append('')
|
|
230
|
+
|
|
231
|
+
for cls in data.get('classes', []):
|
|
232
|
+
name = cls.get('name', '?')
|
|
233
|
+
line = cls.get('start_line') or '?'
|
|
234
|
+
lines.append(f'class {name} ({short}:{line})')
|
|
235
|
+
for m in cls.get('methods', []):
|
|
236
|
+
mname = m.get('name', '?')
|
|
237
|
+
lines.append(f' .{mname}()')
|
|
238
|
+
lines.append('')
|
|
239
|
+
|
|
240
|
+
nfunc = len(data.get('functions', []))
|
|
241
|
+
ncls = len(data.get('classes', []))
|
|
242
|
+
lines.append(f'---')
|
|
243
|
+
lines.append(f'{nfunc} functions, {ncls} classes (via extract)')
|
|
244
|
+
print('\n'.join(lines))
|
|
245
|
+
except:
|
|
246
|
+
pass
|
|
247
|
+
" 2>/dev/null)
|
|
248
|
+
fi
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
# Observability: if BOTH TLDR invocations exited non-zero, the binary itself
|
|
252
|
+
# is broken (dead interpreter, bad shebang after a rename, etc.) — NOT a file
|
|
253
|
+
# with nothing to summarize. The hook still bypasses (exit 0 below) so the
|
|
254
|
+
# agent's Read succeeds, but record it so a broken TLDR install surfaces
|
|
255
|
+
# instead of silently degrading every Read to full-file. A dead binary is
|
|
256
|
+
# otherwise indistinguishable from "no content" (this is exactly how a stale
|
|
257
|
+
# shebang after the panopticon-cli → overdeck rename went unnoticed).
|
|
258
|
+
if [ "${TLDR_EXIT:-0}" -ne 0 ] && [ "${EXTRACT_EXIT:-0}" -ne 0 ]; then
|
|
259
|
+
FAIL_LOG="$PROJECT_DIR/.tldr/failures.log"
|
|
260
|
+
mkdir -p "$(dirname "$FAIL_LOG")" 2>/dev/null
|
|
261
|
+
printf '%s binary_fail context_exit=%s extract_exit=%s %s\n' \
|
|
262
|
+
"$(date +%s)" "$TLDR_EXIT" "$EXTRACT_EXIT" "$REL_PATH" >> "$FAIL_LOG" 2>/dev/null
|
|
263
|
+
fi
|
|
264
|
+
|
|
265
|
+
# Bypass: both context and extract failed or produced nothing useful
|
|
266
|
+
if [ -z "$TLDR_OUTPUT" ]; then
|
|
267
|
+
exit 0
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
# Also get the file's imports and format them
|
|
271
|
+
TLDR_IMPORTS_RAW=$("$TLDR_BIN" imports "$REL_PATH" --lang "$TLDR_LANG" 2>/dev/null || true)
|
|
272
|
+
TLDR_IMPORTS=""
|
|
273
|
+
if [ -n "$TLDR_IMPORTS_RAW" ]; then
|
|
274
|
+
TLDR_IMPORTS=$(echo "$TLDR_IMPORTS_RAW" | python3 -c "
|
|
275
|
+
import json, sys
|
|
276
|
+
try:
|
|
277
|
+
data = json.load(sys.stdin)
|
|
278
|
+
lines = []
|
|
279
|
+
for imp in data:
|
|
280
|
+
mod = imp.get('module', '?')
|
|
281
|
+
names = imp.get('names', [])
|
|
282
|
+
default = imp.get('default')
|
|
283
|
+
parts = []
|
|
284
|
+
if default:
|
|
285
|
+
parts.append(default)
|
|
286
|
+
if names:
|
|
287
|
+
parts.append('{ ' + ', '.join(names) + ' }')
|
|
288
|
+
if parts:
|
|
289
|
+
lines.append(f'import {', '.join(parts)} from \"{mod}\"')
|
|
290
|
+
else:
|
|
291
|
+
lines.append(f'import \"{mod}\"')
|
|
292
|
+
print('\n'.join(lines))
|
|
293
|
+
except:
|
|
294
|
+
# If JSON parsing fails, use raw output (may already be formatted)
|
|
295
|
+
sys.stdout.write(sys.stdin.read() if hasattr(sys, '_raw') else '')
|
|
296
|
+
" 2>/dev/null)
|
|
297
|
+
# If Python formatting failed, fall back to raw
|
|
298
|
+
if [ -z "$TLDR_IMPORTS" ]; then
|
|
299
|
+
TLDR_IMPORTS="$TLDR_IMPORTS_RAW"
|
|
300
|
+
fi
|
|
301
|
+
fi
|
|
302
|
+
|
|
303
|
+
# Build the summary that Claude will see instead of the raw file
|
|
304
|
+
SUMMARY="[TLDR Summary — ${FILE_SIZE} bytes saved from context]
|
|
305
|
+
|
|
306
|
+
File: ${FILE_PATH}
|
|
307
|
+
|
|
308
|
+
## Structure & Exports
|
|
309
|
+
${TLDR_OUTPUT}"
|
|
310
|
+
|
|
311
|
+
if [ -n "$TLDR_IMPORTS" ]; then
|
|
312
|
+
SUMMARY="${SUMMARY}
|
|
313
|
+
|
|
314
|
+
## Imports
|
|
315
|
+
${TLDR_IMPORTS}"
|
|
316
|
+
fi
|
|
317
|
+
|
|
318
|
+
SUMMARY="${SUMMARY}
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
To read the full file, use Read with offset/limit parameters for the specific section you need to edit."
|
|
322
|
+
|
|
323
|
+
# Deny the read and provide TLDR context instead
|
|
324
|
+
# Use a temp file for the JSON to handle multiline safely
|
|
325
|
+
TEMP_JSON=$(mktemp /tmp/tldr-hook-XXXXXX.json)
|
|
326
|
+
jq -n --arg reason "TLDR summary provided instead of full file read (${FILE_SIZE} bytes → ~1K tokens)" \
|
|
327
|
+
--arg context "$SUMMARY" \
|
|
328
|
+
'{
|
|
329
|
+
hookSpecificOutput: {
|
|
330
|
+
hookEventName: "PreToolUse",
|
|
331
|
+
permissionDecision: "deny",
|
|
332
|
+
permissionDecisionReason: $reason,
|
|
333
|
+
additionalContext: $context
|
|
334
|
+
}
|
|
335
|
+
}' > "$TEMP_JSON" 2>/dev/null
|
|
336
|
+
|
|
337
|
+
cat "$TEMP_JSON"
|
|
338
|
+
rm -f "$TEMP_JSON"
|
|
339
|
+
|
|
340
|
+
exit 0
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ~/.overdeck/bin/tmux-send-keys-guard (PAN-1084)
|
|
3
|
+
#
|
|
4
|
+
# PreToolUse hook on Bash — prevents work agents from self-approving permission
|
|
5
|
+
# prompts (or any other input) in another agent's tmux session by blocking
|
|
6
|
+
# `tmux send-keys` and `tmux paste-buffer` that target a session other than
|
|
7
|
+
# their own.
|
|
8
|
+
#
|
|
9
|
+
# The work-agent prompt already forbids interacting with permission prompts via
|
|
10
|
+
# tmux keystrokes. This hook is the mechanical enforcement: it rewrites the
|
|
11
|
+
# Bash command to a failing no-op when it would write to a non-self session.
|
|
12
|
+
#
|
|
13
|
+
# Never breaks Claude Code: on any error the hook exits 0 silently and lets the
|
|
14
|
+
# original command through.
|
|
15
|
+
|
|
16
|
+
set +e
|
|
17
|
+
|
|
18
|
+
INPUT=$(cat 2>/dev/null || echo '{}')
|
|
19
|
+
|
|
20
|
+
# Only enforce for work agents (agent-<prefix>-<number>). Planning, test, review,
|
|
21
|
+
# inspect, strike, flywheel, conversation, and human sessions must keep normal
|
|
22
|
+
# tmux behavior — this guard is not meant for them.
|
|
23
|
+
case "${OVERDECK_AGENT_ID:-}" in
|
|
24
|
+
agent-*[0-9]) : ;;
|
|
25
|
+
*) exit 0 ;;
|
|
26
|
+
esac
|
|
27
|
+
|
|
28
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
29
|
+
# Without jq we cannot safely parse the payload. Allow the call.
|
|
30
|
+
exit 0
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
TOOL_NAME=$(printf '%s' "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null)
|
|
34
|
+
if [ "$TOOL_NAME" != "Bash" ]; then
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
COMMAND=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // ""' 2>/dev/null)
|
|
39
|
+
if [ -z "$COMMAND" ]; then
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Only guard tmux subcommands that write keystrokes/buffers to a target pane.
|
|
44
|
+
if ! printf '%s' "$COMMAND" | grep -qE '\btmux\b.*\b(send-keys|paste-buffer)\b'; then
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Determine this agent's own tmux session name.
|
|
49
|
+
SELF_SESSION=""
|
|
50
|
+
if [ -n "${OVERDECK_AGENT_ID:-}" ]; then
|
|
51
|
+
SELF_SESSION="$OVERDECK_AGENT_ID"
|
|
52
|
+
elif [ -n "${TMUX:-}" ]; then
|
|
53
|
+
SELF_SESSION=$(tmux display-message -p '#S' 2>/dev/null)
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Extract the explicit -t target, if any. `tmux send-keys` / `tmux paste-buffer`
|
|
57
|
+
# without `-t` target the current pane (self), so those are allowed.
|
|
58
|
+
TARGET=$(printf '%s' "$COMMAND" | grep -oE -- '-t[[:space:]]+[^[:space:]]+' | tail -n1 | sed -E 's/^-t[[:space:]]+//' 2>/dev/null)
|
|
59
|
+
if [ -z "$TARGET" ]; then
|
|
60
|
+
exit 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Normalize session names for comparison. tmux pane targets look like
|
|
64
|
+
# "session:window.pane" or "session.window-pane"; the session is the prefix.
|
|
65
|
+
TARGET_SESSION=$(printf '%s' "$TARGET" | sed -E 's/[:.].*$//' 2>/dev/null)
|
|
66
|
+
|
|
67
|
+
if [ -n "$SELF_SESSION" ] && [ "$TARGET_SESSION" = "$SELF_SESSION" ]; then
|
|
68
|
+
exit 0
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Target is explicitly another session (or we cannot determine self). Rewrite
|
|
72
|
+
# to a failing command so the agent sees a clear error and cannot silently
|
|
73
|
+
# drive another session.
|
|
74
|
+
BLOCKED_REASON="BLOCKED: tmux send-keys/paste-buffer targeting another tmux session (${TARGET_SESSION}) is forbidden (PAN-1084). Capture the pane with tmux -L overdeck capture-pane -t <session> -p and surface the issue via pan tell instead."
|
|
75
|
+
|
|
76
|
+
jq -n \
|
|
77
|
+
--arg reason "$BLOCKED_REASON" \
|
|
78
|
+
'{
|
|
79
|
+
hookSpecificOutput: {
|
|
80
|
+
hookEventName: "PreToolUse",
|
|
81
|
+
updatedInput: {
|
|
82
|
+
command: ("printf '\''%s\\n'\'' \"" + $reason + "\" >&2; false")
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}'
|
|
86
|
+
|
|
87
|
+
exit 0
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from 'tsdown';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: ['record-cost-event.ts', 'gh-issue-trailer-hook.ts'],
|
|
5
|
+
format: 'esm',
|
|
6
|
+
platform: 'node',
|
|
7
|
+
shims: true,
|
|
8
|
+
outDir: '.',
|
|
9
|
+
clean: false,
|
|
10
|
+
outExtensions: () => ({ js: '.js' }),
|
|
11
|
+
// Bundle all dependencies inline — this script runs standalone at ~/.overdeck/bin/
|
|
12
|
+
// with no node_modules, so imports like 'yaml' must be embedded.
|
|
13
|
+
noExternal: [/.*/],
|
|
14
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ~/.overdeck/bin/user-prompt-submit-hook
|
|
3
|
+
#
|
|
4
|
+
# Fires on Claude Code UserPromptSubmit. Emits three events:
|
|
5
|
+
# 1. agent.waiting_cleared — clears hasPendingQuestion / suspension
|
|
6
|
+
# 2. agent.message_received — updates lastActivity + lastMessageAt
|
|
7
|
+
# 3. agent.activity_changed(thinking) — Claude is processing the prompt now
|
|
8
|
+
#
|
|
9
|
+
# Previously emitted activity=idle "so the dashboard spinner restarts." That
|
|
10
|
+
# was a UI hack that lied about runtime state: Claude is NOT idle right after
|
|
11
|
+
# the user submits a prompt — it's about to start thinking and may take many
|
|
12
|
+
# minutes before the first PreToolUse hook fires. The deacon's stale-active
|
|
13
|
+
# check would then read state=idle + old lastActivity and nudge with a
|
|
14
|
+
# "you appear to have stopped working" message, cancelling Claude mid-think
|
|
15
|
+
# (PAN-1024 reproduced this loop). Emitting activity=thinking keeps the
|
|
16
|
+
# runtime snapshot honest until pre-tool-hook takes over.
|
|
17
|
+
|
|
18
|
+
set +e
|
|
19
|
+
|
|
20
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
21
|
+
# shellcheck source=pan-hook-lib.sh
|
|
22
|
+
. "$SCRIPT_DIR/pan-hook-lib.sh" 2>/dev/null || exit 0
|
|
23
|
+
|
|
24
|
+
pan_resolve_agent_id || exit 0
|
|
25
|
+
|
|
26
|
+
INPUT=$(cat 2>/dev/null || echo '{}')
|
|
27
|
+
TS=$(date -Iseconds)
|
|
28
|
+
|
|
29
|
+
pan_emit_event "$AGENT_ID" "{\"kind\":\"waiting_clear\",\"clearedBy\":\"user_response\",\"timestamp\":\"$TS\"}"
|
|
30
|
+
pan_emit_event "$AGENT_ID" "{\"kind\":\"message_received\",\"direction\":\"to_agent\",\"source\":\"user\",\"timestamp\":\"$TS\"}"
|
|
31
|
+
pan_emit_event "$AGENT_ID" "{\"kind\":\"thinking_start\",\"lastToolAt\":\"$TS\",\"timestamp\":\"$TS\"}"
|
|
32
|
+
|
|
33
|
+
INTERNAL_TOKEN="${OVERDECK_INTERNAL_TOKEN:-}"
|
|
34
|
+
if [ -z "$INTERNAL_TOKEN" ]; then
|
|
35
|
+
TOKEN_PATH="${OVERDECK_HOME:-$HOME/.overdeck}/internal-token"
|
|
36
|
+
if [ -f "$TOKEN_PATH" ]; then
|
|
37
|
+
INTERNAL_TOKEN=$(cat "$TOKEN_PATH" 2>/dev/null || true)
|
|
38
|
+
fi
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
if command -v jq >/dev/null 2>&1; then
|
|
42
|
+
TITLE_BODY=$(printf '%s' "$INPUT" | jq -c '{session_id: (.session_id // ""), prompt: (.prompt // .message // .input // "")}' 2>/dev/null)
|
|
43
|
+
if [ -n "$TITLE_BODY" ]; then
|
|
44
|
+
curl -s -m 1 -X POST -H 'Content-Type: application/json' -H "x-overdeck-internal-token: $INTERNAL_TOKEN" --data "$TITLE_BODY" "$PAN_DASHBOARD_URL/api/hooks/user-prompt-submit" >/dev/null 2>&1 || true
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
INJECT_BODY=$(printf '%s' "$INPUT" | jq -c --arg agentId "$AGENT_ID" '{prompt: (.prompt // .message // .input // ""), sessionId: (.session_id // ""), agentId: $agentId}' 2>/dev/null)
|
|
48
|
+
if [ -n "$INJECT_BODY" ]; then
|
|
49
|
+
INJECT_RESPONSE=$(curl -s -m 1 -X POST -H 'Content-Type: application/json' -H "x-overdeck-internal-token: $INTERNAL_TOKEN" --data "$INJECT_BODY" "$PAN_DASHBOARD_URL/api/memory/inject" 2>/dev/null || true)
|
|
50
|
+
INJECT_CONTEXT=$(printf '%s' "$INJECT_RESPONSE" | jq -r 'if .ok == true and (.context // "") != "" then .context else empty end' 2>/dev/null)
|
|
51
|
+
if [ -n "$INJECT_CONTEXT" ]; then
|
|
52
|
+
printf '%s\n' "$INJECT_CONTEXT"
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
exit 0
|