@overdeck/core 0.45.10 → 0.45.11
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/dist/{agent-state-KVbJEG5f.js → agent-state-RLhS7ckO.js} +1 -1
- package/dist/{agents-pp8FO7Uj.js → agents-By3u_fQ8.js} +1 -1
- package/dist/{agents-CQHK0CSA.js → agents-CgVr77Qq.js} +12 -12
- package/dist/{agents-CQHK0CSA.js.map → agents-CgVr77Qq.js.map} +1 -1
- package/dist/{backlog-auto-trigger-CyuoS0nl.js → backlog-auto-trigger-B_-1tk4e.js} +5 -5
- package/dist/{backlog-auto-trigger-CyuoS0nl.js.map → backlog-auto-trigger-B_-1tk4e.js.map} +1 -1
- package/dist/cli/index.js +45 -45
- package/dist/{cli-Cewlu3yU.js → cli-DGeSW85B.js} +2 -2
- package/dist/{cli-Cewlu3yU.js.map → cli-DGeSW85B.js.map} +1 -1
- package/dist/cli-MTB9IOoR.js +3 -0
- package/dist/{close-issue-BJGX9_z7.js → close-issue-Djajb6Sv.js} +2 -2
- package/dist/{close-issue-BJGX9_z7.js.map → close-issue-Djajb6Sv.js.map} +1 -1
- package/dist/{concurrency-Ca-fC7tA.js → concurrency-4rzjHAQA.js} +1 -1
- package/dist/{conversation-compaction-B_6s9EvM.js → conversation-compaction-BQvZh09I.js} +4 -4
- package/dist/{conversation-compaction-B_6s9EvM.js.map → conversation-compaction-BQvZh09I.js.map} +1 -1
- package/dist/dashboard/{advancing-selfheal-CMlGznKv.js → advancing-selfheal-BezNfM3P.js} +3 -3
- package/dist/dashboard/{advancing-selfheal-CMlGznKv.js.map → advancing-selfheal-BezNfM3P.js.map} +1 -1
- package/dist/dashboard/{agent-state-xk_G8t90.js → agent-state-BUANcaA7.js} +1 -1
- package/dist/dashboard/{agent-state-service-C1iUF9Ft.js → agent-state-service-DmFpIMbP.js} +1 -1
- package/dist/dashboard/{agent-state-service-5ge9xxhx.js → agent-state-service-tXUdp6UF.js} +2 -2
- package/dist/dashboard/{agent-state-service-5ge9xxhx.js.map → agent-state-service-tXUdp6UF.js.map} +1 -1
- package/dist/dashboard/{agents-BIggLvi_.js → agents-C-vqmKDi.js} +1 -1
- package/dist/dashboard/{agents-DHvsjsuP.js → agents-C7V4odQ6.js} +11 -11
- package/dist/dashboard/{agents-DHvsjsuP.js.map → agents-C7V4odQ6.js.map} +1 -1
- package/dist/dashboard/{backlog-auto-trigger-COm_R96V.js → backlog-auto-trigger-Cb8PR-5w.js} +2 -2
- package/dist/dashboard/{backlog-auto-trigger-COm_R96V.js.map → backlog-auto-trigger-Cb8PR-5w.js.map} +1 -1
- package/dist/dashboard/{cli-CvK9xuSS.js → cli-BgzbB6h3.js} +2 -2
- package/dist/dashboard/{cli-CvK9xuSS.js.map → cli-BgzbB6h3.js.map} +1 -1
- package/dist/dashboard/cli-DCqy_wFa.js +3 -0
- package/dist/dashboard/{close-issue-BnpErnD1.js → close-issue-BWf3pxn4.js} +2 -2
- package/dist/dashboard/{close-issue-BnpErnD1.js.map → close-issue-BWf3pxn4.js.map} +1 -1
- package/dist/dashboard/{closed-issue-reaper-DRqK5k39.js → closed-issue-reaper-D7XPq5pY.js} +4 -4
- package/dist/dashboard/{closed-issue-reaper-DRqK5k39.js.map → closed-issue-reaper-D7XPq5pY.js.map} +1 -1
- package/dist/dashboard/{closed-issue-reaper-BLCQwTpF.js → closed-issue-reaper-VSTSTROK.js} +1 -1
- package/dist/dashboard/{conflict-gate-JdFuhKuF.js → conflict-gate-DwOslTij.js} +1 -1
- package/dist/dashboard/{conflict-gate-BhKvrPxn.js → conflict-gate-FFEvTDVA.js} +3 -3
- package/dist/dashboard/{conflict-gate-BhKvrPxn.js.map → conflict-gate-FFEvTDVA.js.map} +1 -1
- package/dist/dashboard/{conversation-compaction-C5o_eKEm.js → conversation-compaction-CCqN4hWk.js} +4 -4
- package/dist/dashboard/{conversation-compaction-C5o_eKEm.js.map → conversation-compaction-CCqN4hWk.js.map} +1 -1
- package/dist/dashboard/{conversation-compaction-Ba5aZdrb.js → conversation-compaction-CL5Ti4j4.js} +1 -1
- package/dist/dashboard/{deacon-j3qSZ7--.js → deacon-CGHl90eC.js} +107 -50
- package/dist/dashboard/{deacon-j3qSZ7--.js.map → deacon-CGHl90eC.js.map} +1 -1
- package/dist/dashboard/{deacon-Cv2RMfHs.js → deacon-DMPh40Im.js} +2 -2
- package/dist/dashboard/deacon-swarm-CVTiNL0N.js +2 -0
- package/dist/dashboard/{deacon-swarm-DadWNi5J.js → deacon-swarm-aMMJTq6t.js} +4 -4
- package/dist/dashboard/{deacon-swarm-DadWNi5J.js.map → deacon-swarm-aMMJTq6t.js.map} +1 -1
- package/dist/dashboard/deacon.js +4 -4
- package/dist/dashboard/{feedback-target-oE4-Esxl.js → feedback-target-dJjFfITP.js} +4 -4
- package/dist/dashboard/{feedback-target-oE4-Esxl.js.map → feedback-target-dJjFfITP.js.map} +1 -1
- package/dist/dashboard/{feedback-target-C4DaDSZ8.js → feedback-target-nQSM6ygL.js} +1 -1
- package/dist/dashboard/{flywheel-ClMjGW_u.js → flywheel-BLoVNtJV.js} +6 -6
- package/dist/dashboard/{flywheel-ClMjGW_u.js.map → flywheel-BLoVNtJV.js.map} +1 -1
- package/dist/dashboard/{flywheel-DefHRzY4.js → flywheel-Cqf8vu7N.js} +6 -6
- package/dist/dashboard/{flywheel-DefHRzY4.js.map → flywheel-Cqf8vu7N.js.map} +1 -1
- package/dist/dashboard/{flywheel-BqDdGvrQ.js → flywheel-PJsbrXNY.js} +1 -1
- package/dist/dashboard/{flywheel-merge-order-CuDcqTRJ.js → flywheel-merge-order-B7BH8mZ3.js} +2 -2
- package/dist/dashboard/{flywheel-merge-order-CuDcqTRJ.js.map → flywheel-merge-order-B7BH8mZ3.js.map} +1 -1
- package/dist/dashboard/{flywheel-merge-order-B6YDSElh.js → flywheel-merge-order-CCwF60b-.js} +1 -1
- package/dist/dashboard/{harness-resolve-DKeSVsJL.js → harness-resolve-B3f9G1Kp.js} +2 -2
- package/dist/dashboard/{harness-resolve-DKeSVsJL.js.map → harness-resolve-B3f9G1Kp.js.map} +1 -1
- package/dist/dashboard/{inspect-agent-BKKc0XnB.js → inspect-agent-CKF5-SJr.js} +3 -3
- package/dist/dashboard/{inspect-agent-BKKc0XnB.js.map → inspect-agent-CKF5-SJr.js.map} +1 -1
- package/dist/dashboard/inspect-agent-CqpEWGWy.js +2 -0
- package/dist/dashboard/{issue-lifecycle-DnhQgddB.js → issue-lifecycle-5LbOcATP.js} +7 -7
- package/dist/dashboard/{issue-lifecycle-DnhQgddB.js.map → issue-lifecycle-5LbOcATP.js.map} +1 -1
- package/dist/dashboard/{issue-lifecycle-nY4esZn8.js → issue-lifecycle-CjYqQ669.js} +1 -1
- package/dist/dashboard/{issue-service-singleton-Bnqv1uaa.js → issue-service-singleton-B8iu_TKV.js} +1 -1
- package/dist/dashboard/{issue-service-singleton-_AquSBTl.js → issue-service-singleton-CDGt__oQ.js} +2 -2
- package/dist/dashboard/{issue-service-singleton-_AquSBTl.js.map → issue-service-singleton-CDGt__oQ.js.map} +1 -1
- package/dist/dashboard/{lifecycle-CGKm7doE.js → lifecycle-CEg4sHZH.js} +4 -4
- package/dist/dashboard/{lifecycle-CGKm7doE.js.map → lifecycle-CEg4sHZH.js.map} +1 -1
- package/dist/dashboard/{merge-agent-Dh8Y9PDO.js → merge-agent-7nBiCytp.js} +1 -1
- package/dist/dashboard/{merge-agent-BcgAYStl.js → merge-agent-C81xPIGd.js} +6 -6
- package/dist/dashboard/{merge-agent-BcgAYStl.js.map → merge-agent-C81xPIGd.js.map} +1 -1
- package/dist/dashboard/merge-ops-DE_6CnmZ.js +2 -0
- package/dist/dashboard/{merge-train-DmxlYbEo.js → merge-train-D3qzRccL.js} +2 -2
- package/dist/dashboard/{merge-train-DmxlYbEo.js.map → merge-train-D3qzRccL.js.map} +1 -1
- package/dist/dashboard/{merge-train-deps-DBHsOWt9.js → merge-train-deps-Be5ElC_P.js} +2 -2
- package/dist/dashboard/{merge-train-deps-DBHsOWt9.js.map → merge-train-deps-Be5ElC_P.js.map} +1 -1
- package/dist/dashboard/{orphan-proposed-reconciler-Db8tUhce.js → orphan-proposed-reconciler-Boq_XaRe.js} +3 -3
- package/dist/dashboard/{orphan-proposed-reconciler-Db8tUhce.js.map → orphan-proposed-reconciler-Boq_XaRe.js.map} +1 -1
- package/dist/dashboard/{orphan-proposed-reconciler-mXV--tcB.js → orphan-proposed-reconciler-C0sPnDq_.js} +1 -1
- package/dist/dashboard/{reconstruct-cache-_tDZ2D72.js → reconstruct-cache-C2pCltOq.js} +3 -3
- package/dist/dashboard/{reconstruct-cache-_tDZ2D72.js.map → reconstruct-cache-C2pCltOq.js.map} +1 -1
- package/dist/dashboard/{remote-completion-Bklh6loJ.js → remote-completion-BmxD5UMQ.js} +3 -3
- package/dist/dashboard/{remote-completion-Bklh6loJ.js.map → remote-completion-BmxD5UMQ.js.map} +1 -1
- package/dist/dashboard/resume-C-nxu9Y4.js +3 -0
- package/dist/dashboard/{review-agent-phzqNqIs.js → review-agent-D6P6d3pz.js} +26 -17
- package/dist/dashboard/review-agent-D6P6d3pz.js.map +1 -0
- package/dist/dashboard/review-agent-DTINEffB.js +3 -0
- package/dist/dashboard/{review-context-CCq56O_Y.js → review-context-Dyo0tsBa.js} +2 -2
- package/dist/dashboard/{review-context-CCq56O_Y.js.map → review-context-Dyo0tsBa.js.map} +1 -1
- package/dist/dashboard/{review-status-BQjqQXZG.js → review-status-B5ZASOo4.js} +18 -5
- package/dist/dashboard/review-status-B5ZASOo4.js.map +1 -0
- package/dist/dashboard/{review-status-bBkqUj5i.js → review-status-h7BXIA4z.js} +1 -1
- package/dist/dashboard/{review-verdict-feedback-wqnikhMK.js → review-verdict-feedback-B70VbfRL.js} +4 -4
- package/dist/dashboard/{review-verdict-feedback-wqnikhMK.js.map → review-verdict-feedback-B70VbfRL.js.map} +1 -1
- package/dist/dashboard/{review-verdict-feedback-cZh9Wi9G.js → review-verdict-feedback-CorgH49f.js} +1 -1
- package/dist/dashboard/{sequence-io-B2GmilSI.js → sequence-io-6YP8fVpH.js} +2 -2
- package/dist/dashboard/{sequence-io-B2GmilSI.js.map → sequence-io-6YP8fVpH.js.map} +1 -1
- package/dist/dashboard/{sequencer-agent-D8pW2aU_.js → sequencer-agent-ja-nkEc1.js} +5 -5
- package/dist/dashboard/{sequencer-agent-D8pW2aU_.js.map → sequencer-agent-ja-nkEc1.js.map} +1 -1
- package/dist/dashboard/server.js +66 -55
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/{service-CILd-uOt.js → service-HKDrIy0h.js} +24 -24
- package/dist/dashboard/{service-CILd-uOt.js.map → service-HKDrIy0h.js.map} +1 -1
- package/dist/dashboard/{smart-compaction-Bgp_gwcA.js → smart-compaction-L0LSnF0_.js} +1 -1
- package/dist/dashboard/{smart-compaction-CrP90OFE.js → smart-compaction-uke1npUz.js} +2 -2
- package/dist/dashboard/{smart-compaction-CrP90OFE.js.map → smart-compaction-uke1npUz.js.map} +1 -1
- package/dist/dashboard/{spawn-planning-session-D15KbPOy.js → spawn-planning-session-CSMWco8B.js} +1 -1
- package/dist/dashboard/{spawn-planning-session-BmJWHSCu.js → spawn-planning-session-CXc0NkwV.js} +3 -3
- package/dist/dashboard/{spawn-planning-session-BmJWHSCu.js.map → spawn-planning-session-CXc0NkwV.js.map} +1 -1
- package/dist/dashboard/{specialist-context-CwKkcXL9.js → specialist-context-BGCJ24LH.js} +3 -3
- package/dist/dashboard/{specialist-context-CwKkcXL9.js.map → specialist-context-BGCJ24LH.js.map} +1 -1
- package/dist/dashboard/{specialist-logs-CvDxquV_.js → specialist-logs--Uz-r8ia.js} +2 -2
- package/dist/dashboard/{specialist-logs-CvDxquV_.js.map → specialist-logs--Uz-r8ia.js.map} +1 -1
- package/dist/dashboard/{specialists-BCjcG4uE.js → specialists-Ca9XSBCS.js} +1 -1
- package/dist/dashboard/{specialists-D07ybnam.js → specialists-DEfrAbWs.js} +36 -36
- package/dist/dashboard/{specialists-D07ybnam.js.map → specialists-DEfrAbWs.js.map} +1 -1
- package/dist/dashboard/{specialists-F2uMO4QS.js → specialists-DeZx9xom.js} +1 -1
- package/dist/dashboard/{specialists-BYi0k8CZ.js → specialists-nZ0mRwpZ.js} +12 -12
- package/dist/dashboard/{specialists-BYi0k8CZ.js.map → specialists-nZ0mRwpZ.js.map} +1 -1
- package/dist/dashboard/{summary-fork-DedqguZb.js → summary-fork-2a1L2DIU.js} +2 -2
- package/dist/dashboard/{summary-fork-EjvOkEPl.js → summary-fork-Xn0QUNmb.js} +3 -3
- package/dist/dashboard/{summary-fork-EjvOkEPl.js.map → summary-fork-Xn0QUNmb.js.map} +1 -1
- package/dist/dashboard/{teardown-workspace-5LCVbjfq.js → teardown-workspace-DhA6oAIK.js} +2 -2
- package/dist/dashboard/{teardown-workspace-5LCVbjfq.js.map → teardown-workspace-DhA6oAIK.js.map} +1 -1
- package/dist/dashboard/{test-agent-queue-qfsq6uaC.js → test-agent-queue-B_ukPyIK.js} +3 -3
- package/dist/dashboard/{test-agent-queue-qfsq6uaC.js.map → test-agent-queue-B_ukPyIK.js.map} +1 -1
- package/dist/dashboard/{uat-train-CtNGgXxj.js → uat-train-BLBAbJ8Y.js} +10 -10
- package/dist/dashboard/{uat-train-CtNGgXxj.js.map → uat-train-BLBAbJ8Y.js.map} +1 -1
- package/dist/dashboard/{uat-train-C3hWXtip.js → uat-train-DPfGR9_I.js} +1 -1
- package/dist/dashboard/{verification-runner-DuZRHjPU.js → verification-runner-KTGTNugM.js} +1 -1
- package/dist/dashboard/{verification-runner-BPAhPWR7.js → verification-runner-R2-4XgMO.js} +4 -4
- package/dist/dashboard/{verification-runner-BPAhPWR7.js.map → verification-runner-R2-4XgMO.js.map} +1 -1
- package/dist/dashboard/{workflows-H-COJ84X.js → workflows-CSKX5MhC.js} +7 -7
- package/dist/dashboard/{workflows-H-COJ84X.js.map → workflows-CSKX5MhC.js.map} +1 -1
- package/dist/dashboard/workflows-DVwXauef.js +2 -0
- package/dist/dashboard/{workspaces-CRU9_vRn.js → workspaces-DXLDgXo2.js} +32 -32
- package/dist/dashboard/{workspaces-CRU9_vRn.js.map → workspaces-DXLDgXo2.js.map} +1 -1
- package/dist/docs-index.sqlite +0 -0
- package/dist/{feedback-target-DTGAhFkM.js → feedback-target-BsKN4Tr_.js} +4 -4
- package/dist/{feedback-target-DTGAhFkM.js.map → feedback-target-BsKN4Tr_.js.map} +1 -1
- package/dist/{feedback-target-DutF088V.js → feedback-target-DM1WzOKy.js} +1 -1
- package/dist/{harness-resolve-Bz1prk6B.js → harness-resolve-B-YDNwNW.js} +2 -2
- package/dist/{harness-resolve-Bz1prk6B.js.map → harness-resolve-B-YDNwNW.js.map} +1 -1
- package/dist/{issue-lifecycle-fVqvCdKM.js → issue-lifecycle-Bc1l3U9f.js} +7 -7
- package/dist/{issue-lifecycle-fVqvCdKM.js.map → issue-lifecycle-Bc1l3U9f.js.map} +1 -1
- package/dist/{issue-service-singleton-CZm8p6Rj.js → issue-service-singleton-D-8Q6tdT.js} +1 -1
- package/dist/{issue-service-singleton-Cr73JAaR.js → issue-service-singleton-D1433I7n.js} +2 -2
- package/dist/{issue-service-singleton-Cr73JAaR.js.map → issue-service-singleton-D1433I7n.js.map} +1 -1
- package/dist/{lifecycle-CR6tZfl1.js → lifecycle-SmrqysDf.js} +7 -7
- package/dist/{lifecycle-CR6tZfl1.js.map → lifecycle-SmrqysDf.js.map} +1 -1
- package/dist/{lifecycle-D_EWiUjk.js → lifecycle-mRMyiIXs.js} +2 -2
- package/dist/{merge-agent-LM4avOtA.js → merge-agent-B9hIZ6Z0.js} +6 -6
- package/dist/{merge-agent-LM4avOtA.js.map → merge-agent-B9hIZ6Z0.js.map} +1 -1
- package/dist/{merge-agent-Bj046HE1.js → merge-agent-DUj22cXL.js} +1 -1
- package/dist/{merge-fulfillment-DrnC1Kmg.js → merge-fulfillment-__P4WE-T.js} +3 -3
- package/dist/{merge-fulfillment-DrnC1Kmg.js.map → merge-fulfillment-__P4WE-T.js.map} +1 -1
- package/dist/{reconstruct-cache-NPqoAUg-.js → reconstruct-cache-9SWp82SQ.js} +3 -3
- package/dist/{reconstruct-cache-NPqoAUg-.js.map → reconstruct-cache-9SWp82SQ.js.map} +1 -1
- package/dist/{records-BIkN1LQ4.js → records-CTmvuRzz.js} +14 -1
- package/dist/{records-BIkN1LQ4.js.map → records-CTmvuRzz.js.map} +1 -1
- package/dist/records-backfill-BQcmTmwF.js +2 -0
- package/dist/{records-backfill-HM0Pln6N.js → records-backfill-BrNsv_zT.js} +2 -2
- package/dist/{records-backfill-HM0Pln6N.js.map → records-backfill-BrNsv_zT.js.map} +1 -1
- package/dist/resume-Bn4kDk9x.js +3 -0
- package/dist/{review-agent-DFosQzCG.js → review-agent-PhqOhpx3.js} +24 -16
- package/dist/{review-agent-DFosQzCG.js.map → review-agent-PhqOhpx3.js.map} +1 -1
- package/dist/review-agent-hLbRRxZF.js +3 -0
- package/dist/{review-status-iJwfEoNX.js → review-status-B_XXomV0.js} +6 -6
- package/dist/{review-status-iJwfEoNX.js.map → review-status-B_XXomV0.js.map} +1 -1
- package/dist/{review-status-BbNVlXh1.js → review-status-Bo-EFVKh.js} +1 -1
- package/dist/{review-verdict-feedback-BGPw3z1X.js → review-verdict-feedback-CXHkoiKZ.js} +1 -1
- package/dist/{review-verdict-feedback-CCZ05atV.js → review-verdict-feedback-DGV13LDb.js} +4 -4
- package/dist/{review-verdict-feedback-CCZ05atV.js.map → review-verdict-feedback-DGV13LDb.js.map} +1 -1
- package/dist/{sequence-io-CcxZNHcD.js → sequence-io-Cg4NHAco.js} +1 -1
- package/dist/{sequence-io-Cx1usxG3.js → sequence-io-CyxvNHfA.js} +2 -2
- package/dist/{sequence-io-Cx1usxG3.js.map → sequence-io-CyxvNHfA.js.map} +1 -1
- package/dist/{smart-compaction-ByUEgQkF.js → smart-compaction-ByKXTQNy.js} +2 -2
- package/dist/{smart-compaction-ByUEgQkF.js.map → smart-compaction-ByKXTQNy.js.map} +1 -1
- package/dist/{smart-compaction-DfLe_CtH.js → smart-compaction-U6e_uB1E.js} +1 -1
- package/dist/{specialist-context-McuGkaeR.js → specialist-context-BUTadO-U.js} +3 -3
- package/dist/{specialist-context-McuGkaeR.js.map → specialist-context-BUTadO-U.js.map} +1 -1
- package/dist/{specialist-logs-CUUJ4eiB.js → specialist-logs-pEMCTtGZ.js} +2 -2
- package/dist/{specialist-logs-CUUJ4eiB.js.map → specialist-logs-pEMCTtGZ.js.map} +1 -1
- package/dist/{specialists-BSrylD1S.js → specialists-BGFnrQ8n.js} +1 -1
- package/dist/{specialists-B0elgInc.js → specialists-DeTkkp8b.js} +12 -12
- package/dist/{specialists-B0elgInc.js.map → specialists-DeTkkp8b.js.map} +1 -1
- package/dist/{summary-fork-DskMRnyb.js → summary-fork-CgzThE2-.js} +2 -2
- package/dist/{summary-fork-CPUTKcAT.js → summary-fork-Dx1RMuvU.js} +3 -3
- package/dist/{summary-fork-CPUTKcAT.js.map → summary-fork-Dx1RMuvU.js.map} +1 -1
- package/dist/{sync-BiNVQHBf.js → sync-Bsww9tuj.js} +2 -2
- package/dist/{sync-BiNVQHBf.js.map → sync-Bsww9tuj.js.map} +1 -1
- package/dist/sync-CylE_SjB.js +2 -0
- package/dist/{verdict-restore-DQiV7_fe.js → verdict-restore-DGpX0ZOJ.js} +5 -5
- package/dist/{verdict-restore-DQiV7_fe.js.map → verdict-restore-DGpX0ZOJ.js.map} +1 -1
- package/dist/{webhook-handlers-DHBSEDEm.js → webhook-handlers-BjsfIL7u.js} +3 -3
- package/dist/{webhook-handlers-DHBSEDEm.js.map → webhook-handlers-BjsfIL7u.js.map} +1 -1
- package/dist/{workspace-migrate-duUsWNpd.js → workspace-migrate-BBQ8nAnP.js} +2 -2
- package/dist/{workspace-migrate-duUsWNpd.js.map → workspace-migrate-BBQ8nAnP.js.map} +1 -1
- package/dist/{workspace-reap-DLCIoJmn.js → workspace-reap-12O9354k.js} +2 -2
- package/dist/{workspace-reap-DLCIoJmn.js.map → workspace-reap-12O9354k.js.map} +1 -1
- package/package.json +1 -1
- package/scripts/file-size-baseline.txt +1 -1
- package/dist/cli-DBWG12XK.js +0 -3
- package/dist/dashboard/cli-CJDWXE_Y.js +0 -3
- package/dist/dashboard/deacon-swarm-D1iAUX-P.js +0 -2
- package/dist/dashboard/inspect-agent-vm88mLYr.js +0 -2
- package/dist/dashboard/merge-ops-QdBiQ8XB.js +0 -2
- package/dist/dashboard/resume-DnIsmIgC.js +0 -3
- package/dist/dashboard/review-agent-DgySDb-G.js +0 -3
- package/dist/dashboard/review-agent-phzqNqIs.js.map +0 -1
- package/dist/dashboard/review-status-BQjqQXZG.js.map +0 -1
- package/dist/dashboard/workflows-Cz8OtiB4.js +0 -2
- package/dist/records-backfill-DEgtRyKL.js +0 -2
- package/dist/resume-DGymuXZM.js +0 -3
- package/dist/review-agent-DjVadURa.js +0 -3
- package/dist/sync-4jqukkxz.js +0 -2
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as runModelSummary, c as truncateHeadTail, i as parseEntries, n as generateSummaryFromPrompt, o as serializeConversation, r as init_smart_compaction, s as summarizeSerializedText, t as generateSmartSummary } from "./smart-compaction-
|
|
1
|
+
import { a as runModelSummary, c as truncateHeadTail, i as parseEntries, n as generateSummaryFromPrompt, o as serializeConversation, r as init_smart_compaction, s as summarizeSerializedText, t as generateSmartSummary } from "./smart-compaction-uke1npUz.js";
|
|
2
2
|
init_smart_compaction();
|
|
3
3
|
export { generateSmartSummary, generateSummaryFromPrompt, parseEntries, runModelSummary, serializeConversation, summarizeSerializedText, truncateHeadTail };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as __esmMin } from "./rolldown-runtime-DNCzzKnI.js";
|
|
2
2
|
import { cr as FsError, mr as ProcessSpawnError, vr as init_errors } from "./config-yaml-DPAieL_G.js";
|
|
3
3
|
import { a as getHarnessBehavior } from "./src-fgbU-jJ-.js";
|
|
4
|
-
import { D as init_context_overflow, O as isContextOverflowError, ln as getProviderEnvForModel, sn as buildSpawnEnvForModel, t as init_agents } from "./agents-
|
|
4
|
+
import { D as init_context_overflow, O as isContextOverflowError, ln as getProviderEnvForModel, sn as buildSpawnEnvForModel, t as init_agents } from "./agents-C7V4odQ6.js";
|
|
5
5
|
import { t as init_behavior } from "./behavior-By-2Wipv.js";
|
|
6
6
|
import { a as init_claude_permissions, i as getClaudePermissionFlagsSync } from "./claude-permissions-DrRAs_0F.js";
|
|
7
7
|
import { n as recordBackgroundAiCost, t as init_cost } from "./cost-DaOG8sUB.js";
|
|
@@ -850,4 +850,4 @@ Be thorough. Preserve exact file paths, function names, error messages, and code
|
|
|
850
850
|
//#endregion
|
|
851
851
|
export { runModelSummary as a, truncateHeadTail as c, parseEntries as i, generateSummaryFromPrompt as n, serializeConversation as o, init_smart_compaction as r, summarizeSerializedText as s, generateSmartSummary as t };
|
|
852
852
|
|
|
853
|
-
//# sourceMappingURL=smart-compaction-
|
|
853
|
+
//# sourceMappingURL=smart-compaction-uke1npUz.js.map
|
package/dist/dashboard/{smart-compaction-CrP90OFE.js.map → smart-compaction-uke1npUz.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smart-compaction-CrP90OFE.js","names":["self.runModelSummary"],"sources":["../../src/lib/conversations/smart-compaction.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport { mkdtemp, readFile, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { Effect } from 'effect';\nimport * as self from './smart-compaction.js';\nimport { buildSpawnEnvForModel, getProviderEnvForModel } from '../agents.js';\nimport { getClaudePermissionFlagsSync } from '../claude-permissions.js';\nimport { getHarnessBehavior } from '../runtimes/behavior.js';\nimport type { RuntimeName } from '../runtimes/types.js';\nimport { FsError, ProcessSpawnError } from '../errors.js';\nimport { recordBackgroundAiCost } from '../background-ai/cost.js';\nimport type { AIProvider } from '../cost.js';\nimport { isContextOverflowError } from '../context-overflow.js';\n\n/** Record summary-fork/compaction spend from a `claude -p --output-format json`\n * envelope. Best-effort; never throws into the caller (PAN-1589). */\nfunction recordSummaryForkCost(model: string, envelope: Record<string, unknown>): void {\n const usage = (envelope['usage'] ?? {}) as Record<string, unknown>;\n const num = (v: unknown): number => (typeof v === 'number' ? v : 0);\n const m = model.toLowerCase();\n const provider: AIProvider = m.includes('gpt') ? 'openai' : m.includes('gemini') ? 'google' : 'anthropic';\n recordBackgroundAiCost({\n feature: 'summaryFork',\n provider,\n model,\n usage: {\n inputTokens: num(usage['input_tokens']),\n outputTokens: num(usage['output_tokens']),\n cacheReadTokens: num(usage['cache_read_input_tokens']),\n cacheWriteTokens: num(usage['cache_creation_input_tokens']),\n },\n costUsd: typeof envelope['total_cost_usd'] === 'number' ? (envelope['total_cost_usd'] as number) : undefined,\n });\n}\n\nconst SUMMARY_TIMEOUT_MS = 60_000;\nconst FORK_SUMMARY_TIMEOUT_MS = 300_000;\nconst DEFAULT_SUMMARY_MODEL = 'claude-haiku-4-5-20251001';\n\nexport interface CompactionOptions {\n jsonlPath: string;\n model?: string;\n keepRecentTokens?: number;\n reserveTokens?: number;\n richMode?: boolean;\n /** 'compact' = native compaction (returns stub if nothing to summarize). 'fork' = always produce a real summary for conversation forks. */\n mode?: 'compact' | 'fork';\n /** When true, include thinking block content in the serialized conversation sent to the summary model. Default: true. */\n includeThinkingInSummary?: boolean;\n /** Runtime harness used for model-backed summary generation. */\n harness?: RuntimeName;\n}\n\nexport interface CompactionResult {\n summary: string;\n tokensBefore: number;\n firstKeptEntryIndex: number;\n summaryModel: string | null;\n readFiles: string[];\n modifiedFiles: string[];\n}\n\ninterface FileOperations {\n read: Set<string>;\n written: Set<string>;\n edited: Set<string>;\n}\n\ninterface CutPointResult {\n firstKeptEntryIndex: number;\n turnStartIndex: number;\n isSplitTurn: boolean;\n}\n\n// ============================================================================\n// Entry parsing\n// ============================================================================\n\nexport async function parseEntries(jsonlPath: string): Promise<any[]> {\n const content = await readFile(jsonlPath, 'utf-8');\n const entries: any[] = [];\n for (const line of content.split('\\n')) {\n if (!line.trim()) continue;\n try {\n entries.push(JSON.parse(line));\n } catch {\n // skip malformed\n }\n }\n return entries;\n}\n\n// ============================================================================\n// Token estimation (chars/4 heuristic, conservative)\n// ============================================================================\n\nfunction estimateTokens(entry: any): number {\n if (!entry) return 0;\n\n // Compact boundary / system entries\n if (entry.type === 'system' || entry.subtype === 'compact_boundary') {\n const text = entry.content || '';\n return Math.ceil(text.length / 4);\n }\n\n // User entries (including compact summaries and tool results)\n if (entry.type === 'user' && entry.message) {\n const content = entry.message.content;\n if (typeof content === 'string') {\n return Math.ceil(content.length / 4);\n }\n if (Array.isArray(content)) {\n let chars = 0;\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n chars += block.text.length;\n } else if (block.type === 'tool_result') {\n // Estimate tool result content\n if (typeof block.content === 'string') {\n chars += block.content.length;\n } else if (Array.isArray(block.content)) {\n for (const b of block.content) {\n if (b.text) chars += b.text.length;\n }\n }\n } else if (block.type === 'image') {\n chars += 4800; // ~1200 tokens\n }\n }\n return Math.ceil(chars / 4);\n }\n }\n\n // Assistant entries\n if (entry.type === 'assistant' && entry.message) {\n const content = entry.message.content;\n if (Array.isArray(content)) {\n let chars = 0;\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n chars += block.text.length;\n } else if (block.type === 'thinking' && block.thinking) {\n chars += block.thinking.length;\n } else if (block.type === 'tool_use') {\n chars += block.name?.length || 0;\n chars += JSON.stringify(block.input || {}).length;\n }\n }\n return Math.ceil(chars / 4);\n }\n if (typeof content === 'string') {\n return Math.ceil(content.length / 4);\n }\n }\n\n return 0;\n}\n\nfunction estimateContextTokens(entries: any[]): number {\n // Use the last assistant usage if available, otherwise heuristic\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n if (entry.type === 'assistant' && entry.message?.usage) {\n const u = entry.message.usage;\n if (typeof u.input_tokens === 'number') {\n let total = u.input_tokens || 0;\n if (typeof u.output_tokens === 'number') total += u.output_tokens;\n if (typeof u.cache_creation_input_tokens === 'number') total += u.cache_creation_input_tokens;\n if (typeof u.cache_read_input_tokens === 'number') total += u.cache_read_input_tokens;\n if (total <= 0) continue;\n // Add trailing entries after this assistant\n for (let j = i + 1; j < entries.length; j++) {\n total += estimateTokens(entries[j]);\n }\n return total;\n }\n if (typeof u.inputTokens === 'number') {\n let total = u.inputTokens || 0;\n if (typeof u.outputTokens === 'number') total += u.outputTokens;\n if (typeof u.cacheCreationInputTokens === 'number') total += u.cacheCreationInputTokens;\n if (typeof u.cacheReadInputTokens === 'number') total += u.cacheReadInputTokens;\n if (total <= 0) continue;\n for (let j = i + 1; j < entries.length; j++) {\n total += estimateTokens(entries[j]);\n }\n return total;\n }\n }\n }\n\n // Fallback: sum all heuristics\n return entries.reduce((sum, e) => sum + estimateTokens(e), 0);\n}\n\n// ============================================================================\n// File operation tracking\n// ============================================================================\n\nfunction createFileOps(): FileOperations {\n return { read: new Set(), written: new Set(), edited: new Set() };\n}\n\nfunction extractFileOpsFromEntries(entries: any[]): FileOperations {\n const fileOps = createFileOps();\n for (const entry of entries) {\n if (entry.type !== 'assistant' || !entry.message?.content) continue;\n const content = entry.message.content;\n if (!Array.isArray(content)) continue;\n for (const block of content) {\n if (block.type !== 'tool_use' || !block.input) continue;\n const path = block.input.file_path || block.input.path;\n if (!path) continue;\n switch (block.name) {\n case 'Read':\n case 'read':\n fileOps.read.add(path);\n break;\n case 'Write':\n case 'write':\n fileOps.written.add(path);\n break;\n case 'Edit':\n case 'edit':\n fileOps.edited.add(path);\n break;\n }\n }\n }\n return fileOps;\n}\n\nfunction computeFileLists(fileOps: FileOperations): { readFiles: string[]; modifiedFiles: string[] } {\n const modified = new Set([...fileOps.edited, ...fileOps.written]);\n const readOnly = [...fileOps.read].filter(f => !modified.has(f)).sort();\n return { readFiles: readOnly, modifiedFiles: [...modified].sort() };\n}\n\nfunction formatFileOperations(readFiles: string[], modifiedFiles: string[]): string {\n const sections: string[] = [];\n if (readFiles.length > 0) {\n sections.push(`<read-files>\\n${readFiles.join('\\n')}\\n</read-files>`);\n }\n if (modifiedFiles.length > 0) {\n sections.push(`<modified-files>\\n${modifiedFiles.join('\\n')}\\n</modified-files>`);\n }\n if (sections.length === 0) return '';\n return '\\n\\n' + sections.join('\\n\\n');\n}\n\n// ============================================================================\n// Previous compact boundary detection\n// ============================================================================\n\nfunction findPreviousCompactBoundary(entries: any[]): { index: number; summary: string } | null {\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n // Overdeck native compaction writes compact_boundary then a user summary entry\n if (entry.type === 'system' && entry.subtype === 'compact_boundary') {\n // Look immediately after for the summary user message\n if (i + 1 < entries.length) {\n const next = entries[i + 1];\n if (next.type === 'user' && next.isCompactSummary && next.message?.content) {\n return { index: i, summary: next.message.content };\n }\n }\n }\n // Also detect older compact summary entries\n if (entry.type === 'user' && entry.isCompactSummary && entry.message?.content) {\n return { index: i, summary: entry.message.content };\n }\n }\n return null;\n}\n\n// ============================================================================\n// Cut point detection (inspired by Pi agent)\n// ============================================================================\n\nfunction isUserMessageEntry(entry: any): boolean {\n if (entry.type !== 'user' || !entry.message) return false;\n const content = entry.message.content;\n // A pure tool_result user entry is not a turn-starting user message\n if (Array.isArray(content)) {\n const hasText = content.some((b: any) => b.type === 'text' && b.text?.trim());\n return hasText;\n }\n if (typeof content === 'string') {\n return content.trim().length > 0;\n }\n return false;\n}\n\nfunction isAssistantEntry(entry: any): boolean {\n return entry.type === 'assistant' && !!entry.message;\n}\n\nfunction findValidCutPoints(entries: any[], startIndex: number, endIndex: number): number[] {\n const cutPoints: number[] = [];\n for (let i = startIndex; i < endIndex; i++) {\n if (isUserMessageEntry(entries[i]) || isAssistantEntry(entries[i])) {\n cutPoints.push(i);\n }\n }\n return cutPoints;\n}\n\nfunction findTurnStartIndex(entries: any[], entryIndex: number, startIndex: number): number {\n for (let i = entryIndex; i >= startIndex; i--) {\n if (isUserMessageEntry(entries[i])) {\n return i;\n }\n }\n return -1;\n}\n\nfunction findCutPoint(\n entries: any[],\n startIndex: number,\n endIndex: number,\n keepRecentTokens: number,\n): CutPointResult {\n const cutPoints = findValidCutPoints(entries, startIndex, endIndex);\n if (cutPoints.length === 0) {\n return { firstKeptEntryIndex: startIndex, turnStartIndex: -1, isSplitTurn: false };\n }\n\n let accumulatedTokens = 0;\n let cutIndex = cutPoints[0];\n\n for (let i = endIndex - 1; i >= startIndex; i--) {\n const tokens = estimateTokens(entries[i]);\n accumulatedTokens += tokens;\n\n if (accumulatedTokens >= keepRecentTokens) {\n for (let c = 0; c < cutPoints.length; c++) {\n if (cutPoints[c] >= i) {\n cutIndex = cutPoints[c];\n break;\n }\n }\n break;\n }\n }\n\n // Scan backwards to include non-message metadata entries after a boundary.\n // Never scan past the previous valid cut point (or the original cut point\n // itself if it's the first valid one).\n const originalCutIndex = cutIndex;\n const cutPointArrayIndex = cutPoints.findIndex((cp) => cp === originalCutIndex);\n const minCutIndex = cutPointArrayIndex > 0 ? cutPoints[cutPointArrayIndex - 1]! + 1 : originalCutIndex;\n\n while (cutIndex > startIndex && cutIndex > minCutIndex) {\n const prev = entries[cutIndex - 1];\n if (prev.type === 'system' && prev.subtype === 'compact_boundary') break;\n if (isUserMessageEntry(prev) || isAssistantEntry(prev)) break;\n cutIndex--;\n }\n\n const isUser = isUserMessageEntry(entries[cutIndex]);\n const turnStartIndex = isUser ? -1 : findTurnStartIndex(entries, cutIndex, startIndex);\n\n return {\n firstKeptEntryIndex: cutIndex,\n turnStartIndex,\n isSplitTurn: !isUser && turnStartIndex !== -1,\n };\n}\n\n// ============================================================================\n// Conversation serialization\n// ============================================================================\n\nconst TOOL_RESULT_MAX_CHARS = 2000;\n\nfunction truncateForSummary(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text;\n return `${text.slice(0, maxChars)}\\n\\n[... ${text.length - maxChars} more characters truncated]`;\n}\n\nfunction serializeEntry(entry: any, includeThinking: boolean = true): string | undefined {\n if (entry.type === 'user' && entry.message) {\n const content = entry.message.content;\n let text = '';\n if (typeof content === 'string') {\n text = content;\n } else if (Array.isArray(content)) {\n const parts: string[] = [];\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n parts.push(block.text);\n } else if (block.type === 'tool_result') {\n let resultText = '';\n if (typeof block.content === 'string') {\n resultText = block.content;\n } else if (Array.isArray(block.content)) {\n resultText = block.content\n .filter((b: any) => b.type === 'text' && b.text)\n .map((b: any) => b.text)\n .join('\\n');\n }\n if (resultText) {\n parts.push(`[Tool result]: ${truncateForSummary(resultText, TOOL_RESULT_MAX_CHARS)}`);\n }\n }\n }\n text = parts.join('\\n');\n }\n if (text.trim()) {\n return `[User]: ${text.trim()}`;\n }\n }\n\n if (entry.type === 'assistant' && entry.message) {\n const content = entry.message.content;\n const parts: string[] = [];\n if (Array.isArray(content)) {\n const textParts: string[] = [];\n const toolCalls: string[] = [];\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n textParts.push(block.text);\n } else if (block.type === 'thinking' && block.thinking && includeThinking) {\n textParts.push(`[thinking]: ${block.thinking}`);\n } else if (block.type === 'tool_use') {\n const args = block.input || {};\n const argsStr = Object.entries(args)\n .map(([k, v]) => `${k}=${JSON.stringify(v)}`)\n .join(', ');\n toolCalls.push(`${block.name}(${argsStr})`);\n }\n }\n if (textParts.length) parts.push(`[Assistant]: ${textParts.join('\\n')}`);\n if (toolCalls.length) parts.push(`[Assistant tool calls]: ${toolCalls.join('; ')}`);\n } else if (typeof content === 'string') {\n parts.push(`[Assistant]: ${content}`);\n }\n if (parts.length) {\n return parts.join('\\n\\n');\n }\n }\n\n if (entry.type === 'system' && entry.subtype === 'compact_boundary' && entry.content) {\n return `[Context checkpoint]: ${entry.content}`;\n }\n\n return undefined;\n}\n\nexport function serializeConversation(entries: any[], includeThinking: boolean = true): string {\n const parts: string[] = [];\n for (const entry of entries) {\n const serialized = serializeEntry(entry, includeThinking);\n if (serialized) parts.push(serialized);\n }\n return parts.join('\\n\\n');\n}\n\n// ============================================================================\n// Summarization prompts\n// ============================================================================\n\nconst SUMMARIZATION_SYSTEM_PROMPT = `You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`;\n\nconst SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work.\n\nUse this EXACT format:\n\n## Goal\n[What is the user trying to accomplish? Can be multiple items if the session covers different tasks.]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements mentioned by user]\n- [Or \"(none)\" if none were mentioned]\n\n## Progress\n### Done\n- [x] [Completed tasks/changes]\n\n### In Progress\n- [ ] [Current work]\n\n### Blocked\n- [Issues preventing progress, if any]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Ordered list of what should happen next]\n\n## Critical Context\n- [Any data, examples, or references needed to continue]\n- [Or \"(none)\" if not applicable]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`;\n\nconst UPDATE_SUMMARIZATION_PROMPT = `The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.\n\nUpdate the existing structured summary with new information. RULES:\n- PRESERVE all existing information from the previous summary\n- ADD new progress, decisions, and context from the new messages\n- UPDATE the Progress section: move items from \"In Progress\" to \"Done\" when completed\n- UPDATE \"Next Steps\" based on what was accomplished\n- PRESERVE exact file paths, function names, and error messages\n- If something is no longer relevant, you may remove it\n\nUse this EXACT format:\n\n## Goal\n[Preserve existing goals, add new ones if the task expanded]\n\n## Constraints & Preferences\n- [Preserve existing, add new ones discovered]\n\n## Progress\n### Done\n- [x] [Include previously done items AND newly completed items]\n\n### In Progress\n- [ ] [Current work - update based on progress]\n\n### Blocked\n- [Current blockers - remove if resolved]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale] (preserve all previous, add new)\n\n## Next Steps\n1. [Update based on current state]\n\n## Critical Context\n- [Preserve important context, add new if needed]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`;\n\nconst TURN_PREFIX_PROMPT = `This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.`;\n\n// ============================================================================\n// Rich summarization prompts (9-section format, more verbose)\n// ============================================================================\n\nconst RICH_SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a comprehensive continuation summary that another LLM will use to continue the work without losing context.\n\nUse this EXACT format:\n\n## Primary Request and Intent\n[What is the user trying to accomplish? Include explicit asks, constraints, and intended outcome.]\n\n## Key Technical Concepts\n- [Major technical topics, tools, frameworks, libraries, patterns, and architectural ideas]\n- [Or \"(none)\" if none were mentioned]\n\n## Files and Code Sections\n- [File name]: [why it matters, what was examined or changed, include important code snippets in full when applicable]\n- [Or \"(none)\" if not applicable]\n\n## Errors and fixes\n- [What went wrong and how it was fixed or addressed]\n- [Or \"(none)\" if none occurred]\n\n## Problem Solving\n[Problems resolved and any ongoing troubleshooting]\n\n## All user messages\n- [Every user message in the conversation that was not a tool result. Do not omit any.]\n- [Or \"(none)\" if not applicable]\n\n## Pending Tasks\n- [All unfinished work the user has explicitly asked for]\n- [Or \"(none)\" if not applicable]\n\n## Current Work\n[Exactly what was being worked on immediately before this summarization request. Focus on the latest messages.]\n\n## Optional Next Step\n[The next action that should be taken, but only if it directly follows from the user's most recent request. Include exact quoted lines where useful.]\n\nBe thorough, specific, and technically accurate. Preserve exact file paths, function names, error messages, and code snippets.`;\n\nconst RICH_UPDATE_SUMMARIZATION_PROMPT = `The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.\n\nUpdate the existing structured summary with new information. RULES:\n- PRESERVE all existing information from the previous summary\n- ADD new progress, decisions, user messages, and context from the new messages\n- UPDATE the \"Current Work\" section to reflect the latest state\n- UPDATE \"Pending Tasks\" based on what was completed or newly requested\n- PRESERVE exact file paths, function names, error messages, and code snippets\n- If something is no longer relevant, you may remove it\n\nUse this EXACT format:\n\n## Primary Request and Intent\n[Preserve existing intent, add new ones if the task expanded]\n\n## Key Technical Concepts\n- [Preserve existing, add new ones discovered]\n\n## Files and Code Sections\n- [Preserve existing files, add new ones, update changed ones with full code snippets]\n\n## Errors and fixes\n- [Preserve existing, add new ones, mark resolved if appropriate]\n\n## Problem Solving\n[Update with new resolutions and ongoing troubleshooting]\n\n## All user messages\n- [Preserve existing user messages, add new ones from the recent conversation]\n\n## Pending Tasks\n- [Update based on what was completed or newly requested]\n\n## Current Work\n[Update to reflect the latest state immediately before this request]\n\n## Optional Next Step\n[Update based on current state]\n\nBe thorough. Preserve exact file paths, function names, error messages, and code snippets.`;\n\n// ============================================================================\n// LLM call\n// ============================================================================\n\nasync function runPiModelSummary(prompt: string, model: string, timeoutMs?: number): Promise<string> {\n const sessionDir = await mkdtemp(join(tmpdir(), 'overdeck-pi-summary-'));\n const effectiveTimeout = timeoutMs ?? SUMMARY_TIMEOUT_MS;\n const spawnEnv = await buildSpawnEnvForModel(model);\n\n const child = spawn('omp', [\n '--mode', 'rpc',\n '--model', model,\n '--session-dir', sessionDir,\n '--no-context-files',\n ], {\n env: spawnEnv,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n child.stdout.setEncoding('utf-8');\n child.stderr.setEncoding('utf-8');\n child.stdout.on('data', chunk => { stdout += chunk; });\n child.stderr.on('data', chunk => { stderr += chunk; });\n\n try {\n return await new Promise<string>((resolve, reject) => {\n const timeout = setTimeout(() => {\n child.kill('SIGTERM');\n reject(new Error(`Pi summary generation timed out after ${effectiveTimeout}ms`));\n }, effectiveTimeout);\n\n child.on('error', err => {\n clearTimeout(timeout);\n reject(err);\n });\n child.on('close', code => {\n clearTimeout(timeout);\n if (code !== 0 && !stdout.trim()) {\n const detail = stderr.trim() || `exit code ${code}`;\n reject(new Error(`Pi summary generation failed: ${detail}`));\n return;\n }\n const summary = stdout.trim();\n if (!summary) {\n reject(new Error('Pi summary generation returned empty output'));\n return;\n }\n resolve(summary);\n });\n\n child.stdin.end(`${JSON.stringify({ id: randomUUID(), type: 'prompt', message: prompt })}\\n`);\n });\n } finally {\n await rm(sessionDir, { recursive: true, force: true }).catch(() => undefined);\n }\n}async function runModelSummaryPromise(prompt: string, model?: string, timeoutMs?: number, harness: RuntimeName = 'claude-code', allowedTools?: string[]): Promise<string> {\n const useModel = model || DEFAULT_SUMMARY_MODEL;\n console.log(`[claude-invoke] purpose=smart-summary | model=${useModel} | harness=${harness} | source=smart-compaction.ts:runModelSummary | promptChars=${prompt.length} | timeoutMs=${timeoutMs ?? SUMMARY_TIMEOUT_MS}`);\n\n if (getHarnessBehavior(harness).deliveryKind === 'rpc-fifo') {\n // Pi/omp runs in rpc mode and auto-executes tools, so it needs no allowlist.\n const summary = await runPiModelSummary(prompt, useModel, timeoutMs);\n console.log(`[claude-invoke] SUCCESS purpose=smart-summary | model=${useModel} | harness=${harness} | outputChars=${summary.length}`);\n return summary;\n }\n\n const args = [\n '-p',\n '--output-format', 'json',\n '--model', useModel,\n ...getClaudePermissionFlagsSync(),\n // Plain summary generation uses no tools; callers that instruct the model\n // to write a file (e.g. external handoff authoring) pass an allowlist so\n // the tool is auto-approved instead of stalling on a permission prompt\n // that headless `-p` mode can never answer.\n ...(allowedTools && allowedTools.length > 0 ? ['--allowedTools', ...allowedTools] : []),\n ];\n\n // Sanitize parent provider env (strip ANTHROPIC_BASE_URL etc.) and inject the\n // correct provider env for `useModel`. If provider env lookup fails (e.g.\n // missing API key), let it throw — the caller (compactConversationNative)\n // falls back to a heuristic summary.\n const spawnEnv = await buildSpawnEnvForModel(useModel);\n const injectedKeys = Object.keys(await getProviderEnvForModel(useModel));\n const command = 'claude';\n if (injectedKeys.length > 0) {\n console.log(`[smart-compaction] Spawning ${command} for summary with model ${useModel}, injecting provider env: ${injectedKeys.join(', ')}`);\n } else {\n console.log(`[smart-compaction] Spawning ${command} for summary with model ${useModel} (anthropic, parent provider env stripped)`);\n }\n\n const child = spawn(command, args, {\n env: spawnEnv,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n const effectiveTimeout = timeoutMs ?? SUMMARY_TIMEOUT_MS;\n\n return await new Promise<string>((resolve, reject) => {\n const timeout = setTimeout(() => {\n child.kill('SIGTERM');\n reject(new Error(`Summary generation timed out after ${effectiveTimeout}ms`));\n }, effectiveTimeout);\n\n child.stdin.end(prompt);\n child.stdout.setEncoding('utf-8');\n child.stderr.setEncoding('utf-8');\n child.stdout.on('data', chunk => { stdout += chunk; });\n child.stderr.on('data', chunk => { stderr += chunk; });\n child.on('error', err => {\n clearTimeout(timeout);\n reject(err);\n });\n child.on('close', code => {\n clearTimeout(timeout);\n if (code !== 0) {\n const detail = stderr.trim() || stdout.trim() || `exit code ${code}`;\n console.error(`[claude-invoke] FAILED purpose=smart-summary | model=${useModel} | error=\"exit code ${code}: ${detail.slice(0, 200)}\"`);\n reject(new Error(`Summary generation failed: ${detail}`));\n return;\n }\n const raw = stdout.trim();\n if (!raw) {\n console.error(`[claude-invoke] FAILED purpose=smart-summary | model=${useModel} | error=\"empty output\"`);\n reject(new Error(`Summary generation returned empty output`));\n return;\n }\n // `--output-format json` returns { result, usage, total_cost_usd, ... }.\n // Extract the summary text and record spend; fall back to raw stdout if\n // the output isn't the expected JSON envelope (defensive — PAN-1589).\n let summary = raw;\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (parsed && typeof parsed['result'] === 'string') {\n summary = (parsed['result'] as string).trim();\n recordSummaryForkCost(useModel, parsed);\n }\n } catch {\n // Not JSON — treat the raw stdout as the summary (older CLI / unexpected).\n }\n if (!summary) {\n console.error(`[claude-invoke] FAILED purpose=smart-summary | model=${useModel} | error=\"empty result\"`);\n reject(new Error(`Summary generation returned empty output`));\n return;\n }\n console.log(`[claude-invoke] SUCCESS purpose=smart-summary | model=${useModel} | outputChars=${summary.length}`);\n resolve(summary);\n });\n });\n}\n\nexport function truncateHeadTail(input: string, ceilingChars: number): string {\n if (input.length <= ceilingChars) return input;\n const truncatedCount = input.length - ceilingChars;\n const marker = `[... ${truncatedCount} characters truncated ...]`;\n const headLength = Math.ceil(ceilingChars / 2);\n const tailLength = Math.floor(ceilingChars / 2);\n return `${input.slice(0, headLength)}${marker}${input.slice(input.length - tailLength)}`;\n}\n\nexport async function generateSummaryFromPrompt(\n serialized: string,\n previousSummary: string | undefined,\n model: string | undefined,\n richMode: boolean,\n timeoutMs?: number,\n harness: RuntimeName = 'claude-code',\n): Promise<string> {\n const conversationText = `<conversation>\\n${serialized}\\n</conversation>`;\n let promptText = `${conversationText}\\n\\n`;\n\n const updatePrompt = richMode ? RICH_UPDATE_SUMMARIZATION_PROMPT : UPDATE_SUMMARIZATION_PROMPT;\n const initPrompt = richMode ? RICH_SUMMARIZATION_PROMPT : SUMMARIZATION_PROMPT;\n\n if (previousSummary) {\n promptText += `<previous-summary>\\n${previousSummary}\\n</previous-summary>\\n\\n${updatePrompt}`;\n } else {\n promptText += initPrompt;\n }\n\n const messages = [\n {\n role: 'user' as const,\n content: [{ type: 'text' as const, text: promptText }],\n },\n ];\n\n // Wrap in system prompt via claude -p\n const fullPrompt = `${SUMMARIZATION_SYSTEM_PROMPT}\\n\\n${messages[0].content[0].text}`;\n\n try {\n return (await Effect.runPromise(self.runModelSummary(fullPrompt, model, timeoutMs, harness)));\n } catch (err) {\n if (!isContextOverflowError(err)) throw err;\n\n const ceiling = getChunkBudgetChars(model);\n const truncatedSerialized = truncateHeadTail(serialized, ceiling);\n const truncatedPrevious = previousSummary ? truncateHeadTail(previousSummary, ceiling) : undefined;\n\n const truncatedConversationText = `<conversation>\\n${truncatedSerialized}\\n</conversation>`;\n let retryPromptText = `${truncatedConversationText}\\n\\n`;\n if (truncatedPrevious) {\n retryPromptText += `<previous-summary>\\n${truncatedPrevious}\\n</previous-summary>\\n\\n${updatePrompt}`;\n } else {\n retryPromptText += initPrompt;\n }\n const retryFullPrompt = `${SUMMARIZATION_SYSTEM_PROMPT}\\n\\n${retryPromptText}`;\n return (await Effect.runPromise(self.runModelSummary(retryFullPrompt, model, timeoutMs, harness)));\n }\n}\n\nasync function generateTurnPrefixSummary(\n serialized: string,\n model: string | undefined,\n timeoutMs?: number,\n harness: RuntimeName = 'claude-code',\n): Promise<string> {\n const promptText = `<conversation>\\n${serialized}\\n</conversation>\\n\\n${TURN_PREFIX_PROMPT}`;\n const fullPrompt = `${SUMMARIZATION_SYSTEM_PROMPT}\\n\\n${promptText}`;\n return (await Effect.runPromise(self.runModelSummary(fullPrompt, model, timeoutMs, harness)));\n}\n\n// ============================================================================\n// Chunked incremental summarization\n// ============================================================================\n\n// Per-chunk serialized-content budget (in characters). Leaves room in the\n// model's context window for the prompt template, the carried-forward\n// <previous-summary>, and the generated output. Intentionally conservative\n// — code-heavy content tokenizes denser than the 4-chars/token heuristic.\nconst CHUNK_BUDGET_CHARS_BY_MODEL: Record<string, number> = {\n 'claude-haiku-4-5-20251001': 300_000, // ~75k tokens content, 200k window\n 'claude-sonnet-5': 1_200_000, // ~300k tokens content, 1M window\n 'claude-sonnet-4-6': 1_200_000, // ~300k tokens content, 1M window\n 'claude-fable-5': 1_200_000, // ~300k tokens content, large window\n 'claude-opus-4-8': 1_200_000, // ~300k tokens content, 1M window\n 'claude-opus-4-7': 1_200_000, // ~300k tokens content, 1M window\n 'claude-opus-4-6': 1_200_000, // ~300k tokens content, 1M window\n};\nconst DEFAULT_CHUNK_BUDGET_CHARS = 300_000;\n\nfunction getChunkBudgetChars(model: string | undefined): number {\n if (!model) return DEFAULT_CHUNK_BUDGET_CHARS;\n return CHUNK_BUDGET_CHARS_BY_MODEL[model] ?? DEFAULT_CHUNK_BUDGET_CHARS;\n}\n\nfunction chunkEntriesByBudget(entries: any[], budgetChars: number): any[][] {\n const chunks: any[][] = [];\n let current: any[] = [];\n let currentChars = 0;\n for (const entry of entries) {\n const serialized = serializeEntry(entry);\n const size = serialized ? serialized.length + 2 : 0;\n if (currentChars + size > budgetChars && current.length > 0) {\n chunks.push(current);\n current = [];\n currentChars = 0;\n }\n current.push(entry);\n currentChars += size;\n }\n if (current.length > 0) chunks.push(current);\n return chunks;\n}\n\nasync function generateChunkedSummary(\n entries: any[],\n initialPreviousSummary: string | undefined,\n model: string | undefined,\n richMode: boolean,\n timeoutMs: number,\n includeThinking: boolean = true,\n harness: RuntimeName = 'claude-code',\n): Promise<string> {\n const budget = getChunkBudgetChars(model);\n const chunks = chunkEntriesByBudget(entries, budget);\n if (chunks.length === 0) {\n return initialPreviousSummary ?? '';\n }\n\n let running: string | undefined = initialPreviousSummary;\n for (let i = 0; i < chunks.length; i++) {\n const serialized = serializeConversation(chunks[i], includeThinking);\n if (!serialized.trim()) continue;\n console.log(\n `[smart-compaction] Summarizing chunk ${i + 1}/${chunks.length} ` +\n `(${serialized.length} chars, ${chunks[i].length} entries) with ${model ?? DEFAULT_SUMMARY_MODEL}`,\n );\n running = await generateSummaryFromPrompt(serialized, running, model, richMode, timeoutMs, harness);\n }\n\n return running ?? '';\n}\n\n/**\n * Split already-serialized transcript text into chunks that fit the summarizer\n * model's context budget. Splits on turn boundaries (the canonical serialized\n * form separates turns with a blank line) so a chunk never cuts mid-turn unless\n * a single turn is itself larger than the budget.\n */\nfunction chunkSerializedTextByBudget(text: string, budgetChars: number): string[] {\n if (text.length <= budgetChars) return text.trim() ? [text] : [];\n const turns = text.split('\\n\\n');\n const chunks: string[] = [];\n let current = '';\n for (const turn of turns) {\n const candidate = current ? `${current}\\n\\n${turn}` : turn;\n if (candidate.length > budgetChars && current) {\n chunks.push(current);\n current = turn;\n } else {\n current = candidate;\n }\n }\n if (current.trim()) chunks.push(current);\n return chunks;\n}\n\n/**\n * Harness-agnostic chunk-and-merge summarizer. Takes transcript text already\n * serialized by a ConversationTranscriptAdapter (so it works for any harness)\n * and runs the same incremental summary prompt the Claude-Code entry path uses,\n * carrying a running <previous-summary> forward across chunks. Returns the\n * final structured summary string.\n *\n * `harness` selects the summarizer LLM backend (claude-code or pi) and is\n * independent of which harness produced the transcript.\n */\nexport async function summarizeSerializedText(\n serialized: string,\n options: {\n model?: string;\n richMode?: boolean;\n timeoutMs?: number;\n harness?: RuntimeName;\n } = {},\n): Promise<string> {\n const model = options.model;\n const richMode = options.richMode ?? false;\n const timeoutMs = options.timeoutMs ?? FORK_SUMMARY_TIMEOUT_MS;\n const harness = options.harness ?? 'claude-code';\n\n const budget = getChunkBudgetChars(model);\n const chunks = chunkSerializedTextByBudget(serialized, budget);\n if (chunks.length === 0) return '';\n\n let running: string | undefined;\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i]!;\n if (!chunk.trim()) continue;\n console.log(\n `[smart-compaction] Summarizing serialized chunk ${i + 1}/${chunks.length} ` +\n `(${chunk.length} chars) with ${model ?? DEFAULT_SUMMARY_MODEL}`,\n );\n running = await generateSummaryFromPrompt(chunk, running, model, richMode, timeoutMs, harness);\n }\n return running ?? '';\n}\n\nasync function generateSmartSummaryPromise(options: CompactionOptions): Promise<CompactionResult> {\n const entries = await parseEntries(options.jsonlPath);\n if (entries.length === 0) {\n throw new Error(`Session file is empty: ${options.jsonlPath}`);\n }\n\n const isFork = options.mode === 'fork';\n // Forks summarize the entire conversation (no \"kept\" recent portion);\n // compaction keeps recent entries verbatim and only summarizes older history.\n const keepRecentTokens = options.keepRecentTokens ?? (isFork ? Number.MAX_SAFE_INTEGER : 20000);\n const model = options.model || DEFAULT_SUMMARY_MODEL;\n const richMode = options.richMode ?? false;\n const includeThinking = options.includeThinkingInSummary ?? true;\n const harness = options.harness ?? 'claude-code';\n const tokensBefore = estimateContextTokens(entries);\n\n // Detect previous compact boundary for incremental summarization\n const prevBoundary = findPreviousCompactBoundary(entries);\n let boundaryStart = 0;\n let previousSummary: string | undefined;\n if (prevBoundary) {\n boundaryStart = prevBoundary.index;\n previousSummary = prevBoundary.summary;\n }\n\n const boundaryEnd = entries.length;\n const cutPoint = findCutPoint(entries, boundaryStart, boundaryEnd, keepRecentTokens);\n\n // Determine which entries to summarize\n const historyEnd = cutPoint.isSplitTurn ? cutPoint.turnStartIndex : cutPoint.firstKeptEntryIndex;\n\n const messagesToSummarize: any[] = [];\n for (let i = boundaryStart; i < historyEnd; i++) {\n messagesToSummarize.push(entries[i]);\n }\n\n const turnPrefixMessages: any[] = [];\n if (cutPoint.isSplitTurn) {\n for (let i = cutPoint.turnStartIndex; i < cutPoint.firstKeptEntryIndex; i++) {\n turnPrefixMessages.push(entries[i]);\n }\n }\n\n // Extract file ops from all relevant entries (summary + prefix + kept boundary)\n const fileOps = extractFileOpsFromEntries(messagesToSummarize);\n if (cutPoint.isSplitTurn) {\n const prefixOps = extractFileOpsFromEntries(turnPrefixMessages);\n prefixOps.read.forEach(f => fileOps.read.add(f));\n prefixOps.written.forEach(f => fileOps.written.add(f));\n prefixOps.edited.forEach(f => fileOps.edited.add(f));\n }\n // Also include file ops from entries AFTER the cut point up to the end\n // so the summary captures files touched in the \"kept\" recent work too\n const recentOps = extractFileOpsFromEntries(entries.slice(cutPoint.firstKeptEntryIndex));\n recentOps.read.forEach(f => fileOps.read.add(f));\n recentOps.written.forEach(f => fileOps.written.add(f));\n recentOps.edited.forEach(f => fileOps.edited.add(f));\n\n // Generate summaries\n const llmTimeoutMs = isFork ? FORK_SUMMARY_TIMEOUT_MS : undefined;\n let summary: string;\n let serializedHistory = serializeConversation(messagesToSummarize, includeThinking);\n let hasHistory = serializedHistory.trim().length > 0;\n\n // For forks, always produce a real summary. If the selected history slice is\n // empty (e.g. only metadata entries before the first valid cut point), fall\n // back to serializing the entire conversation.\n if (isFork && !hasHistory && !cutPoint.isSplitTurn) {\n const allMessages = entries.slice(boundaryStart, cutPoint.firstKeptEntryIndex);\n if (allMessages.length > 0) {\n serializedHistory = serializeConversation(allMessages, includeThinking);\n hasHistory = serializedHistory.trim().length > 0;\n }\n }\n\n const hasPrefix = cutPoint.isSplitTurn && turnPrefixMessages.length > 0;\n\n if (!hasHistory && !hasPrefix) {\n // Nothing to summarize — return previous summary or a minimal stub.\n // For forks, summarize the entire conversation via chunked incremental\n // passes (carrying <previous-summary> forward) so arbitrarily large\n // JSONL files fit the selected model's context window.\n if (isFork) {\n const forkTimeoutMs = llmTimeoutMs ?? FORK_SUMMARY_TIMEOUT_MS;\n // Summarize from the previous compact boundary (if any) forward — the\n // previousSummary already covers everything before boundaryStart.\n const forkEntries = boundaryStart > 0 ? entries.slice(boundaryStart) : entries;\n const anyContent = forkEntries.some((e) => serializeEntry(e, includeThinking));\n if (anyContent) {\n try {\n summary = await generateChunkedSummary(forkEntries, previousSummary, model, richMode, forkTimeoutMs, includeThinking, harness);\n } catch (error) {\n throw new Error(`Smart summary generation failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n if (!summary.trim()) {\n throw new Error('Smart summary generation failed: chunked summarization produced empty output');\n }\n } else {\n summary = previousSummary || '## Goal\\nContinue the current task.\\n\\n## Constraints & Preferences\\n- (none)\\n\\n## Progress\\n### Done\\n- (none)\\n\\n### In Progress\\n- [ ] Awaiting next instruction\\n\\n### Blocked\\n- (none)\\n\\n## Key Decisions\\n- (none)\\n\\n## Next Steps\\n1. Await user instruction\\n\\n## Critical Context\\n- (none)';\n }\n } else {\n const minimalStub = richMode\n ? '## Primary Request and Intent\\nContinue the current task.\\n\\n## Key Technical Concepts\\n- (none)\\n\\n## Files and Code Sections\\n- (none)\\n\\n## Errors and fixes\\n- (none)\\n\\n## Problem Solving\\nNo issues encountered.\\n\\n## All user messages\\n- (none)\\n\\n## Pending Tasks\\n- (none)\\n\\n## Current Work\\nAwaiting next instruction.\\n\\n## Optional Next Step\\nAwait user instruction.'\n : '## Goal\\nContinue the current task.\\n\\n## Constraints & Preferences\\n- (none)\\n\\n## Progress\\n### Done\\n- (none)\\n\\n### In Progress\\n- [ ] Awaiting next instruction\\n\\n### Blocked\\n- (none)\\n\\n## Key Decisions\\n- (none)\\n\\n## Next Steps\\n1. Await user instruction\\n\\n## Critical Context\\n- (none)';\n summary = previousSummary || minimalStub;\n }\n } else {\n try {\n if (hasPrefix) {\n const [historyResult, turnPrefixResult] = await Promise.all([\n hasHistory\n ? generateSummaryFromPrompt(serializedHistory, previousSummary, model, richMode, llmTimeoutMs, harness)\n : Promise.resolve('No prior history.'),\n generateTurnPrefixSummary(serializeConversation(turnPrefixMessages, includeThinking), model, llmTimeoutMs, harness),\n ]);\n summary = `${historyResult}\\n\\n---\\n\\n**Turn Context (split turn):**\\n\\n${turnPrefixResult}`;\n } else {\n summary = await generateSummaryFromPrompt(\n serializedHistory,\n previousSummary,\n model,\n richMode,\n llmTimeoutMs,\n harness,\n );\n }\n } catch (error) {\n throw new Error(`Smart summary generation failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n // Append file operations\n const { readFiles, modifiedFiles } = computeFileLists(fileOps);\n summary += formatFileOperations(readFiles, modifiedFiles);\n\n return {\n summary,\n tokensBefore,\n firstKeptEntryIndex: cutPoint.firstKeptEntryIndex,\n summaryModel: model,\n readFiles,\n modifiedFiles,\n };\n}\n\n// ─── Effect variants (PAN-1249, additive) ────────────────────────────────────\n//\n// Additive Effect surface for smart-compaction. The underlying Promise\n// functions remain canonical; these wrappers map failures to typed errors\n// (ProcessSpawnError for spawn / generation failures, FsError for IO).\n\n/** Effect variant of runModelSummary. */\nexport function runModelSummary(\n prompt: string,\n model?: string,\n timeoutMs?: number,\n harness: RuntimeName = 'claude-code',\n allowedTools?: string[],\n): Effect.Effect<string, ProcessSpawnError> {\n return Effect.tryPromise({\n try: () => runModelSummaryPromise(prompt, model, timeoutMs, harness, allowedTools),\n catch: (cause) =>\n new ProcessSpawnError({\n command: getHarnessBehavior(harness).deliveryKind === 'rpc-fifo' ? getHarnessBehavior(harness).executableName : 'claude',\n args: ['-p', model ?? 'default'],\n message: cause instanceof Error ? cause.message : String(cause),\n cause,\n }),\n });\n}\n\n/** Effect variant of generateSmartSummary. */\nexport function generateSmartSummary(\n options: CompactionOptions,\n): Effect.Effect<CompactionResult, FsError | ProcessSpawnError> {\n return Effect.tryPromise({\n try: () => generateSmartSummaryPromise(options),\n catch: (cause) => {\n const msg = cause instanceof Error ? cause.message : String(cause);\n // Distinguish between fs failures (read jsonl) and spawn failures (LLM).\n // The underlying impl throws plain Error in both cases; we map to\n // FsError when the message hints at file IO, otherwise spawn.\n if (msg.toLowerCase().includes('enoent') || msg.toLowerCase().includes('no such file')) {\n return new FsError({ path: options.jsonlPath, operation: 'smart-summary-read', cause });\n }\n return new ProcessSpawnError({\n command: 'claude',\n args: ['-p', options.model ?? 'default'],\n message: msg,\n cause,\n });\n },\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"smart-compaction-uke1npUz.js","names":["self.runModelSummary"],"sources":["../../src/lib/conversations/smart-compaction.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport { randomUUID } from 'node:crypto';\nimport { mkdtemp, readFile, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { Effect } from 'effect';\nimport * as self from './smart-compaction.js';\nimport { buildSpawnEnvForModel, getProviderEnvForModel } from '../agents.js';\nimport { getClaudePermissionFlagsSync } from '../claude-permissions.js';\nimport { getHarnessBehavior } from '../runtimes/behavior.js';\nimport type { RuntimeName } from '../runtimes/types.js';\nimport { FsError, ProcessSpawnError } from '../errors.js';\nimport { recordBackgroundAiCost } from '../background-ai/cost.js';\nimport type { AIProvider } from '../cost.js';\nimport { isContextOverflowError } from '../context-overflow.js';\n\n/** Record summary-fork/compaction spend from a `claude -p --output-format json`\n * envelope. Best-effort; never throws into the caller (PAN-1589). */\nfunction recordSummaryForkCost(model: string, envelope: Record<string, unknown>): void {\n const usage = (envelope['usage'] ?? {}) as Record<string, unknown>;\n const num = (v: unknown): number => (typeof v === 'number' ? v : 0);\n const m = model.toLowerCase();\n const provider: AIProvider = m.includes('gpt') ? 'openai' : m.includes('gemini') ? 'google' : 'anthropic';\n recordBackgroundAiCost({\n feature: 'summaryFork',\n provider,\n model,\n usage: {\n inputTokens: num(usage['input_tokens']),\n outputTokens: num(usage['output_tokens']),\n cacheReadTokens: num(usage['cache_read_input_tokens']),\n cacheWriteTokens: num(usage['cache_creation_input_tokens']),\n },\n costUsd: typeof envelope['total_cost_usd'] === 'number' ? (envelope['total_cost_usd'] as number) : undefined,\n });\n}\n\nconst SUMMARY_TIMEOUT_MS = 60_000;\nconst FORK_SUMMARY_TIMEOUT_MS = 300_000;\nconst DEFAULT_SUMMARY_MODEL = 'claude-haiku-4-5-20251001';\n\nexport interface CompactionOptions {\n jsonlPath: string;\n model?: string;\n keepRecentTokens?: number;\n reserveTokens?: number;\n richMode?: boolean;\n /** 'compact' = native compaction (returns stub if nothing to summarize). 'fork' = always produce a real summary for conversation forks. */\n mode?: 'compact' | 'fork';\n /** When true, include thinking block content in the serialized conversation sent to the summary model. Default: true. */\n includeThinkingInSummary?: boolean;\n /** Runtime harness used for model-backed summary generation. */\n harness?: RuntimeName;\n}\n\nexport interface CompactionResult {\n summary: string;\n tokensBefore: number;\n firstKeptEntryIndex: number;\n summaryModel: string | null;\n readFiles: string[];\n modifiedFiles: string[];\n}\n\ninterface FileOperations {\n read: Set<string>;\n written: Set<string>;\n edited: Set<string>;\n}\n\ninterface CutPointResult {\n firstKeptEntryIndex: number;\n turnStartIndex: number;\n isSplitTurn: boolean;\n}\n\n// ============================================================================\n// Entry parsing\n// ============================================================================\n\nexport async function parseEntries(jsonlPath: string): Promise<any[]> {\n const content = await readFile(jsonlPath, 'utf-8');\n const entries: any[] = [];\n for (const line of content.split('\\n')) {\n if (!line.trim()) continue;\n try {\n entries.push(JSON.parse(line));\n } catch {\n // skip malformed\n }\n }\n return entries;\n}\n\n// ============================================================================\n// Token estimation (chars/4 heuristic, conservative)\n// ============================================================================\n\nfunction estimateTokens(entry: any): number {\n if (!entry) return 0;\n\n // Compact boundary / system entries\n if (entry.type === 'system' || entry.subtype === 'compact_boundary') {\n const text = entry.content || '';\n return Math.ceil(text.length / 4);\n }\n\n // User entries (including compact summaries and tool results)\n if (entry.type === 'user' && entry.message) {\n const content = entry.message.content;\n if (typeof content === 'string') {\n return Math.ceil(content.length / 4);\n }\n if (Array.isArray(content)) {\n let chars = 0;\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n chars += block.text.length;\n } else if (block.type === 'tool_result') {\n // Estimate tool result content\n if (typeof block.content === 'string') {\n chars += block.content.length;\n } else if (Array.isArray(block.content)) {\n for (const b of block.content) {\n if (b.text) chars += b.text.length;\n }\n }\n } else if (block.type === 'image') {\n chars += 4800; // ~1200 tokens\n }\n }\n return Math.ceil(chars / 4);\n }\n }\n\n // Assistant entries\n if (entry.type === 'assistant' && entry.message) {\n const content = entry.message.content;\n if (Array.isArray(content)) {\n let chars = 0;\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n chars += block.text.length;\n } else if (block.type === 'thinking' && block.thinking) {\n chars += block.thinking.length;\n } else if (block.type === 'tool_use') {\n chars += block.name?.length || 0;\n chars += JSON.stringify(block.input || {}).length;\n }\n }\n return Math.ceil(chars / 4);\n }\n if (typeof content === 'string') {\n return Math.ceil(content.length / 4);\n }\n }\n\n return 0;\n}\n\nfunction estimateContextTokens(entries: any[]): number {\n // Use the last assistant usage if available, otherwise heuristic\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n if (entry.type === 'assistant' && entry.message?.usage) {\n const u = entry.message.usage;\n if (typeof u.input_tokens === 'number') {\n let total = u.input_tokens || 0;\n if (typeof u.output_tokens === 'number') total += u.output_tokens;\n if (typeof u.cache_creation_input_tokens === 'number') total += u.cache_creation_input_tokens;\n if (typeof u.cache_read_input_tokens === 'number') total += u.cache_read_input_tokens;\n if (total <= 0) continue;\n // Add trailing entries after this assistant\n for (let j = i + 1; j < entries.length; j++) {\n total += estimateTokens(entries[j]);\n }\n return total;\n }\n if (typeof u.inputTokens === 'number') {\n let total = u.inputTokens || 0;\n if (typeof u.outputTokens === 'number') total += u.outputTokens;\n if (typeof u.cacheCreationInputTokens === 'number') total += u.cacheCreationInputTokens;\n if (typeof u.cacheReadInputTokens === 'number') total += u.cacheReadInputTokens;\n if (total <= 0) continue;\n for (let j = i + 1; j < entries.length; j++) {\n total += estimateTokens(entries[j]);\n }\n return total;\n }\n }\n }\n\n // Fallback: sum all heuristics\n return entries.reduce((sum, e) => sum + estimateTokens(e), 0);\n}\n\n// ============================================================================\n// File operation tracking\n// ============================================================================\n\nfunction createFileOps(): FileOperations {\n return { read: new Set(), written: new Set(), edited: new Set() };\n}\n\nfunction extractFileOpsFromEntries(entries: any[]): FileOperations {\n const fileOps = createFileOps();\n for (const entry of entries) {\n if (entry.type !== 'assistant' || !entry.message?.content) continue;\n const content = entry.message.content;\n if (!Array.isArray(content)) continue;\n for (const block of content) {\n if (block.type !== 'tool_use' || !block.input) continue;\n const path = block.input.file_path || block.input.path;\n if (!path) continue;\n switch (block.name) {\n case 'Read':\n case 'read':\n fileOps.read.add(path);\n break;\n case 'Write':\n case 'write':\n fileOps.written.add(path);\n break;\n case 'Edit':\n case 'edit':\n fileOps.edited.add(path);\n break;\n }\n }\n }\n return fileOps;\n}\n\nfunction computeFileLists(fileOps: FileOperations): { readFiles: string[]; modifiedFiles: string[] } {\n const modified = new Set([...fileOps.edited, ...fileOps.written]);\n const readOnly = [...fileOps.read].filter(f => !modified.has(f)).sort();\n return { readFiles: readOnly, modifiedFiles: [...modified].sort() };\n}\n\nfunction formatFileOperations(readFiles: string[], modifiedFiles: string[]): string {\n const sections: string[] = [];\n if (readFiles.length > 0) {\n sections.push(`<read-files>\\n${readFiles.join('\\n')}\\n</read-files>`);\n }\n if (modifiedFiles.length > 0) {\n sections.push(`<modified-files>\\n${modifiedFiles.join('\\n')}\\n</modified-files>`);\n }\n if (sections.length === 0) return '';\n return '\\n\\n' + sections.join('\\n\\n');\n}\n\n// ============================================================================\n// Previous compact boundary detection\n// ============================================================================\n\nfunction findPreviousCompactBoundary(entries: any[]): { index: number; summary: string } | null {\n for (let i = entries.length - 1; i >= 0; i--) {\n const entry = entries[i];\n // Overdeck native compaction writes compact_boundary then a user summary entry\n if (entry.type === 'system' && entry.subtype === 'compact_boundary') {\n // Look immediately after for the summary user message\n if (i + 1 < entries.length) {\n const next = entries[i + 1];\n if (next.type === 'user' && next.isCompactSummary && next.message?.content) {\n return { index: i, summary: next.message.content };\n }\n }\n }\n // Also detect older compact summary entries\n if (entry.type === 'user' && entry.isCompactSummary && entry.message?.content) {\n return { index: i, summary: entry.message.content };\n }\n }\n return null;\n}\n\n// ============================================================================\n// Cut point detection (inspired by Pi agent)\n// ============================================================================\n\nfunction isUserMessageEntry(entry: any): boolean {\n if (entry.type !== 'user' || !entry.message) return false;\n const content = entry.message.content;\n // A pure tool_result user entry is not a turn-starting user message\n if (Array.isArray(content)) {\n const hasText = content.some((b: any) => b.type === 'text' && b.text?.trim());\n return hasText;\n }\n if (typeof content === 'string') {\n return content.trim().length > 0;\n }\n return false;\n}\n\nfunction isAssistantEntry(entry: any): boolean {\n return entry.type === 'assistant' && !!entry.message;\n}\n\nfunction findValidCutPoints(entries: any[], startIndex: number, endIndex: number): number[] {\n const cutPoints: number[] = [];\n for (let i = startIndex; i < endIndex; i++) {\n if (isUserMessageEntry(entries[i]) || isAssistantEntry(entries[i])) {\n cutPoints.push(i);\n }\n }\n return cutPoints;\n}\n\nfunction findTurnStartIndex(entries: any[], entryIndex: number, startIndex: number): number {\n for (let i = entryIndex; i >= startIndex; i--) {\n if (isUserMessageEntry(entries[i])) {\n return i;\n }\n }\n return -1;\n}\n\nfunction findCutPoint(\n entries: any[],\n startIndex: number,\n endIndex: number,\n keepRecentTokens: number,\n): CutPointResult {\n const cutPoints = findValidCutPoints(entries, startIndex, endIndex);\n if (cutPoints.length === 0) {\n return { firstKeptEntryIndex: startIndex, turnStartIndex: -1, isSplitTurn: false };\n }\n\n let accumulatedTokens = 0;\n let cutIndex = cutPoints[0];\n\n for (let i = endIndex - 1; i >= startIndex; i--) {\n const tokens = estimateTokens(entries[i]);\n accumulatedTokens += tokens;\n\n if (accumulatedTokens >= keepRecentTokens) {\n for (let c = 0; c < cutPoints.length; c++) {\n if (cutPoints[c] >= i) {\n cutIndex = cutPoints[c];\n break;\n }\n }\n break;\n }\n }\n\n // Scan backwards to include non-message metadata entries after a boundary.\n // Never scan past the previous valid cut point (or the original cut point\n // itself if it's the first valid one).\n const originalCutIndex = cutIndex;\n const cutPointArrayIndex = cutPoints.findIndex((cp) => cp === originalCutIndex);\n const minCutIndex = cutPointArrayIndex > 0 ? cutPoints[cutPointArrayIndex - 1]! + 1 : originalCutIndex;\n\n while (cutIndex > startIndex && cutIndex > minCutIndex) {\n const prev = entries[cutIndex - 1];\n if (prev.type === 'system' && prev.subtype === 'compact_boundary') break;\n if (isUserMessageEntry(prev) || isAssistantEntry(prev)) break;\n cutIndex--;\n }\n\n const isUser = isUserMessageEntry(entries[cutIndex]);\n const turnStartIndex = isUser ? -1 : findTurnStartIndex(entries, cutIndex, startIndex);\n\n return {\n firstKeptEntryIndex: cutIndex,\n turnStartIndex,\n isSplitTurn: !isUser && turnStartIndex !== -1,\n };\n}\n\n// ============================================================================\n// Conversation serialization\n// ============================================================================\n\nconst TOOL_RESULT_MAX_CHARS = 2000;\n\nfunction truncateForSummary(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text;\n return `${text.slice(0, maxChars)}\\n\\n[... ${text.length - maxChars} more characters truncated]`;\n}\n\nfunction serializeEntry(entry: any, includeThinking: boolean = true): string | undefined {\n if (entry.type === 'user' && entry.message) {\n const content = entry.message.content;\n let text = '';\n if (typeof content === 'string') {\n text = content;\n } else if (Array.isArray(content)) {\n const parts: string[] = [];\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n parts.push(block.text);\n } else if (block.type === 'tool_result') {\n let resultText = '';\n if (typeof block.content === 'string') {\n resultText = block.content;\n } else if (Array.isArray(block.content)) {\n resultText = block.content\n .filter((b: any) => b.type === 'text' && b.text)\n .map((b: any) => b.text)\n .join('\\n');\n }\n if (resultText) {\n parts.push(`[Tool result]: ${truncateForSummary(resultText, TOOL_RESULT_MAX_CHARS)}`);\n }\n }\n }\n text = parts.join('\\n');\n }\n if (text.trim()) {\n return `[User]: ${text.trim()}`;\n }\n }\n\n if (entry.type === 'assistant' && entry.message) {\n const content = entry.message.content;\n const parts: string[] = [];\n if (Array.isArray(content)) {\n const textParts: string[] = [];\n const toolCalls: string[] = [];\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n textParts.push(block.text);\n } else if (block.type === 'thinking' && block.thinking && includeThinking) {\n textParts.push(`[thinking]: ${block.thinking}`);\n } else if (block.type === 'tool_use') {\n const args = block.input || {};\n const argsStr = Object.entries(args)\n .map(([k, v]) => `${k}=${JSON.stringify(v)}`)\n .join(', ');\n toolCalls.push(`${block.name}(${argsStr})`);\n }\n }\n if (textParts.length) parts.push(`[Assistant]: ${textParts.join('\\n')}`);\n if (toolCalls.length) parts.push(`[Assistant tool calls]: ${toolCalls.join('; ')}`);\n } else if (typeof content === 'string') {\n parts.push(`[Assistant]: ${content}`);\n }\n if (parts.length) {\n return parts.join('\\n\\n');\n }\n }\n\n if (entry.type === 'system' && entry.subtype === 'compact_boundary' && entry.content) {\n return `[Context checkpoint]: ${entry.content}`;\n }\n\n return undefined;\n}\n\nexport function serializeConversation(entries: any[], includeThinking: boolean = true): string {\n const parts: string[] = [];\n for (const entry of entries) {\n const serialized = serializeEntry(entry, includeThinking);\n if (serialized) parts.push(serialized);\n }\n return parts.join('\\n\\n');\n}\n\n// ============================================================================\n// Summarization prompts\n// ============================================================================\n\nconst SUMMARIZATION_SYSTEM_PROMPT = `You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`;\n\nconst SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work.\n\nUse this EXACT format:\n\n## Goal\n[What is the user trying to accomplish? Can be multiple items if the session covers different tasks.]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements mentioned by user]\n- [Or \"(none)\" if none were mentioned]\n\n## Progress\n### Done\n- [x] [Completed tasks/changes]\n\n### In Progress\n- [ ] [Current work]\n\n### Blocked\n- [Issues preventing progress, if any]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Ordered list of what should happen next]\n\n## Critical Context\n- [Any data, examples, or references needed to continue]\n- [Or \"(none)\" if not applicable]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`;\n\nconst UPDATE_SUMMARIZATION_PROMPT = `The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.\n\nUpdate the existing structured summary with new information. RULES:\n- PRESERVE all existing information from the previous summary\n- ADD new progress, decisions, and context from the new messages\n- UPDATE the Progress section: move items from \"In Progress\" to \"Done\" when completed\n- UPDATE \"Next Steps\" based on what was accomplished\n- PRESERVE exact file paths, function names, and error messages\n- If something is no longer relevant, you may remove it\n\nUse this EXACT format:\n\n## Goal\n[Preserve existing goals, add new ones if the task expanded]\n\n## Constraints & Preferences\n- [Preserve existing, add new ones discovered]\n\n## Progress\n### Done\n- [x] [Include previously done items AND newly completed items]\n\n### In Progress\n- [ ] [Current work - update based on progress]\n\n### Blocked\n- [Current blockers - remove if resolved]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale] (preserve all previous, add new)\n\n## Next Steps\n1. [Update based on current state]\n\n## Critical Context\n- [Preserve important context, add new if needed]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`;\n\nconst TURN_PREFIX_PROMPT = `This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.`;\n\n// ============================================================================\n// Rich summarization prompts (9-section format, more verbose)\n// ============================================================================\n\nconst RICH_SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a comprehensive continuation summary that another LLM will use to continue the work without losing context.\n\nUse this EXACT format:\n\n## Primary Request and Intent\n[What is the user trying to accomplish? Include explicit asks, constraints, and intended outcome.]\n\n## Key Technical Concepts\n- [Major technical topics, tools, frameworks, libraries, patterns, and architectural ideas]\n- [Or \"(none)\" if none were mentioned]\n\n## Files and Code Sections\n- [File name]: [why it matters, what was examined or changed, include important code snippets in full when applicable]\n- [Or \"(none)\" if not applicable]\n\n## Errors and fixes\n- [What went wrong and how it was fixed or addressed]\n- [Or \"(none)\" if none occurred]\n\n## Problem Solving\n[Problems resolved and any ongoing troubleshooting]\n\n## All user messages\n- [Every user message in the conversation that was not a tool result. Do not omit any.]\n- [Or \"(none)\" if not applicable]\n\n## Pending Tasks\n- [All unfinished work the user has explicitly asked for]\n- [Or \"(none)\" if not applicable]\n\n## Current Work\n[Exactly what was being worked on immediately before this summarization request. Focus on the latest messages.]\n\n## Optional Next Step\n[The next action that should be taken, but only if it directly follows from the user's most recent request. Include exact quoted lines where useful.]\n\nBe thorough, specific, and technically accurate. Preserve exact file paths, function names, error messages, and code snippets.`;\n\nconst RICH_UPDATE_SUMMARIZATION_PROMPT = `The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.\n\nUpdate the existing structured summary with new information. RULES:\n- PRESERVE all existing information from the previous summary\n- ADD new progress, decisions, user messages, and context from the new messages\n- UPDATE the \"Current Work\" section to reflect the latest state\n- UPDATE \"Pending Tasks\" based on what was completed or newly requested\n- PRESERVE exact file paths, function names, error messages, and code snippets\n- If something is no longer relevant, you may remove it\n\nUse this EXACT format:\n\n## Primary Request and Intent\n[Preserve existing intent, add new ones if the task expanded]\n\n## Key Technical Concepts\n- [Preserve existing, add new ones discovered]\n\n## Files and Code Sections\n- [Preserve existing files, add new ones, update changed ones with full code snippets]\n\n## Errors and fixes\n- [Preserve existing, add new ones, mark resolved if appropriate]\n\n## Problem Solving\n[Update with new resolutions and ongoing troubleshooting]\n\n## All user messages\n- [Preserve existing user messages, add new ones from the recent conversation]\n\n## Pending Tasks\n- [Update based on what was completed or newly requested]\n\n## Current Work\n[Update to reflect the latest state immediately before this request]\n\n## Optional Next Step\n[Update based on current state]\n\nBe thorough. Preserve exact file paths, function names, error messages, and code snippets.`;\n\n// ============================================================================\n// LLM call\n// ============================================================================\n\nasync function runPiModelSummary(prompt: string, model: string, timeoutMs?: number): Promise<string> {\n const sessionDir = await mkdtemp(join(tmpdir(), 'overdeck-pi-summary-'));\n const effectiveTimeout = timeoutMs ?? SUMMARY_TIMEOUT_MS;\n const spawnEnv = await buildSpawnEnvForModel(model);\n\n const child = spawn('omp', [\n '--mode', 'rpc',\n '--model', model,\n '--session-dir', sessionDir,\n '--no-context-files',\n ], {\n env: spawnEnv,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n child.stdout.setEncoding('utf-8');\n child.stderr.setEncoding('utf-8');\n child.stdout.on('data', chunk => { stdout += chunk; });\n child.stderr.on('data', chunk => { stderr += chunk; });\n\n try {\n return await new Promise<string>((resolve, reject) => {\n const timeout = setTimeout(() => {\n child.kill('SIGTERM');\n reject(new Error(`Pi summary generation timed out after ${effectiveTimeout}ms`));\n }, effectiveTimeout);\n\n child.on('error', err => {\n clearTimeout(timeout);\n reject(err);\n });\n child.on('close', code => {\n clearTimeout(timeout);\n if (code !== 0 && !stdout.trim()) {\n const detail = stderr.trim() || `exit code ${code}`;\n reject(new Error(`Pi summary generation failed: ${detail}`));\n return;\n }\n const summary = stdout.trim();\n if (!summary) {\n reject(new Error('Pi summary generation returned empty output'));\n return;\n }\n resolve(summary);\n });\n\n child.stdin.end(`${JSON.stringify({ id: randomUUID(), type: 'prompt', message: prompt })}\\n`);\n });\n } finally {\n await rm(sessionDir, { recursive: true, force: true }).catch(() => undefined);\n }\n}async function runModelSummaryPromise(prompt: string, model?: string, timeoutMs?: number, harness: RuntimeName = 'claude-code', allowedTools?: string[]): Promise<string> {\n const useModel = model || DEFAULT_SUMMARY_MODEL;\n console.log(`[claude-invoke] purpose=smart-summary | model=${useModel} | harness=${harness} | source=smart-compaction.ts:runModelSummary | promptChars=${prompt.length} | timeoutMs=${timeoutMs ?? SUMMARY_TIMEOUT_MS}`);\n\n if (getHarnessBehavior(harness).deliveryKind === 'rpc-fifo') {\n // Pi/omp runs in rpc mode and auto-executes tools, so it needs no allowlist.\n const summary = await runPiModelSummary(prompt, useModel, timeoutMs);\n console.log(`[claude-invoke] SUCCESS purpose=smart-summary | model=${useModel} | harness=${harness} | outputChars=${summary.length}`);\n return summary;\n }\n\n const args = [\n '-p',\n '--output-format', 'json',\n '--model', useModel,\n ...getClaudePermissionFlagsSync(),\n // Plain summary generation uses no tools; callers that instruct the model\n // to write a file (e.g. external handoff authoring) pass an allowlist so\n // the tool is auto-approved instead of stalling on a permission prompt\n // that headless `-p` mode can never answer.\n ...(allowedTools && allowedTools.length > 0 ? ['--allowedTools', ...allowedTools] : []),\n ];\n\n // Sanitize parent provider env (strip ANTHROPIC_BASE_URL etc.) and inject the\n // correct provider env for `useModel`. If provider env lookup fails (e.g.\n // missing API key), let it throw — the caller (compactConversationNative)\n // falls back to a heuristic summary.\n const spawnEnv = await buildSpawnEnvForModel(useModel);\n const injectedKeys = Object.keys(await getProviderEnvForModel(useModel));\n const command = 'claude';\n if (injectedKeys.length > 0) {\n console.log(`[smart-compaction] Spawning ${command} for summary with model ${useModel}, injecting provider env: ${injectedKeys.join(', ')}`);\n } else {\n console.log(`[smart-compaction] Spawning ${command} for summary with model ${useModel} (anthropic, parent provider env stripped)`);\n }\n\n const child = spawn(command, args, {\n env: spawnEnv,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n const effectiveTimeout = timeoutMs ?? SUMMARY_TIMEOUT_MS;\n\n return await new Promise<string>((resolve, reject) => {\n const timeout = setTimeout(() => {\n child.kill('SIGTERM');\n reject(new Error(`Summary generation timed out after ${effectiveTimeout}ms`));\n }, effectiveTimeout);\n\n child.stdin.end(prompt);\n child.stdout.setEncoding('utf-8');\n child.stderr.setEncoding('utf-8');\n child.stdout.on('data', chunk => { stdout += chunk; });\n child.stderr.on('data', chunk => { stderr += chunk; });\n child.on('error', err => {\n clearTimeout(timeout);\n reject(err);\n });\n child.on('close', code => {\n clearTimeout(timeout);\n if (code !== 0) {\n const detail = stderr.trim() || stdout.trim() || `exit code ${code}`;\n console.error(`[claude-invoke] FAILED purpose=smart-summary | model=${useModel} | error=\"exit code ${code}: ${detail.slice(0, 200)}\"`);\n reject(new Error(`Summary generation failed: ${detail}`));\n return;\n }\n const raw = stdout.trim();\n if (!raw) {\n console.error(`[claude-invoke] FAILED purpose=smart-summary | model=${useModel} | error=\"empty output\"`);\n reject(new Error(`Summary generation returned empty output`));\n return;\n }\n // `--output-format json` returns { result, usage, total_cost_usd, ... }.\n // Extract the summary text and record spend; fall back to raw stdout if\n // the output isn't the expected JSON envelope (defensive — PAN-1589).\n let summary = raw;\n try {\n const parsed = JSON.parse(raw) as Record<string, unknown>;\n if (parsed && typeof parsed['result'] === 'string') {\n summary = (parsed['result'] as string).trim();\n recordSummaryForkCost(useModel, parsed);\n }\n } catch {\n // Not JSON — treat the raw stdout as the summary (older CLI / unexpected).\n }\n if (!summary) {\n console.error(`[claude-invoke] FAILED purpose=smart-summary | model=${useModel} | error=\"empty result\"`);\n reject(new Error(`Summary generation returned empty output`));\n return;\n }\n console.log(`[claude-invoke] SUCCESS purpose=smart-summary | model=${useModel} | outputChars=${summary.length}`);\n resolve(summary);\n });\n });\n}\n\nexport function truncateHeadTail(input: string, ceilingChars: number): string {\n if (input.length <= ceilingChars) return input;\n const truncatedCount = input.length - ceilingChars;\n const marker = `[... ${truncatedCount} characters truncated ...]`;\n const headLength = Math.ceil(ceilingChars / 2);\n const tailLength = Math.floor(ceilingChars / 2);\n return `${input.slice(0, headLength)}${marker}${input.slice(input.length - tailLength)}`;\n}\n\nexport async function generateSummaryFromPrompt(\n serialized: string,\n previousSummary: string | undefined,\n model: string | undefined,\n richMode: boolean,\n timeoutMs?: number,\n harness: RuntimeName = 'claude-code',\n): Promise<string> {\n const conversationText = `<conversation>\\n${serialized}\\n</conversation>`;\n let promptText = `${conversationText}\\n\\n`;\n\n const updatePrompt = richMode ? RICH_UPDATE_SUMMARIZATION_PROMPT : UPDATE_SUMMARIZATION_PROMPT;\n const initPrompt = richMode ? RICH_SUMMARIZATION_PROMPT : SUMMARIZATION_PROMPT;\n\n if (previousSummary) {\n promptText += `<previous-summary>\\n${previousSummary}\\n</previous-summary>\\n\\n${updatePrompt}`;\n } else {\n promptText += initPrompt;\n }\n\n const messages = [\n {\n role: 'user' as const,\n content: [{ type: 'text' as const, text: promptText }],\n },\n ];\n\n // Wrap in system prompt via claude -p\n const fullPrompt = `${SUMMARIZATION_SYSTEM_PROMPT}\\n\\n${messages[0].content[0].text}`;\n\n try {\n return (await Effect.runPromise(self.runModelSummary(fullPrompt, model, timeoutMs, harness)));\n } catch (err) {\n if (!isContextOverflowError(err)) throw err;\n\n const ceiling = getChunkBudgetChars(model);\n const truncatedSerialized = truncateHeadTail(serialized, ceiling);\n const truncatedPrevious = previousSummary ? truncateHeadTail(previousSummary, ceiling) : undefined;\n\n const truncatedConversationText = `<conversation>\\n${truncatedSerialized}\\n</conversation>`;\n let retryPromptText = `${truncatedConversationText}\\n\\n`;\n if (truncatedPrevious) {\n retryPromptText += `<previous-summary>\\n${truncatedPrevious}\\n</previous-summary>\\n\\n${updatePrompt}`;\n } else {\n retryPromptText += initPrompt;\n }\n const retryFullPrompt = `${SUMMARIZATION_SYSTEM_PROMPT}\\n\\n${retryPromptText}`;\n return (await Effect.runPromise(self.runModelSummary(retryFullPrompt, model, timeoutMs, harness)));\n }\n}\n\nasync function generateTurnPrefixSummary(\n serialized: string,\n model: string | undefined,\n timeoutMs?: number,\n harness: RuntimeName = 'claude-code',\n): Promise<string> {\n const promptText = `<conversation>\\n${serialized}\\n</conversation>\\n\\n${TURN_PREFIX_PROMPT}`;\n const fullPrompt = `${SUMMARIZATION_SYSTEM_PROMPT}\\n\\n${promptText}`;\n return (await Effect.runPromise(self.runModelSummary(fullPrompt, model, timeoutMs, harness)));\n}\n\n// ============================================================================\n// Chunked incremental summarization\n// ============================================================================\n\n// Per-chunk serialized-content budget (in characters). Leaves room in the\n// model's context window for the prompt template, the carried-forward\n// <previous-summary>, and the generated output. Intentionally conservative\n// — code-heavy content tokenizes denser than the 4-chars/token heuristic.\nconst CHUNK_BUDGET_CHARS_BY_MODEL: Record<string, number> = {\n 'claude-haiku-4-5-20251001': 300_000, // ~75k tokens content, 200k window\n 'claude-sonnet-5': 1_200_000, // ~300k tokens content, 1M window\n 'claude-sonnet-4-6': 1_200_000, // ~300k tokens content, 1M window\n 'claude-fable-5': 1_200_000, // ~300k tokens content, large window\n 'claude-opus-4-8': 1_200_000, // ~300k tokens content, 1M window\n 'claude-opus-4-7': 1_200_000, // ~300k tokens content, 1M window\n 'claude-opus-4-6': 1_200_000, // ~300k tokens content, 1M window\n};\nconst DEFAULT_CHUNK_BUDGET_CHARS = 300_000;\n\nfunction getChunkBudgetChars(model: string | undefined): number {\n if (!model) return DEFAULT_CHUNK_BUDGET_CHARS;\n return CHUNK_BUDGET_CHARS_BY_MODEL[model] ?? DEFAULT_CHUNK_BUDGET_CHARS;\n}\n\nfunction chunkEntriesByBudget(entries: any[], budgetChars: number): any[][] {\n const chunks: any[][] = [];\n let current: any[] = [];\n let currentChars = 0;\n for (const entry of entries) {\n const serialized = serializeEntry(entry);\n const size = serialized ? serialized.length + 2 : 0;\n if (currentChars + size > budgetChars && current.length > 0) {\n chunks.push(current);\n current = [];\n currentChars = 0;\n }\n current.push(entry);\n currentChars += size;\n }\n if (current.length > 0) chunks.push(current);\n return chunks;\n}\n\nasync function generateChunkedSummary(\n entries: any[],\n initialPreviousSummary: string | undefined,\n model: string | undefined,\n richMode: boolean,\n timeoutMs: number,\n includeThinking: boolean = true,\n harness: RuntimeName = 'claude-code',\n): Promise<string> {\n const budget = getChunkBudgetChars(model);\n const chunks = chunkEntriesByBudget(entries, budget);\n if (chunks.length === 0) {\n return initialPreviousSummary ?? '';\n }\n\n let running: string | undefined = initialPreviousSummary;\n for (let i = 0; i < chunks.length; i++) {\n const serialized = serializeConversation(chunks[i], includeThinking);\n if (!serialized.trim()) continue;\n console.log(\n `[smart-compaction] Summarizing chunk ${i + 1}/${chunks.length} ` +\n `(${serialized.length} chars, ${chunks[i].length} entries) with ${model ?? DEFAULT_SUMMARY_MODEL}`,\n );\n running = await generateSummaryFromPrompt(serialized, running, model, richMode, timeoutMs, harness);\n }\n\n return running ?? '';\n}\n\n/**\n * Split already-serialized transcript text into chunks that fit the summarizer\n * model's context budget. Splits on turn boundaries (the canonical serialized\n * form separates turns with a blank line) so a chunk never cuts mid-turn unless\n * a single turn is itself larger than the budget.\n */\nfunction chunkSerializedTextByBudget(text: string, budgetChars: number): string[] {\n if (text.length <= budgetChars) return text.trim() ? [text] : [];\n const turns = text.split('\\n\\n');\n const chunks: string[] = [];\n let current = '';\n for (const turn of turns) {\n const candidate = current ? `${current}\\n\\n${turn}` : turn;\n if (candidate.length > budgetChars && current) {\n chunks.push(current);\n current = turn;\n } else {\n current = candidate;\n }\n }\n if (current.trim()) chunks.push(current);\n return chunks;\n}\n\n/**\n * Harness-agnostic chunk-and-merge summarizer. Takes transcript text already\n * serialized by a ConversationTranscriptAdapter (so it works for any harness)\n * and runs the same incremental summary prompt the Claude-Code entry path uses,\n * carrying a running <previous-summary> forward across chunks. Returns the\n * final structured summary string.\n *\n * `harness` selects the summarizer LLM backend (claude-code or pi) and is\n * independent of which harness produced the transcript.\n */\nexport async function summarizeSerializedText(\n serialized: string,\n options: {\n model?: string;\n richMode?: boolean;\n timeoutMs?: number;\n harness?: RuntimeName;\n } = {},\n): Promise<string> {\n const model = options.model;\n const richMode = options.richMode ?? false;\n const timeoutMs = options.timeoutMs ?? FORK_SUMMARY_TIMEOUT_MS;\n const harness = options.harness ?? 'claude-code';\n\n const budget = getChunkBudgetChars(model);\n const chunks = chunkSerializedTextByBudget(serialized, budget);\n if (chunks.length === 0) return '';\n\n let running: string | undefined;\n for (let i = 0; i < chunks.length; i++) {\n const chunk = chunks[i]!;\n if (!chunk.trim()) continue;\n console.log(\n `[smart-compaction] Summarizing serialized chunk ${i + 1}/${chunks.length} ` +\n `(${chunk.length} chars) with ${model ?? DEFAULT_SUMMARY_MODEL}`,\n );\n running = await generateSummaryFromPrompt(chunk, running, model, richMode, timeoutMs, harness);\n }\n return running ?? '';\n}\n\nasync function generateSmartSummaryPromise(options: CompactionOptions): Promise<CompactionResult> {\n const entries = await parseEntries(options.jsonlPath);\n if (entries.length === 0) {\n throw new Error(`Session file is empty: ${options.jsonlPath}`);\n }\n\n const isFork = options.mode === 'fork';\n // Forks summarize the entire conversation (no \"kept\" recent portion);\n // compaction keeps recent entries verbatim and only summarizes older history.\n const keepRecentTokens = options.keepRecentTokens ?? (isFork ? Number.MAX_SAFE_INTEGER : 20000);\n const model = options.model || DEFAULT_SUMMARY_MODEL;\n const richMode = options.richMode ?? false;\n const includeThinking = options.includeThinkingInSummary ?? true;\n const harness = options.harness ?? 'claude-code';\n const tokensBefore = estimateContextTokens(entries);\n\n // Detect previous compact boundary for incremental summarization\n const prevBoundary = findPreviousCompactBoundary(entries);\n let boundaryStart = 0;\n let previousSummary: string | undefined;\n if (prevBoundary) {\n boundaryStart = prevBoundary.index;\n previousSummary = prevBoundary.summary;\n }\n\n const boundaryEnd = entries.length;\n const cutPoint = findCutPoint(entries, boundaryStart, boundaryEnd, keepRecentTokens);\n\n // Determine which entries to summarize\n const historyEnd = cutPoint.isSplitTurn ? cutPoint.turnStartIndex : cutPoint.firstKeptEntryIndex;\n\n const messagesToSummarize: any[] = [];\n for (let i = boundaryStart; i < historyEnd; i++) {\n messagesToSummarize.push(entries[i]);\n }\n\n const turnPrefixMessages: any[] = [];\n if (cutPoint.isSplitTurn) {\n for (let i = cutPoint.turnStartIndex; i < cutPoint.firstKeptEntryIndex; i++) {\n turnPrefixMessages.push(entries[i]);\n }\n }\n\n // Extract file ops from all relevant entries (summary + prefix + kept boundary)\n const fileOps = extractFileOpsFromEntries(messagesToSummarize);\n if (cutPoint.isSplitTurn) {\n const prefixOps = extractFileOpsFromEntries(turnPrefixMessages);\n prefixOps.read.forEach(f => fileOps.read.add(f));\n prefixOps.written.forEach(f => fileOps.written.add(f));\n prefixOps.edited.forEach(f => fileOps.edited.add(f));\n }\n // Also include file ops from entries AFTER the cut point up to the end\n // so the summary captures files touched in the \"kept\" recent work too\n const recentOps = extractFileOpsFromEntries(entries.slice(cutPoint.firstKeptEntryIndex));\n recentOps.read.forEach(f => fileOps.read.add(f));\n recentOps.written.forEach(f => fileOps.written.add(f));\n recentOps.edited.forEach(f => fileOps.edited.add(f));\n\n // Generate summaries\n const llmTimeoutMs = isFork ? FORK_SUMMARY_TIMEOUT_MS : undefined;\n let summary: string;\n let serializedHistory = serializeConversation(messagesToSummarize, includeThinking);\n let hasHistory = serializedHistory.trim().length > 0;\n\n // For forks, always produce a real summary. If the selected history slice is\n // empty (e.g. only metadata entries before the first valid cut point), fall\n // back to serializing the entire conversation.\n if (isFork && !hasHistory && !cutPoint.isSplitTurn) {\n const allMessages = entries.slice(boundaryStart, cutPoint.firstKeptEntryIndex);\n if (allMessages.length > 0) {\n serializedHistory = serializeConversation(allMessages, includeThinking);\n hasHistory = serializedHistory.trim().length > 0;\n }\n }\n\n const hasPrefix = cutPoint.isSplitTurn && turnPrefixMessages.length > 0;\n\n if (!hasHistory && !hasPrefix) {\n // Nothing to summarize — return previous summary or a minimal stub.\n // For forks, summarize the entire conversation via chunked incremental\n // passes (carrying <previous-summary> forward) so arbitrarily large\n // JSONL files fit the selected model's context window.\n if (isFork) {\n const forkTimeoutMs = llmTimeoutMs ?? FORK_SUMMARY_TIMEOUT_MS;\n // Summarize from the previous compact boundary (if any) forward — the\n // previousSummary already covers everything before boundaryStart.\n const forkEntries = boundaryStart > 0 ? entries.slice(boundaryStart) : entries;\n const anyContent = forkEntries.some((e) => serializeEntry(e, includeThinking));\n if (anyContent) {\n try {\n summary = await generateChunkedSummary(forkEntries, previousSummary, model, richMode, forkTimeoutMs, includeThinking, harness);\n } catch (error) {\n throw new Error(`Smart summary generation failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n if (!summary.trim()) {\n throw new Error('Smart summary generation failed: chunked summarization produced empty output');\n }\n } else {\n summary = previousSummary || '## Goal\\nContinue the current task.\\n\\n## Constraints & Preferences\\n- (none)\\n\\n## Progress\\n### Done\\n- (none)\\n\\n### In Progress\\n- [ ] Awaiting next instruction\\n\\n### Blocked\\n- (none)\\n\\n## Key Decisions\\n- (none)\\n\\n## Next Steps\\n1. Await user instruction\\n\\n## Critical Context\\n- (none)';\n }\n } else {\n const minimalStub = richMode\n ? '## Primary Request and Intent\\nContinue the current task.\\n\\n## Key Technical Concepts\\n- (none)\\n\\n## Files and Code Sections\\n- (none)\\n\\n## Errors and fixes\\n- (none)\\n\\n## Problem Solving\\nNo issues encountered.\\n\\n## All user messages\\n- (none)\\n\\n## Pending Tasks\\n- (none)\\n\\n## Current Work\\nAwaiting next instruction.\\n\\n## Optional Next Step\\nAwait user instruction.'\n : '## Goal\\nContinue the current task.\\n\\n## Constraints & Preferences\\n- (none)\\n\\n## Progress\\n### Done\\n- (none)\\n\\n### In Progress\\n- [ ] Awaiting next instruction\\n\\n### Blocked\\n- (none)\\n\\n## Key Decisions\\n- (none)\\n\\n## Next Steps\\n1. Await user instruction\\n\\n## Critical Context\\n- (none)';\n summary = previousSummary || minimalStub;\n }\n } else {\n try {\n if (hasPrefix) {\n const [historyResult, turnPrefixResult] = await Promise.all([\n hasHistory\n ? generateSummaryFromPrompt(serializedHistory, previousSummary, model, richMode, llmTimeoutMs, harness)\n : Promise.resolve('No prior history.'),\n generateTurnPrefixSummary(serializeConversation(turnPrefixMessages, includeThinking), model, llmTimeoutMs, harness),\n ]);\n summary = `${historyResult}\\n\\n---\\n\\n**Turn Context (split turn):**\\n\\n${turnPrefixResult}`;\n } else {\n summary = await generateSummaryFromPrompt(\n serializedHistory,\n previousSummary,\n model,\n richMode,\n llmTimeoutMs,\n harness,\n );\n }\n } catch (error) {\n throw new Error(`Smart summary generation failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n // Append file operations\n const { readFiles, modifiedFiles } = computeFileLists(fileOps);\n summary += formatFileOperations(readFiles, modifiedFiles);\n\n return {\n summary,\n tokensBefore,\n firstKeptEntryIndex: cutPoint.firstKeptEntryIndex,\n summaryModel: model,\n readFiles,\n modifiedFiles,\n };\n}\n\n// ─── Effect variants (PAN-1249, additive) ────────────────────────────────────\n//\n// Additive Effect surface for smart-compaction. The underlying Promise\n// functions remain canonical; these wrappers map failures to typed errors\n// (ProcessSpawnError for spawn / generation failures, FsError for IO).\n\n/** Effect variant of runModelSummary. */\nexport function runModelSummary(\n prompt: string,\n model?: string,\n timeoutMs?: number,\n harness: RuntimeName = 'claude-code',\n allowedTools?: string[],\n): Effect.Effect<string, ProcessSpawnError> {\n return Effect.tryPromise({\n try: () => runModelSummaryPromise(prompt, model, timeoutMs, harness, allowedTools),\n catch: (cause) =>\n new ProcessSpawnError({\n command: getHarnessBehavior(harness).deliveryKind === 'rpc-fifo' ? getHarnessBehavior(harness).executableName : 'claude',\n args: ['-p', model ?? 'default'],\n message: cause instanceof Error ? cause.message : String(cause),\n cause,\n }),\n });\n}\n\n/** Effect variant of generateSmartSummary. */\nexport function generateSmartSummary(\n options: CompactionOptions,\n): Effect.Effect<CompactionResult, FsError | ProcessSpawnError> {\n return Effect.tryPromise({\n try: () => generateSmartSummaryPromise(options),\n catch: (cause) => {\n const msg = cause instanceof Error ? cause.message : String(cause);\n // Distinguish between fs failures (read jsonl) and spawn failures (LLM).\n // The underlying impl throws plain Error in both cases; we map to\n // FsError when the message hints at file IO, otherwise spawn.\n if (msg.toLowerCase().includes('enoent') || msg.toLowerCase().includes('no such file')) {\n return new FsError({ path: options.jsonlPath, operation: 'smart-summary-read', cause });\n }\n return new ProcessSpawnError({\n command: 'claude',\n args: ['-p', options.model ?? 'default'],\n message: msg,\n cause,\n });\n },\n });\n}\n"],"mappings":"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"}
|
package/dist/dashboard/{spawn-planning-session-D15KbPOy.js → spawn-planning-session-CSMWco8B.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { o as spawnPlanningSession } from "./spawn-planning-session-
|
|
1
|
+
import { o as spawnPlanningSession } from "./spawn-planning-session-CXc0NkwV.js";
|
|
2
2
|
export { spawnPlanningSession };
|
package/dist/dashboard/{spawn-planning-session-BmJWHSCu.js → spawn-planning-session-CXc0NkwV.js}
RENAMED
|
@@ -2,11 +2,11 @@ import { Dt as getProjectConfigFromWorkspacePath, Ft as resolveProjectForIssue,
|
|
|
2
2
|
import { L as sessionExists, W as BLANKED_PROVIDER_ENV, d as exactPaneTarget, o as createSession, q as init_child_env, r as buildTmuxCommandString, w as killSession, x as init_tmux, z as setOption } from "./tmux-ePNhMIMU.js";
|
|
3
3
|
import { a as getHarnessBehavior } from "./src-fgbU-jJ-.js";
|
|
4
4
|
import { n as ensureSessionContextBriefingFile, r as init_briefing_freshness } from "./briefing-freshness-CXhZdnB8.js";
|
|
5
|
-
import { Gt as getAgentRuntimeBaseCommand, It as retrieveSpawnTimeMemoryContext, Jn as saveAgentStateSync, Kt as getCodexLauncherFields, Pn as getAgentStateSync, Qt as roleAgentDefinitionPath, Xt as init_runtime_command, qt as getOhmypiLauncherFields, t as init_agents, un as getProviderExportsForModel, wt as deliverInitialPromptWithRetry } from "./agents-
|
|
5
|
+
import { Gt as getAgentRuntimeBaseCommand, It as retrieveSpawnTimeMemoryContext, Jn as saveAgentStateSync, Kt as getCodexLauncherFields, Pn as getAgentStateSync, Qt as roleAgentDefinitionPath, Xt as init_runtime_command, qt as getOhmypiLauncherFields, t as init_agents, un as getProviderExportsForModel, wt as deliverInitialPromptWithRetry } from "./agents-C7V4odQ6.js";
|
|
6
6
|
import { t as init_behavior } from "./behavior-By-2Wipv.js";
|
|
7
7
|
import { a as init_launcher_generator, i as generateLauncherScriptSync } from "./state-home-Bgj7i-C7.js";
|
|
8
8
|
import { h as workspaceContextFile, o as init_layers } from "./layers-vdvlpFki.js";
|
|
9
|
-
import { n as resolveHarness, t as init_harness_resolve } from "./harness-resolve-
|
|
9
|
+
import { n as resolveHarness, t as init_harness_resolve } from "./harness-resolve-B3f9G1Kp.js";
|
|
10
10
|
import { c as ensureWorkspacePanDir, r as writeWorkspaceContext, t as init_pan_dir } from "./pan-dir-BgBeeZDX.js";
|
|
11
11
|
import { r as init_workspace_manager, t as createWorkspace } from "./workspace-manager-CEWK-OXd.js";
|
|
12
12
|
import { n as renderPrompt, t as init_prompts } from "./prompts-CelsUdrx.js";
|
|
@@ -541,4 +541,4 @@ async function spawnPlanningSession(opts) {
|
|
|
541
541
|
//#endregion
|
|
542
542
|
export { resolvePlanningSessionHarness as a, resolveAutoSpawnOnFinalize as i, buildPlanningPrompt as n, spawnPlanningSession as o, readAutoSpawnOnFinalizeFlag as r, writeFeatureContext as s, autoSpawnOnFinalizeFlagPath as t };
|
|
543
543
|
|
|
544
|
-
//# sourceMappingURL=spawn-planning-session-
|
|
544
|
+
//# sourceMappingURL=spawn-planning-session-CXc0NkwV.js.map
|