@overdeck/desktop 0.45.24 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/drizzle/overdeck/0000_overdeck_init.sql +32 -0
- package/package.json +1 -1
- package/server/{acceptance-criteria-DDCnXF58.js → acceptance-criteria-CCwFGICj.js} +2 -2
- package/server/activity-logger-CMthG6Vd.js +3 -0
- package/server/{activity-logger-DDlOIAML.js → activity-logger-CyteR4JO.js} +24 -13
- package/server/{advancing-selfheal-BVwW4qRn.js → advancing-selfheal-De1L-Sb4.js} +6 -6
- package/server/{agent-gc-CHcnvonI.js → agent-gc-CBULruzm.js} +5 -5
- package/server/agent-state-VQk8fY9F.js +3 -0
- package/server/{agent-state-service-BsgWxZuB.js → agent-state-service-BlnSkRFA.js} +5 -5
- package/server/{agent-state-service-D5UGKIJL.js → agent-state-service-hZpxIw1E.js} +1 -1
- package/server/agents-BKKkxKgK.js +3 -0
- package/server/{agents-EbI0zCJl.js → agents-C5rWYhb6.js} +4 -4
- package/server/archive-planning-0FJ6Xd3b.js +2 -0
- package/server/{archive-planning-Du25Jtst.js → archive-planning-C0lAbNB_.js} +16 -24
- package/server/{artifact-index-jobs-CbEDfCDu.js → artifact-index-jobs-ug6ZxIP5.js} +2 -2
- package/server/{assemble-J2ZZ2C15.js → assemble-DnffNpOo.js} +2 -2
- package/server/{backlog-auto-trigger-2R2jog7n.js → backlog-auto-trigger-Dh-i9PQf.js} +3 -3
- package/server/{behavior-B3exJ42O.js → behavior-CfIg6pKp.js} +2 -2
- package/server/bridge-pool-patrol-CUFmjVDN.js +136 -0
- package/server/{briefing-freshness-D1wzUIWv.js → briefing-freshness-DHmCSLar.js} +2 -2
- package/server/{build-info-CZk_TITh.js → build-info-BP160gU7.js} +1 -1
- package/server/{build-info-Ie_D0_BT.js → build-info-CuFfxZxp.js} +5 -3
- package/server/{checkpoint-manager-BI1Wxoku.js → checkpoint-manager-DEWD82qK.js} +2 -2
- package/server/{checkpoint-manager-DwbQoqrC.js → checkpoint-manager-Dxh0FYsv.js} +1 -1
- package/server/checkpoint-worker.js +1 -1
- package/server/{checkpoints-CQB1h765.js → checkpoints-CZvbtLnr.js} +2 -2
- package/server/{checkpoints-BJIs5QIA.js → checkpoints-DMTgXuLG.js} +1 -1
- package/server/{claude-hooks-provision-8Ngo8TpT.js → claude-hooks-provision-CN-xo-do.js} +1 -1
- package/server/{claude-hooks-provision-D8GXF3_s.js → claude-hooks-provision-fvy4RD2b.js} +13 -2
- package/server/{claude-permissions-DNWEVV6z.js → claude-permissions-CN0cSCPp.js} +2 -2
- package/server/{claude-settings-overlay-CEdaqpWI.js → claude-settings-overlay-CJn35FHQ.js} +2 -2
- package/server/{claude-settings-overlay-DWy-Bb4Y.js → claude-settings-overlay-Dabi9slj.js} +1 -1
- package/server/cli-DmXETsw-.js +3 -0
- package/server/{cli-RoOx5DUf.js → cli-oCWYA1pE.js} +9 -9
- package/server/{cliproxy-C8a1vtTU.js → cliproxy-C8mB3KuB.js} +2 -2
- package/server/{cliproxy-fHfIeiGd.js → cliproxy-PGwTX_o8.js} +1 -1
- package/server/{close-issue-DoOifFIK.js → close-issue-D5MF5GqF.js} +5 -5
- package/server/{closed-issue-reaper-CktPXo8m.js → closed-issue-reaper-CJ24u0Zt.js} +1 -1
- package/server/{closed-issue-reaper-Bk3SU4RC.js → closed-issue-reaper-Cltx86x5.js} +37 -16
- package/server/{codex-GcHuUF-k.js → codex-BdEsUFWh.js} +1 -1
- package/server/{codex-BZXGhUVB.js → codex-Drlf5Xhf.js} +36 -7
- package/server/{codex-parser-CFZ1_1Jl.js → codex-parser-DpB89Vqa.js} +2 -2
- package/server/compaction-continuation-K2AxQX4H.js +200 -0
- package/server/{config-CKxYiCmX.js → config-B2IMcBxx.js} +4 -3
- package/server/{config-DzV30TOm.js → config-DV-grfQc.js} +1 -1
- package/server/{config-BZ0sHTju.js → config-Dr3pW6w6.js} +2 -2
- package/server/{config-yaml-DySPNmKN.js → config-yaml-CmOPzmBb.js} +268 -14
- package/server/{conflict-gate-BaCVrH-N.js → conflict-gate-B9cN3SBi.js} +4 -4
- package/server/{conflict-gate-BhAY7TUd.js → conflict-gate-Dh754uyA.js} +1 -1
- package/server/{context-layers-BrPmE__h.js → context-layers-D6LZo3l1.js} +2 -2
- package/server/{context-layers-igZ4FI4_.js → context-layers-dR5YxHYB.js} +3 -3
- package/server/{control-settings-BQp7_4uD.js → control-settings-C7DUehE1.js} +49 -19
- package/server/{conversation-compaction-CgrR8YYp.js → conversation-compaction-BoqdDXWF.js} +8 -8
- package/server/{conversation-compaction-eQB5CkOe.js → conversation-compaction-Dj4FAKoZ.js} +1 -1
- package/server/{conversation-service-DPJ71F33.js → conversation-service-5aCnq1zR.js} +8 -7
- package/server/conversation-service-BCxl4f8Z.js +3 -0
- package/server/{conversations-6AfUfbwc.js → conversations-BUpYsOZg.js} +4 -4
- package/server/{conversations-CAsJF9kh.js → conversations-C34dyIb9.js} +1 -1
- package/server/{cost-B2ddP6wq.js → cost-Bgcub5kW.js} +12 -2
- package/server/{cost-R-m6Yi-W.js → cost-CvxRrucd.js} +3 -3
- package/server/{cost-sync-BsN6ER0n.js → cost-sync-Dv3LUaNW.js} +3 -3
- package/server/{dag-B1ucnjDU.js → dag-ombYYt4s.js} +2 -2
- package/server/{dangerous-git-ops-BXqeWVSf.js → dangerous-git-ops-BcJPC5Rr.js} +1 -1
- package/server/dashboard-db-worker.js +7 -7
- package/server/deacon-DrXqT9LQ.js +4 -0
- package/server/{deacon-CU_cAYSR.js → deacon-hi9KLPLT.js} +2933 -2704
- package/server/{deacon-nudge-log-6wVqAaqz.js → deacon-nudge-log-BNBebzeL.js} +3 -3
- package/server/deacon-pending-lifecycle-Cpk0k7Hi.js +33 -0
- package/server/{deacon-swarm-BXZZ1Z2-.js → deacon-swarm-DBxUaO-A.js} +13 -13
- package/server/deacon-swarm-I2JfX5Tg.js +2 -0
- package/server/deacon.js +14 -19
- package/server/dead-end-trip-CQcP70ND.js +13 -0
- package/server/delivery-Da0zEMY4.js +3 -0
- package/server/{deploy-patrol-AiFoP8dw.js → deploy-patrol-Df-Tmaq0.js} +69 -18
- package/server/deploy-queue-9SrhZR63.js +3 -0
- package/server/deploy-queue-UjKGYsDe.js +169 -0
- package/server/deploy-window-jOiPRHL0.js +3 -0
- package/server/{deploy-window-C3F-tihF.js → deploy-window-rpqpWqHA.js} +40 -16
- package/server/{dev-supervisor-bcOWqdQE.js → dev-supervisor-CC46Ig8q.js} +2 -2
- package/server/{devcontainer-renderer-_d6XhyND.js → devcontainer-renderer-68CSCRnu.js} +3 -3
- package/server/{dist-Cb_0uvpS.js → dist-CJy72uEg.js} +1 -1
- package/server/dist-DSlxIU1H.js +3 -0
- package/server/{dist-src-BSoS7mkd.js → dist-src-Bik83hFi.js} +1 -1
- package/server/docker-BMVTSFL5.js +3 -0
- package/server/{docker-DcMTFTUC.js → docker-Dam7mbIB.js} +2 -2
- package/server/{dod-C6n9RV3G.js → dod-Dar-yheg.js} +8 -4
- package/server/durable-review-pipeline-CGZ5QBxh.js +17 -0
- package/server/durable-review-pipeline-jpgCJZFp.js +3 -0
- package/server/{ensure-devcontainer-DNi-ono3.js → ensure-devcontainer-B057YA81.js} +4 -4
- package/server/{ensure-devcontainer-BZgOhRo7.js → ensure-devcontainer-C98V8yW-.js} +1 -1
- package/server/{esm-shims-OSHAYaS1.js → esm-shims-Br9BPdkR.js} +1 -1
- package/server/{event-store-EV2cMiXj.js → event-store-ELqkVOn0.js} +1 -1
- package/server/{event-store-CQL6NeqB.js → event-store-zY5MJHgF.js} +23 -4
- package/server/{events-BTdrdEq8.js → events-D6pyqhzM.js} +1 -1
- package/server/{events-DTfAe4My.js → events-D9PR1IC0.js} +3 -3
- package/server/{factory-CFibJuaw.js → factory-CRoOpGsF.js} +5 -5
- package/server/{feature-registry-population-DKZFMbFt.js → feature-registry-population--YUXU999.js} +4 -4
- package/server/{feature-registry-storage-BdPuLcBX.js → feature-registry-storage-BORBTo0y.js} +2 -2
- package/server/{features-ez2271oH.js → features--nFkJY8v.js} +2 -2
- package/server/{feedback-target-CoFDHiM8.js → feedback-target-C0ZzyHvU.js} +1 -1
- package/server/{feedback-target-7mqqwrX6.js → feedback-target-Dt9BsapX.js} +8 -8
- package/server/{feedback-writer-CY5L1lB7.js → feedback-writer-BG0RUZiu.js} +5 -5
- package/server/{feedback-writer-D3a22RCd.js → feedback-writer-D1fm-5Z8.js} +1 -1
- package/server/{flywheel-SVF02Jpq.js → flywheel-BekukH4i.js} +1 -1
- package/server/{flywheel-DHrgCphM.js → flywheel-BiT3odRb.js} +23 -15
- package/server/{flywheel-DzGtWnJ1.js → flywheel-CLVB55Be.js} +16 -15
- package/server/flywheel-merge-order-BJv1DZz1.js +462 -0
- package/server/flywheel-merge-order-BKw9o6ku.js +2 -0
- package/server/forge-CZbSg6Ds.js +383 -0
- package/server/forge-DK3blQb_.js +3 -0
- package/server/{from-kNxT0bZC.js → from-D_4_dk7i.js} +1 -1
- package/server/{fts-db-CE46vDkZ.js → fts-db-BeOomFa-.js} +2 -2
- package/server/{fts-operations-CqY6zl-i.js → fts-operations-BdewJ_g9.js} +2 -2
- package/server/git-utils-CI6cwyyC.js +3 -0
- package/server/{git-utils-CRw2zLPC.js → git-utils-ameCgDdy.js} +30 -5
- package/server/{github-app-C3QrAUd0.js → github-app-CQ1Lo6LA.js} +3 -3
- package/server/{github-app-ClZ2lk8D.js → github-app-DtAsvwzK.js} +1 -1
- package/server/{github-client-BnIsSrEN.js → github-client-BfyDxuRN.js} +2 -2
- package/server/{github-client-DfQYVUaw.js → github-client-Cj0yl_07.js} +1 -1
- package/server/github-pr-lookup-BDq6Wznz.js +58 -0
- package/server/{harness-binary-DPUi-Pv8.js → harness-binary-DqkftwTb.js} +2 -2
- package/server/{harness-resolve-3lNZkyT4.js → harness-resolve-CqMqM1Mb.js} +4 -4
- package/server/{health-events-BBcTYQKU.js → health-events-CazRxJUS.js} +2 -2
- package/server/{health-events-BDOHby5Q.js → health-events-_xfTaOUs.js} +1 -1
- package/server/{hooks-CKZgXlJb.js → hooks-BO3QT1sn.js} +2 -2
- package/server/{hooks-DPVX1rwQ.js → hooks-BnJsxlSq.js} +1 -1
- package/server/{hume-Cz8igP9E.js → hume-CDYJxqx-.js} +2 -2
- package/server/hume-Dq--7rOQ.js +3 -0
- package/server/{idle-stack-reaper-CuLF0j2H.js → idle-stack-reaper-BYqERdkE.js} +1 -1
- package/server/{idle-stack-reaper-DDIRwxUY.js → idle-stack-reaper-CnGx_PO_.js} +99 -6
- package/server/in-flight-guard-Bq3epG58.js +45 -0
- package/server/{infra-BEqFxlJc.js → infra-BjuxvjdS.js} +70 -5
- package/server/{injection-CPUIqNhI.js → injection-DZxlV2al.js} +1 -1
- package/server/{injection-C8aiVJrF.js → injection-UCf8EsjX.js} +7 -7
- package/server/{inspect-agent-BLuJ1AkT.js → inspect-agent-6kylZnrm.js} +26 -25
- package/server/inspect-agent-BVwDrVrz.js +2 -0
- package/server/{internal-token-s0-oKybJ.js → internal-token-DvMTQSOS.js} +2 -2
- package/server/{internal-token-BrcU6qfe.js → internal-token-M9omeXM1.js} +1 -1
- package/server/{io-C9kF1wtJ.js → io-VHvc0Ssp.js} +43 -26
- package/server/{issue-closed-CDJk4pIp.js → issue-closed-B6KJkmHZ.js} +7 -7
- package/server/{issue-lifecycle-B8sZHVHh.js → issue-lifecycle-9gk3fnXN.js} +1 -1
- package/server/{issue-lifecycle-ojZAzDBP.js → issue-lifecycle-C4Zj0WmE.js} +34 -28
- package/server/{issue-service-singleton-Yx5DdmVJ.js → issue-service-singleton-DmCh7EHj.js} +10 -10
- package/server/{issue-service-singleton-BvJ09SaR.js → issue-service-singleton-PMx8F1jr.js} +1 -1
- package/server/{issues-BMmP_77e.js → issues-CgnQ1OGQ.js} +2 -2
- package/server/{jsonl-parser-BXSlHwEh.js → jsonl-parser-DJOH_O-w.js} +5 -4
- package/server/{label-cleanup-B0UJwnv5.js → label-cleanup-Dv7AV_R1.js} +3 -3
- package/server/{label-reconciler-B4iOAjlC.js → label-reconciler--F85rufp.js} +4 -4
- package/server/{lifecycle-yPd___5E.js → lifecycle-CTdOWYMi.js} +2 -2
- package/server/{lifecycle-xmBfK2GJ.js → lifecycle-DDN8ApVY.js} +6 -7
- package/server/{lifecycle-io-BREGpnLk.js → lifecycle-io-D-lGdzK3.js} +5 -5
- package/server/{lifecycle-io-DPo7x11I.js → lifecycle-io-D_zTLvP1.js} +1 -1
- package/server/{linear-client-BsuUvkdA.js → linear-client-BQU36QqE.js} +2 -2
- package/server/{linear-client-CTskEeT_.js → linear-client-CY4O_Tu3.js} +1 -1
- package/server/linear-mcp-auth-BnU4TYfY.js +280 -0
- package/server/linear-mcp-auth-NYBq_oHZ.js +2 -0
- package/server/memory-fts-worker.js +1 -1
- package/server/{merge-CefQNAnq.js → merge-Bpx4jjht.js} +13 -11
- package/server/{merge-agent-4WOWlSYA.js → merge-agent-DdMVSV2Y.js} +233 -83
- package/server/{merge-agent-CKkgIBPB.js → merge-agent-DrXa1CpW.js} +1 -1
- package/server/{merge-batch-ClFn2T-y.js → merge-batch-C5q1c1GX.js} +1 -1
- package/server/merge-completeness-BMm8tMyZ.js +277 -0
- package/server/merge-completeness-D0ljXbk3.js +3 -0
- package/server/{merge-B1DiziGU.js → merge-idOG--29.js} +1 -1
- package/server/merge-ops-DdpTiEMt.js +2 -0
- package/server/merge-rebase-DGQpYJU3.js +2 -0
- package/server/{merge-rebase-BfaTyXsw.js → merge-rebase-xLnMlw5h.js} +3 -3
- package/server/{merge-set-DJ8-UErs.js → merge-set-DH7ot3yz.js} +11 -5
- package/server/merge-set-DzsOTBg5.js +3 -0
- package/server/{merge-sync-VPV28g0g.js → merge-sync-CQ-LgZ1_.js} +406 -153
- package/server/merge-sync-Ca7F5JnQ.js +3 -0
- package/server/{merge-train-CHopycP0.js → merge-train-DTEMyIu4.js} +18 -8
- package/server/{merge-train-deps-D1cOZzy2.js → merge-train-deps-CNPJzepw.js} +4 -4
- package/server/merge-verification-x3JO8Dtz.js +220 -0
- package/server/merged-docker-cleanup-worker-CTpC27Bs.js +107 -0
- package/server/merged-docker-cleanup-worker-Cdi9apm-.js +3 -0
- package/server/{multipart-parser-duPAfSBw.js → multipart-parser-IMSBfePV.js} +2 -2
- package/server/{no-resume-mode-Nw29vaFb.js → no-resume-mode-C5ULAXwO.js} +1 -1
- package/server/node_modules/.package-lock.json +27 -27
- package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +3 -3
- package/server/node_modules/@google-cloud/common/package.json +2 -2
- package/server/node_modules/gaxios/build/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/server/node_modules/gaxios/build/esm/tsconfig.tsbuildinfo +1 -1
- package/server/node_modules/gaxios/package.json +1 -1
- package/server/node_modules/google-auth-library/build/src/auth/googleauth.js +24 -19
- package/server/node_modules/google-auth-library/package.json +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/auth.proto +2 -1
- package/server/node_modules/google-gax/build/protos/google/api/backend.proto +12 -1
- package/server/node_modules/google-gax/build/protos/google/api/billing.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/client.proto +165 -53
- package/server/node_modules/google-gax/build/protos/google/api/cloudquotas/v1/resources.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/cloudquotas/v1beta/quota_adjuster_settings.proto +7 -3
- package/server/node_modules/google-gax/build/protos/google/api/cloudquotas/v1beta/resources.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/config_change.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/context.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/control.proto +3 -3
- package/server/node_modules/google-gax/build/protos/google/api/distribution.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/documentation.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/endpoint.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/error_reason.proto +186 -1
- package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/checked.proto +31 -3
- package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/eval.proto +8 -9
- package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/explain.proto +1 -2
- package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/syntax.proto +20 -22
- package/server/node_modules/google-gax/build/protos/google/api/expr/v1alpha1/value.proto +2 -3
- package/server/node_modules/google-gax/build/protos/google/api/field_behavior.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/field_info.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/http.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/httpbody.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/label.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/launch_stage.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/log.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/logging.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/metric.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/monitored_resource.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/monitoring.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/policy.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/quota.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/resource.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/routing.proto +8 -4
- package/server/node_modules/google-gax/build/protos/google/api/service.proto +2 -3
- package/server/node_modules/google-gax/build/protos/google/api/source_info.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/system_parameter.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/api/usage.proto +7 -27
- package/server/node_modules/google-gax/build/protos/google/api/visibility.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/longrunning/operations.proto +20 -1
- package/server/node_modules/google-gax/build/protos/google/protobuf/any.proto +52 -108
- package/server/node_modules/google-gax/build/protos/google/protobuf/compiler/ruby/ruby_generated_code.proto +2 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/cpp_features.proto +21 -1
- package/server/node_modules/google-gax/build/protos/google/protobuf/cpp_file_options.proto +24 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/cpp_options.proto +15 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/descriptor.proto +118 -30
- package/server/node_modules/google-gax/build/protos/google/protobuf/field_mask.proto +16 -18
- package/server/node_modules/google-gax/build/protos/google/protobuf/internal_options.proto +8 -1
- package/server/node_modules/google-gax/build/protos/google/protobuf/json/json_enumval_custom_string.proto +26 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/json_enumvalue_options.proto +29 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/json_options.proto +14 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/struct.proto +38 -22
- package/server/node_modules/google-gax/build/protos/google/protobuf/test_protos/forced_micro_string.proto +3 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/test_protos/repeated_field_proxy_import_message.proto +14 -0
- package/server/node_modules/google-gax/build/protos/google/protobuf/timestamp.proto +9 -8
- package/server/node_modules/google-gax/build/protos/google/protobuf/util/json_format_proto3.proto +18 -0
- package/server/node_modules/google-gax/build/protos/google/rpc/code.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/rpc/context/attribute_context.proto +7 -2
- package/server/node_modules/google-gax/build/protos/google/rpc/context/audit_context.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/rpc/error_details.proto +5 -5
- package/server/node_modules/google-gax/build/protos/google/rpc/http.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/rpc/status.proto +1 -2
- package/server/node_modules/google-gax/build/protos/google/type/calendar_period.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/type/color.proto +9 -10
- package/server/node_modules/google-gax/build/protos/google/type/date.proto +11 -9
- package/server/node_modules/google-gax/build/protos/google/type/datetime.proto +17 -17
- package/server/node_modules/google-gax/build/protos/google/type/dayofweek.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/type/decimal.proto +11 -13
- package/server/node_modules/google-gax/build/protos/google/type/expr.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/type/fraction.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/type/interval.proto +1 -2
- package/server/node_modules/google-gax/build/protos/google/type/latlng.proto +4 -5
- package/server/node_modules/google-gax/build/protos/google/type/localized_text.proto +3 -3
- package/server/node_modules/google-gax/build/protos/google/type/money.proto +1 -2
- package/server/node_modules/google-gax/build/protos/google/type/month.proto +1 -1
- package/server/node_modules/google-gax/build/protos/google/type/phone_number.proto +20 -15
- package/server/node_modules/google-gax/build/protos/google/type/postal_address.proto +39 -39
- package/server/node_modules/google-gax/build/protos/google/type/quaternion.proto +4 -4
- package/server/node_modules/google-gax/build/protos/google/type/timeofday.proto +11 -8
- package/server/node_modules/google-gax/package.json +5 -5
- package/server/node_modules/retry-request/package.json +4 -4
- package/server/node_modules/teeny-request/package.json +5 -5
- package/server/node_modules/undici/lib/cache/memory-cache-store.js +54 -9
- package/server/node_modules/undici/lib/cache/sqlite-cache-store.js +7 -1
- package/server/node_modules/undici/lib/core/request.js +12 -1
- package/server/node_modules/undici/lib/dispatcher/client-h1.js +11 -2
- package/server/node_modules/undici/lib/global.js +36 -16
- package/server/node_modules/undici/lib/handler/cache-handler.js +236 -116
- package/server/node_modules/undici/lib/handler/cache-revalidation-handler.js +3 -3
- package/server/node_modules/undici/lib/handler/retry-handler.js +24 -0
- package/server/node_modules/undici/lib/interceptor/cache.js +152 -62
- package/server/node_modules/undici/lib/interceptor/decompress.js +5 -2
- package/server/node_modules/undici/lib/util/cache.js +328 -66
- package/server/node_modules/undici/lib/util/date.js +23 -6
- package/server/node_modules/undici/lib/web/cookies/util.js +78 -8
- package/server/node_modules/undici/package.json +1 -1
- package/server/{orphan-proposed-reconciler-CTSGcK8p.js → orphan-proposed-reconciler-CWmOdM9-.js} +1 -1
- package/server/{orphan-proposed-reconciler-BvKkWMJQ.js → orphan-proposed-reconciler-Dg6U4ADZ.js} +24 -15
- package/server/package-lock.json +28 -28
- package/server/package.json +1 -1
- package/server/{pan-dir-B0c3w0Ya.js → pan-dir-ubraCiUg.js} +24 -10
- package/server/{paths-D-xWGHdh.js → paths-cXmOwSbh.js} +2 -2
- package/server/pending-lifecycle-claim-DEteYdS9.js +110 -0
- package/server/{pickup-DUCLWrJY.js → pickup-D8xtG1J2.js} +1 -1
- package/server/pipeline-membership-BGSvkT2M.js +3 -0
- package/server/pipeline-membership-CrAPLYtf.js +57 -0
- package/server/{pipeline-membership-mY3GprlK.js → pipeline-membership-gather-CET40frr.js} +177 -109
- package/server/pipeline-membership-gather-DTfcgxLl.js +3 -0
- package/server/{pipeline-notifier-BXkJzDC4.js → pipeline-notifier-BuQ0e4hF.js} +2 -2
- package/server/{pipeline-notifier-BJr8gQX6.js → pipeline-notifier-ImNXknf0.js} +1 -1
- package/server/post-merge-lifecycle-worker-DbO10pum.js +50 -0
- package/server/{project-pipelines-C0MWUeCU.js → project-pipelines-Bim6bThI.js} +2 -2
- package/server/{project-repos-B6GycDh9.js → project-repos-C0nuoBGv.js} +7 -3
- package/server/project-repos-CRE6Ykow.js +3 -0
- package/server/projects-B03Wr-xc.js +3 -0
- package/server/{prompts-DxzFXuLl.js → prompts-BEx08AIu.js} +2 -2
- package/server/{providers-u4Ga0jOr.js → providers-D7IluJe0.js} +1 -1
- package/server/{providers-qQAwGQDW.js → providers-evXhiQeg.js} +7 -7
- package/server/public/assets/{chunk-BO2N2NFS-BamJdinX.js → chunk-BO2N2NFS-D1s4-Sqp.js} +4 -4
- package/server/public/assets/{diagram-OG6HWLK6-DfOB8-w4.js → diagram-OG6HWLK6-1gdMoSF7.js} +1 -1
- package/server/public/assets/{dist-D7zYSEA6.js → dist-CxAOHbil.js} +1 -1
- package/server/public/assets/{dist-ByIuzMQW.js → dist-DqDRYW6P.js} +3 -3
- package/server/public/assets/{ganttDiagram-6RSMTGT7-EdmRyXL3.js → ganttDiagram-6RSMTGT7-BYex-Ec7.js} +1 -1
- package/server/public/assets/{highlighted-body-OFNGDK62-MerOfTX8.js → highlighted-body-OFNGDK62-DlVkiG0S.js} +1 -1
- package/server/public/assets/index-Cc7cnFC4.css +1 -0
- package/server/public/assets/index-K0hAYCgV.js +807 -0
- package/server/public/assets/{linear-BBbArIcK.js → linear-B4cuEFmO.js} +1 -1
- package/server/public/assets/mermaid-GHXKKRXX-DyDHFXHV.js +1 -0
- package/server/public/assets/{pieDiagram-4H26LBE5-BKIddiJN.js → pieDiagram-4H26LBE5-CBHNBIJQ.js} +1 -1
- package/server/public/assets/{prod-B8vYiu52.js → prod-CN2nHBvX.js} +4 -4
- package/server/public/assets/{quadrantDiagram-W4KKPZXB-D6RtoULk.js → quadrantDiagram-W4KKPZXB-Bom87VOQ.js} +1 -1
- package/server/public/assets/{sankeyDiagram-5OEKKPKP-CLrCedZX.js → sankeyDiagram-5OEKKPKP-UrBeyLxk.js} +1 -1
- package/server/public/assets/{xychartDiagram-2RQKCTM6-hznR8DYl.js → xychartDiagram-2RQKCTM6-DhkbrIxR.js} +1 -1
- package/server/public/index.html +2 -2
- package/server/{pull-requests-7N8WKseP.js → pull-requests-Cv7LxzUN.js} +1 -1
- package/server/{pull-requests-_lHueOHW.js → pull-requests-DHWiKxo7.js} +19 -10
- package/server/{queries-CjNIf-Ub.js → queries-DHJm7bTd.js} +631 -110
- package/server/{rally-CyWT_lNO.js → rally-B71M9f4o.js} +3 -3
- package/server/rally-YDjU513q.js +3 -0
- package/server/{rally-api-ClOSd-Tt.js → rally-api-D5uXN08-.js} +1 -1
- package/server/{rally-api-C8e_1JRi.js → rally-api-Dkqmok65.js} +2 -2
- package/server/{rally-client-lc-nokqr.js → rally-client-Bfqm6XI4.js} +4 -4
- package/server/{rally-client-sgtVqzNU.js → rally-client-CxsA6ExK.js} +1 -1
- package/server/{reap-terminal-sessions-7KeHv1R1.js → reap-terminal-sessions-BQ23nriz.js} +2 -2
- package/server/{reap-terminal-sessions-BtHPo6Xc.js → reap-terminal-sessions-CvmwaqKv.js} +2 -2
- package/server/{rebuild-stack-lwtsW0GO.js → rebuild-stack-0EEYReVZ.js} +16 -7
- package/server/{rebuild-stack-CFvcBHsS.js → rebuild-stack-qeRqHZxH.js} +2 -2
- package/server/{reconstruct-cache-C3Ui7ojV.js → reconstruct-cache-BbYFsqLa.js} +7 -6
- package/server/record-CtroO946.js +3 -0
- package/server/record-update-DH6dLJID.js +3 -0
- package/server/{record-update-dE1Aw83j.js → record-update-Z0QCxmMp.js} +124 -34
- package/server/{recovery-trip-BvRWfUXM.js → recovery-trip-eJe26h-f.js} +2 -2
- package/server/{release-engine-Cx48W7z8.js → release-engine-lPUp-MTd.js} +5 -5
- package/server/{release-set-CQfuN9-v.js → release-set-BwGeyZKX.js} +3 -3
- package/server/{remote-C_2hasl7.js → remote-BCd02Es1.js} +3 -3
- package/server/{remote-ChgimyYa.js → remote-CVGUhXMV.js} +3 -3
- package/server/{remote-agents-CA3Ihlxj.js → remote-agents-C1bssi41.js} +2 -2
- package/server/{remote-agents-By1ige5O.js → remote-agents-C_VxssLU.js} +300 -46
- package/server/{remote-completion-fVe9e_3u.js → remote-completion-DAB0P706.js} +12 -12
- package/server/resume-u9byntrq.js +3 -0
- package/server/{review-agent-DNboMyW4.js → review-agent-CD4RCI0Y.js} +1 -1
- package/server/{review-agent-CIGOQYBD.js → review-agent-CHhI66UP.js} +60 -47
- package/server/{review-artifacts-nRDPuMxd.js → review-artifacts-DSMRIfuJ.js} +7 -6
- package/server/{review-context-2uj-YQ8J.js → review-context-oFuBbiEE.js} +8 -8
- package/server/{in-flight-guard-CAAkqPLu.js → review-convoy-liveness-CpzrcJ5F.js} +3 -44
- package/server/review-status-BZH8h-6W.js +3 -0
- package/server/review-status-emit-CUExtHd5.js +50 -0
- package/server/{review-status-enrichment-Dci-ZwEt.js → review-status-enrichment-QV_hQkgS.js} +4 -4
- package/server/{review-status-source-CxuEjLGg.js → review-status-source-CpvJnvnQ.js} +24 -3
- package/server/review-status-source-ylw5QZUR.js +3 -0
- package/server/{review-status-sync-BTOpxtTC.js → review-status-sync-483sujRo.js} +2 -2
- package/server/{review-status-sync-DSDK3OMy.js → review-status-sync-NaWvI9Xf.js} +1 -1
- package/server/review-status-yljtTd-q.js +7521 -0
- package/server/{review-verdict-feedback-CTd4QMBu.js → review-verdict-feedback-BPDn4li_.js} +1 -1
- package/server/{review-verdict-feedback-CCjVA7Uk.js → review-verdict-feedback-CELeUinh.js} +48 -8
- package/server/{rollup-FGsKki9R.js → rollup-DTNvelz9.js} +8 -8
- package/server/{rollup-BKQC7jp4.js → rollup-DYZfq1c4.js} +1 -1
- package/server/{scanner-CnqEZeDy.js → scanner-CV35oSn4.js} +8 -7
- package/server/{sequence-io-D909zgeH.js → sequence-io-DF_8iuhV.js} +4 -4
- package/server/{sequencer-agent-CzkcK6P5.js → sequencer-agent-B2WeCtGi.js} +5 -5
- package/server/server.js +1952 -578
- package/server/{service-CLeAoU6G.js → service-Br9rpBNA.js} +81 -64
- package/server/{session-fork-CHI1XvL9.js → session-fork-D0LY152N.js} +2 -2
- package/server/{session-history-BT3IvqhC.js → session-history-BUyK29eq.js} +4 -4
- package/server/{settings-BTMvpNFU.js → settings-Bse1Pdcj.js} +3 -3
- package/server/settings-CdvIF84R.js +2 -0
- package/server/{settings-C0zgxOGf.js → settings-CvVGqNEs.js} +3 -2
- package/server/{shadow-engineering-BJfgm-hX.js → shadow-engineering-BWLa8ODz.js} +2 -2
- package/server/{shadow-state-7a-524T8.js → shadow-state-B4fpKxOO.js} +2 -2
- package/server/{shadow-state-DnDyjujH.js → shadow-state-FV6PHfEW.js} +1 -1
- package/server/{shadow-utils-Db3oroFG.js → shadow-utils-D7asqxOZ.js} +2 -2
- package/server/{ship-log-D9MlVzYU.js → ship-log-xplJ8t75.js} +1 -1
- package/server/{smart-compaction-CV2ukKND.js → smart-compaction-CPp2Ykf6.js} +1 -1
- package/server/{smart-compaction-KCYScAU1.js → smart-compaction-D3U_79f-.js} +8 -7
- package/server/{spawn-planning-session-qUC2VWu3.js → spawn-planning-session-1nFi3gfk.js} +1 -1
- package/server/{spawn-planning-session-DKpdFyOC.js → spawn-planning-session-DGfZ5B8D.js} +17 -17
- package/server/{specialist-completion-Ky9wCDpb.js → specialist-completion-Br48eiDP.js} +1 -1
- package/server/{specialist-context-Bn3dCGS2.js → specialist-context-cVbGnTa3.js} +5 -5
- package/server/{specialist-handoff-logger-CMEwYxa2.js → specialist-handoff-logger-DK-GTz4s.js} +2 -2
- package/server/{specialist-logs-C5p8G7tx.js → specialist-logs-Cl5-hqT8.js} +3 -3
- package/server/{specialists-CC4r-c2s.js → specialists-CNfYO3G2.js} +975 -227
- package/server/{specialists-jiuuyVkp.js → specialists-Cicieuzu.js} +18 -18
- package/server/{specialists-CShuVGWT.js → specialists-JHsdU3pA.js} +1 -1
- package/server/{specialists-DM6bWjsi.js → specialists-Tdezg_6N.js} +1 -1
- package/server/specs-Bt7WJDoC.js +3 -0
- package/server/src-CRmCHlma.js +11408 -0
- package/server/{src-CXmtj0im.js → src-Ck028hjO.js} +6 -6
- package/server/{src-CdmnTM2m.js → src-UWcGe0Ix.js} +3 -3
- package/server/{stack-health-Bn3o8FBX.js → stack-health-CJLMrLBl.js} +1 -1
- package/server/{stack-health-DxSdG9cW.js → stack-health-DqSqx0zv.js} +7 -5
- package/server/{stale-task-claims-KJKxxiiQ.js → stale-task-claims-CYFOUNlT.js} +4 -4
- package/server/{staleness-CT34nwr9.js → staleness-BQ-0gMYK.js} +1 -1
- package/server/{staleness-DPm7ClwA.js → staleness-D47CUJok.js} +1 -1
- package/server/{state-home-Cn_Qu8IX.js → state-home-BYV7qZTW.js} +2 -2
- package/server/{state-mapping-BL_-3Yt8.js → state-mapping-BVldLhBf.js} +1 -1
- package/server/{state-migrate-BGg2ZaOt.js → state-migrate-CvvBtS0Y.js} +4 -4
- package/server/{stuck-remediation-s9_2qfi6.js → stuck-remediation-Wt0UVvu1.js} +1 -1
- package/server/{stuck-remediation-DYuPRYYw.js → stuck-remediation-mkLC6G_t.js} +79 -22
- package/server/{substrate-bug-weights-service-B-FwCs5V.js → substrate-bug-weights-service-XfLAKnmK.js} +3 -3
- package/server/{summary-fork-DpcxN9tf.js → summary-fork-CD7GOts0.js} +2 -2
- package/server/{summary-fork-D1RAk9rJ.js → summary-fork-xiXBnWG9.js} +8 -8
- package/server/supervisor/{injection-budget-Csw5tqfJ.js → injection-budget-B5SbvDx2.js} +1 -1
- package/server/supervisor/{paths-DehGY2Fj.js → paths-K3noE4N_.js} +1 -1
- package/server/supervisor/pty-supervisor.js +49 -3
- package/server/supervisor/{pty-token-x-ea28Us.js → pty-token-B7lp0ElT.js} +2 -2
- package/server/{supervisor-wM4ooB5O.js → supervisor-DL788vos.js} +3 -3
- package/server/supervisor-UWiQNK-y.js +2 -0
- package/server/{swarm-readiness-DlP_UjHq.js → swarm-readiness-BV14DF5N.js} +3 -3
- package/server/{system-prerequisites-DUDj1YHf.js → system-prerequisites-pdWG6ZQs.js} +2 -2
- package/server/{teardown-workspace-DeTTImn-.js → teardown-workspace-l2F4_zim.js} +15 -16
- package/server/{test-agent-queue-MbxX5vqq.js → test-agent-queue-qakFIIGz.js} +6 -6
- package/server/{test-verdict-bWYBtqBg.js → test-verdict-BJYDggMm.js} +1 -1
- package/server/{test-verdict-gscuksPv.js → test-verdict-Gw-btEfb.js} +1 -1
- package/server/{tldr-daemon-BYFkts95.js → tldr-daemon-BKOYB616.js} +1 -1
- package/server/{tldr-daemon-C-69c3OI.js → tldr-daemon-CBaWkV9k.js} +2 -2
- package/server/{tmux-R7N7y-Mh.js → tmux-B1Wbxz5o.js} +3 -3
- package/server/{tmux-B6z7h_vZ.js → tmux-DQ6jB76i.js} +1 -1
- package/server/{launcher-generator-BBWG_SiS.js → tmux-dedup-DbN6MGzM.js} +428 -9
- package/server/{token-BK6t8BIT.js → token-Cxbk023d.js} +2 -2
- package/server/{token-util-DxXu-vd1.js → token-util-CLq2MmQt.js} +1 -1
- package/server/token-util-zlz9U0ki.js +3 -0
- package/server/{tracker-config-G6latr8C.js → tracker-config-DZ8Zn2nQ.js} +2 -2
- package/server/{tracker-utils-DHv5pSDT.js → tracker-utils-L0FKtjq2.js} +3 -3
- package/server/{traefik-connect-Df2uXPsQ.js → traefik-connect-bNX6jKkb.js} +1 -1
- package/server/{tunnel-CDVKJpRv.js → tunnel-BAm1XgjG.js} +3 -3
- package/server/{tunnel-DGdUkGoZ.js → tunnel-CjSnHdTc.js} +1 -1
- package/server/{types-5M0lupud.js → types-q67TYYg5.js} +1 -1
- package/server/uat-promote-verification-CKB9ZrKC.js +92 -0
- package/server/uat-train-Cu-4nvbf.js +2 -0
- package/server/uat-train-D5UjcyAa.js +0 -0
- package/server/{validate-IfDGkaVR.js → validate-Cxsx5Uz1.js} +8 -6
- package/server/{validation-CC9OPqJZ.js → validation-DEaTZafj.js} +1 -1
- package/server/{validation-Dw1pzDzr.js → validation-VZgJxmqc.js} +4 -4
- package/server/{verification-artifact-B3itKTxu.js → verification-artifact-C85cRTc_.js} +1 -1
- package/server/{verification-artifact-TVFSz_q1.js → verification-artifact-g3yuxQDL.js} +1 -1
- package/server/{verification-runner-BW4HOKAz.js → verification-runner-DlZI8yhw.js} +1 -1
- package/server/{verification-runner-CkgX6EtI.js → verification-runner-KDZIsBj4.js} +40 -18
- package/server/{vtt-parser-DYPbKcIJ.js → vtt-parser-Jr94BF3Y.js} +1 -1
- package/server/{work-agent-prompt-Du8Vh2aJ.js → work-agent-prompt-C-vuP3_J.js} +20 -9
- package/server/workflows-CHrx_hcW.js +2 -0
- package/server/{workflows-mbQzh6mQ.js → workflows-D0oip4eV.js} +161 -78
- package/server/{workspace--8tnhDI0.js → workspace-BqFg__wH.js} +1 -1
- package/server/{workspace-BPUws1-_.js → workspace-C0fH3aek.js} +3 -3
- package/server/workspace-anchor-drift-B4gMRHl4.js +3 -0
- package/server/workspace-anchor-drift-CZKofakh.js +224 -0
- package/server/{workspace-config-CIVWZOQr.js → workspace-config-B123aZl-.js} +1 -1
- package/server/workspace-manager-CDTKjjdU.js +3 -0
- package/server/{workspace-manager-CBhNdzE4.js → workspace-manager-CwO-Hek7.js} +156 -117
- package/server/{workspace-metadata-_WygnyoX.js → workspace-metadata-CQv00QwK.js} +2 -2
- package/server/{workspace-metadata-BzHnwwX4.js → workspace-metadata-D4M8BM4W.js} +1 -1
- package/server/{workspaces-Do_9J0LQ.js → workspaces-j1e_6aAT.js} +719 -292
- package/sync-sources/dev-skills/pan-dashboard-restart/SKILL.md +34 -10
- package/sync-sources/hooks/linear-mcp-auth-hook +97 -0
- package/sync-sources/rules/ask-user-question-self-contained.md +9 -0
- package/sync-sources/skills/pan-close/SKILL.md +5 -3
- package/sync-sources/skills/pan-peer-review/SKILL.md +195 -0
- package/sync-sources/skills/pan-reload/SKILL.md +3 -3
- package/sync-sources/skills/pan-restart/SKILL.md +5 -4
- package/sync-sources/skills/pan-review/SKILL.md +7 -1
- package/sync-sources/skills/pan-sync-main/SKILL.md +9 -8
- package/sync-sources/skills/pipeline-status/SKILL.md +10 -1
- package/sync-sources/skills/workspace-add-repo/SKILL.md +16 -1
- package/server/activity-logger-OEUBdfZ8.js +0 -3
- package/server/agent-state-Bc3tzUC8.js +0 -3
- package/server/agents-wi9NWzs2.js +0 -3
- package/server/archive-planning-BZDgzoEj.js +0 -3
- package/server/cli-B86rejVV.js +0 -3
- package/server/conversation-service-BLd3MYsG.js +0 -3
- package/server/deacon-kiQrb4ZT.js +0 -4
- package/server/deacon-swarm-C-GwfjJy.js +0 -2
- package/server/deploy-window-DkZraDyj.js +0 -3
- package/server/dist-Bzy0y69j.js +0 -3
- package/server/flywheel-merge-order-UU0tiUld.js +0 -245
- package/server/flywheel-merge-order-UUcsCDb6.js +0 -2
- package/server/forge-CNFnyqps.js +0 -270
- package/server/forge-DXnS_YFH.js +0 -2
- package/server/git-utils-D0_yhCgF.js +0 -3
- package/server/github-pr-lookup-D16NGsSO.js +0 -44
- package/server/hume-ccTf4wTX.js +0 -3
- package/server/inspect-agent-Brtz0URj.js +0 -2
- package/server/merge-ops-CR44oU9-.js +0 -2
- package/server/merge-set-bUqbm3yc.js +0 -3
- package/server/merge-sync-BJYeOODr.js +0 -3
- package/server/merge-verification-BkaOqPsw.js +0 -124
- package/server/project-repos-DXKQsc_m.js +0 -3
- package/server/projects-vjjcmiN8.js +0 -3
- package/server/public/assets/index-CWeMerGO.js +0 -804
- package/server/public/assets/index-CenuJ3Cw.css +0 -1
- package/server/public/assets/mermaid-GHXKKRXX-CpPWAFwE.js +0 -1
- package/server/rally-zhhtXuDP.js +0 -3
- package/server/record-CN0pj4_5.js +0 -3
- package/server/record-update-bLJxAXH4.js +0 -3
- package/server/resume-BFv1PGpA.js +0 -3
- package/server/review-status-btEYlaxA.js +0 -3
- package/server/review-status-kZj_KyCk.js +0 -1470
- package/server/settings-66A6uvIA.js +0 -2
- package/server/specs-C8Wsn2XO.js +0 -3
- package/server/src-DtcUOZCq.js +0 -4826
- package/server/supervisor-FTJAIsAK.js +0 -2
- package/server/token-util-DuPuNriz.js +0 -3
- package/server/tracker-utils-B4ylXZQK.js +0 -3
- package/server/uat-train-B05BWkp-.js +0 -2
- package/server/uat-train-DDSrSoV1.js +0 -2152
- package/server/workflows-BQu4RFQ-.js +0 -2
- package/server/workspace-manager-CWT55qeI.js +0 -3
|
@@ -1,46 +1,47 @@
|
|
|
1
1
|
import { a as __toCommonJS } from "./rolldown-runtime-DNCzzKnI.js";
|
|
2
|
-
import { A as canUseHarnessSync,
|
|
3
|
-
import {
|
|
4
|
-
import { d as getOverdeckDatabaseSync, f as init_infra } from "./infra-
|
|
5
|
-
import {
|
|
6
|
-
import { a as init_event_store, n as getEventStore } from "./event-store-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { a as EventStoreService, c as ReadModelService, d as init_read_model, i as init_issue_lifecycle, s as init_domain_services, t as IssueLifecycle
|
|
10
|
-
import { d as isTerminalIssueStage, o as init_agents, u as getIssueStageSync } from "./agents-
|
|
11
|
-
import { n as ensureSessionContextBriefingFile, r as init_briefing_freshness } from "./briefing-freshness-
|
|
12
|
-
import { o as getPricingSync, s as init_cost, t as calculateCostSync } from "./cost-
|
|
13
|
-
import {
|
|
14
|
-
import { a as performHandoff, i as checkAllTriggers, s as getAgentHealth, t as getCloisterService } from "./service-
|
|
15
|
-
import { o as init_persistent_logger, s as logAgentLifecycleSync } from "./session-history-
|
|
16
|
-
import { t as init_behavior } from "./behavior-
|
|
17
|
-
import { a as init_tracker_config, t as getGitHubConfig } from "./tracker-config-
|
|
18
|
-
import { n as init_issue_service_singleton, r as issue_service_singleton_exports } from "./issue-service-singleton-
|
|
19
|
-
import { o as getInternalTokenSync, s as init_internal_token } from "./internal-token-
|
|
2
|
+
import { A as canUseHarnessSync, Cn as resolveStateReadHomeSync, D as resolveTieredExecutionEnabled, Fr as init_errors, Gn as init_projects, H as init_providers, I as UnknownModelError, M as init_harness_policy, Mn as findProjectByPathSync, O as resolveTieredExecutionEnabledForIssue, Sn as init_state_read_home, T as init_tier_table, Tr as FsError, U as piProviderForModel, V as getProviderForModelSync, Yn as listProjectsSync, ar as resolveProjectFromIssueSync, c as isClaudeCodeChannelsEnabled, ci as init_paths, di as resolveOhmypiExtensionPath, ei as encodeClaudeProjectDir, f as loadConfigSync, gr as init_issue_id, h as jsYaml, hn as init_state_plane, hr as extractPrefixSync, m as init_js_yaml, si as getOverdeckHome, t as init_config_yaml, tt as resolveModel, ui as packageRoot, vn as parsePorcelainStatusPaths, vr as parseIssueIdSync, wn as shouldCommitLegacyWorkspaceArtifacts, zn as getProjectSync } from "./config-yaml-CmOPzmBb.js";
|
|
3
|
+
import { n as emitActivityEntryDurable, o as init_activity_logger, r as emitActivityEntrySync } from "./activity-logger-CyteR4JO.js";
|
|
4
|
+
import { d as getOverdeckDatabaseSync, f as init_infra } from "./infra-BjuxvjdS.js";
|
|
5
|
+
import { B as sendKeysAsync, D as killSession, H as sessionExists, M as listSessionNames, N as listSessions, Q as BLANKED_PROVIDER_ENV, T as isHarnessProcessAlive, U as sessionExistsSync, V as sendRawKeystroke, W as setOption, et as buildChildEnvWithoutTmuxSync, g as findManagedServerPidSync, i as capturePane, m as exactPaneTarget, o as capturePaneText, s as createSession, tt as init_child_env, w as init_tmux } from "./tmux-B1Wbxz5o.js";
|
|
6
|
+
import { a as init_event_store, n as getEventStore } from "./event-store-zY5MJHgF.js";
|
|
7
|
+
import { N as normalizeChannelReplyPayload, T as DomainEvent, n as COMPOSER_COMMAND_MANIFEST, s as getHarnessBehavior, t as init_src } from "./src-CRmCHlma.js";
|
|
8
|
+
import { K as stateToOverdeckParamsForDb, S as setReviewStatusSync, U as init_agent_state_sync, V as AGENT_COLUMNS_FOR_DB, f as init_review_status, m as loadReviewStatuses, o as clearWorkspaceStuck, u as getReviewStatusSync } from "./review-status-yljtTd-q.js";
|
|
9
|
+
import { a as EventStoreService, c as ReadModelService, d as getClosedIssueIdsForReadSource, f as init_read_model, i as init_issue_lifecycle, s as init_domain_services, t as IssueLifecycle } from "./issue-lifecycle-C4Zj0WmE.js";
|
|
10
|
+
import { d as isTerminalIssueStage, o as init_agents, u as getIssueStageSync } from "./agents-C5rWYhb6.js";
|
|
11
|
+
import { n as ensureSessionContextBriefingFile, r as init_briefing_freshness } from "./briefing-freshness-DHmCSLar.js";
|
|
12
|
+
import { o as getPricingSync, s as init_cost, t as calculateCostSync } from "./cost-Bgcub5kW.js";
|
|
13
|
+
import { $ as operatorInterventionEvent, $n as getAgentDir, An as getProviderExportsForModel, Bn as dismissDevChannelsDialog, Dr as init_pty_supervisor_locate, Er as writePtyToken, F as init_tier_escalation, Fr as getAgentRuntimeState, G as resumeAgent, Gt as assertWorkspaceStackHealthyForSpawn, H as restartAgent, Hr as checkCodexAuthStatus, Ht as BRIDGE_TOKEN_HEADER, Ir as getAgentRuntimeStateSync, Jt as init_spawn_prep, Mn as init_provider_health, Mt as deliverAgentMessage, Nn as validateProviderHealth, Nt as deliverAgentPermissionDecision, On as determineModel, Or as resolvePtySupervisorScriptPath, P as decideEscalation, Pr as waitForReadySignal, Q as init_operator_interventions, Qt as init_staffing, Rr as saveAgentRuntimeState, Rt as setAgentDeliveryMethod, Sr as writeAgentStateJsonSync, Tr as init_pty_token, Un as writeChannelsBridgeMcpConfig, Ur as init_codex_auth, Ut as init_bridge_token, V as recoverAgent, Wt as writeBridgeTokenSync, X as messageAgent, Xt as transitionIssueToInProgress, Yn as clearAgentTroubled, _r as saveAgentStateSync, b as init_agents$1, bn as init_ohmypi_fifo, cn as getAgentRuntimeBaseCommand, dn as getProviderAuthMode, gn as waitForAcpHostReady, gr as saveAgentState, i as listRunningAgents, it as getSessionId, jr as normalizeAgentId, kr as clearReadySignal, nn as resolveStaffing, nt as getLatestSessionId, ot as saveSessionId, pn as init_runtime_command, pt as stopAgent, qn as clearAgentPaused, r as listAgentStates, rr as getAgentStateSync, rt as getLatestSessionIdSync, sn as getAcpLauncherFields, tn as resolveIssueWorkModel, tr as getAgentState, tt as getActivity, ur as markAgentStoppedState, vn as init_pi_fifo, vr as setAgentPaused, xn as ohmypiFifoPaths, xr as wipeAgentStateDirs, yn as piFifoPaths } from "./queries-DHJm7bTd.js";
|
|
14
|
+
import { a as performHandoff, i as checkAllTriggers, s as getAgentHealth, t as getCloisterService } from "./service-Br9rpBNA.js";
|
|
15
|
+
import { o as init_persistent_logger, s as logAgentLifecycleSync } from "./session-history-BUyK29eq.js";
|
|
16
|
+
import { t as init_behavior } from "./behavior-CfIg6pKp.js";
|
|
17
|
+
import { a as init_tracker_config, t as getGitHubConfig } from "./tracker-config-DZ8Zn2nQ.js";
|
|
18
|
+
import { n as init_issue_service_singleton, r as issue_service_singleton_exports } from "./issue-service-singleton-DmCh7EHj.js";
|
|
19
|
+
import { o as getInternalTokenSync, s as init_internal_token } from "./internal-token-DvMTQSOS.js";
|
|
20
20
|
import { a as PAN_DIRNAME, i as PAN_CONTINUE_FILENAME, p as init_types } from "./types-hraoaQIp.js";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import { _ as
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
21
|
+
import { l as resolveWorkspaceRepoRootsSync, o as resolvePrimaryWorkspaceRepoDirSync, r as init_project_repos } from "./project-repos-C0nuoBGv.js";
|
|
22
|
+
import { a as generateXBriefFilename, o as init_lifecycle } from "./lifecycle-CTdOWYMi.js";
|
|
23
|
+
import { f as readTierOverrides, g as serializeXBriefDocument, h as recordTierPromotion, m as readWorkspacePlanSync, o as init_io, r as findPlan, u as readPlan } from "./io-VHvc0Ssp.js";
|
|
24
|
+
import { B as removeFavorite, E as hasOtherActiveConversationOnTmuxSession, F as markConversationEnded, G as setConversationHarness, K as setConversationModel, M as listConversations, P as markConversationActive, Q as updateConversationDeliveryMethod, S as getConversationByName, W as setConversationEffort, g as backfillConversationModel, h as archiveConversation, k as init_conversations, nt as updateLastAttached, rt as updateSpawnError, x as getConversationById, y as createConversation } from "./conversations-BUpYsOZg.js";
|
|
25
|
+
import { n as recordFeatureRegistryLifecycle, t as init_feature_registry_population } from "./feature-registry-population--YUXU999.js";
|
|
26
|
+
import { d as generateLauncherScriptSync, f as init_launcher_generator, g as requireModelOverrideSync, h as normalizeModelOverrideSync, m as init_model_validation, p as MODEL_ID_PATTERN } from "./tmux-dedup-DbN6MGzM.js";
|
|
27
|
+
import { a as init_claude_permissions, o as resolvePermissionModeSync, r as getClaudePermissionFlagsStringSync, t as BYPASS_PERMISSION_MODE } from "./claude-permissions-CN0cSCPp.js";
|
|
28
|
+
import { E as init_layers, I as workspaceContextFile, k as piGlobalContextFile } from "./assemble-DnffNpOo.js";
|
|
29
|
+
import { i as prepareHarnessLaunch, r as init_harness_binary } from "./harness-binary-DqkftwTb.js";
|
|
30
|
+
import { a as getWorkspaceStackHealth, s as init_stack_health } from "./stack-health-DqSqx0zv.js";
|
|
31
|
+
import { l as init_dag, o as getDispatchableItems } from "./dag-ombYYt4s.js";
|
|
32
|
+
import { n as resolveHarness, t as init_harness_resolve } from "./harness-resolve-CqMqM1Mb.js";
|
|
33
|
+
import { a as loadCloisterConfigSync, r as init_config } from "./config-B2IMcBxx.js";
|
|
34
|
+
import { c as isStateMigrated, o as init_state_home } from "./state-home-BYV7qZTW.js";
|
|
35
|
+
import { a as init_lifecycle_io, c as updatePlanStatus, s as transitionXBriefOnMain } from "./lifecycle-io-D-lGdzK3.js";
|
|
36
|
+
import { _ as init_codex_conversation_parser, b as parseAcpConversationMessages, c as parseEntireConversation, d as init_pi_conversation_parser, g as parseOhmypiConversationMessages, m as init_ohmypi_conversation_parser, p as parsePiConversationMessages, t as init_conversation_service, v as parseCodexConversationMessages, y as init_acp_conversation_parser } from "./conversation-service-5aCnq1zR.js";
|
|
37
|
+
import { _ as normalizeAwaitingInputPrompt, d as getAgentPendingQuestions$1, f as getAgentWorkspace$1, h as detectAwaitingInputForAgent, m as scanPendingInputsPromise, o as getRuntimeForAgent, p as isBlockedOnPendingInput, s as computeAgentEnrichment, u as getAgentJsonlPath$1, v as parseCodexApprovalPrompt } from "./stuck-remediation-mkLC6G_t.js";
|
|
38
|
+
import { B as getBook, H as liveOrderIssueLookup, T as resolveLiveFlywheelRunId, w as readFlywheelLaunchMetadata, y as getFlywheelRunDir, z as computeBookProgress } from "./flywheel-BiT3odRb.js";
|
|
39
|
+
import { Ft as getResourceConfig, Lt as getSystemHealthSnapshot, Ot as classifyMemoryPressure } from "./deacon-hi9KLPLT.js";
|
|
40
|
+
import { o as stopWorkspaceDocker, r as init_workspace_manager } from "./workspace-manager-CwO-Hek7.js";
|
|
41
|
+
import { a as init_jsonl_parser, o as normalizeModelName } from "./jsonl-parser-DJOH_O-w.js";
|
|
42
|
+
import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-Bq3epG58.js";
|
|
43
|
+
import { a as loadWorkspaceMetadataSync } from "./workspace-metadata-CQv00QwK.js";
|
|
44
|
+
import { basename, delimiter, dirname, isAbsolute, join, resolve } from "node:path";
|
|
44
45
|
import { Cause, Data, Effect, Layer, Option, Schema, Stream } from "effect";
|
|
45
46
|
import { join as join$1 } from "path";
|
|
46
47
|
import { homedir, networkInterfaces } from "node:os";
|
|
@@ -52,9 +53,9 @@ import { mkdir as mkdir$1, writeFile as writeFile$1 } from "fs/promises";
|
|
|
52
53
|
import { exec, execFile, spawn } from "node:child_process";
|
|
53
54
|
import { promisify } from "node:util";
|
|
54
55
|
import { createHash as createHash$1, createHmac, randomBytes, randomUUID as randomUUID$1, timingSafeEqual } from "node:crypto";
|
|
56
|
+
import { createInterface } from "node:readline";
|
|
55
57
|
import { pathToFileURL } from "node:url";
|
|
56
58
|
import { request } from "node:http";
|
|
57
|
-
import { createInterface } from "node:readline";
|
|
58
59
|
import * as Result$1 from "effect/Result";
|
|
59
60
|
//#region http-helpers.ts
|
|
60
61
|
init_paths();
|
|
@@ -86,6 +87,7 @@ init_projects();
|
|
|
86
87
|
init_providers();
|
|
87
88
|
init_harness_policy();
|
|
88
89
|
init_tier_table();
|
|
90
|
+
init_js_yaml();
|
|
89
91
|
init_config_yaml();
|
|
90
92
|
init_child_env();
|
|
91
93
|
init_tmux();
|
|
@@ -101,6 +103,7 @@ init_cost();
|
|
|
101
103
|
init_behavior();
|
|
102
104
|
init_persistent_logger();
|
|
103
105
|
init_tracker_config();
|
|
106
|
+
init_project_repos();
|
|
104
107
|
init_lifecycle();
|
|
105
108
|
init_review_status();
|
|
106
109
|
init_io();
|
|
@@ -218,6 +221,27 @@ function addTrustedOrigin(origins, raw) {
|
|
|
218
221
|
const normalized = normalizeOrigin(raw.trim());
|
|
219
222
|
if (normalized) origins.add(normalized);
|
|
220
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Last-resort origin config for launches that carry no origin env at all
|
|
226
|
+
* (manual `node dist/...`, ad-hoc re-exec). `pan up` builds its launch env from
|
|
227
|
+
* this same config.yaml, so reading it here keeps every launch path trusting the
|
|
228
|
+
* same Traefik domain instead of 403ing /ws/* into a "Reconnecting" loop.
|
|
229
|
+
*/
|
|
230
|
+
function readTraefikConfigFromYaml() {
|
|
231
|
+
try {
|
|
232
|
+
const configPath = join(process.env["OVERDECK_HOME"] || join(homedir(), ".overdeck"), "config.yaml");
|
|
233
|
+
if (!existsSync(configPath)) return null;
|
|
234
|
+
const traefik = jsYaml.load(readFileSync(configPath, "utf8"))?.traefik;
|
|
235
|
+
if (!traefik || typeof traefik !== "object") return null;
|
|
236
|
+
if (typeof traefik.domain !== "string" || traefik.domain.trim() === "") return null;
|
|
237
|
+
return {
|
|
238
|
+
enabled: traefik.enabled === true,
|
|
239
|
+
domain: traefik.domain.trim()
|
|
240
|
+
};
|
|
241
|
+
} catch {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
221
245
|
function getTrustedOrigins() {
|
|
222
246
|
if (cachedTrustedOrigins !== void 0) return cachedTrustedOrigins;
|
|
223
247
|
const port = parseInt(process.env["API_PORT"] ?? process.env["PORT"] ?? "3011", 10);
|
|
@@ -232,6 +256,10 @@ function getTrustedOrigins() {
|
|
|
232
256
|
for (const origin of trustedOrigins?.split(",") ?? []) addTrustedOrigin(origins, origin);
|
|
233
257
|
const traefikDomain = process.env["OVERDECK_TRAEFIK_DOMAIN"] ?? process.env["TRAEFIK_DOMAIN"];
|
|
234
258
|
if (process.env["OVERDECK_TRAEFIK_ENABLED"] === "1" && traefikDomain) addTrustedOrigin(origins, `https://${traefikDomain}`);
|
|
259
|
+
if (!(process.env["OVERDECK_TRAEFIK_ENABLED"] !== void 0 || traefikDomain !== void 0 || process.env["OVERDECK_TRUSTED_ORIGINS"] !== void 0)) {
|
|
260
|
+
const fromYaml = readTraefikConfigFromYaml();
|
|
261
|
+
if (fromYaml?.enabled) addTrustedOrigin(origins, `https://${fromYaml.domain}`);
|
|
262
|
+
}
|
|
235
263
|
if (process.env["NODE_ENV"] === "development") {
|
|
236
264
|
addTrustedOrigin(origins, "http://localhost:3000");
|
|
237
265
|
addTrustedOrigin(origins, "http://127.0.0.1:3000");
|
|
@@ -799,7 +827,7 @@ async function resolveCodexRolloutPath(agentId, opts = {}) {
|
|
|
799
827
|
const agentDir = join(opts.agentsDirOverride ?? join(getOverdeckHome(), "agents"), agentId);
|
|
800
828
|
const codexHome = join(agentDir, "codex-home");
|
|
801
829
|
if (!await pathExists$1(codexHome)) return null;
|
|
802
|
-
const { findRolloutPath, findLatestRollout } = await import("./codex-
|
|
830
|
+
const { findRolloutPath, findLatestRollout } = await import("./codex-BdEsUFWh.js");
|
|
803
831
|
const threadId = (await readOptional(join(agentDir, "codex-thread-id")))?.trim();
|
|
804
832
|
if (threadId) {
|
|
805
833
|
const rollout = findRolloutPath(codexHome, threadId);
|
|
@@ -1185,42 +1213,130 @@ async function resolveAgentGitInfo(workspacePath, expectedBranch) {
|
|
|
1185
1213
|
};
|
|
1186
1214
|
}
|
|
1187
1215
|
//#endregion
|
|
1188
|
-
//#region
|
|
1216
|
+
//#region ../../lib/composer-commands/executors.ts
|
|
1217
|
+
const CAPTURED_COMMAND_MAX_OUTPUT_BYTES = 64 * 1024;
|
|
1218
|
+
const TRUNCATION_MESSAGE = "\n\nOutput was truncated after 65,536 bytes.";
|
|
1219
|
+
function runCapturedCommand(argv, dependencies = {}) {
|
|
1220
|
+
const command = `/pan ${argv.join(" ")}`;
|
|
1221
|
+
const spawnCommand = dependencies.spawnPanCli ?? spawnPanCli;
|
|
1222
|
+
const timeoutMs = dependencies.timeoutMs ?? 3e4;
|
|
1223
|
+
const child = spawnCommand(argv, { stdio: [
|
|
1224
|
+
"ignore",
|
|
1225
|
+
"pipe",
|
|
1226
|
+
"pipe"
|
|
1227
|
+
] });
|
|
1228
|
+
return new Promise((resolve) => {
|
|
1229
|
+
const chunks = [];
|
|
1230
|
+
let bufferedBytes = 0;
|
|
1231
|
+
let settled = false;
|
|
1232
|
+
let timeout;
|
|
1233
|
+
let truncated = false;
|
|
1234
|
+
const appendOutput = (data) => {
|
|
1235
|
+
if (truncated) return;
|
|
1236
|
+
const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
1237
|
+
const remaining = CAPTURED_COMMAND_MAX_OUTPUT_BYTES - Buffer.byteLength(TRUNCATION_MESSAGE) - bufferedBytes;
|
|
1238
|
+
if (buffer.length <= remaining) {
|
|
1239
|
+
chunks.push(buffer);
|
|
1240
|
+
bufferedBytes += buffer.length;
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1243
|
+
if (remaining > 0) {
|
|
1244
|
+
chunks.push(buffer.subarray(0, remaining));
|
|
1245
|
+
bufferedBytes += remaining;
|
|
1246
|
+
}
|
|
1247
|
+
truncated = true;
|
|
1248
|
+
};
|
|
1249
|
+
const output = () => {
|
|
1250
|
+
const captured = Buffer.concat(chunks, bufferedBytes).toString("utf8");
|
|
1251
|
+
return truncated ? `${captured}${TRUNCATION_MESSAGE}` : captured;
|
|
1252
|
+
};
|
|
1253
|
+
const finish = (result) => {
|
|
1254
|
+
if (settled) return;
|
|
1255
|
+
settled = true;
|
|
1256
|
+
if (timeout !== void 0) clearTimeout(timeout);
|
|
1257
|
+
resolve(result);
|
|
1258
|
+
};
|
|
1259
|
+
child.stdout?.on("data", appendOutput);
|
|
1260
|
+
child.stderr?.on("data", appendOutput);
|
|
1261
|
+
child.once("error", (error) => {
|
|
1262
|
+
finish({
|
|
1263
|
+
kind: "captured",
|
|
1264
|
+
status: "failed",
|
|
1265
|
+
command,
|
|
1266
|
+
output: `Command ${command} could not start: ${error.message}`,
|
|
1267
|
+
truncated: false
|
|
1268
|
+
});
|
|
1269
|
+
});
|
|
1270
|
+
child.once("close", (code) => {
|
|
1271
|
+
const captured = output();
|
|
1272
|
+
finish({
|
|
1273
|
+
kind: "captured",
|
|
1274
|
+
status: code === 0 ? "completed" : "failed",
|
|
1275
|
+
command,
|
|
1276
|
+
output: captured || `Command ${command} ${code === 0 ? "completed without output." : `failed with exit code ${code ?? "unknown"}.`}`,
|
|
1277
|
+
truncated
|
|
1278
|
+
});
|
|
1279
|
+
});
|
|
1280
|
+
timeout = setTimeout(() => {
|
|
1281
|
+
stopChild(child);
|
|
1282
|
+
finish({
|
|
1283
|
+
kind: "captured",
|
|
1284
|
+
status: "failed",
|
|
1285
|
+
command,
|
|
1286
|
+
output: `Command ${command} timed out after ${Math.round(timeoutMs / 1e3)} seconds and was stopped.`,
|
|
1287
|
+
truncated: false
|
|
1288
|
+
});
|
|
1289
|
+
}, timeoutMs);
|
|
1290
|
+
});
|
|
1291
|
+
}
|
|
1292
|
+
function stopChild(child) {
|
|
1293
|
+
child.kill("SIGTERM");
|
|
1294
|
+
}
|
|
1295
|
+
//#endregion
|
|
1296
|
+
//#region ../../lib/composer-commands/detached.ts
|
|
1189
1297
|
init_paths();
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1298
|
+
const DETACHED_TRUNCATION_MESSAGE = "\n\nOutput was truncated after 65,536 bytes.";
|
|
1299
|
+
function resolveAgentDirectory(overdeckHome, agentId) {
|
|
1300
|
+
if (agentId.length === 0 || agentId === "." || agentId === ".." || agentId.includes("/") || agentId.includes("\\") || isAbsolute(agentId)) throw new Error("Agent ID must be a single filesystem-safe path segment.");
|
|
1301
|
+
return join(resolve(overdeckHome, "agents"), agentId);
|
|
1302
|
+
}
|
|
1303
|
+
async function readBoundedSpawnOutput(spawnLogPath, startOffset) {
|
|
1304
|
+
const maximumPrefixBytes = CAPTURED_COMMAND_MAX_OUTPUT_BYTES - Buffer.byteLength(DETACHED_TRUNCATION_MESSAGE);
|
|
1305
|
+
const handle = await open(spawnLogPath, "r");
|
|
1306
|
+
try {
|
|
1307
|
+
const stats = await handle.stat();
|
|
1308
|
+
const outputBytes = Math.max(0, stats.size - startOffset);
|
|
1309
|
+
if (outputBytes === 0) return "";
|
|
1310
|
+
const bytesToRead = Math.min(outputBytes, maximumPrefixBytes);
|
|
1311
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
1312
|
+
const { bytesRead } = await handle.read(buffer, 0, bytesToRead, startOffset);
|
|
1313
|
+
const output = buffer.subarray(0, bytesRead).toString("utf8");
|
|
1314
|
+
return outputBytes > maximumPrefixBytes ? `${output}${DETACHED_TRUNCATION_MESSAGE}` : output;
|
|
1315
|
+
} finally {
|
|
1316
|
+
await handle.close().catch(() => void 0);
|
|
1317
|
+
}
|
|
1205
1318
|
}
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1319
|
+
async function appendAgentLifecycleLog(agentId, event, details = {}, overdeckHome = getOverdeckHome()) {
|
|
1320
|
+
const agentDir = resolveAgentDirectory(overdeckHome, agentId);
|
|
1321
|
+
await mkdir(agentDir, { recursive: true });
|
|
1322
|
+
const logLine = JSON.stringify({
|
|
1323
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1324
|
+
event,
|
|
1325
|
+
...details
|
|
1326
|
+
});
|
|
1327
|
+
await appendFile(join(agentDir, "lifecycle.log"), `${logLine}\n`);
|
|
1328
|
+
}
|
|
1329
|
+
async function launchPanCommandDetached(input, dependencies = {}) {
|
|
1215
1330
|
const { agentSessionName, issueId, role, workspacePath, args } = input;
|
|
1216
1331
|
const cwd = input.cwd ?? workspacePath;
|
|
1217
|
-
const
|
|
1218
|
-
const
|
|
1332
|
+
const overdeckHome = dependencies.overdeckHome ?? getOverdeckHome();
|
|
1333
|
+
const activityId = input.activityId ?? `activity-${(dependencies.now ?? Date.now)()}`;
|
|
1334
|
+
const agentDir = resolveAgentDirectory(overdeckHome, agentSessionName);
|
|
1219
1335
|
await mkdir(agentDir, { recursive: true });
|
|
1220
1336
|
const spawnLogPath = join(agentDir, "spawn.log");
|
|
1221
1337
|
const spawnLogHandle = await open(spawnLogPath, "a");
|
|
1222
|
-
const
|
|
1223
|
-
const child =
|
|
1338
|
+
const spawnLogStart = (await spawnLogHandle.stat()).size;
|
|
1339
|
+
const child = (dependencies.spawnPanCli ?? spawnPanCli)(args, {
|
|
1224
1340
|
cwd,
|
|
1225
1341
|
detached: true,
|
|
1226
1342
|
stdio: [
|
|
@@ -1229,67 +1345,200 @@ async function spawnPanCommandDetached(input) {
|
|
|
1229
1345
|
spawnLogHandle.fd
|
|
1230
1346
|
]
|
|
1231
1347
|
});
|
|
1348
|
+
let spawned = false;
|
|
1349
|
+
let settleSpawn;
|
|
1350
|
+
let rejectSpawn;
|
|
1351
|
+
const spawnPromise = new Promise((resolve, reject) => {
|
|
1352
|
+
settleSpawn = resolve;
|
|
1353
|
+
rejectSpawn = reject;
|
|
1354
|
+
});
|
|
1355
|
+
const completion = commandCompletion(child, {
|
|
1356
|
+
agentSessionName,
|
|
1357
|
+
issueId,
|
|
1358
|
+
role,
|
|
1359
|
+
workspacePath,
|
|
1360
|
+
activityId,
|
|
1361
|
+
args,
|
|
1362
|
+
cwd,
|
|
1363
|
+
spawnLogPath,
|
|
1364
|
+
spawnLogStart,
|
|
1365
|
+
spawnLogHandle,
|
|
1366
|
+
overdeckHome,
|
|
1367
|
+
onSpawn: () => {
|
|
1368
|
+
spawned = true;
|
|
1369
|
+
settleSpawn?.();
|
|
1370
|
+
},
|
|
1371
|
+
onError: (error) => {
|
|
1372
|
+
if (!spawned) rejectSpawn?.(error);
|
|
1373
|
+
}
|
|
1374
|
+
});
|
|
1375
|
+
completion.catch(() => void 0);
|
|
1376
|
+
await spawnPromise;
|
|
1377
|
+
child.unref();
|
|
1378
|
+
return {
|
|
1379
|
+
activityId,
|
|
1380
|
+
spawnLogPath,
|
|
1381
|
+
spawnLogStart,
|
|
1382
|
+
completion
|
|
1383
|
+
};
|
|
1384
|
+
}
|
|
1385
|
+
function commandCompletion(child, context) {
|
|
1232
1386
|
child.once("spawn", () => {
|
|
1233
|
-
appendAgentLifecycleLog(agentSessionName, "agent.work_spawn_process_spawned", {
|
|
1234
|
-
issueId,
|
|
1235
|
-
role,
|
|
1236
|
-
workspacePath,
|
|
1237
|
-
activityId,
|
|
1387
|
+
appendAgentLifecycleLog(context.agentSessionName, "agent.work_spawn_process_spawned", {
|
|
1388
|
+
issueId: context.issueId,
|
|
1389
|
+
role: context.role,
|
|
1390
|
+
workspacePath: context.workspacePath,
|
|
1391
|
+
activityId: context.activityId,
|
|
1238
1392
|
pid: child.pid,
|
|
1239
|
-
args,
|
|
1240
|
-
cwd,
|
|
1241
|
-
spawnLogPath
|
|
1242
|
-
}).catch(() => void 0);
|
|
1393
|
+
args: context.args,
|
|
1394
|
+
cwd: context.cwd,
|
|
1395
|
+
spawnLogPath: context.spawnLogPath
|
|
1396
|
+
}, context.overdeckHome).catch(() => void 0).finally(context.onSpawn);
|
|
1243
1397
|
});
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1398
|
+
return new Promise((resolve, reject) => {
|
|
1399
|
+
let settled = false;
|
|
1400
|
+
const finish = async (error) => {
|
|
1401
|
+
if (settled) return;
|
|
1402
|
+
settled = true;
|
|
1403
|
+
await context.spawnLogHandle.close().catch(() => void 0);
|
|
1404
|
+
if (error) reject(error);
|
|
1405
|
+
else resolve();
|
|
1406
|
+
};
|
|
1407
|
+
child.once("error", (error) => {
|
|
1408
|
+
(async () => {
|
|
1409
|
+
await appendAgentLifecycleLog(context.agentSessionName, "agent.work_spawn_process_error", {
|
|
1410
|
+
issueId: context.issueId,
|
|
1411
|
+
role: context.role,
|
|
1412
|
+
workspacePath: context.workspacePath,
|
|
1413
|
+
activityId: context.activityId,
|
|
1252
1414
|
error: error.message,
|
|
1253
|
-
args,
|
|
1254
|
-
cwd,
|
|
1255
|
-
spawnLogPath
|
|
1256
|
-
}).catch(() => void 0);
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1415
|
+
args: context.args,
|
|
1416
|
+
cwd: context.cwd,
|
|
1417
|
+
spawnLogPath: context.spawnLogPath
|
|
1418
|
+
}, context.overdeckHome).catch(() => void 0);
|
|
1419
|
+
context.onError(error);
|
|
1420
|
+
await finish(error);
|
|
1421
|
+
})();
|
|
1422
|
+
});
|
|
1423
|
+
child.once("close", (code, signal) => {
|
|
1424
|
+
(async () => {
|
|
1425
|
+
await appendAgentLifecycleLog(context.agentSessionName, "agent.work_spawn_process_closed", {
|
|
1426
|
+
issueId: context.issueId,
|
|
1427
|
+
role: context.role,
|
|
1428
|
+
workspacePath: context.workspacePath,
|
|
1429
|
+
activityId: context.activityId,
|
|
1265
1430
|
code,
|
|
1266
1431
|
signal,
|
|
1267
|
-
args,
|
|
1268
|
-
cwd,
|
|
1269
|
-
spawnLogPath
|
|
1270
|
-
}).catch(() => void 0);
|
|
1271
|
-
|
|
1432
|
+
args: context.args,
|
|
1433
|
+
cwd: context.cwd,
|
|
1434
|
+
spawnLogPath: context.spawnLogPath
|
|
1435
|
+
}, context.overdeckHome).catch(() => void 0);
|
|
1436
|
+
if (code === 0) {
|
|
1437
|
+
await finish();
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1440
|
+
const output = await readBoundedSpawnOutput(context.spawnLogPath, context.spawnLogStart).catch(() => "");
|
|
1441
|
+
const error = new Error(output.trim() || `pan ${context.args.join(" ")} exited with code ${code ?? "null"}`);
|
|
1442
|
+
Object.assign(error, {
|
|
1443
|
+
activityId: context.activityId,
|
|
1444
|
+
spawnLogPath: context.spawnLogPath,
|
|
1272
1445
|
code,
|
|
1273
|
-
signal
|
|
1446
|
+
signal,
|
|
1447
|
+
output
|
|
1274
1448
|
});
|
|
1275
|
-
|
|
1449
|
+
await finish(error);
|
|
1450
|
+
})();
|
|
1276
1451
|
});
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
async function runDetachedCommand(argv, dependencies = {}) {
|
|
1455
|
+
const issueId = argv[1] ?? "";
|
|
1456
|
+
const parsedIssueId = parseIssueIdSync(issueId);
|
|
1457
|
+
if (!parsedIssueId) return {
|
|
1458
|
+
kind: "terminal-only",
|
|
1459
|
+
status: "rejected",
|
|
1460
|
+
message: `/pan ${argv[0] ?? "command"} requires a canonical issue ID such as PAN-1525.`
|
|
1461
|
+
};
|
|
1462
|
+
const role = argv[0] === "plan" ? "plan" : "work";
|
|
1463
|
+
const agentSessionName = `${role === "plan" ? "planning" : "agent"}-${parsedIssueId.normalized}`;
|
|
1464
|
+
const command = `/pan ${argv.join(" ")}`;
|
|
1465
|
+
const activityId = `activity-${(dependencies.now ?? Date.now)()}`;
|
|
1466
|
+
const emitActivity = dependencies.emitActivity ?? emitActivityEntryDurable;
|
|
1467
|
+
const source = role === "plan" ? "planning-agent" : "work-agent";
|
|
1468
|
+
const emitTransition = (status, level, message, output) => emitActivity({
|
|
1469
|
+
id: activityId,
|
|
1470
|
+
source,
|
|
1471
|
+
level,
|
|
1472
|
+
status,
|
|
1473
|
+
command,
|
|
1474
|
+
message,
|
|
1475
|
+
details: output,
|
|
1476
|
+
output,
|
|
1477
|
+
issueId
|
|
1478
|
+
});
|
|
1479
|
+
await emitTransition("accepted", "info", `Accepted ${command} for ${issueId} as activity ${activityId}.`);
|
|
1480
|
+
let launch;
|
|
1481
|
+
try {
|
|
1482
|
+
launch = await launchPanCommandDetached({
|
|
1483
|
+
agentSessionName,
|
|
1484
|
+
issueId,
|
|
1485
|
+
role,
|
|
1486
|
+
workspacePath: process.cwd(),
|
|
1487
|
+
args: argv,
|
|
1488
|
+
activityId
|
|
1489
|
+
}, dependencies);
|
|
1490
|
+
} catch (error) {
|
|
1491
|
+
const output = error instanceof Error ? error.message : String(error);
|
|
1492
|
+
await emitTransition("failed", "error", `Activity ${activityId} failed to start ${command} for ${issueId}.`, output).catch(() => void 0);
|
|
1493
|
+
throw error;
|
|
1292
1494
|
}
|
|
1495
|
+
await emitTransition("running", "info", `Activity ${activityId} is running ${command} for ${issueId}.`).catch(() => void 0);
|
|
1496
|
+
launch.completion.then(async () => {
|
|
1497
|
+
const output = await readBoundedSpawnOutput(launch.spawnLogPath, launch.spawnLogStart).catch(() => "");
|
|
1498
|
+
await emitTransition("completed", "success", `Activity ${activityId} completed ${command} for ${issueId}.`, output || `Command ${command} completed without output.`);
|
|
1499
|
+
}, async (error) => {
|
|
1500
|
+
const activityError = error;
|
|
1501
|
+
const output = activityError.output?.trim() || activityError.message;
|
|
1502
|
+
await emitTransition("failed", "error", `Activity ${activityId} failed ${command} for ${issueId}.`, output);
|
|
1503
|
+
}).catch(() => void 0);
|
|
1504
|
+
return {
|
|
1505
|
+
kind: "activity",
|
|
1506
|
+
status: "accepted",
|
|
1507
|
+
command,
|
|
1508
|
+
activityId: launch.activityId,
|
|
1509
|
+
message: `Started ${command} for ${issueId}. Watch activity ${launch.activityId} or the ${issueId} issue view for progress.`
|
|
1510
|
+
};
|
|
1511
|
+
}
|
|
1512
|
+
//#endregion
|
|
1513
|
+
//#region routes/agents/shared.ts
|
|
1514
|
+
init_paths();
|
|
1515
|
+
init_agents$1();
|
|
1516
|
+
init_activity_logger();
|
|
1517
|
+
init_tmux();
|
|
1518
|
+
const execAsync$2 = promisify(exec);
|
|
1519
|
+
const execFileAsync$2 = promisify(execFile);
|
|
1520
|
+
function buildPanStartArgs(input) {
|
|
1521
|
+
return [
|
|
1522
|
+
"start",
|
|
1523
|
+
input.issueId,
|
|
1524
|
+
"--local",
|
|
1525
|
+
"--model",
|
|
1526
|
+
input.model,
|
|
1527
|
+
...input.harness ? ["--harness", input.harness] : [],
|
|
1528
|
+
...input.allowHost ? ["--host", "--yes"] : [],
|
|
1529
|
+
...input.offBook ? ["--off-book"] : []
|
|
1530
|
+
];
|
|
1531
|
+
}
|
|
1532
|
+
/**
|
|
1533
|
+
* PAN-1985: detached-spawn helper for `pan <args>`, shared between the
|
|
1534
|
+
* standard work-spawn route and the restart-fresh route. The neutral launcher
|
|
1535
|
+
* owns process/log lifecycle; this route-compatible wrapper preserves the
|
|
1536
|
+
* original behavior by waiting for a successful child exit.
|
|
1537
|
+
*/
|
|
1538
|
+
async function spawnPanCommandDetached(input, dependencies = {}) {
|
|
1539
|
+
const launch = await launchPanCommandDetached(input, dependencies);
|
|
1540
|
+
await launch.completion;
|
|
1541
|
+
return launch.activityId;
|
|
1293
1542
|
}
|
|
1294
1543
|
function emitStartAgentPhase(issueId, phase, status, reason, details = {}) {
|
|
1295
1544
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1344,16 +1593,6 @@ async function validateAgentRuntimeEventAuth(request) {
|
|
|
1344
1593
|
}, { status: 403 })
|
|
1345
1594
|
};
|
|
1346
1595
|
}
|
|
1347
|
-
async function appendAgentLifecycleLog(agentId, event, details = {}) {
|
|
1348
|
-
const agentDir = join(homedir(), ".overdeck", "agents", agentId);
|
|
1349
|
-
await mkdir(agentDir, { recursive: true });
|
|
1350
|
-
const logLine = JSON.stringify({
|
|
1351
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1352
|
-
event,
|
|
1353
|
-
...details
|
|
1354
|
-
});
|
|
1355
|
-
await appendFile(join(agentDir, "lifecycle.log"), logLine + "\n");
|
|
1356
|
-
}
|
|
1357
1596
|
function updateRegistryForAgentStart(issueId, workspacePath, agentId) {
|
|
1358
1597
|
recordFeatureRegistryLifecycle({
|
|
1359
1598
|
issueId,
|
|
@@ -1537,13 +1776,14 @@ async function getWorkspaceLocation(issueId) {
|
|
|
1537
1776
|
}
|
|
1538
1777
|
} catch {}
|
|
1539
1778
|
}
|
|
1540
|
-
async function getGitStatusAsync(workspacePath) {
|
|
1779
|
+
async function getGitStatusAsync(issueId, workspacePath) {
|
|
1541
1780
|
try {
|
|
1542
1781
|
if (!existsSync(workspacePath)) return null;
|
|
1782
|
+
const repoDir = resolvePrimaryWorkspaceRepoDirSync(issueId, workspacePath);
|
|
1543
1783
|
const [branchResult, uncommittedResult, commitResult] = await Promise.all([
|
|
1544
|
-
execAsync$2("git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"\"", { cwd:
|
|
1545
|
-
execAsync$2("git status --porcelain 2>/dev/null | wc -l", { cwd:
|
|
1546
|
-
execAsync$2("git log -1 --pretty=format:\"%s\" 2>/dev/null || echo \"\"", { cwd:
|
|
1784
|
+
execAsync$2("git rev-parse --abbrev-ref HEAD 2>/dev/null || echo \"\"", { cwd: repoDir }),
|
|
1785
|
+
execAsync$2("git status --porcelain 2>/dev/null | wc -l", { cwd: repoDir }),
|
|
1786
|
+
execAsync$2("git log -1 --pretty=format:\"%s\" 2>/dev/null || echo \"\"", { cwd: repoDir })
|
|
1547
1787
|
]);
|
|
1548
1788
|
const branch = branchResult.stdout.trim();
|
|
1549
1789
|
const uncommitted = uncommittedResult.stdout.trim();
|
|
@@ -1700,6 +1940,22 @@ const getAgentPendingQuestions = getAgentPendingQuestions$1;
|
|
|
1700
1940
|
//#region routes/agents/listing.ts
|
|
1701
1941
|
init_agents$1();
|
|
1702
1942
|
init_tmux();
|
|
1943
|
+
/**
|
|
1944
|
+
* PAN-3070 — the health status a live agent row reports.
|
|
1945
|
+
*
|
|
1946
|
+
* A live tmux session used to mean `healthy` unconditionally, so an agent frozen
|
|
1947
|
+
* for hours on an unanswered tool-permission prompt was reported
|
|
1948
|
+
* `status: healthy` / `resolution: working` while the Decisions surface
|
|
1949
|
+
* simultaneously showed it as needing the operator. Two surfaces answering "is
|
|
1950
|
+
* this agent stuck?" from different evidence, and this one stale.
|
|
1951
|
+
*
|
|
1952
|
+
* `warning` is the value `src/lib/health.ts` already reports for an agent
|
|
1953
|
+
* waiting on a human, and it stays inside the fleet-view status set, so a
|
|
1954
|
+
* blocked agent is flagged without disappearing from any existing list.
|
|
1955
|
+
*/
|
|
1956
|
+
function liveAgentHealthStatus(enrichment) {
|
|
1957
|
+
return isBlockedOnPendingInput(enrichment) ? "warning" : "healthy";
|
|
1958
|
+
}
|
|
1703
1959
|
const getAgentsRoute = HttpRouter.add("GET", "/api/agents", httpHandler(Effect.gen(function* () {
|
|
1704
1960
|
const now = Date.now();
|
|
1705
1961
|
if (agentsCache.data && now - agentsCache.timestamp < 5e3) return jsonResponse(agentsCache.data);
|
|
@@ -1833,7 +2089,7 @@ const getAgentsRoute = HttpRouter.add("GET", "/api/agents", httpHandler(Effect.g
|
|
|
1833
2089
|
const enrichment = await Effect.runPromise(computeAgentEnrichment(name, startedAt, hasActiveSpecialist));
|
|
1834
2090
|
const workspaceLocation = isRemote ? "remote" : await getWorkspaceLocation(issueId);
|
|
1835
2091
|
const workspace = isRemote && remoteState.vmName ? `/workspace (${String(remoteState.vmName)})` : state.workspace || null;
|
|
1836
|
-
const gitStatus = workspace && !isRemote ? await getGitStatusAsync(workspace) : null;
|
|
2092
|
+
const gitStatus = workspace && !isRemote ? await getGitStatusAsync(issueId, workspace) : null;
|
|
1837
2093
|
let contextPercent = null;
|
|
1838
2094
|
let initialContextPercent = null;
|
|
1839
2095
|
const agentCtxDir = join(homedir(), ".overdeck", "agents", name);
|
|
@@ -1843,12 +2099,13 @@ const getAgentsRoute = HttpRouter.add("GET", "/api/agents", httpHandler(Effect.g
|
|
|
1843
2099
|
const initCtxFile = join(agentCtxDir, "initial-context-pct");
|
|
1844
2100
|
initialContextPercent = parseInt((await readFile(initCtxFile, "utf-8").catch(() => "")).trim(), 10) || null;
|
|
1845
2101
|
} catch {}
|
|
2102
|
+
const blockedOnPendingInput = isBlockedOnPendingInput(enrichment);
|
|
1846
2103
|
return {
|
|
1847
2104
|
id: name,
|
|
1848
2105
|
issueId,
|
|
1849
2106
|
runtime: state.harness ?? "claude-code",
|
|
1850
2107
|
model: state.model || (isPlanning ? "opus" : "sonnet"),
|
|
1851
|
-
status:
|
|
2108
|
+
status: liveAgentHealthStatus(enrichment),
|
|
1852
2109
|
startedAt,
|
|
1853
2110
|
...buildAgentGateFailureSnapshot(state),
|
|
1854
2111
|
killCount: health.killCount || 0,
|
|
@@ -1865,7 +2122,7 @@ const getAgentsRoute = HttpRouter.add("GET", "/api/agents", httpHandler(Effect.g
|
|
|
1865
2122
|
pendingInputCount: enrichment.pendingInputCount,
|
|
1866
2123
|
pendingInputKinds: enrichment.pendingInputKinds,
|
|
1867
2124
|
pendingAskUserQuestion: enrichment.pendingAskUserQuestion,
|
|
1868
|
-
resolution: runtimeData?.resolution || enrichment.resolution || "working",
|
|
2125
|
+
resolution: blockedOnPendingInput ? "needs_input" : runtimeData?.resolution || enrichment.resolution || "working",
|
|
1869
2126
|
resolutionCount: runtimeData?.resolutionCount || enrichment.resolutionCount || 0,
|
|
1870
2127
|
contextPercent,
|
|
1871
2128
|
initialContextPercent,
|
|
@@ -1951,7 +2208,7 @@ const getAgentOutputRoute = HttpRouter.add("GET", "/api/agents/:id/output", http
|
|
|
1951
2208
|
} catch {}
|
|
1952
2209
|
let stdout;
|
|
1953
2210
|
if (isRemote && vmName) {
|
|
1954
|
-
const { getRemoteAgentOutput } = await import("./remote-agents-
|
|
2211
|
+
const { getRemoteAgentOutput } = await import("./remote-agents-C1bssi41.js");
|
|
1955
2212
|
stdout = await getRemoteAgentOutput(id, vmName, parseInt(String(lines), 10) || 100);
|
|
1956
2213
|
} else stdout = await Effect.runPromise(capturePane(id, parseInt(String(lines), 10) || 100));
|
|
1957
2214
|
if (!stdout || stdout.trim() === "" || stdout.trim() === "Session not found") {
|
|
@@ -2104,6 +2361,352 @@ const getAgentTimelineRoute = HttpRouter.add("GET", "/api/agents/:id/timeline",
|
|
|
2104
2361
|
return jsonResponse({ timeline: events.slice(0, limit) });
|
|
2105
2362
|
})));
|
|
2106
2363
|
//#endregion
|
|
2364
|
+
//#region ../../lib/composer-commands/confirmations.ts
|
|
2365
|
+
const COMPOSER_CONFIRMATION_TTL_MS = 300 * 1e3;
|
|
2366
|
+
function composerCommandConfirmationFromBody(body) {
|
|
2367
|
+
if (!("confirmationNonce" in body) && !("confirmationText" in body)) return void 0;
|
|
2368
|
+
return {
|
|
2369
|
+
nonce: body["confirmationNonce"],
|
|
2370
|
+
typedText: body["confirmationText"]
|
|
2371
|
+
};
|
|
2372
|
+
}
|
|
2373
|
+
var ComposerCommandConfirmationError = class extends Error {
|
|
2374
|
+
code = "invalid-confirmation";
|
|
2375
|
+
constructor(message) {
|
|
2376
|
+
super(message);
|
|
2377
|
+
this.name = "ComposerCommandConfirmationError";
|
|
2378
|
+
}
|
|
2379
|
+
};
|
|
2380
|
+
function createComposerConfirmationStore(dependencies = {}) {
|
|
2381
|
+
const entries = /* @__PURE__ */ new Map();
|
|
2382
|
+
const now = dependencies.now ?? Date.now;
|
|
2383
|
+
const createNonce = dependencies.createNonce ?? (() => randomBytes(24).toString("base64url"));
|
|
2384
|
+
function pruneExpired() {
|
|
2385
|
+
const currentTime = now();
|
|
2386
|
+
for (const [nonce, entry] of entries) if (entry.expiresAt <= currentTime) entries.delete(nonce);
|
|
2387
|
+
}
|
|
2388
|
+
return {
|
|
2389
|
+
issue({ target, argv, policy, display }) {
|
|
2390
|
+
if (policy.safety === "destructive" && !policy.typedConfirmation) throw new Error(`Destructive composer policy for ${display} must define typedConfirmation.`);
|
|
2391
|
+
pruneExpired();
|
|
2392
|
+
const nonce = createNonce();
|
|
2393
|
+
entries.set(nonce, {
|
|
2394
|
+
targetKind: target.kind,
|
|
2395
|
+
targetId: target.id,
|
|
2396
|
+
argv: [...argv],
|
|
2397
|
+
safety: policy.safety,
|
|
2398
|
+
typedText: policy.typedConfirmation,
|
|
2399
|
+
expiresAt: now() + COMPOSER_CONFIRMATION_TTL_MS
|
|
2400
|
+
});
|
|
2401
|
+
return {
|
|
2402
|
+
kind: "confirmation",
|
|
2403
|
+
status: "confirmation_required",
|
|
2404
|
+
nonce,
|
|
2405
|
+
consequence: policy.confirmationText ?? `Running ${display} requires confirmation before Overdeck continues.`,
|
|
2406
|
+
...policy.typedConfirmation ? { typedText: policy.typedConfirmation } : {}
|
|
2407
|
+
};
|
|
2408
|
+
},
|
|
2409
|
+
consume({ target, argv, policy, confirmation }) {
|
|
2410
|
+
if (typeof confirmation.nonce !== "string") throw new ComposerCommandConfirmationError("A valid confirmation nonce is required before this command can run.");
|
|
2411
|
+
const entry = entries.get(confirmation.nonce);
|
|
2412
|
+
entries.delete(confirmation.nonce);
|
|
2413
|
+
if (!entry) throw new ComposerCommandConfirmationError("This command confirmation is missing, invalid, or has already been used. Request a new confirmation and try again.");
|
|
2414
|
+
if (entry.expiresAt <= now()) throw new ComposerCommandConfirmationError("This command confirmation has expired. Request a new confirmation and try again.");
|
|
2415
|
+
if (entry.targetKind !== target.kind || entry.targetId !== target.id || entry.safety !== policy.safety || !sameArgv(entry.argv, argv)) throw new ComposerCommandConfirmationError("This command confirmation does not match the current target or command. Request a new confirmation and try again.");
|
|
2416
|
+
if (policy.safety === "destructive" && (typeof confirmation.typedText !== "string" || confirmation.typedText !== entry.typedText)) throw new ComposerCommandConfirmationError(`Type "${entry.typedText ?? ""}" exactly to confirm this destructive command.`);
|
|
2417
|
+
}
|
|
2418
|
+
};
|
|
2419
|
+
}
|
|
2420
|
+
function sameArgv(left, right) {
|
|
2421
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
2422
|
+
}
|
|
2423
|
+
const composerConfirmationStore = createComposerConfirmationStore();
|
|
2424
|
+
//#endregion
|
|
2425
|
+
//#region ../../lib/composer-commands/parser.ts
|
|
2426
|
+
var ComposerCommandParseError = class extends Error {
|
|
2427
|
+
constructor(code, message, token, expected) {
|
|
2428
|
+
super(message);
|
|
2429
|
+
this.code = code;
|
|
2430
|
+
this.token = token;
|
|
2431
|
+
this.expected = expected;
|
|
2432
|
+
this.name = "ComposerCommandParseError";
|
|
2433
|
+
}
|
|
2434
|
+
};
|
|
2435
|
+
const FORBIDDEN_TOKEN = /\$\(|[;|&<>`]/;
|
|
2436
|
+
function expectedSyntax(entry) {
|
|
2437
|
+
const args = entry.args.map((argument) => {
|
|
2438
|
+
const name = argument.variadic ? `${argument.name}...` : argument.name;
|
|
2439
|
+
return argument.required ? `<${name}>` : `[${name}]`;
|
|
2440
|
+
});
|
|
2441
|
+
const options = entry.options.length > 0 ? ["[options]"] : [];
|
|
2442
|
+
return [
|
|
2443
|
+
entry.display,
|
|
2444
|
+
...args,
|
|
2445
|
+
...options
|
|
2446
|
+
].join(" ");
|
|
2447
|
+
}
|
|
2448
|
+
function tokenize(input) {
|
|
2449
|
+
const tokens = [];
|
|
2450
|
+
let current = "";
|
|
2451
|
+
let quote = null;
|
|
2452
|
+
let escaped = false;
|
|
2453
|
+
const pushCurrent = () => {
|
|
2454
|
+
if (current.length === 0) return;
|
|
2455
|
+
tokens.push(current);
|
|
2456
|
+
current = "";
|
|
2457
|
+
};
|
|
2458
|
+
for (const character of input) {
|
|
2459
|
+
if (escaped) {
|
|
2460
|
+
current += character;
|
|
2461
|
+
escaped = false;
|
|
2462
|
+
continue;
|
|
2463
|
+
}
|
|
2464
|
+
if (character === "\\") {
|
|
2465
|
+
escaped = true;
|
|
2466
|
+
continue;
|
|
2467
|
+
}
|
|
2468
|
+
if (quote !== null) {
|
|
2469
|
+
if (character === quote) quote = null;
|
|
2470
|
+
else current += character;
|
|
2471
|
+
continue;
|
|
2472
|
+
}
|
|
2473
|
+
if (character === "\"" || character === "'") {
|
|
2474
|
+
quote = character;
|
|
2475
|
+
continue;
|
|
2476
|
+
}
|
|
2477
|
+
if (/\s/.test(character)) {
|
|
2478
|
+
pushCurrent();
|
|
2479
|
+
continue;
|
|
2480
|
+
}
|
|
2481
|
+
current += character;
|
|
2482
|
+
}
|
|
2483
|
+
if (escaped) current += "\\";
|
|
2484
|
+
if (quote !== null) throw new ComposerCommandParseError("missing-argument", `Unclosed ${quote} quote. Close the quoted value before submitting the command.`, quote, `a closing ${quote}`);
|
|
2485
|
+
pushCurrent();
|
|
2486
|
+
return tokens;
|
|
2487
|
+
}
|
|
2488
|
+
function aliasesForPath(entry) {
|
|
2489
|
+
let candidates = [[]];
|
|
2490
|
+
for (let index = 0; index < entry.path.length; index += 1) {
|
|
2491
|
+
const prefix = entry.path.slice(0, index + 1);
|
|
2492
|
+
const prefixEntry = COMPOSER_COMMAND_MANIFEST.find((candidate) => candidate.path.length === prefix.length && candidate.path.every((part, partIndex) => part === prefix[partIndex]));
|
|
2493
|
+
const names = [entry.path[index], ...prefixEntry?.aliases ?? []];
|
|
2494
|
+
candidates = candidates.flatMap((candidate) => names.map((name) => [...candidate, name]));
|
|
2495
|
+
}
|
|
2496
|
+
return candidates;
|
|
2497
|
+
}
|
|
2498
|
+
function resolveEntry(tokens) {
|
|
2499
|
+
const match = COMPOSER_COMMAND_MANIFEST.flatMap((entry) => aliasesForPath(entry).filter((path) => path.every((part, index) => tokens[index] === part)).map((path) => ({
|
|
2500
|
+
entry,
|
|
2501
|
+
pathLength: path.length
|
|
2502
|
+
}))).sort((left, right) => right.pathLength - left.pathLength)[0];
|
|
2503
|
+
if (match) return match;
|
|
2504
|
+
const token = tokens[0] ?? "";
|
|
2505
|
+
throw new ComposerCommandParseError("unknown-command", token ? `Unknown Overdeck command "${token}". Type /pan to list available commands.` : "Missing an Overdeck command after /pan. Type /pan to list available commands.", token, "/pan <command>");
|
|
2506
|
+
}
|
|
2507
|
+
function optionDefinitions(entry) {
|
|
2508
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
2509
|
+
for (const option of entry.options) {
|
|
2510
|
+
const flags = option.flags.split(/[ ,|]+/).filter((part) => part.startsWith("-"));
|
|
2511
|
+
const canonicalFlag = flags.find((flag) => flag.startsWith("--")) ?? flags[0];
|
|
2512
|
+
for (const flag of flags) definitions.set(flag, {
|
|
2513
|
+
option,
|
|
2514
|
+
canonicalFlag
|
|
2515
|
+
});
|
|
2516
|
+
}
|
|
2517
|
+
return definitions;
|
|
2518
|
+
}
|
|
2519
|
+
function splitFlag(token) {
|
|
2520
|
+
const separator = token.indexOf("=");
|
|
2521
|
+
if (separator === -1) return { flag: token };
|
|
2522
|
+
return {
|
|
2523
|
+
flag: token.slice(0, separator),
|
|
2524
|
+
inlineValue: token.slice(separator + 1)
|
|
2525
|
+
};
|
|
2526
|
+
}
|
|
2527
|
+
function parseOverdeckComposerCommand(message) {
|
|
2528
|
+
if (!/^\/pan(?:\s|$)/.test(message)) return null;
|
|
2529
|
+
const forbidden = message.match(FORBIDDEN_TOKEN)?.[0];
|
|
2530
|
+
if (forbidden !== void 0) throw new ComposerCommandParseError("forbidden-token", `The token "${forbidden}" is not allowed in /pan commands. Run compound shell syntax in a terminal instead.`, forbidden, "plain arguments without shell operators");
|
|
2531
|
+
const tokens = tokenize(message.slice(4).trim());
|
|
2532
|
+
const { entry, pathLength } = resolveEntry(tokens);
|
|
2533
|
+
const remaining = tokens.slice(pathLength);
|
|
2534
|
+
const definitions = optionDefinitions(entry);
|
|
2535
|
+
const positionals = [];
|
|
2536
|
+
const flags = [];
|
|
2537
|
+
for (let index = 0; index < remaining.length; index += 1) {
|
|
2538
|
+
const token = remaining[index];
|
|
2539
|
+
if (!token.startsWith("-")) {
|
|
2540
|
+
positionals.push(token);
|
|
2541
|
+
continue;
|
|
2542
|
+
}
|
|
2543
|
+
const { flag, inlineValue } = splitFlag(token);
|
|
2544
|
+
const definition = definitions.get(flag);
|
|
2545
|
+
if (definition === void 0) throw new ComposerCommandParseError("unknown-flag", `Unknown flag "${flag}" for ${entry.display}. Expected syntax: ${expectedSyntax(entry)}.`, flag, expectedSyntax(entry));
|
|
2546
|
+
flags.push(definition.canonicalFlag);
|
|
2547
|
+
if (definition.option.valueHint === null) {
|
|
2548
|
+
if (inlineValue !== void 0) throw new ComposerCommandParseError("unknown-flag", `Flag "${flag}" does not accept a value. Expected syntax: ${expectedSyntax(entry)}.`, token, expectedSyntax(entry));
|
|
2549
|
+
continue;
|
|
2550
|
+
}
|
|
2551
|
+
if (inlineValue !== void 0) {
|
|
2552
|
+
if (inlineValue.length === 0 && definition.option.required) throw new ComposerCommandParseError("missing-argument", `Flag "${flag}" requires <${definition.option.valueHint}>. Expected syntax: ${expectedSyntax(entry)}.`, flag, expectedSyntax(entry));
|
|
2553
|
+
if (inlineValue.length > 0) flags.push(inlineValue);
|
|
2554
|
+
continue;
|
|
2555
|
+
}
|
|
2556
|
+
const next = remaining[index + 1];
|
|
2557
|
+
const nextIsFlag = next?.startsWith("-") === true;
|
|
2558
|
+
if (definition.option.required && (next === void 0 || nextIsFlag)) throw new ComposerCommandParseError("missing-argument", `Flag "${flag}" requires <${definition.option.valueHint}>. Expected syntax: ${expectedSyntax(entry)}.`, flag, expectedSyntax(entry));
|
|
2559
|
+
if (next !== void 0 && !nextIsFlag) {
|
|
2560
|
+
flags.push(next);
|
|
2561
|
+
index += 1;
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
if (!(entry.args.at(-1)?.variadic === true) && positionals.length > entry.args.length) {
|
|
2565
|
+
const token = positionals[entry.args.length];
|
|
2566
|
+
throw new ComposerCommandParseError("unknown-command", `Unexpected token "${token}" for ${entry.display}. Expected syntax: ${expectedSyntax(entry)}.`, token, expectedSyntax(entry));
|
|
2567
|
+
}
|
|
2568
|
+
const missing = entry.args.find((argument, index) => argument.required && positionals[index] === void 0);
|
|
2569
|
+
if (missing !== void 0) throw new ComposerCommandParseError("missing-argument", `Missing required argument <${missing.name}> for ${entry.display}. Expected syntax: ${expectedSyntax(entry)}.`, missing.name, expectedSyntax(entry));
|
|
2570
|
+
return {
|
|
2571
|
+
entry,
|
|
2572
|
+
argv: [
|
|
2573
|
+
...entry.path,
|
|
2574
|
+
...positionals,
|
|
2575
|
+
...flags
|
|
2576
|
+
]
|
|
2577
|
+
};
|
|
2578
|
+
}
|
|
2579
|
+
//#endregion
|
|
2580
|
+
//#region ../../lib/composer-commands/policy.ts
|
|
2581
|
+
init_src();
|
|
2582
|
+
const COMPOSER_COMMAND_POLICIES = {
|
|
2583
|
+
start: {
|
|
2584
|
+
mode: "detached",
|
|
2585
|
+
safety: "safe"
|
|
2586
|
+
},
|
|
2587
|
+
plan: {
|
|
2588
|
+
mode: "detached",
|
|
2589
|
+
safety: "safe"
|
|
2590
|
+
},
|
|
2591
|
+
show: {
|
|
2592
|
+
mode: "captured",
|
|
2593
|
+
safety: "safe"
|
|
2594
|
+
},
|
|
2595
|
+
status: {
|
|
2596
|
+
mode: "captured",
|
|
2597
|
+
safety: "safe"
|
|
2598
|
+
},
|
|
2599
|
+
tell: {
|
|
2600
|
+
mode: "captured",
|
|
2601
|
+
safety: "safe"
|
|
2602
|
+
},
|
|
2603
|
+
handoff: {
|
|
2604
|
+
mode: "ui",
|
|
2605
|
+
safety: "dialog",
|
|
2606
|
+
uiAction: "handoff",
|
|
2607
|
+
confirmationText: "This opens the handoff dialog for the selected conversation. Review the destination and focus before continuing."
|
|
2608
|
+
},
|
|
2609
|
+
fork: {
|
|
2610
|
+
mode: "ui",
|
|
2611
|
+
safety: "dialog",
|
|
2612
|
+
uiAction: "fork",
|
|
2613
|
+
confirmationText: "This opens the fork dialog for the selected conversation. Review the fork mode and destination before continuing."
|
|
2614
|
+
}
|
|
2615
|
+
};
|
|
2616
|
+
const DEFAULT_POLICY = {
|
|
2617
|
+
mode: "terminal-only",
|
|
2618
|
+
safety: "safe"
|
|
2619
|
+
};
|
|
2620
|
+
function assertPolicyOverlayIntegrity(policies = COMPOSER_COMMAND_POLICIES, manifest = COMPOSER_COMMAND_MANIFEST) {
|
|
2621
|
+
for (const path of Object.keys(policies)) {
|
|
2622
|
+
const matches = manifest.filter((entry) => entry.path.join(" ") === path);
|
|
2623
|
+
if (matches.length !== 1) throw new Error(`Composer command policy path "${path}" must match exactly one manifest entry; found ${matches.length}.`);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
function resolvePolicy(path) {
|
|
2627
|
+
return COMPOSER_COMMAND_POLICIES[path.join(" ")] ?? DEFAULT_POLICY;
|
|
2628
|
+
}
|
|
2629
|
+
assertPolicyOverlayIntegrity();
|
|
2630
|
+
//#endregion
|
|
2631
|
+
//#region ../../lib/composer-commands/router.ts
|
|
2632
|
+
const UI_COMMAND_PATTERNS = [{
|
|
2633
|
+
action: "handoff",
|
|
2634
|
+
pattern: /^\/(?:handoff|pan-handoff|pan\s+handoff)(?:\s+([\s\S]+))?$/i
|
|
2635
|
+
}, {
|
|
2636
|
+
action: "fork",
|
|
2637
|
+
pattern: /^\/pan\s+fork(?:\s+([\s\S]+))?$/i
|
|
2638
|
+
}];
|
|
2639
|
+
function isComposerCommandMessage(message) {
|
|
2640
|
+
return UI_COMMAND_PATTERNS.some(({ pattern }) => pattern.test(message)) || /^\/pan(?:\s|$)/.test(message);
|
|
2641
|
+
}
|
|
2642
|
+
async function handleComposerCommandMessage({ message, target, confirmation }, dependencies = {}) {
|
|
2643
|
+
for (const { action, pattern } of UI_COMMAND_PATTERNS) {
|
|
2644
|
+
const match = message.match(pattern);
|
|
2645
|
+
if (match) {
|
|
2646
|
+
const parsed = parseOverdeckComposerCommand(`/pan ${action}`);
|
|
2647
|
+
const focus = match[1]?.trim();
|
|
2648
|
+
if (focus) parsed.argv.push(focus);
|
|
2649
|
+
return handleComposerCommand({
|
|
2650
|
+
parsed,
|
|
2651
|
+
target,
|
|
2652
|
+
confirmation
|
|
2653
|
+
}, dependencies);
|
|
2654
|
+
}
|
|
2655
|
+
}
|
|
2656
|
+
const parsed = parseOverdeckComposerCommand(message);
|
|
2657
|
+
if (parsed === null) return null;
|
|
2658
|
+
return handleComposerCommand({
|
|
2659
|
+
parsed,
|
|
2660
|
+
target,
|
|
2661
|
+
confirmation
|
|
2662
|
+
}, dependencies);
|
|
2663
|
+
}
|
|
2664
|
+
async function handleComposerCommand({ parsed, target, confirmation }, dependencies = {}) {
|
|
2665
|
+
const policy = (dependencies.resolvePolicy ?? resolvePolicy)(parsed.entry.path);
|
|
2666
|
+
if (policy.safety !== "safe") {
|
|
2667
|
+
const confirmationStore = dependencies.confirmationStore ?? composerConfirmationStore;
|
|
2668
|
+
if (confirmation === void 0) return confirmationStore.issue({
|
|
2669
|
+
target,
|
|
2670
|
+
argv: parsed.argv,
|
|
2671
|
+
policy,
|
|
2672
|
+
display: parsed.entry.display
|
|
2673
|
+
});
|
|
2674
|
+
confirmationStore.consume({
|
|
2675
|
+
target,
|
|
2676
|
+
argv: parsed.argv,
|
|
2677
|
+
policy,
|
|
2678
|
+
confirmation
|
|
2679
|
+
});
|
|
2680
|
+
}
|
|
2681
|
+
if (policy.mode === "captured") return runCapturedCommand(parsed.argv);
|
|
2682
|
+
if (policy.mode === "detached") return runDetachedCommand(parsed.argv);
|
|
2683
|
+
if (policy.mode === "ui" && policy.uiAction) return uiCommandResult(policy.uiAction, parsed.argv.slice(parsed.entry.path.length).join(" ") || void 0);
|
|
2684
|
+
if (policy.mode === "terminal-only") return {
|
|
2685
|
+
kind: "terminal-only",
|
|
2686
|
+
status: "rejected",
|
|
2687
|
+
message: `${parsed.entry.display} must run in a terminal. Composer execution has not been enabled for this command.`
|
|
2688
|
+
};
|
|
2689
|
+
return missingExecutorResult(parsed.entry.display, policy);
|
|
2690
|
+
}
|
|
2691
|
+
function uiCommandResult(action, focus) {
|
|
2692
|
+
return {
|
|
2693
|
+
kind: "ui",
|
|
2694
|
+
status: "requires_ui",
|
|
2695
|
+
action,
|
|
2696
|
+
args: focus ? { focus } : {}
|
|
2697
|
+
};
|
|
2698
|
+
}
|
|
2699
|
+
function missingExecutorResult(display, policy) {
|
|
2700
|
+
return {
|
|
2701
|
+
kind: "terminal-only",
|
|
2702
|
+
status: "rejected",
|
|
2703
|
+
message: `${display} is recognized as a ${policy.mode} command, but its composer executor is not registered yet. Run it in a terminal for now.`
|
|
2704
|
+
};
|
|
2705
|
+
}
|
|
2706
|
+
function composerCommandResultHttpStatus(result) {
|
|
2707
|
+
return result.kind === "terminal-only" ? 422 : 200;
|
|
2708
|
+
}
|
|
2709
|
+
//#endregion
|
|
2107
2710
|
//#region routes/agents/messaging.ts
|
|
2108
2711
|
init_agents$1();
|
|
2109
2712
|
async function sendAgentMessage(id, message) {
|
|
@@ -2119,6 +2722,55 @@ async function sendAgentMessage(id, message) {
|
|
|
2119
2722
|
remote: true
|
|
2120
2723
|
} : { success: true };
|
|
2121
2724
|
}
|
|
2725
|
+
async function handleAgentMessage(id, message, confirmation) {
|
|
2726
|
+
try {
|
|
2727
|
+
if (isComposerCommandMessage(message)) {
|
|
2728
|
+
let agentState;
|
|
2729
|
+
try {
|
|
2730
|
+
agentState = await Effect.runPromise(getAgentState(id));
|
|
2731
|
+
} catch {
|
|
2732
|
+
return jsonResponse({
|
|
2733
|
+
error: `Failed to resolve agent target: ${id}`,
|
|
2734
|
+
code: "agent-resolution-failed"
|
|
2735
|
+
}, { status: 503 });
|
|
2736
|
+
}
|
|
2737
|
+
if (!agentState) return jsonResponse({
|
|
2738
|
+
error: `Agent not found: ${id}`,
|
|
2739
|
+
code: "agent-not-found"
|
|
2740
|
+
}, { status: 404 });
|
|
2741
|
+
if (!agentState.harness) return jsonResponse({
|
|
2742
|
+
error: `Agent harness could not be resolved: ${id}`,
|
|
2743
|
+
code: "agent-harness-unresolved"
|
|
2744
|
+
}, { status: 503 });
|
|
2745
|
+
const result = await handleComposerCommandMessage({
|
|
2746
|
+
message,
|
|
2747
|
+
confirmation,
|
|
2748
|
+
target: {
|
|
2749
|
+
kind: "agent",
|
|
2750
|
+
id,
|
|
2751
|
+
harness: agentState.harness,
|
|
2752
|
+
cwd: agentState.workspace,
|
|
2753
|
+
issueId: agentState.issueId
|
|
2754
|
+
}
|
|
2755
|
+
});
|
|
2756
|
+
if (result !== null) return jsonResponse(result, { status: composerCommandResultHttpStatus(result) });
|
|
2757
|
+
}
|
|
2758
|
+
} catch (error) {
|
|
2759
|
+
if (error instanceof ComposerCommandConfirmationError) return jsonResponse({
|
|
2760
|
+
error: error.message,
|
|
2761
|
+
code: error.code
|
|
2762
|
+
}, { status: 422 });
|
|
2763
|
+
if (!(error instanceof ComposerCommandParseError)) throw error;
|
|
2764
|
+
const status = error.code === "unknown-command" ? 404 : error.code === "unknown-flag" ? 422 : 400;
|
|
2765
|
+
return jsonResponse({
|
|
2766
|
+
error: error.message,
|
|
2767
|
+
code: error.code,
|
|
2768
|
+
token: error.token,
|
|
2769
|
+
expected: error.expected
|
|
2770
|
+
}, { status });
|
|
2771
|
+
}
|
|
2772
|
+
return jsonResponse(await sendAgentMessage(id, message));
|
|
2773
|
+
}
|
|
2122
2774
|
function validateAgentMessageOrigin(request) {
|
|
2123
2775
|
const originCheck = validateOrigin(request);
|
|
2124
2776
|
if (!originCheck.ok) return {
|
|
@@ -2135,9 +2787,10 @@ function postAgentMessageLikeRoute(path) {
|
|
|
2135
2787
|
const originCheck = validateAgentMessageOrigin(yield* HttpServerRequest.HttpServerRequest);
|
|
2136
2788
|
if (!originCheck.ok) return originCheck.response;
|
|
2137
2789
|
const id = (yield* HttpRouter.params)["id"] ?? "";
|
|
2138
|
-
const
|
|
2790
|
+
const body = yield* readJsonBody$1;
|
|
2791
|
+
const { message } = body;
|
|
2139
2792
|
if (!message) return jsonResponse({ error: "Message required" }, { status: 400 });
|
|
2140
|
-
return yield* Effect.promise(() =>
|
|
2793
|
+
return yield* Effect.promise(() => handleAgentMessage(id, message, composerCommandConfirmationFromBody(body)));
|
|
2141
2794
|
})));
|
|
2142
2795
|
}
|
|
2143
2796
|
const postAgentMessageRoute = postAgentMessageLikeRoute("/api/agents/:id/message");
|
|
@@ -2386,7 +3039,7 @@ async function cleanupConversationAttachments(name) {
|
|
|
2386
3039
|
* sessions that the lifecycle poller missed. */
|
|
2387
3040
|
async function cleanupOrphanedConversationAttachments() {
|
|
2388
3041
|
try {
|
|
2389
|
-
const { listConversations } = await import("./conversations-
|
|
3042
|
+
const { listConversations } = await import("./conversations-C34dyIb9.js");
|
|
2390
3043
|
const convNames = new Set(listConversations().map((c) => c.name));
|
|
2391
3044
|
const root = getConversationAttachmentsRoot();
|
|
2392
3045
|
await runInBatches((await readdir(root, { withFileTypes: true })).filter((entry) => entry.isDirectory() && !convNames.has(entry.name)).map((entry) => join(root, entry.name)), 10, (path) => rm(path, {
|
|
@@ -2811,6 +3464,21 @@ async function handleConversationSwitchModel(name, body) {
|
|
|
2811
3464
|
function getPtySupervisorSocketPath(agentId) {
|
|
2812
3465
|
return join(getOverdeckHome(), "sockets", `pty-${agentId}.sock`);
|
|
2813
3466
|
}
|
|
3467
|
+
/**
|
|
3468
|
+
* Pull the supervisor's own failure out of the tmux pane it died in.
|
|
3469
|
+
*
|
|
3470
|
+
* A supervisor that cannot load its native node-pty exits instantly with an
|
|
3471
|
+
* ERR_MODULE_NOT_FOUND on stderr; all the spawn path sees is the socket that
|
|
3472
|
+
* never appeared. Reporting only the timeout hides the actual cause and sent
|
|
3473
|
+
* an operator hunting the memory governor instead (PAN-3172).
|
|
3474
|
+
*/
|
|
3475
|
+
function extractSupervisorFailure(paneText) {
|
|
3476
|
+
const lines = paneText.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
3477
|
+
const errors = lines.filter((line) => /error|cannot find|ERR_[A-Z_]+|pty-supervisor:/i.test(line));
|
|
3478
|
+
const chosen = (errors.length > 0 ? errors : lines).slice(-3);
|
|
3479
|
+
if (chosen.length === 0) return null;
|
|
3480
|
+
return chosen.join(" | ").slice(0, 500);
|
|
3481
|
+
}
|
|
2814
3482
|
async function waitForPtySupervisorSocket(agentId, timeoutMs = PTY_SUPERVISOR_SOCKET_WAIT_MS) {
|
|
2815
3483
|
const socketPath = getPtySupervisorSocketPath(agentId);
|
|
2816
3484
|
const start = Date.now();
|
|
@@ -2820,7 +3488,8 @@ async function waitForPtySupervisorSocket(agentId, timeoutMs = PTY_SUPERVISOR_SO
|
|
|
2820
3488
|
} catch {}
|
|
2821
3489
|
await new Promise((r) => setTimeout(r, 250));
|
|
2822
3490
|
}
|
|
2823
|
-
|
|
3491
|
+
const failure = extractSupervisorFailure(await capturePaneText(agentId, 40));
|
|
3492
|
+
throw new Error(`Timed out waiting for PTY supervisor socket ${socketPath}` + (failure ? ` — supervisor output: ${failure}` : ""));
|
|
2824
3493
|
}
|
|
2825
3494
|
async function extractModelFromSessionFile(sessionFile) {
|
|
2826
3495
|
try {
|
|
@@ -2980,7 +3649,7 @@ async function spawnConversationSession(tmuxSession, cwd, claudeSessionId, model
|
|
|
2980
3649
|
const codexApprovalPolicy = codexPermMode === "full-access" ? "never" : "on-request";
|
|
2981
3650
|
const codexSandboxMode = codexPermMode === "full-access" ? "danger-full-access" : codexPermMode === "read-only" ? "read-only" : "workspace-write";
|
|
2982
3651
|
const codexApprovalsReviewer = codexPermMode === "auto-review" ? "auto_review" : void 0;
|
|
2983
|
-
const { initCodexHome, extractThreadIdFromRollout } = await import("./codex-
|
|
3652
|
+
const { initCodexHome, extractThreadIdFromRollout } = await import("./codex-BdEsUFWh.js");
|
|
2984
3653
|
initCodexHome(codexHome, {
|
|
2985
3654
|
trustedDir: cwd,
|
|
2986
3655
|
approvalPolicy: codexApprovalPolicy,
|
|
@@ -3049,7 +3718,7 @@ async function spawnConversationSession(tmuxSession, cwd, claudeSessionId, model
|
|
|
3049
3718
|
} catch {}
|
|
3050
3719
|
console.log(`[claude-invoke] purpose=conversation-session | model=${model || "default"} | source=conversations.ts:spawnConversationSession | session=${tmuxSession} | resume=${resume} | command="${runtimeCommand}"`);
|
|
3051
3720
|
try {
|
|
3052
|
-
const { preTrustDirectory } = await import("./workspace-manager-
|
|
3721
|
+
const { preTrustDirectory } = await import("./workspace-manager-CDTKjjdU.js");
|
|
3053
3722
|
preTrustDirectory(cwd);
|
|
3054
3723
|
} catch {}
|
|
3055
3724
|
try {
|
|
@@ -3066,7 +3735,7 @@ async function spawnConversationSession(tmuxSession, cwd, claudeSessionId, model
|
|
|
3066
3735
|
const codexHomeDir = codexFields.codexHome;
|
|
3067
3736
|
(async () => {
|
|
3068
3737
|
try {
|
|
3069
|
-
const { waitForCodexRollout, extractThreadIdFromRollout, writeThreadId } = await import("./codex-
|
|
3738
|
+
const { waitForCodexRollout, extractThreadIdFromRollout, writeThreadId } = await import("./codex-BdEsUFWh.js");
|
|
3070
3739
|
const rollout = await waitForCodexRollout(codexHomeDir, 12e4);
|
|
3071
3740
|
if (rollout) {
|
|
3072
3741
|
const threadId = extractThreadIdFromRollout(rollout);
|
|
@@ -3957,7 +4626,7 @@ const postInternalAgentPermissionRequestRoute = HttpRouter.add("POST", "/api/int
|
|
|
3957
4626
|
error: "missing agent id"
|
|
3958
4627
|
}, { status: 400 });
|
|
3959
4628
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
3960
|
-
const { INTERNAL_TOKEN_HEADER, getInternalTokenSync } = yield* Effect.promise(() => import("./internal-token-
|
|
4629
|
+
const { INTERNAL_TOKEN_HEADER, getInternalTokenSync } = yield* Effect.promise(() => import("./internal-token-M9omeXM1.js"));
|
|
3961
4630
|
const expected = getInternalTokenSync();
|
|
3962
4631
|
if (!expected) return jsonResponse({
|
|
3963
4632
|
ok: false,
|
|
@@ -4093,6 +4762,7 @@ const postAgentPermissionResponseRoute = HttpRouter.add("POST", "/api/agents/:id
|
|
|
4093
4762
|
* pollers (PAN-1134). Extracted from routes/agents.ts so Pi event polling
|
|
4094
4763
|
* can reuse bodyToEvent without importing a heavy route module.
|
|
4095
4764
|
*/
|
|
4765
|
+
init_src();
|
|
4096
4766
|
/**
|
|
4097
4767
|
* Translate a decoded body into an unsigned DomainEvent (no sequence yet).
|
|
4098
4768
|
* Returns null if the body doesn't map to a runtime event.
|
|
@@ -4213,6 +4883,25 @@ const bodyToEvent = (agentId, body, timestamp) => {
|
|
|
4213
4883
|
contextSaturatedAt: source["contextSaturatedAt"]
|
|
4214
4884
|
}
|
|
4215
4885
|
};
|
|
4886
|
+
case "linear_mcp_auth_required": return {
|
|
4887
|
+
type: "linear_mcp_auth.required",
|
|
4888
|
+
timestamp,
|
|
4889
|
+
payload: {
|
|
4890
|
+
agentId,
|
|
4891
|
+
issueId: source["issueId"] ?? null,
|
|
4892
|
+
authUrl: source["authUrl"] ?? null,
|
|
4893
|
+
expiresAt: source["expiresAt"] ?? null
|
|
4894
|
+
}
|
|
4895
|
+
};
|
|
4896
|
+
case "linear_mcp_auth_healthy": return {
|
|
4897
|
+
type: "linear_mcp_auth.healthy",
|
|
4898
|
+
timestamp,
|
|
4899
|
+
payload: {
|
|
4900
|
+
agentId,
|
|
4901
|
+
issueId: source["issueId"] ?? null,
|
|
4902
|
+
source: "hook"
|
|
4903
|
+
}
|
|
4904
|
+
};
|
|
4216
4905
|
default: return null;
|
|
4217
4906
|
}
|
|
4218
4907
|
};
|
|
@@ -4224,7 +4913,7 @@ const getAgentHealthHistoryRoute = HttpRouter.add("GET", "/api/agents/:id/health
|
|
|
4224
4913
|
const request = yield* HttpServerRequest.HttpServerRequest;
|
|
4225
4914
|
const urlOpt = HttpServerRequest.toURL(request);
|
|
4226
4915
|
const hours = Option.isSome(urlOpt) ? urlOpt.value.searchParams.get("hours") ?? "24" : "24";
|
|
4227
|
-
const { getHealthHistory } = yield* Effect.promise(() => import("./health-events-
|
|
4916
|
+
const { getHealthHistory } = yield* Effect.promise(() => import("./health-events-_xfTaOUs.js"));
|
|
4228
4917
|
const endTime = /* @__PURE__ */ new Date();
|
|
4229
4918
|
const startTime = /* @__PURE__ */ new Date(endTime.getTime() - parseInt(hours) * 60 * 60 * 1e3);
|
|
4230
4919
|
const events = getHealthHistory(id, startTime.toISOString(), endTime.toISOString());
|
|
@@ -4237,9 +4926,18 @@ const getAgentHealthHistoryRoute = HttpRouter.add("GET", "/api/agents/:id/health
|
|
|
4237
4926
|
})));
|
|
4238
4927
|
function emitAgentRuntimeEvent(id, body, timestamp) {
|
|
4239
4928
|
return Effect.gen(function* () {
|
|
4929
|
+
let eventBody = body;
|
|
4930
|
+
if (body["kind"] === "linear_mcp_auth_required" || body["kind"] === "linear_mcp_auth_healthy") {
|
|
4931
|
+
const { AgentStateService } = yield* Effect.promise(() => import("./agent-state-service-hZpxIw1E.js"));
|
|
4932
|
+
const snapshot = yield* (yield* AgentStateService).get(id);
|
|
4933
|
+
eventBody = {
|
|
4934
|
+
...body,
|
|
4935
|
+
issueId: snapshot?.currentIssue ?? null
|
|
4936
|
+
};
|
|
4937
|
+
}
|
|
4240
4938
|
let raw;
|
|
4241
4939
|
try {
|
|
4242
|
-
raw = bodyToEvent(id,
|
|
4940
|
+
raw = bodyToEvent(id, eventBody, timestamp);
|
|
4243
4941
|
} catch (error) {
|
|
4244
4942
|
return {
|
|
4245
4943
|
ok: false,
|
|
@@ -4265,7 +4963,7 @@ function emitAgentRuntimeEvent(id, body, timestamp) {
|
|
|
4265
4963
|
detail: String(decoded.failure)
|
|
4266
4964
|
}, { status: 400 })
|
|
4267
4965
|
};
|
|
4268
|
-
const { AgentStateService } = yield* Effect.promise(() => import("./agent-state-service-
|
|
4966
|
+
const { AgentStateService } = yield* Effect.promise(() => import("./agent-state-service-hZpxIw1E.js"));
|
|
4269
4967
|
yield* (yield* AgentStateService).emit(decoded.success);
|
|
4270
4968
|
return {
|
|
4271
4969
|
ok: true,
|
|
@@ -4347,7 +5045,7 @@ const getAgentRuntimeRoute = HttpRouter.add("GET", "/api/agents/:id/runtime", ht
|
|
|
4347
5045
|
success: false,
|
|
4348
5046
|
error: "missing agent id"
|
|
4349
5047
|
}, { status: 400 });
|
|
4350
|
-
const { AgentStateService } = yield* Effect.promise(() => import("./agent-state-service-
|
|
5048
|
+
const { AgentStateService } = yield* Effect.promise(() => import("./agent-state-service-hZpxIw1E.js"));
|
|
4351
5049
|
const snapshot = yield* (yield* AgentStateService).get(id);
|
|
4352
5050
|
if (!snapshot) return jsonResponse({
|
|
4353
5051
|
success: false,
|
|
@@ -4532,8 +5230,8 @@ function createAgentStopHandler(lifecycleEvent) {
|
|
|
4532
5230
|
yield* stopAgent(id);
|
|
4533
5231
|
if (stateBeforeStop?.issueId) yield* Effect.promise(async () => {
|
|
4534
5232
|
try {
|
|
4535
|
-
const { resolveProjectFromIssueSync } = await import("./projects-
|
|
4536
|
-
const { findWorkspacePath } = await import("./archive-planning-
|
|
5233
|
+
const { resolveProjectFromIssueSync } = await import("./projects-B03Wr-xc.js");
|
|
5234
|
+
const { findWorkspacePath } = await import("./archive-planning-0FJ6Xd3b.js");
|
|
4537
5235
|
const issueLower = stateBeforeStop.issueId.toLowerCase();
|
|
4538
5236
|
const workspacePath = findWorkspacePath(resolveProjectFromIssueSync(stateBeforeStop.issueId)?.projectPath ?? process.cwd(), issueLower);
|
|
4539
5237
|
if (workspacePath) {
|
|
@@ -4673,7 +5371,7 @@ const postAgentUnpauseRoute = HttpRouter.add("POST", "/api/agents/:id/unpause",
|
|
|
4673
5371
|
if ((yield* getWorkAgentLifecycleState(id)).canResumeSession && updatedState.troubled !== true) {
|
|
4674
5372
|
resumeTriggered = true;
|
|
4675
5373
|
yield* Effect.promise(() => appendAgentLifecycleLog(id, "agent.unpause_immediate_resume_triggered"));
|
|
4676
|
-
import("./resume-
|
|
5374
|
+
import("./resume-u9byntrq.js").then(({ resumeAgent }) => resumeAgent(id)).then((result) => {
|
|
4677
5375
|
if (!result.success) console.warn(`[agents] immediate resume after unpause failed for ${id}: ${result.error}`);
|
|
4678
5376
|
}).catch((err) => console.warn(`[agents] immediate resume after unpause errored for ${id}:`, err));
|
|
4679
5377
|
}
|
|
@@ -5963,15 +6661,15 @@ init_agents$1();
|
|
|
5963
6661
|
function handleRemoteAgentSpawn(input) {
|
|
5964
6662
|
return Effect.gen(function* () {
|
|
5965
6663
|
const { issueId, workspacePath, workspaceMetadata, spawnModel, projectPath, spawnGuardrails, lifecycle } = input;
|
|
5966
|
-
const { spawnRemoteAgent, checkRemoteSpendCap } = yield* Effect.promise(() => import("./remote-agents-
|
|
5967
|
-
const { createFlyProviderFromConfig } = yield* Effect.promise(() => import("./remote-
|
|
5968
|
-
const { loadConfigSync: loadPanConfig } = yield* Effect.promise(() => import("./config-
|
|
6664
|
+
const { spawnRemoteAgent, checkRemoteSpendCap } = yield* Effect.promise(() => import("./remote-agents-C1bssi41.js"));
|
|
6665
|
+
const { createFlyProviderFromConfig } = yield* Effect.promise(() => import("./remote-CVGUhXMV.js"));
|
|
6666
|
+
const { loadConfigSync: loadPanConfig } = yield* Effect.promise(() => import("./config-DV-grfQc.js"));
|
|
5969
6667
|
const panConfig = loadPanConfig();
|
|
5970
6668
|
const spendCap = checkRemoteSpendCap(panConfig);
|
|
5971
6669
|
if (!spendCap.allowed) return jsonResponse({ error: spendCap.message }, { status: 429 });
|
|
5972
6670
|
const fly = createFlyProviderFromConfig(panConfig.remote);
|
|
5973
6671
|
yield* Effect.promise(() => fly.syncAllCredentials(workspaceMetadata.vmName));
|
|
5974
|
-
const { buildWorkAgentPrompt, getTrackerContext } = yield* Effect.promise(() => import("./work-agent-prompt-
|
|
6672
|
+
const { buildWorkAgentPrompt, getTrackerContext } = yield* Effect.promise(() => import("./work-agent-prompt-C-vuP3_J.js"));
|
|
5975
6673
|
const trackerContext = yield* Effect.promise(() => getTrackerContext(issueId, workspacePath));
|
|
5976
6674
|
const agentPrompt = yield* Effect.promise(() => buildWorkAgentPrompt({
|
|
5977
6675
|
issueId,
|
|
@@ -6287,10 +6985,12 @@ function handleContainerOrchestration(input) {
|
|
|
6287
6985
|
//#endregion
|
|
6288
6986
|
//#region routes/agents/spawn.ts
|
|
6289
6987
|
init_agents$1();
|
|
6988
|
+
init_staffing();
|
|
6290
6989
|
init_operator_interventions();
|
|
6291
6990
|
init_child_env();
|
|
6292
6991
|
init_harness_policy();
|
|
6293
6992
|
init_activity_logger();
|
|
6993
|
+
init_issue_id();
|
|
6294
6994
|
init_projects();
|
|
6295
6995
|
init_review_status();
|
|
6296
6996
|
init_state_read_home();
|
|
@@ -6328,20 +7028,17 @@ function emitDirtyWorkspaceRefusalActivity(issueId, porcelain) {
|
|
|
6328
7028
|
});
|
|
6329
7029
|
} catch {}
|
|
6330
7030
|
}
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
]);
|
|
7031
|
+
/**
|
|
7032
|
+
* Both workspace runtime directories are Overdeck-owned in full, so both get a
|
|
7033
|
+
* blanket prefix match. The legacy `.pan/` allowlist only matched the collapsed
|
|
7034
|
+
* `?? .pan/` porcelain form plus a closed set of files — but this gate always
|
|
7035
|
+
* runs with `--untracked-files=all`, which expands untracked directories into
|
|
7036
|
+
* individual paths. A pipeline-authored `.pan/drafts/<ISSUE>.md` therefore read
|
|
7037
|
+
* as operator dirt and 409'd the planning→work auto-handoff (PAN-3042).
|
|
7038
|
+
*/
|
|
6340
7039
|
function isOverdeckWorkspaceRuntimePath(path) {
|
|
6341
7040
|
if (path === ".overdeck" || path.startsWith(".overdeck/")) return true;
|
|
6342
|
-
|
|
6343
|
-
if (LEGACY_WORKSPACE_RUNTIME_FILES.has(path)) return true;
|
|
6344
|
-
return path.startsWith(".pan/feedback/") || path.startsWith(".pan/review/") || path.startsWith(".pan/test/") || path.startsWith(".pan/handoff-");
|
|
7041
|
+
return path === ".pan" || path === ".pan/" || path.startsWith(".pan/");
|
|
6345
7042
|
}
|
|
6346
7043
|
/** True when git porcelain contains only Overdeck-owned workspace runtime files. */
|
|
6347
7044
|
function isOnlyOverdeckRuntimeWorkspaceChanges(porcelain) {
|
|
@@ -6534,7 +7231,7 @@ const postAgentsRoute = HttpRouter.add("POST", "/api/agents", httpHandler(Effect
|
|
|
6534
7231
|
let spawnModel;
|
|
6535
7232
|
try {
|
|
6536
7233
|
spawnModel = determineModel({
|
|
6537
|
-
model: body.model,
|
|
7234
|
+
model: body.model ?? resolveIssueWorkModel(issueId),
|
|
6538
7235
|
role,
|
|
6539
7236
|
spawnKey: `${role}:${issueId}`
|
|
6540
7237
|
});
|
|
@@ -6692,7 +7389,7 @@ const postAgentsRoute = HttpRouter.add("POST", "/api/agents", httpHandler(Effect
|
|
|
6692
7389
|
console.warn(`[start-agent] Failed to set plan.status=running (non-fatal): ${planStatusErr?.message ?? planStatusErr}`);
|
|
6693
7390
|
}
|
|
6694
7391
|
try {
|
|
6695
|
-
const { appendSessionEntry, getProjectConfigFromWorkspacePath, resolveProjectForIssue } = await import("./record-
|
|
7392
|
+
const { appendSessionEntry, getProjectConfigFromWorkspacePath, resolveProjectForIssue } = await import("./record-CtroO946.js");
|
|
6696
7393
|
await appendSessionEntry(resolveProjectForIssue(issueId) ?? getProjectConfigFromWorkspacePath(workspacePath), issueId, {
|
|
6697
7394
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6698
7395
|
reason: "start",
|
|
@@ -7142,16 +7839,26 @@ const readJsonBody = Effect.gen(function* () {
|
|
|
7142
7839
|
const postMergeGuard = createInFlightGuard();
|
|
7143
7840
|
const _serverManagedMerges = /* @__PURE__ */ new Set();
|
|
7144
7841
|
function firePostMergeLifecycle(issueId, options) {
|
|
7145
|
-
const
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7842
|
+
const parsedIssueId = parseIssueIdSync(issueId.trim());
|
|
7843
|
+
if (!parsedIssueId) {
|
|
7844
|
+
console.error(`[merge] Refusing post-merge lifecycle for invalid issue ID: ${issueId}`);
|
|
7845
|
+
return false;
|
|
7846
|
+
}
|
|
7847
|
+
const normalizedIssueId = parsedIssueId.normalized.toUpperCase();
|
|
7848
|
+
const started = postMergeGuard.run(normalizedIssueId, async () => {
|
|
7849
|
+
const projectPath = getProjectPathForIssue(parsedIssueId.prefix);
|
|
7850
|
+
const { postMergeLifecycle } = await import("./merge-agent-DrXa1CpW.js");
|
|
7851
|
+
const lifecycleOptions = {
|
|
7852
|
+
...options?.verifiedMergedRef ? { verifiedMergedRef: options.verifiedMergedRef } : {},
|
|
7853
|
+
...options?.verifiedMergedRepos?.length ? { verifiedMergedRepos: options.verifiedMergedRepos } : {}
|
|
7854
|
+
};
|
|
7855
|
+
await postMergeLifecycle(normalizedIssueId, projectPath, options?.sourceBranch, Object.keys(lifecycleOptions).length > 0 ? lifecycleOptions : void 0);
|
|
7856
|
+
console.log(`[merge] post-merge lifecycle completed for ${normalizedIssueId}`);
|
|
7857
|
+
const { runMergeTrainReconcile } = await import("./merge-train-DTEMyIu4.js");
|
|
7858
|
+
const outcomes = await runMergeTrainReconcile(normalizedIssueId);
|
|
7859
|
+
if (outcomes.length > 0) console.log(`[merge-train] reconciled ${outcomes.length} sibling(s) after ${normalizedIssueId}: ` + outcomes.map((o) => `${o.issueId}=${o.result}`).join(", "));
|
|
7860
|
+
}, (err) => console.error(`[merge] post-merge lifecycle failed for ${normalizedIssueId}:`, err));
|
|
7861
|
+
if (!started) console.log(`[merge] firePostMergeLifecycle: skipping ${normalizedIssueId} — already in flight`);
|
|
7155
7862
|
return started;
|
|
7156
7863
|
}
|
|
7157
7864
|
function getProjectPathForIssue(issuePrefix) {
|
|
@@ -7168,15 +7875,15 @@ init_io();
|
|
|
7168
7875
|
init_domain_services();
|
|
7169
7876
|
init_tmux();
|
|
7170
7877
|
const getSpecialistsRoute = HttpRouter.add("GET", "/api/specialists", httpHandler(Effect.gen(function* () {
|
|
7171
|
-
const { getAllSpecialistStatus, getAllProjectSpecialistStatuses } = yield* Effect.promise(() => import("./specialists-
|
|
7878
|
+
const { getAllSpecialistStatus, getAllProjectSpecialistStatuses } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7172
7879
|
return jsonResponse({
|
|
7173
7880
|
specialists: yield* Effect.promise(() => getAllSpecialistStatus()),
|
|
7174
7881
|
projects: yield* Effect.promise(() => getAllProjectSpecialistStatuses())
|
|
7175
7882
|
});
|
|
7176
7883
|
})));
|
|
7177
7884
|
const postSpecialistsResetAllRoute = HttpRouter.add("POST", "/api/specialists/reset-all", httpHandler(Effect.gen(function* () {
|
|
7178
|
-
const { getAllSpecialists, isRunning, getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-
|
|
7179
|
-
const { clearHookSync } = yield* Effect.promise(() => import("./hooks-
|
|
7885
|
+
const { getAllSpecialists, isRunning, getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7886
|
+
const { clearHookSync } = yield* Effect.promise(() => import("./hooks-BnJsxlSq.js"));
|
|
7180
7887
|
const specialists = getAllSpecialists();
|
|
7181
7888
|
const results = [];
|
|
7182
7889
|
for (const specialist of specialists) {
|
|
@@ -7211,7 +7918,7 @@ const postSpecialistsResetAllRoute = HttpRouter.add("POST", "/api/specialists/re
|
|
|
7211
7918
|
const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done", httpHandler(Effect.gen(function* () {
|
|
7212
7919
|
const body = yield* readJsonBody;
|
|
7213
7920
|
const eventStore = yield* EventStoreService;
|
|
7214
|
-
const { specialist, issueId, status, notes, itemId } = body;
|
|
7921
|
+
const { specialist, issueId, status, notes, itemId, runId } = body;
|
|
7215
7922
|
const validSpecialists = [
|
|
7216
7923
|
"review",
|
|
7217
7924
|
"test",
|
|
@@ -7232,7 +7939,7 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
7232
7939
|
}
|
|
7233
7940
|
console.log(`[specialists/done] ${specialist} signaling ${status} for ${normalizedIssueId}`);
|
|
7234
7941
|
if (specialist === "merge") {
|
|
7235
|
-
const { reportSpecialistCompletion } = yield* Effect.promise(() => import("./specialist-completion-
|
|
7942
|
+
const { reportSpecialistCompletion } = yield* Effect.promise(() => import("./specialist-completion-Br48eiDP.js"));
|
|
7236
7943
|
if (yield* reportSpecialistCompletion(normalizedIssueId, {
|
|
7237
7944
|
status,
|
|
7238
7945
|
notes
|
|
@@ -7276,10 +7983,27 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
7276
7983
|
break;
|
|
7277
7984
|
}
|
|
7278
7985
|
const updatedStatus = setReviewStatusSync(normalizedIssueId, update);
|
|
7279
|
-
if (specialist === "inspect" && status === "failed")
|
|
7986
|
+
if (specialist === "inspect" && status === "failed") {
|
|
7987
|
+
yield* Effect.promise(() => reportTieredInspectFailureEscalation(normalizedIssueId, notes));
|
|
7988
|
+
yield* Effect.promise(async () => {
|
|
7989
|
+
try {
|
|
7990
|
+
const failedItemId = itemId ?? getReviewStatusSync(normalizedIssueId)?.inspectBeadId ?? void 0;
|
|
7991
|
+
const project = resolveProjectFromIssueSync(normalizedIssueId);
|
|
7992
|
+
if (project && failedItemId) {
|
|
7993
|
+
const workspacePath = join(project.projectPath, "workspaces", `feature-${normalizedIssueId.toLowerCase()}`);
|
|
7994
|
+
if (existsSync(workspacePath)) {
|
|
7995
|
+
const { onInspectComplete } = await import("./inspect-agent-BVwDrVrz.js");
|
|
7996
|
+
await Effect.runPromise(onInspectComplete(project.projectKey, normalizedIssueId, failedItemId, "failed", workspacePath, notes));
|
|
7997
|
+
}
|
|
7998
|
+
}
|
|
7999
|
+
} catch (err) {
|
|
8000
|
+
console.error(`[specialists/done] Error delivering failed inspect verdict for ${normalizedIssueId}:`, err);
|
|
8001
|
+
}
|
|
8002
|
+
});
|
|
8003
|
+
}
|
|
7280
8004
|
yield* Effect.promise(async () => {
|
|
7281
8005
|
try {
|
|
7282
|
-
const { getTmuxSessionName, updateRunMetadata, makeSpecialistRegistryKey } = await import("./specialists-
|
|
8006
|
+
const { getTmuxSessionName, updateRunMetadata, makeSpecialistRegistryKey } = await import("./specialists-Tdezg_6N.js");
|
|
7283
8007
|
const projectKey = resolveProjectFromIssueSync(normalizedIssueId)?.projectKey;
|
|
7284
8008
|
const tmuxSession = projectKey ? getTmuxSessionName(`${specialist}-agent`, projectKey, normalizedIssueId) : getTmuxSessionName(`${specialist}-agent`);
|
|
7285
8009
|
saveAgentRuntimeState(tmuxSession, {
|
|
@@ -7298,7 +8022,7 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
7298
8022
|
});
|
|
7299
8023
|
console.log(`[specialists/done] Cleared registry lock for ${registryKey} (${projectKey})`);
|
|
7300
8024
|
}
|
|
7301
|
-
const { updateSpecialistHandoffStatus } = await import("./specialist-handoff-logger-
|
|
8025
|
+
const { updateSpecialistHandoffStatus } = await import("./specialist-handoff-logger-DK-GTz4s.js");
|
|
7302
8026
|
if (await Effect.runPromise(updateSpecialistHandoffStatus(normalizedIssueId, `${specialist}-agent`, status === "passed" ? "completed" : "failed", status === "passed" ? "success" : "failure"))) console.log(`[specialists/done] Updated handoff log: ${specialist}-agent ${normalizedIssueId} → ${status}`);
|
|
7303
8027
|
} catch (err) {
|
|
7304
8028
|
console.error(`[specialists/done] Error managing specialist state:`, err);
|
|
@@ -7310,10 +8034,12 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
7310
8034
|
if (project) {
|
|
7311
8035
|
const workspacePath = join(project.projectPath, "workspaces", `feature-${normalizedIssueId.toLowerCase()}`);
|
|
7312
8036
|
if (existsSync(workspacePath)) {
|
|
7313
|
-
const {
|
|
7314
|
-
const
|
|
7315
|
-
|
|
7316
|
-
|
|
8037
|
+
const { formatAnchorShort, snapshotWorkspaceHeadsPromise } = await import("./git-utils-CI6cwyyC.js");
|
|
8038
|
+
const headAnchor = await snapshotWorkspaceHeadsPromise(normalizedIssueId, workspacePath);
|
|
8039
|
+
if (headAnchor) {
|
|
8040
|
+
setReviewStatusSync(normalizedIssueId, { reviewedAtCommit: headAnchor });
|
|
8041
|
+
console.log(`[specialists/done] Snapshotted reviewedAtCommit=${formatAnchorShort(headAnchor)} for ${normalizedIssueId}`);
|
|
8042
|
+
}
|
|
7317
8043
|
}
|
|
7318
8044
|
}
|
|
7319
8045
|
} catch (err) {
|
|
@@ -7322,11 +8048,11 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
7322
8048
|
});
|
|
7323
8049
|
if (specialist === "inspect" && status === "passed") yield* Effect.promise(async () => {
|
|
7324
8050
|
try {
|
|
7325
|
-
const { onInspectComplete } = await import("./inspect-agent-
|
|
8051
|
+
const { onInspectComplete } = await import("./inspect-agent-BVwDrVrz.js");
|
|
7326
8052
|
const project = resolveProjectFromIssueSync(normalizedIssueId);
|
|
7327
8053
|
if (project) {
|
|
7328
8054
|
const workspacePath = join(project.projectPath, "workspaces", `feature-${normalizedIssueId.toLowerCase()}`);
|
|
7329
|
-
if (existsSync(workspacePath)) await Effect.runPromise(onInspectComplete(project.projectKey, normalizedIssueId, itemId, "passed", workspacePath));
|
|
8055
|
+
if (existsSync(workspacePath)) await Effect.runPromise(onInspectComplete(project.projectKey, normalizedIssueId, itemId, "passed", workspacePath, notes));
|
|
7330
8056
|
}
|
|
7331
8057
|
} catch (err) {
|
|
7332
8058
|
console.error(`[specialists/done] Error saving inspect checkpoint:`, err);
|
|
@@ -7338,7 +8064,7 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
7338
8064
|
if (project) {
|
|
7339
8065
|
if (existsSync(join(project.projectPath, "workspaces", `feature-${normalizedIssueId.toLowerCase()}`))) {
|
|
7340
8066
|
setReviewStatusSync(normalizedIssueId, { testStatus: "passed" });
|
|
7341
|
-
const { initEventStore } = await import("./event-store-
|
|
8067
|
+
const { initEventStore } = await import("./event-store-ELqkVOn0.js");
|
|
7342
8068
|
await (await initEventStore()).appendAsync({
|
|
7343
8069
|
type: "test.passed",
|
|
7344
8070
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -7391,8 +8117,8 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
7391
8117
|
if (notes?.toLowerCase().includes("conflict")) yield* Effect.promise(async () => {
|
|
7392
8118
|
try {
|
|
7393
8119
|
const workAgentId = `agent-${normalizedIssueId.toLowerCase()}`;
|
|
7394
|
-
const { sessionExists } = await import("./tmux-
|
|
7395
|
-
const { messageAgent, spawnAgent, getAgentStateSync } = await import("./agents-
|
|
8120
|
+
const { sessionExists } = await import("./tmux-DQ6jB76i.js");
|
|
8121
|
+
const { messageAgent, spawnAgent, getAgentStateSync } = await import("./agents-BKKkxKgK.js");
|
|
7396
8122
|
if (await Effect.runPromise(sessionExists(workAgentId))) {
|
|
7397
8123
|
await messageAgent(workAgentId, `MERGE CONFLICT: The merge-agent could not rebase your branch onto main due to conflicts. Please fix this now:\n\n1. git fetch origin main\n2. git rebase origin/main\n3. Resolve any conflicts (git add <file> && git rebase --continue)\n4. git push --force-with-lease\n5. Resubmit: curl -s -X POST http://localhost:3011/api/review/${normalizedIssueId}/request -H "Content-Type: application/json" -d "{}"\n\nConflict details: ${notes}`);
|
|
7398
8124
|
console.log(`[specialists/done] Sent rebase instructions to ${workAgentId}`);
|
|
@@ -7406,19 +8132,38 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
7406
8132
|
try {
|
|
7407
8133
|
const project = resolveProjectFromIssueSync(normalizedIssueId);
|
|
7408
8134
|
const workspacePath = project ? join(project.projectPath, "workspaces", `feature-${normalizedIssueId.toLowerCase()}`) : void 0;
|
|
7409
|
-
const { deliverReviewVerdictFeedback } = await import("./review-verdict-feedback-
|
|
8135
|
+
const { deliverReviewVerdictFeedback } = await import("./review-verdict-feedback-BPDn4li_.js");
|
|
7410
8136
|
const result = await Effect.runPromise(deliverReviewVerdictFeedback({
|
|
7411
8137
|
issueId: normalizedIssueId,
|
|
7412
8138
|
verdict: status === "failed" ? "failed" : "blocked",
|
|
7413
8139
|
notes,
|
|
7414
8140
|
workspacePath,
|
|
7415
|
-
prUrl: updatedStatus.prUrl
|
|
8141
|
+
prUrl: updatedStatus.prUrl,
|
|
8142
|
+
...runId ? { runId } : {}
|
|
7416
8143
|
}));
|
|
7417
8144
|
console.log(`[specialists/done] Delivered review verdict feedback for ${normalizedIssueId} (feedback=${result.feedbackPath ?? "none"}, synthesis=${result.synthesisPath ?? "none"}, prComment=${result.prCommentPosted})`);
|
|
7418
8145
|
} catch (err) {
|
|
7419
8146
|
console.warn(`[specialists/done] Failed to deliver review verdict feedback: ${err.message}`);
|
|
7420
8147
|
}
|
|
7421
8148
|
});
|
|
8149
|
+
if (specialist === "review" && status === "failed") yield* Effect.promise(async () => {
|
|
8150
|
+
try {
|
|
8151
|
+
const project = resolveProjectFromIssueSync(normalizedIssueId);
|
|
8152
|
+
if (project) {
|
|
8153
|
+
const workspacePath = join(project.projectPath, "workspaces", `feature-${normalizedIssueId.toLowerCase()}`);
|
|
8154
|
+
if (existsSync(workspacePath)) {
|
|
8155
|
+
const { formatAnchorShort, snapshotWorkspaceHeadsPromise } = await import("./git-utils-CI6cwyyC.js");
|
|
8156
|
+
const reviewedAtCommit = await snapshotWorkspaceHeadsPromise(normalizedIssueId, workspacePath);
|
|
8157
|
+
if (reviewedAtCommit) {
|
|
8158
|
+
setReviewStatusSync(normalizedIssueId, { reviewedAtCommit });
|
|
8159
|
+
console.log(`[specialists/done] Snapshotted blocked reviewedAtCommit=${formatAnchorShort(reviewedAtCommit)} for ${normalizedIssueId}`);
|
|
8160
|
+
}
|
|
8161
|
+
}
|
|
8162
|
+
}
|
|
8163
|
+
} catch (err) {
|
|
8164
|
+
console.error(`[specialists/done] Failed to snapshot blocked reviewedAtCommit for ${normalizedIssueId}:`, err);
|
|
8165
|
+
}
|
|
8166
|
+
});
|
|
7422
8167
|
const eventRole = specialistEventRole(specialist);
|
|
7423
8168
|
if (eventRole) if (status === "passed") yield* eventStore.append({
|
|
7424
8169
|
type: "specialist.completed",
|
|
@@ -7447,7 +8192,7 @@ const postSpecialistsDoneRoute = HttpRouter.add("POST", "/api/specialists/done",
|
|
|
7447
8192
|
});
|
|
7448
8193
|
})));
|
|
7449
8194
|
const postSpecialistsLogsCleanupAllRoute = HttpRouter.add("POST", "/api/specialists/logs/cleanup-all", httpHandler(Effect.gen(function* () {
|
|
7450
|
-
const { cleanupAllLogsSync } = yield* Effect.promise(() => import("./specialist-logs-
|
|
8195
|
+
const { cleanupAllLogsSync } = yield* Effect.promise(() => import("./specialist-logs-Cl5-hqT8.js"));
|
|
7451
8196
|
const results = cleanupAllLogsSync();
|
|
7452
8197
|
return jsonResponse({
|
|
7453
8198
|
success: true,
|
|
@@ -7457,7 +8202,7 @@ const postSpecialistsLogsCleanupAllRoute = HttpRouter.add("POST", "/api/speciali
|
|
|
7457
8202
|
});
|
|
7458
8203
|
})));
|
|
7459
8204
|
const getSpecialistsProjectsRoute = HttpRouter.add("GET", "/api/specialists/projects", httpHandler(Effect.gen(function* () {
|
|
7460
|
-
const { getAllProjectSpecialistStatuses } = yield* Effect.promise(() => import("./specialists-
|
|
8205
|
+
const { getAllProjectSpecialistStatuses } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7461
8206
|
return jsonResponse(yield* Effect.promise(() => getAllProjectSpecialistStatuses()));
|
|
7462
8207
|
})));
|
|
7463
8208
|
const postSpecialistWakeRoute = HttpRouter.add("POST", "/api/specialists/:name/wake", httpHandler(Effect.gen(function* () {
|
|
@@ -7501,7 +8246,7 @@ const postSpecialistReportStatusRoute = HttpRouter.add("POST", "/api/specialists
|
|
|
7501
8246
|
"blocked",
|
|
7502
8247
|
"failed"
|
|
7503
8248
|
].includes(status)) {
|
|
7504
|
-
const { getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-
|
|
8249
|
+
const { getTmuxSessionName } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7505
8250
|
saveAgentRuntimeState(getTmuxSessionName(name), {
|
|
7506
8251
|
state: "idle",
|
|
7507
8252
|
lastActivity: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -7600,6 +8345,7 @@ const specialistsLegacyRouteLayer = Layer.mergeAll(getSpecialistsRoute, getSpeci
|
|
|
7600
8345
|
//#endregion
|
|
7601
8346
|
//#region routes/specialists/project-routes.ts
|
|
7602
8347
|
init_config_yaml();
|
|
8348
|
+
init_project_repos();
|
|
7603
8349
|
init_projects();
|
|
7604
8350
|
init_review_status();
|
|
7605
8351
|
init_tmux();
|
|
@@ -7622,7 +8368,7 @@ const postProjectSpecialistKillRoute = HttpRouter.add("POST", "/api/specialists/
|
|
|
7622
8368
|
const issueId = params["issueId"];
|
|
7623
8369
|
const type = params["type"];
|
|
7624
8370
|
if (!validateSpecialistAgentName(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
7625
|
-
const { getTmuxSessionName, makeSpecialistRegistryKey, getRunMetadata } = yield* Effect.promise(() => import("./specialists-
|
|
8371
|
+
const { getTmuxSessionName, makeSpecialistRegistryKey, getRunMetadata } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7626
8372
|
const tmuxSession = getRunMetadata(project, makeSpecialistRegistryKey(type, issueId)).tmuxSession ?? getTmuxSessionName(type, project, issueId);
|
|
7627
8373
|
yield* Effect.promise(() => Effect.runPromise(killSession(tmuxSession)).catch(() => {}));
|
|
7628
8374
|
saveAgentRuntimeState(tmuxSession, {
|
|
@@ -7649,7 +8395,7 @@ const getProjectSpecialistRunsRoute = HttpRouter.add("GET", "/api/specialists/:p
|
|
|
7649
8395
|
if (limitParam) limit = parseInt(limitParam, 10);
|
|
7650
8396
|
if (offsetParam) offset = parseInt(offsetParam, 10);
|
|
7651
8397
|
}
|
|
7652
|
-
const { listRunLogsSync } = yield* Effect.promise(() => import("./specialist-logs-
|
|
8398
|
+
const { listRunLogsSync } = yield* Effect.promise(() => import("./specialist-logs-Cl5-hqT8.js"));
|
|
7653
8399
|
return jsonResponse(listRunLogsSync(project, type, {
|
|
7654
8400
|
limit,
|
|
7655
8401
|
offset
|
|
@@ -7660,7 +8406,7 @@ const getProjectSpecialistRunStreamRoute = HttpRouter.add("GET", "/api/specialis
|
|
|
7660
8406
|
const project = params["project"];
|
|
7661
8407
|
const type = params["type"];
|
|
7662
8408
|
const runId = params["runId"];
|
|
7663
|
-
const { getRunLogPath, isRunLogActive } = yield* Effect.promise(() => import("./specialist-logs-
|
|
8409
|
+
const { getRunLogPath, isRunLogActive } = yield* Effect.promise(() => import("./specialist-logs-Cl5-hqT8.js"));
|
|
7664
8410
|
const logPath = getRunLogPath(project, type, runId);
|
|
7665
8411
|
if (!existsSync(logPath)) return jsonResponse({ error: "Run log not found" }, { status: 404 });
|
|
7666
8412
|
const encoder = new TextEncoder();
|
|
@@ -7719,7 +8465,7 @@ const getProjectSpecialistRunRoute = HttpRouter.add("GET", "/api/specialists/:pr
|
|
|
7719
8465
|
const project = params["project"];
|
|
7720
8466
|
const type = params["type"];
|
|
7721
8467
|
const runId = params["runId"];
|
|
7722
|
-
const { getRunLogSync, parseLogMetadata } = yield* Effect.promise(() => import("./specialist-logs-
|
|
8468
|
+
const { getRunLogSync, parseLogMetadata } = yield* Effect.promise(() => import("./specialist-logs-Cl5-hqT8.js"));
|
|
7723
8469
|
const content = getRunLogSync(project, type, runId);
|
|
7724
8470
|
if (!content) return jsonResponse({ error: "Run log not found" }, { status: 404 });
|
|
7725
8471
|
return jsonResponse({
|
|
@@ -7733,7 +8479,7 @@ const postProjectSpecialistRunTerminateRoute = HttpRouter.add("POST", "/api/spec
|
|
|
7733
8479
|
const project = params["project"];
|
|
7734
8480
|
const type = params["type"];
|
|
7735
8481
|
if (!validateSpecialistAgentName(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
7736
|
-
const { terminateSpecialist } = yield* Effect.promise(() => import("./specialists-
|
|
8482
|
+
const { terminateSpecialist } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7737
8483
|
yield* Effect.promise(() => terminateSpecialist(project, type));
|
|
7738
8484
|
return jsonResponse({
|
|
7739
8485
|
success: true,
|
|
@@ -7745,7 +8491,7 @@ const postProjectSpecialistGracePauseRoute = HttpRouter.add("POST", "/api/specia
|
|
|
7745
8491
|
const project = params["project"];
|
|
7746
8492
|
const type = params["type"];
|
|
7747
8493
|
if (!validateSpecialistAgentName(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
7748
|
-
const { pauseGracePeriod } = yield* Effect.promise(() => import("./specialists-
|
|
8494
|
+
const { pauseGracePeriod } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7749
8495
|
if (pauseGracePeriod(project, type)) return jsonResponse({
|
|
7750
8496
|
success: true,
|
|
7751
8497
|
message: "Grace period paused"
|
|
@@ -7757,7 +8503,7 @@ const postProjectSpecialistGraceResumeRoute = HttpRouter.add("POST", "/api/speci
|
|
|
7757
8503
|
const project = params["project"];
|
|
7758
8504
|
const type = params["type"];
|
|
7759
8505
|
if (!validateSpecialistAgentName(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
7760
|
-
const { resumeGracePeriod } = yield* Effect.promise(() => import("./specialists-
|
|
8506
|
+
const { resumeGracePeriod } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7761
8507
|
if (resumeGracePeriod(project, type)) return jsonResponse({
|
|
7762
8508
|
success: true,
|
|
7763
8509
|
message: "Grace period resumed"
|
|
@@ -7769,7 +8515,7 @@ const postProjectSpecialistGraceExitRoute = HttpRouter.add("POST", "/api/special
|
|
|
7769
8515
|
const project = params["project"];
|
|
7770
8516
|
const type = params["type"];
|
|
7771
8517
|
if (!validateSpecialistAgentName(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
7772
|
-
const { exitGracePeriod } = yield* Effect.promise(() => import("./specialists-
|
|
8518
|
+
const { exitGracePeriod } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7773
8519
|
exitGracePeriod(project, type);
|
|
7774
8520
|
return jsonResponse({
|
|
7775
8521
|
success: true,
|
|
@@ -7781,7 +8527,7 @@ const getProjectSpecialistGraceRoute = HttpRouter.add("GET", "/api/specialists/:
|
|
|
7781
8527
|
const project = params["project"];
|
|
7782
8528
|
const type = params["type"];
|
|
7783
8529
|
if (!validateSpecialistAgentName(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
7784
|
-
const { getGracePeriodState } = yield* Effect.promise(() => import("./specialists-
|
|
8530
|
+
const { getGracePeriodState } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7785
8531
|
const state = getGracePeriodState(project, type);
|
|
7786
8532
|
if (state) return jsonResponse(state);
|
|
7787
8533
|
else return jsonResponse({ error: "No active grace period" }, { status: 404 });
|
|
@@ -7790,7 +8536,7 @@ const getProjectSpecialistContextRoute = HttpRouter.add("GET", "/api/specialists
|
|
|
7790
8536
|
const params = yield* HttpRouter.params;
|
|
7791
8537
|
const project = params["project"];
|
|
7792
8538
|
const type = params["type"];
|
|
7793
|
-
const { loadContextDigest } = yield* Effect.promise(() => import("./specialist-context-
|
|
8539
|
+
const { loadContextDigest } = yield* Effect.promise(() => import("./specialist-context-cVbGnTa3.js"));
|
|
7794
8540
|
const digest = loadContextDigest(project, type);
|
|
7795
8541
|
if (digest) return jsonResponse({ digest });
|
|
7796
8542
|
else return jsonResponse({ error: "No context digest found" }, { status: 404 });
|
|
@@ -7799,7 +8545,7 @@ const postProjectSpecialistContextRegenerateRoute = HttpRouter.add("POST", "/api
|
|
|
7799
8545
|
const params = yield* HttpRouter.params;
|
|
7800
8546
|
const project = params["project"];
|
|
7801
8547
|
const type = params["type"];
|
|
7802
|
-
const { regenerateContextDigest } = yield* Effect.promise(() => import("./specialist-context-
|
|
8548
|
+
const { regenerateContextDigest } = yield* Effect.promise(() => import("./specialist-context-cVbGnTa3.js"));
|
|
7803
8549
|
const digest = yield* Effect.promise(() => regenerateContextDigest(project, type));
|
|
7804
8550
|
if (digest) return jsonResponse({
|
|
7805
8551
|
digest,
|
|
@@ -7818,7 +8564,7 @@ const postProjectSpecialistCompleteRoute = HttpRouter.add("POST", "/api/speciali
|
|
|
7818
8564
|
"blocked"
|
|
7819
8565
|
].includes(status)) return jsonResponse({ error: "Valid status (passed/failed/blocked) is required" }, { status: 400 });
|
|
7820
8566
|
if (!validateSpecialistAgentName(type)) return jsonResponse({ error: "Invalid specialist type. Must be review-agent, test-agent, or merge-agent" }, { status: 400 });
|
|
7821
|
-
const { signalSpecialistCompletion } = yield* Effect.promise(() => import("./specialists-
|
|
8567
|
+
const { signalSpecialistCompletion } = yield* Effect.promise(() => import("./specialists-Tdezg_6N.js"));
|
|
7822
8568
|
signalSpecialistCompletion(project, type, {
|
|
7823
8569
|
status,
|
|
7824
8570
|
notes
|
|
@@ -7852,8 +8598,8 @@ const postProjectSpecialistLogsCleanupRoute = HttpRouter.add("POST", "/api/speci
|
|
|
7852
8598
|
const params = yield* HttpRouter.params;
|
|
7853
8599
|
const project = params["project"];
|
|
7854
8600
|
const type = params["type"];
|
|
7855
|
-
const { cleanupOldLogsSync } = yield* Effect.promise(() => import("./specialist-logs-
|
|
7856
|
-
const { getSpecialistRetention } = yield* Effect.promise(() => import("./projects-
|
|
8601
|
+
const { cleanupOldLogsSync } = yield* Effect.promise(() => import("./specialist-logs-Cl5-hqT8.js"));
|
|
8602
|
+
const { getSpecialistRetention } = yield* Effect.promise(() => import("./projects-B03Wr-xc.js"));
|
|
7857
8603
|
const retention = getSpecialistRetention(project);
|
|
7858
8604
|
const deleted = cleanupOldLogsSync(project, type, {
|
|
7859
8605
|
maxDays: retention.max_days,
|
|
@@ -7874,21 +8620,23 @@ const postProjectReviewRestartRoute = HttpRouter.add("POST", "/api/specialists/:
|
|
|
7874
8620
|
const project = params["project"];
|
|
7875
8621
|
const issueId = params["issueId"];
|
|
7876
8622
|
const { model, harness } = yield* readJsonBody;
|
|
7877
|
-
const { killAllReviewerSessions } = yield* Effect.promise(() => import("./review-agent-
|
|
8623
|
+
const { killAllReviewerSessions } = yield* Effect.promise(() => import("./review-agent-CD4RCI0Y.js"));
|
|
7878
8624
|
const killResult = yield* killAllReviewerSessions(project, issueId);
|
|
7879
8625
|
const projectConfig = resolveProjectFromIssueSync(issueId);
|
|
7880
8626
|
if (!projectConfig) return jsonResponse({ error: `Cannot resolve project for ${issueId}` }, { status: 404 });
|
|
7881
8627
|
const workspacePath = join(projectConfig.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
|
|
7882
8628
|
if (!existsSync(workspacePath)) return jsonResponse({ error: `Workspace not found: ${workspacePath}` }, { status: 404 });
|
|
7883
|
-
|
|
8629
|
+
const primaryRepo = resolveWorkspaceRepoRootsSync(issueId, workspacePath)[0];
|
|
8630
|
+
let branch = primaryRepo.sourceBranch;
|
|
7884
8631
|
try {
|
|
7885
|
-
const { stdout } = yield* Effect.promise(() => execAsync(
|
|
8632
|
+
const { stdout } = yield* Effect.promise(() => execAsync("git branch --show-current", {
|
|
8633
|
+
cwd: resolvePrimaryWorkspaceRepoDirSync(issueId, workspacePath),
|
|
7886
8634
|
encoding: "utf-8",
|
|
7887
8635
|
timeout: 5e3
|
|
7888
8636
|
}));
|
|
7889
|
-
branch = stdout.trim() ||
|
|
8637
|
+
branch = stdout.trim() || primaryRepo.sourceBranch;
|
|
7890
8638
|
} catch {}
|
|
7891
|
-
const { spawnReviewRoleForIssue } = yield* Effect.promise(() => import("./review-agent-
|
|
8639
|
+
const { spawnReviewRoleForIssue } = yield* Effect.promise(() => import("./review-agent-CD4RCI0Y.js"));
|
|
7892
8640
|
const prUrl = getReviewStatusSync(issueId)?.prUrl;
|
|
7893
8641
|
const result = yield* spawnReviewRoleForIssue({
|
|
7894
8642
|
issueId,
|
|
@@ -8037,6 +8785,6 @@ const specialistsProjectRouteLayer = Layer.mergeAll(getProjectSpecialistStatusRo
|
|
|
8037
8785
|
*/
|
|
8038
8786
|
const specialistsRouteLayer = Layer.mergeAll(specialistsLegacyRouteLayer, specialistsProjectRouteLayer);
|
|
8039
8787
|
//#endregion
|
|
8040
|
-
export {
|
|
8788
|
+
export { composerCommandConfirmationFromBody as $, resolveAllowedHarness as A, cleanupUnreferencedConversationAttachments as B, handleConversationCreate as C, isTrustedOriginForHost as Ct, handleConversationStop as D, getDefaultCwd as Dt, handleConversationResume as E, httpHandler as Et, tmuxSessionExists as F, isManagedConversationAttachmentPath as G, extractConversationAttachmentPaths as H, waitForPiTuiReady as I, composerCommandResultHttpStatus as J, removeConversationAttachment as K, waitForTmuxSession as L, spawnConversationSession as M, startConversationModelBackfill as N, handleConversationSwitchModel as O, jsonResponse as Ot, stopConversationRuntime as P, ComposerCommandConfirmationError as Q, cleanupConversationAttachments as R, conversationSessionAliveFromState as S, getHeaderFromMap as St, handleConversationRestartAll as T, validateOriginHeaders as Tt, getConversationAttachmentsRoot as U, ensureConversationAttachmentDir as V, hasConversationAttachment as W, resolvePolicy as X, handleComposerCommandMessage as Y, ComposerCommandParseError as Z, isPiControlChannelHarness as _, rejectUnauthorizedDashboardRequest as _t, agentsRouteLayer as a, panCliInvocation as at, validateConversationControlAckOrigin as b, isRespawnPending as bt, codexConversationPendingInput as c, resolveAcpTranscriptPath as ct, handleConversationCodexApproval as d, resolveCodexRolloutPath as dt, evaluateSpawnGuardrails as et, handleConversationCompact as f, resolveJsonlPath as ft, handleConversationThinkingLevel as g, hasDashboardInternalToken as gt, handleConversationPlanAction as h, dashboardSessionCookieHeader as ht, validateSpecialistAutoCompleteMetadata as i, getWorkAgentLifecycleStateSync as it, shouldReportUnresolvedLiveSession as j, isInsideGitWorkTree as k, jsonStringResponse as kt, deliverConversationViaControlChannel as l, resolveAgentHarness as lt, handleConversationDeliveryMethod as m, dashboardCsrfToken as mt, _serverManagedMerges as n, resolveAgentGitInfo as nt, saveAgentStateAndEmitEvent as o, spawnPanCli as ot, handleConversationControlAck as p, resolvePiSessionPath as pt, runInBatches as q, firePostMergeLifecycle as r, resolveConversationGitInfo as rt, saveAgentStateAndEmitEventProgram as s, readLauncherPinnedSessionId as st, specialistsRouteLayer as t, invalidateAgentsCache as tt, handleConversationAbort as u, resolveClaudeSessionId as ut, pickDeliverAs as v, rejectUnauthorizedDashboardSessionMintRequest as vt, handleConversationDelete as w, validateOrigin as wt, conversationNeedsRunningRepair as x, waitForSessionRespawn as xt, resolveConversationDeliveryMethod as y, rejectUnsafeDashboardMutationRequest as yt, cleanupOrphanedConversationAttachments as z };
|
|
8041
8789
|
|
|
8042
|
-
//# sourceMappingURL=specialists-
|
|
8790
|
+
//# sourceMappingURL=specialists-CNfYO3G2.js.map
|