@askexenow/exe-os 0.9.341 → 0.9.342
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/README.md +159 -196
- package/deploy/compose/.env.customer.example +1 -0
- package/deploy/compose/.env.example +1 -0
- package/deploy/compose/docker-compose.yml +13 -4
- package/deploy/compose/generate-env.ts +4 -0
- package/dist/{active-agent-AIQP4DFL.js → active-agent-PVGE57FY.js} +5 -5
- package/dist/{active-agent-LW45DSJ4.js → active-agent-TNIO6IY3.js} +5 -5
- package/dist/{agentic-ontology-RVUNRCQY.js → agentic-ontology-3FXYMHKW.js} +1 -1
- package/dist/{backfill-gate-J7UXFNXU.js → backfill-gate-65LSYVE5.js} +3 -3
- package/dist/{backfill-metadata-ZSDJ4O2T.js → backfill-metadata-ZSMZC45J.js} +8 -8
- package/dist/{background-jobs-STURKDCS.js → background-jobs-EXR5RVGG.js} +3 -3
- package/dist/{backup-verify-ZAJLEL4X.js → backup-verify-3Y2FHGZU.js} +4 -4
- package/dist/{behaviors-EO7KCP3H.js → behaviors-KYRB3NGJ.js} +9 -9
- package/dist/bin/age-ontology-load.js +3 -3
- package/dist/bin/agentic-ontology-backfill.js +10 -10
- package/dist/bin/agentic-reflection-backfill.js +11 -11
- package/dist/bin/agentic-semantic-label.js +10 -10
- package/dist/bin/backfill-conversations.js +10 -10
- package/dist/bin/backfill-responses.js +10 -10
- package/dist/bin/backfill-vectors.js +14 -14
- package/dist/bin/bulk-sync-postgres.js +19 -19
- package/dist/bin/cc-doctor.js +10 -8
- package/dist/bin/cleanup-stale-review-tasks.js +25 -23
- package/dist/bin/cli.js +79 -25
- package/dist/bin/customer-readiness.js +1 -1
- package/dist/bin/deferred-daemon-restart.js +98 -92
- package/dist/bin/exe-agent-config.js +9 -8
- package/dist/bin/exe-agent.js +17 -17
- package/dist/bin/exe-assign.js +12 -12
- package/dist/bin/exe-boot.js +200 -67
- package/dist/bin/exe-call.js +7 -7
- package/dist/bin/exe-cloud.js +20 -20
- package/dist/bin/exe-config-dump.js +9 -8
- package/dist/bin/exe-dispatch.js +25 -23
- package/dist/bin/exe-doctor.js +10 -6
- package/dist/bin/exe-export-behaviors.js +11 -11
- package/dist/bin/exe-forget.js +12 -10
- package/dist/bin/exe-gateway.js +15 -10
- package/dist/bin/exe-grant.js +5 -5
- package/dist/bin/exe-healthcheck.js +14 -8
- package/dist/bin/exe-heartbeat.js +28 -27
- package/dist/bin/exe-kill.js +30 -28
- package/dist/bin/exe-launch-agent.js +128 -67
- package/dist/bin/exe-memory-reads.js +257 -0
- package/dist/bin/exe-new-employee.js +12 -11
- package/dist/bin/exe-pending-messages.js +26 -24
- package/dist/bin/exe-pending-notifications.js +25 -23
- package/dist/bin/exe-pending-reviews.js +25 -23
- package/dist/bin/exe-rename.js +7 -7
- package/dist/bin/exe-review.js +29 -27
- package/dist/bin/exe-search.js +11 -9
- package/dist/bin/exe-session-cleanup.js +115 -85
- package/dist/bin/exe-settings.js +24 -23
- package/dist/bin/exe-start-codex.js +163 -41
- package/dist/bin/exe-start-opencode.js +15 -15
- package/dist/bin/exe-status.js +26 -24
- package/dist/bin/exe-support.js +5 -5
- package/dist/bin/exe-team.js +5 -5
- package/dist/bin/exe-timers.js +32 -213
- package/dist/bin/exe-watchdog.js +6 -5
- package/dist/bin/git-sweep.js +26 -24
- package/dist/bin/graph-backfill.js +11 -11
- package/dist/bin/graph-export.js +9 -9
- package/dist/bin/import-history.js +13 -13
- package/dist/bin/install.js +103 -97
- package/dist/bin/intercom-check.js +4 -4
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +6 -6
- package/dist/bin/postgres-agentic-reflection-backfill.js +5 -5
- package/dist/bin/postgres-agentic-semantic-backfill.js +7 -7
- package/dist/bin/pre-publish.js +5 -3
- package/dist/bin/reconcile-backlog.js +2 -2
- package/dist/bin/registry-proxy.js +1 -1
- package/dist/bin/scan-tasks.js +25 -23
- package/dist/bin/setup.js +6 -5
- package/dist/bin/shard-migrate.js +9 -9
- package/dist/bin/stack-update.js +6 -6
- package/dist/bin/update.js +1 -1
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/{boot-generation-GSMPJOWM.js → boot-generation-BL2ISK4U.js} +5 -5
- package/dist/boot-review-sections-DBMQJT5N.js +107 -0
- package/dist/branch-hygiene-TZWK6QCF.js +224 -0
- package/dist/{branding-JTEOF4ZV.js → branding-DVXBGVDH.js} +3 -3
- package/dist/{browser-session-store-CXQMOSEC.js → browser-session-store-B2NR3LIX.js} +2 -1
- package/dist/{capability-cards-OBYQNAKZ.js → capability-cards-DN5UIKVN.js} +4 -4
- package/dist/{capacity-monitor-MG3FTUD5.js → capacity-monitor-ZG5GGFR2.js} +26 -24
- package/dist/{catchup-brief-BVJOF3GL.js → catchup-brief-D6HH6DWS.js} +31 -28
- package/dist/{chunk-Q5AIPSSC.js → chunk-25X4JD2V.js} +10 -6
- package/dist/{chunk-6MVI4QH2.js → chunk-2KZNGDSW.js} +1 -1
- package/dist/{chunk-WH7XN5ER.js → chunk-2WAVZ5UJ.js} +1 -1
- package/dist/{chunk-PTJBWC77.js → chunk-2ZYO73KO.js} +4 -3
- package/dist/{chunk-CLAYNAXC.js → chunk-3EUMUSLE.js} +1 -1
- package/dist/{chunk-BVV6NHKQ.js → chunk-3SW4OEHB.js} +5 -5
- package/dist/{task-enforcement-X5QVL6RE.js → chunk-4CMVFVFC.js} +173 -69
- package/dist/{chunk-2YCFNBC4.js → chunk-4J4PMPXZ.js} +3 -2
- package/dist/{chunk-EDOO23B2.js → chunk-4N2NRGCM.js} +2 -2
- package/dist/chunk-4QCFFW2H.js +378 -0
- package/dist/{chunk-6MVC43X7.js → chunk-4VSV5P4D.js} +2 -2
- package/dist/{chunk-HJX6NCJF.js → chunk-4ZCD2UWW.js} +39 -10
- package/dist/{chunk-C445WRUX.js → chunk-5ERDIOV3.js} +2 -2
- package/dist/chunk-5H47VHB7.js +30 -0
- package/dist/{chunk-BJ23BNED.js → chunk-5TY4FPH6.js} +1 -1
- package/dist/{chunk-WD55PEBM.js → chunk-6CH3TPHR.js} +3 -3
- package/dist/{chunk-TIXTHUVJ.js → chunk-6WQ3NNCE.js} +3 -3
- package/dist/{chunk-7LF5DS3A.js → chunk-6XWTQUO4.js} +1 -1
- package/dist/chunk-76CJBM36.js +88 -0
- package/dist/{chunk-NFBW7N4D.js → chunk-7CTRGNLW.js} +2 -2
- package/dist/{chunk-ITMEE7PQ.js → chunk-7V4JADD6.js} +3 -3
- package/dist/{chunk-RMOBQ6A5.js → chunk-AD2VCHSS.js} +1 -1
- package/dist/{chunk-DNVFWFYF.js → chunk-AJYCFKJR.js} +1 -1
- package/dist/chunk-AM7S2TY6.js +54 -0
- package/dist/{chunk-RWSLVYTE.js → chunk-AOHXREB7.js} +295 -67
- package/dist/{chunk-DGGDUKH6.js → chunk-ASAFVDVR.js} +1 -1
- package/dist/{chunk-NTI22F3R.js → chunk-BUCXNV32.js} +1 -1
- package/dist/{chunk-SHIICYJW.js → chunk-BYTDMAGB.js} +4 -2
- package/dist/{chunk-32SXNM3G.js → chunk-C5QAPURN.js} +1 -1
- package/dist/{chunk-BMHQPIJ2.js → chunk-CE7F6RHG.js} +585 -75
- package/dist/{chunk-YWQMWFYR.js → chunk-CNVBKDEY.js} +21 -15
- package/dist/{chunk-KPIN44GZ.js → chunk-CWXVH7WV.js} +1 -1
- package/dist/chunk-D74XYSA3.js +621 -0
- package/dist/{chunk-A47MXY2I.js → chunk-EQHQF5IM.js} +50 -32
- package/dist/{chunk-YHUNDGVV.js → chunk-EUS4QUKP.js} +1 -1
- package/dist/{chunk-6D2PI4QD.js → chunk-EV46QTD3.js} +1 -1
- package/dist/{chunk-N7A5D25S.js → chunk-F27XXN6C.js} +1 -1
- package/dist/{chunk-XQNNB5GY.js → chunk-F55P3H4S.js} +37 -2
- package/dist/{chunk-MWZFF3Q7.js → chunk-F5O7V7UK.js} +1 -1
- package/dist/{chunk-MC4ATFJV.js → chunk-FPFPLPUY.js} +6 -6
- package/dist/{chunk-UU4UINUX.js → chunk-G4RGKBCA.js} +2 -2
- package/dist/{chunk-HAZO7TRD.js → chunk-G5T6KDG4.js} +1 -1
- package/dist/{chunk-TWXZM34M.js → chunk-GBTTBXAF.js} +6 -6
- package/dist/{chunk-LA2Z6RMS.js → chunk-GDIJE6D7.js} +1 -1
- package/dist/{chunk-4QSJVMMT.js → chunk-GG5NDQNN.js} +2 -2
- package/dist/{chunk-6BQG7EKO.js → chunk-GJ26DULE.js} +2 -2
- package/dist/chunk-GL57PO3K.js +104 -0
- package/dist/chunk-GWDSB25T.js +6 -0
- package/dist/{chunk-HSYJ6DZ2.js → chunk-H6BV5TKD.js} +39 -24
- package/dist/{chunk-HCJCW7X4.js → chunk-H7I47RS5.js} +34 -1
- package/dist/{chunk-GFDGDFBF.js → chunk-HA5R6USD.js} +22 -5
- package/dist/{chunk-L2YGXJGF.js → chunk-HAF2DJYV.js} +3 -3
- package/dist/chunk-HJ447YER.js +224 -0
- package/dist/{chunk-6QW6JHRE.js → chunk-HV4KESRY.js} +59 -32
- package/dist/{chunk-BJOBR6P2.js → chunk-I26FWCSP.js} +216 -9
- package/dist/{chunk-X2FHTDIU.js → chunk-IBYL4DHM.js} +1 -1
- package/dist/{chunk-JCBKARSK.js → chunk-IOEUAQWP.js} +1 -1
- package/dist/{chunk-2UGGBIDL.js → chunk-JGIPOUIK.js} +3 -3
- package/dist/{chunk-LLU6WZLK.js → chunk-JLZ4RYSD.js} +2 -2
- package/dist/{chunk-WWNQFOSP.js → chunk-JMYHW3AL.js} +2 -2
- package/dist/{chunk-KP4PY2Z2.js → chunk-JPUZPAAF.js} +4 -4
- package/dist/{chunk-4LWV633D.js → chunk-JTBIS4R5.js} +1 -1
- package/dist/{chunk-PPZOWQHP.js → chunk-K7KFGDWF.js} +1 -1
- package/dist/{chunk-HNLXMD2V.js → chunk-KGWRTRKC.js} +2 -2
- package/dist/{chunk-IB336P52.js → chunk-KP3U5QGJ.js} +1 -1
- package/dist/{chunk-OUEFW4RK.js → chunk-KW2SD2FL.js} +2 -2
- package/dist/{chunk-2P4WJNN5.js → chunk-KWZMQACA.js} +11 -7
- package/dist/{chunk-ATKW3SYL.js → chunk-L2R3LN2P.js} +1 -1
- package/dist/{chunk-IELUDZAA.js → chunk-L4A5DL6Z.js} +3 -3
- package/dist/{chunk-2C455MU3.js → chunk-LU2FALL6.js} +3 -3
- package/dist/{chunk-LOBCQXV5.js → chunk-MKYFAKDW.js} +4 -4
- package/dist/{chunk-3BRVLPPA.js → chunk-MOPUCPXK.js} +4 -0
- package/dist/{chunk-BR4423AS.js → chunk-MR6LHP4F.js} +1 -1
- package/dist/chunk-MVYB76QG.js +341 -0
- package/dist/{chunk-ZNE6H2JO.js → chunk-MZM6EJCU.js} +4 -4
- package/dist/{chunk-FOV57K47.js → chunk-N7QJKQMX.js} +258 -14
- package/dist/{chunk-AYLNJGCS.js → chunk-NBZL5CGA.js} +93 -12
- package/dist/{chunk-YLQXP7T7.js → chunk-NN2B2QKU.js} +1 -1
- package/dist/chunk-NX5INHHG.js +40 -0
- package/dist/{chunk-B75BOKEI.js → chunk-NXUSDL37.js} +2 -2
- package/dist/{chunk-TPHCZDE3.js → chunk-O5V57XYE.js} +1 -1
- package/dist/chunk-O7LWR36Z.js +269 -0
- package/dist/{chunk-BV6GBSRP.js → chunk-OLMQ4UOF.js} +42 -10
- package/dist/{chunk-UIU2DGRV.js → chunk-OTF44GXL.js} +4 -4
- package/dist/{chunk-GOGSWXNZ.js → chunk-OZEBAGKR.js} +277 -137
- package/dist/{chunk-NDSNM5OH.js → chunk-P5HIWY2E.js} +1 -1
- package/dist/{chunk-MJB5ZFQM.js → chunk-PDWS3E22.js} +55 -4
- package/dist/{chunk-4FJZ6SO7.js → chunk-PPCDBE6Z.js} +1 -1
- package/dist/{chunk-7SEC2AG5.js → chunk-PQIDGXSG.js} +13 -4
- package/dist/chunk-PWUFMX75.js +186 -0
- package/dist/{chunk-GPW32HVB.js → chunk-QDGZJ653.js} +3 -3
- package/dist/{chunk-CYA5S5OD.js → chunk-QOO5RW3K.js} +6 -5
- package/dist/{chunk-IXBIVKWZ.js → chunk-QQ4E2RYW.js} +95 -18
- package/dist/{chunk-2WMTTIAZ.js → chunk-QRYVCDWS.js} +2 -2
- package/dist/{chunk-Z42MXYWW.js → chunk-QWVXN224.js} +110 -28
- package/dist/{chunk-XSMRR4IW.js → chunk-QYZJHTNE.js} +26 -27
- package/dist/{chunk-I7ECEP3W.js → chunk-R2NN3JKH.js} +43 -6
- package/dist/{chunk-B7CUBLF7.js → chunk-RACAOE2Z.js} +13 -13
- package/dist/{chunk-5RACW3LX.js → chunk-RAXVPNMR.js} +1 -1
- package/dist/{chunk-CMR64RYM.js → chunk-RHWZUUS4.js} +17 -17
- package/dist/{chunk-RNAYCUNM.js → chunk-S3THSOWV.js} +1 -1
- package/dist/{chunk-U2MREVXQ.js → chunk-S7QUM2UK.js} +2 -2
- package/dist/{chunk-SSTLTIF3.js → chunk-SKGMF2SO.js} +25 -2
- package/dist/{chunk-J6SEDDOR.js → chunk-SQKXKV2Y.js} +2 -2
- package/dist/{chunk-DPFQ2WQX.js → chunk-TLT7NZCW.js} +4 -4
- package/dist/chunk-TTCUG2CF.js +91 -0
- package/dist/{chunk-W6K4XB6G.js → chunk-UEA3LXOB.js} +1 -1
- package/dist/{chunk-WNKVKNOM.js → chunk-UNXQBELK.js} +1 -1
- package/dist/{chunk-KKOLHBNC.js → chunk-UP75Z5X7.js} +904 -167
- package/dist/{chunk-Y3S4H77G.js → chunk-USSB56WK.js} +1 -1
- package/dist/{chunk-PVIH3ZGV.js → chunk-UUEKJDK6.js} +90 -10
- package/dist/{chunk-T2PYVVZ5.js → chunk-UUQBZPJJ.js} +1 -1
- package/dist/{chunk-32YHCHWW.js → chunk-V3EEVY4L.js} +1 -1
- package/dist/{chunk-2IWBY7XK.js → chunk-VPZHJCKW.js} +2 -2
- package/dist/chunk-VRAQTFD6.js +265 -0
- package/dist/{chunk-EDH54E5A.js → chunk-VSRPS3J7.js} +14 -14
- package/dist/{chunk-5ZNY7IZI.js → chunk-WMESXBJM.js} +37 -3
- package/dist/{chunk-54QCG45Y.js → chunk-WOYADZF5.js} +56 -5
- package/dist/{chunk-7Y5UDEVM.js → chunk-WZHZCDDO.js} +6 -5
- package/dist/{chunk-3NGZ4PL7.js → chunk-X2Q5NLUL.js} +11 -2
- package/dist/{chunk-CCIEIRV2.js → chunk-X33NYQYJ.js} +2 -2
- package/dist/{chunk-K6KRBXQP.js → chunk-XHK3FS3W.js} +3 -2
- package/dist/{chunk-AP455LBW.js → chunk-XZXBB3TN.js} +2 -2
- package/dist/{chunk-JSKBHUR7.js → chunk-YCANDMI2.js} +2 -2
- package/dist/{chunk-YIIME2OW.js → chunk-YLXTKI6M.js} +1 -1
- package/dist/{chunk-LEJ25726.js → chunk-YTCFACP4.js} +650 -434
- package/dist/{chunk-HUSVERE6.js → chunk-Z6RSN7KS.js} +7 -6
- package/dist/{cleanup-graph-garbage-MXQ4Q2MA.js → cleanup-graph-garbage-XWUFAMFO.js} +8 -8
- package/dist/{co-activation-QI5BK4RT.js → co-activation-ZCHPLLP6.js} +4 -4
- package/dist/{co-occurrence-BYSQNZSV.js → co-occurrence-KG3LKALN.js} +6 -6
- package/dist/{code-context-index-BNBHDXHW.js → code-context-index-WSOJQ72R.js} +5 -5
- package/dist/{content-extractor-JRJDNIHP.js → content-extractor-NXYNEF5K.js} +2 -2
- package/dist/{conversation-entity-extractor-FPAMTL3C.js → conversation-entity-extractor-D3EFTLT4.js} +2 -2
- package/dist/{conversation-wiki-populator-WU4HEQ7C.js → conversation-wiki-populator-WQN3IUU6.js} +1 -1
- package/dist/{crdt-sync-ETPKNBCU.js → crdt-sync-4PFGPZXV.js} +8 -1
- package/dist/{crm-webhook-M566ZMZS.js → crm-webhook-II7Z45Q6.js} +2 -2
- package/dist/cto-delegation-gate-JWWOJPNC.js +669 -0
- package/dist/{daemon-auth-7IFSV5FG.js → daemon-auth-3FEAHFWC.js} +5 -3
- package/dist/{daemon-orchestration-XV5GN73R.js → daemon-orchestration-FX4XZDR5.js} +45 -26
- package/dist/{daemon-ready-RKKB4P6K.js → daemon-ready-4JTSFKAY.js} +1 -1
- package/dist/{daemon-ready-signal-WKEJQNRA.js → daemon-ready-signal-LPAZWQOV.js} +3 -1
- package/dist/daemon-restart-circuit-breaker-PEGEIP6H.js +35 -0
- package/dist/daemon-timer-report-NM44WQRH.js +25 -0
- package/dist/{db-backup-MX2G3CEK.js → db-backup-W2QFSYQC.js} +15 -5
- package/dist/{db-restore-events-JVEEP52Z.js → db-restore-events-MQ2DBGEQ.js} +2 -2
- package/dist/dispatch-ack-VYH3ONSS.js +27 -0
- package/dist/{doc-graph-extractor-LR5KMPH7.js → doc-graph-extractor-F6ODFIID.js} +6 -6
- package/dist/{documents-FA6N7QDA.js → documents-23WX2FPQ.js} +12 -12
- package/dist/dreaming-NWD22UQ5.js +46 -0
- package/dist/{exe-drift-TUKTCXZE.js → exe-drift-CW72FBGE.js} +5 -5
- package/dist/{exe-export-ZLHBXMZC.js → exe-export-AUJ7CV7G.js} +11 -11
- package/dist/{exe-import-VVKBZWSA.js → exe-import-JX4I52VE.js} +11 -11
- package/dist/{exe-key-QJXFBF6G.js → exe-key-2N6LY2BU.js} +242 -228
- package/dist/{exe-org-BGZNNE4H.js → exe-org-X4CSNCKS.js} +3 -3
- package/dist/{exe-snapshot-JRLUO645.js → exe-snapshot-XZ7FVCYZ.js} +30 -28
- package/dist/{fast-db-init-JKJEEHUI.js → fast-db-init-4CWHSOOR.js} +1 -1
- package/dist/{founder-context-HWPLMZVR.js → founder-context-7L3CFPYN.js} +4 -4
- package/dist/gateway/index.js +25 -25
- package/dist/{gateway-client-GRBOJQYC.js → gateway-client-7LMZKHTH.js} +1 -1
- package/dist/git-main-guard-UZP3KXYI.js +39 -0
- package/dist/{git-staleness-X5XZONX3.js → git-staleness-CI2R4QOJ.js} +4 -4
- package/dist/{global-procedures-VIIVWB6R.js → global-procedures-XQX3LUH6.js} +6 -6
- package/dist/{graph-auto-extract-HCQQF5AG.js → graph-auto-extract-OURWMGBS.js} +6 -6
- package/dist/{graph-rag-WAK2BRJH.js → graph-rag-JZZAB7PC.js} +2 -2
- package/dist/{hook-integrity-WURH6DS3.js → hook-integrity-XY47IM7G.js} +1 -1
- package/dist/hook-prefetch-PHRRKY4C.js +137 -0
- package/dist/hooks/bug-report-worker.js +31 -27
- package/dist/hooks/codex-stop-task-finalizer.js +31 -27
- package/dist/hooks/commit-complete.js +28 -26
- package/dist/hooks/error-recall.js +12 -11
- package/dist/hooks/exe-heartbeat-hook.js +6 -6
- package/dist/hooks/ingest-worker.js +11 -11
- package/dist/hooks/ingest.js +18 -18
- package/dist/hooks/instructions-loaded.js +7 -7
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +7 -7
- package/dist/hooks/post-compact.js +27 -25
- package/dist/hooks/post-tool-combined.js +12 -12
- package/dist/hooks/pre-compact.js +28 -26
- package/dist/hooks/pre-tool-use.js +179 -46
- package/dist/hooks/prompt-submit.js +323 -272
- package/dist/hooks/session-end.js +34 -32
- package/dist/hooks/session-start.js +28 -21
- package/dist/hooks/stop.js +34 -32
- package/dist/hooks/subagent-stop.js +27 -25
- package/dist/hooks/summary-worker.js +35 -33
- package/dist/index.js +40 -38
- package/dist/{installer-6IFVEQI4.js → installer-G3JAO3NT.js} +9 -9
- package/dist/{installer-NX2CLNV5.js → installer-JND3RJ6Q.js} +9 -9
- package/dist/{installer-T2LGHZKL.js → installer-L7EVH5U5.js} +9 -9
- package/dist/{intercom-queue-KYHXXZCQ.js → intercom-queue-ZFEQALR3.js} +24 -22
- package/dist/{key-backup-status-TNEHXA2X.js → key-backup-status-LOSMVATJ.js} +2 -2
- package/dist/lib/agent-config.js +4 -3
- package/dist/lib/cloud-sync.js +19 -19
- package/dist/lib/config.js +2 -2
- package/dist/lib/consolidation.js +11 -11
- package/dist/lib/crypto.js +3 -3
- package/dist/lib/database.js +6 -4
- package/dist/lib/db-daemon-client.js +5 -5
- package/dist/lib/db-read-worker-client.js +9 -3
- package/dist/lib/db.js +6 -4
- package/dist/lib/device-registry.js +3 -3
- package/dist/lib/embed-worker.js +2 -2
- package/dist/lib/embedder.js +5 -5
- package/dist/lib/employee-templates.js +7 -7
- package/dist/lib/employees.js +10 -4
- package/dist/lib/exe-daemon-client.js +4 -4
- package/dist/lib/exe-daemon.js +588 -164
- package/dist/lib/hybrid-search.js +11 -9
- package/dist/lib/identity.js +4 -4
- package/dist/lib/keychain.js +1 -1
- package/dist/lib/license.js +4 -4
- package/dist/lib/messaging.js +27 -23
- package/dist/lib/post-tool-memory.js +3 -3
- package/dist/lib/registry-proxy.js +1 -1
- package/dist/lib/reminders.js +15 -7
- package/dist/lib/schedules.js +9 -9
- package/dist/lib/session-registry.js +6 -6
- package/dist/lib/skill-learning.js +10 -10
- package/dist/lib/status-brief.js +4 -4
- package/dist/lib/store.js +8 -8
- package/dist/lib/task-router.js +5 -5
- package/dist/lib/tasks.js +28 -24
- package/dist/lib/tmux-routing.js +55 -24
- package/dist/lib/tmux-status.js +9 -3
- package/dist/lib/tmux-transport.js +1 -1
- package/dist/lib/token-spend.js +5 -5
- package/dist/lib/transport.js +2 -2
- package/dist/lib/ws-client.js +1 -1
- package/dist/{license-gate-MGDR4YNI.js → license-gate-QTRQHV4F.js} +5 -5
- package/dist/{license-sync-UWE6GEB4.js → license-sync-N3UJFWAW.js} +4 -4
- package/dist/mcp/register-tools.js +97 -91
- package/dist/mcp/server.js +99 -93
- package/dist/mcp/tools/complete-reminder.js +6 -6
- package/dist/mcp/tools/create-reminder.js +6 -6
- package/dist/mcp/tools/create-task.js +36 -27
- package/dist/mcp/tools/deactivate-behavior.js +11 -11
- package/dist/mcp/tools/list-reminders.js +6 -6
- package/dist/mcp/tools/list-tasks.js +34 -28
- package/dist/mcp/tools/send-message.js +27 -25
- package/dist/mcp/tools/update-task.js +33 -27
- package/dist/{mcp-http-config-RQLYEPTL.js → mcp-http-config-BDL36JZ3.js} +6 -6
- package/dist/{mcp-port-config-FFAMMLLE.js → mcp-port-config-6HYY6J7K.js} +2 -2
- package/dist/mcp-session-identity-T7H2EKFQ.js +177 -0
- package/dist/{memory-cards-VYQ5DPMR.js → memory-cards-ZRDW7QBX.js} +8 -8
- package/dist/{memory-graph-extractor-GX2HNYLU.js → memory-graph-extractor-QLXDMHRS.js} +7 -7
- package/dist/{memory-poisoning-defense-TX7627BD.js → memory-poisoning-defense-HJTXYCWH.js} +4 -4
- package/dist/{memory-pressure-watchdog-MLNNH26B.js → memory-pressure-watchdog-HN5X7AVN.js} +75 -36
- package/dist/{memory-queue-X2CSEAKE.js → memory-queue-2UOOF27L.js} +5 -3
- package/dist/{memory-queue-client-YRL6XTGU.js → memory-queue-client-O5U6F6XP.js} +6 -6
- package/dist/{memory-reflection-KIGEFSI4.js → memory-reflection-WVNFBJAA.js} +4 -4
- package/dist/{monitor-grants-RZOVSYVO.js → monitor-grants-E3ELDEWD.js} +5 -5
- package/dist/{monitor-identity-MOXISYNG.js → monitor-identity-GLFZSEAH.js} +2 -2
- package/dist/{notification-ledger-B6AVEGMV.js → notification-ledger-SZEPGJQ7.js} +25 -23
- package/dist/{notifications-DWXV7SVL.js → notifications-4UT53CDG.js} +24 -22
- package/dist/{orchestration-events-ZG7O4HRY.js → orchestration-events-WV4NWKZH.js} +5 -5
- package/dist/{orchestration-phase-CXRCBCK7.js → orchestration-phase-AWBXPO52.js} +3 -3
- package/dist/orchestrator-UAC3RW2T.js +47 -0
- package/dist/{pipeline-router-RTLAGZTA.js → pipeline-router-LM53NMWJ.js} +5 -5
- package/dist/{plan-limits-WLQZTCSF.js → plan-limits-2FEY2GOS.js} +7 -7
- package/dist/platform-procedures-X5DFJFV7.js +13 -0
- package/dist/{preferences-TYTGDXQZ.js → preferences-TWIXZBKS.js} +2 -2
- package/dist/{project-boot-6CGQ3EAH.js → project-boot-4NUH5FRU.js} +2 -2
- package/dist/{projection-worker-44SEKTZ5.js → projection-worker-FZ7YSN3G.js} +5 -5
- package/dist/{prospective-memory-UACFTYXK.js → prospective-memory-6D2ASWM3.js} +4 -4
- package/dist/{push-notifications-W5JRXLKJ.js → push-notifications-U6FIBQRW.js} +3 -3
- package/dist/{reranker-NL4YAV6R.js → reranker-GYYRPANK.js} +3 -3
- package/dist/{retrieval-health-4C2PO6HH.js → retrieval-health-4Z242P3B.js} +1 -1
- package/dist/{review-polling-W5AMHNLT.js → review-polling-HXAFJZDA.js} +25 -23
- package/dist/runtime/index.js +35 -33
- package/dist/{session-events-PGL5GJEB.js → session-events-O3BV56ZX.js} +25 -23
- package/dist/{session-kill-telemetry-6YDGEF27.js → session-kill-telemetry-AELE4JDK.js} +25 -23
- package/dist/session-mcp-config-YKNXG5DW.js +50 -0
- package/dist/{session-scope-3MEOO557.js → session-scope-5EAPUT45.js} +24 -22
- package/dist/setup-wizard-NB6R4QVS.js +14 -0
- package/dist/{shard-manager-MBWQEYNG.js → shard-manager-35PWFR3B.js} +3 -3
- package/dist/{skill-refinement-EOROTBPX.js → skill-refinement-DVSYXBBP.js} +5 -5
- package/dist/{stack-release-PR2XKJ4Q.js → stack-release-HGFFFCGC.js} +90 -15
- package/dist/{stack-update-LMDM27ZW.js → stack-update-ATCJFOEK.js} +5 -5
- package/dist/{steward-gate-4A2XHYFD.js → steward-gate-3GQ5XKMJ.js} +5 -5
- package/dist/{support-inbox-Z77ACQUY.js → support-inbox-4L62P4EP.js} +7 -6
- package/dist/{support-outbox-GB5SQFRJ.js → support-outbox-WHGPUYL2.js} +2 -2
- package/dist/task-enforcement-IPIZX2MM.js +90 -0
- package/dist/{task-scope-EKYDCVUF.js → task-scope-FOIW25HR.js} +26 -22
- package/dist/{tasks-crud-6LBNU43G.js → tasks-crud-HBDKE6C5.js} +34 -22
- package/dist/tasks-notify-G2U2U2YA.js +53 -0
- package/dist/{tasks-review-PBIUYXAL.js → tasks-review-27SFX5XN.js} +26 -22
- package/dist/{telemetry-upload-WQDFABTF.js → telemetry-upload-ZOXHRWR5.js} +9 -9
- package/dist/tmux-command-guard-KSJKIX3C.js +117 -0
- package/dist/{token-budget-KWGL5DY7.js → token-budget-5Y4YPDO3.js} +5 -5
- package/dist/{tool-capability-index-EH3HQVHU.js → tool-capability-index-VYF5GNJ2.js} +1 -1
- package/dist/{tool-telemetry-UC55LSIH.js → tool-telemetry-KBXSBDTK.js} +1 -1
- package/dist/tui/App.js +39 -37
- package/dist/{tui-data-M3RBSJL3.js → tui-data-NLFMBIQI.js} +24 -22
- package/dist/{update-check-HFO4VHO4.js → update-check-3FHAWIG2.js} +7 -3
- package/dist/{update-support-VPBD5SD2.js → update-support-UVUSZG7R.js} +93 -93
- package/dist/{whatsapp-accounts-BWRZUY23.js → whatsapp-accounts-BFIOXYW5.js} +1 -1
- package/dist/{whatsapp-config-GOSELKTE.js → whatsapp-config-FAX6EA5K.js} +20 -13
- package/dist/{worker-gate-4QLLMXZM.js → worker-gate-3KUBAU32.js} +3 -3
- package/dist/{workflow-engine-MMEHKUN4.js → workflow-engine-YITHXZR5.js} +2 -2
- package/dist/{working-memory-PY4AG577.js → working-memory-NUVB5SFV.js} +1 -1
- package/dist/worktree-LL62PLQB.js +47 -0
- package/dist/{worktree-sweep-5WKBU7E6.js → worktree-sweep-WTK3MTKH.js} +7 -7
- package/package.json +3 -2
- package/release-notes.json +75 -43
- package/dist/branch-hygiene-R5NVTRAY.js +0 -138
- package/dist/chunk-7YORGTXC.js +0 -138
- package/dist/chunk-CCPHEPLU.js +0 -30
- package/dist/chunk-HMP5VT6A.js +0 -118
- package/dist/chunk-PVYR4FCQ.js +0 -113
- package/dist/chunk-RP5GETX5.js +0 -140
- package/dist/chunk-YGAAZN3E.js +0 -47
- package/dist/cto-delegation-gate-S734XDXT.js +0 -290
- package/dist/dispatch-ack-4S44HBWB.js +0 -15
- package/dist/dreaming-UKGTQT6I.js +0 -44
- package/dist/orchestrator-PGHJDUUT.js +0 -45
- package/dist/setup-wizard-CJIYDSSP.js +0 -13
- package/dist/tasks-notify-TFJLSQ3B.js +0 -50
- package/dist/worktree-YXBDRYOC.js +0 -31
- package/dist/{chunk-7UMCQQWS.js → chunk-A4DVMPYB.js} +3 -3
- /package/dist/{chunk-2KLAYDFB.js → chunk-GIBYNT6W.js} +0 -0
- /package/dist/{chunk-MC6VPZKS.js → chunk-JRM4TAGS.js} +0 -0
- /package/dist/{chunk-3NCZKWPO.js → chunk-MGGOSFCR.js} +0 -0
- /package/dist/{chunk-C2SRRCRK.js → chunk-QIFYLIUF.js} +0 -0
- /package/dist/{chunk-OADURIIN.js → chunk-WTH4CSAP.js} +0 -0
- /package/dist/{core-memory-3IBWM4WR.js → core-memory-GAC6EWOQ.js} +0 -0
- /package/dist/{entity-boost-DWAWXFKN.js → entity-boost-NT6UO2Z3.js} +0 -0
- /package/dist/{message-queue-client-3PTHPG5Q.js → message-queue-client-4EOQRUXW.js} +0 -0
- /package/dist/{oauth-server-M5TGXT6D.js → oauth-server-67YBDP32.js} +0 -0
- /package/dist/{webhook-pipe-FZYLO6RR.js → webhook-pipe-LEXMUQ5B.js} +0 -0
- /package/dist/{wiki-acl-7CROE3MJ.js → wiki-acl-74BLWG6J.js} +0 -0
- /package/dist/{wiki-client-VNDOBK63.js → wiki-client-EAN7F5LV.js} +0 -0
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
readBreakerAlert,
|
|
3
|
+
recordDaemonRestart,
|
|
4
|
+
restartBootsInWindow,
|
|
5
|
+
restartBreakerAlertPath,
|
|
6
|
+
writeDaemonExitBreadcrumb
|
|
7
|
+
} from "../chunk-HJ447YER.js";
|
|
5
8
|
import {
|
|
6
9
|
pushNotifyAsync
|
|
7
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-3SW4OEHB.js";
|
|
11
|
+
import {
|
|
12
|
+
clearDaemonReady,
|
|
13
|
+
eventLoopHeartbeatPath,
|
|
14
|
+
writeDaemonReady
|
|
15
|
+
} from "../chunk-MOPUCPXK.js";
|
|
8
16
|
import {
|
|
9
17
|
getMcpToolFamily,
|
|
10
18
|
inferMcpRuntime,
|
|
11
19
|
recordMcpHttpEvent
|
|
12
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-RAXVPNMR.js";
|
|
13
21
|
import {
|
|
14
22
|
deserializeArgs,
|
|
15
23
|
serializeResultSet
|
|
@@ -21,8 +29,11 @@ import {
|
|
|
21
29
|
findScopedDuplicate,
|
|
22
30
|
governMemoryRecord,
|
|
23
31
|
schedulePostWriteMemoryHygiene
|
|
24
|
-
} from "../chunk-
|
|
25
|
-
import "../chunk-
|
|
32
|
+
} from "../chunk-6XWTQUO4.js";
|
|
33
|
+
import "../chunk-4QCFFW2H.js";
|
|
34
|
+
import {
|
|
35
|
+
BUSY_PATTERN
|
|
36
|
+
} from "../chunk-GWDSB25T.js";
|
|
26
37
|
import {
|
|
27
38
|
attributeSignalSource,
|
|
28
39
|
consumeRestartIntentDetail,
|
|
@@ -30,10 +41,11 @@ import {
|
|
|
30
41
|
requestRestart
|
|
31
42
|
} from "../chunk-AFNRE2RV.js";
|
|
32
43
|
import {
|
|
44
|
+
assessInitialBindIdentity,
|
|
33
45
|
ensureDaemonToken,
|
|
34
46
|
reconcileSessionAgentIdentity,
|
|
35
47
|
shouldEnforceSessionIdentity
|
|
36
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-X2Q5NLUL.js";
|
|
37
49
|
import {
|
|
38
50
|
DAEMON_RSS_RESTART_DEBOUNCE,
|
|
39
51
|
DAEMON_RSS_STARTUP_GRACE_MS,
|
|
@@ -70,8 +82,8 @@ import {
|
|
|
70
82
|
EXE_AI_DIR,
|
|
71
83
|
MODELS_DIR,
|
|
72
84
|
resolveEmbedModelFile
|
|
73
|
-
} from "../chunk-
|
|
74
|
-
import "../chunk-
|
|
85
|
+
} from "../chunk-WZHZCDDO.js";
|
|
86
|
+
import "../chunk-BYTDMAGB.js";
|
|
75
87
|
import "../chunk-MLKGABMK.js";
|
|
76
88
|
|
|
77
89
|
// src/lib/exe-daemon.ts
|
|
@@ -79,11 +91,41 @@ import os2 from "os";
|
|
|
79
91
|
import net from "net";
|
|
80
92
|
import v8 from "v8";
|
|
81
93
|
import { createServer as createHttpServer, request as httpRequest } from "http";
|
|
82
|
-
import { randomUUID } from "crypto";
|
|
94
|
+
import { randomUUID, timingSafeEqual } from "crypto";
|
|
83
95
|
import { writeFileSync as writeFileSync3, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2, existsSync as existsSync4, readFileSync as readFileSync4, chmodSync, readdirSync, renameSync, statSync } from "fs";
|
|
84
96
|
import { writeFile } from "fs/promises";
|
|
85
97
|
import { execSync as execSyncNode, execFile as execFileNode } from "child_process";
|
|
86
98
|
import { promisify } from "util";
|
|
99
|
+
|
|
100
|
+
// src/lib/coo-respawn.ts
|
|
101
|
+
var NPM_ROOT_RETRY_MS = (() => {
|
|
102
|
+
const raw = process.env.EXE_NPM_ROOT_RETRY_MS;
|
|
103
|
+
const n = raw !== void 0 ? Number(raw) : NaN;
|
|
104
|
+
return Number.isFinite(n) && n >= 0 ? n : 5 * 6e4;
|
|
105
|
+
})();
|
|
106
|
+
function createMemoizedNpmGlobalRootResolver(execFile, log = (m) => void process.stderr.write(m), opts = {}) {
|
|
107
|
+
const retryMs = opts.retryMs ?? NPM_ROOT_RETRY_MS;
|
|
108
|
+
const now = opts.now ?? (() => Date.now());
|
|
109
|
+
let memo = null;
|
|
110
|
+
let failedAt = null;
|
|
111
|
+
return async () => {
|
|
112
|
+
if (memo !== null) return memo;
|
|
113
|
+
if (failedAt !== null && now() - failedAt < retryMs) return null;
|
|
114
|
+
try {
|
|
115
|
+
const { stdout } = await execFile("npm", ["root", "-g"], { timeout: 5e3, encoding: "utf8" });
|
|
116
|
+
memo = stdout.trim();
|
|
117
|
+
failedAt = null;
|
|
118
|
+
return memo;
|
|
119
|
+
} catch (err) {
|
|
120
|
+
failedAt = now();
|
|
121
|
+
log(`[exed] npm root -g resolution failed (memoized, retry after ${Math.round(retryMs / 1e3)}s): ${err instanceof Error ? err.message : String(err)}
|
|
122
|
+
`);
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/lib/exe-daemon.ts
|
|
87
129
|
import path3 from "path";
|
|
88
130
|
import { fileURLToPath } from "url";
|
|
89
131
|
import { fork, spawn } from "child_process";
|
|
@@ -192,6 +234,10 @@ function validateWriteShape(maskedSql) {
|
|
|
192
234
|
}
|
|
193
235
|
return null;
|
|
194
236
|
}
|
|
237
|
+
function isOffloadableDaemonReadSql(sql) {
|
|
238
|
+
const masked = maskSqlLiteralsAndComments(sql.trim());
|
|
239
|
+
return DAEMON_READ_SQL_RE.test(masked);
|
|
240
|
+
}
|
|
195
241
|
function validateDaemonDbSql(sql) {
|
|
196
242
|
const original = sql.trim();
|
|
197
243
|
if (!original) return "empty SQL is not allowed";
|
|
@@ -330,6 +376,20 @@ async function awaitPendingMcpInit(ownerKey, requestSessionId, deps, transientMa
|
|
|
330
376
|
return null;
|
|
331
377
|
}
|
|
332
378
|
|
|
379
|
+
// src/lib/daemon-self-heal-dispatch.ts
|
|
380
|
+
function dispatchSelfHealRestart(lagMs, trigger, deps) {
|
|
381
|
+
deps.writeBreadcrumb(lagMs, trigger);
|
|
382
|
+
deps.shutdown(75);
|
|
383
|
+
}
|
|
384
|
+
function resolveSelfHealThresholds(env = process.env) {
|
|
385
|
+
return {
|
|
386
|
+
singleMs: parseFloat(env.EXE_SELF_HEAL_SINGLE_MS ?? "") || 12e4,
|
|
387
|
+
thresholdMs: parseFloat(env.EXE_SELF_HEAL_THRESHOLD_MS ?? "") || 3e4,
|
|
388
|
+
consecutive: parseInt(env.EXE_SELF_HEAL_CONSECUTIVE ?? "") || 3,
|
|
389
|
+
starvationRatio: parseFloat(env.EXE_STARVATION_LOAD_RATIO ?? "1.5")
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
333
393
|
// src/lib/daemon-restart-backoff.ts
|
|
334
394
|
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync, mkdirSync } from "fs";
|
|
335
395
|
import { createHash } from "crypto";
|
|
@@ -815,7 +875,7 @@ async function capturePaneAsync(session, lines = 20) {
|
|
|
815
875
|
}
|
|
816
876
|
}
|
|
817
877
|
function classifyPaneState(pane) {
|
|
818
|
-
const busyPattern =
|
|
878
|
+
const busyPattern = BUSY_PATTERN;
|
|
819
879
|
if (!pane.includes("\u276F") && !pane.includes("Claude Code") && !busyPattern.test(pane) && !/Running…/.test(pane)) {
|
|
820
880
|
if (/\$\s*$/.test(pane) || /% $/.test(pane.trimEnd())) return "no_claude";
|
|
821
881
|
}
|
|
@@ -884,7 +944,7 @@ async function batchPaneAlive(sessions) {
|
|
|
884
944
|
}
|
|
885
945
|
return alive;
|
|
886
946
|
}
|
|
887
|
-
var CACHED_SESSION_BUSY_PATTERN =
|
|
947
|
+
var CACHED_SESSION_BUSY_PATTERN = BUSY_PATTERN;
|
|
888
948
|
function getCachedSessionState(sessionName, paneCache, aliveSessions) {
|
|
889
949
|
if (!aliveSessions.has(sessionName)) return "offline";
|
|
890
950
|
const pane = paneCache.get(sessionName);
|
|
@@ -974,6 +1034,46 @@ function shouldTraceDaemonTimer(durationMs = 0) {
|
|
|
974
1034
|
return Date.now() - _startedAt2 < TIMER_TRACE_BOOT_WINDOW_MS || durationMs >= TIMER_TRACE_SLOW_MS;
|
|
975
1035
|
}
|
|
976
1036
|
var yieldToEventLoop = () => new Promise((resolve) => setImmediate(resolve));
|
|
1037
|
+
var _lastBlockingTimer = null;
|
|
1038
|
+
function getLastBlockingTimer() {
|
|
1039
|
+
return _lastBlockingTimer;
|
|
1040
|
+
}
|
|
1041
|
+
var _exitBreadcrumbWritten = false;
|
|
1042
|
+
function recordExitBreadcrumb(kind, exitCode, reason, extra) {
|
|
1043
|
+
if (_exitBreadcrumbWritten) return;
|
|
1044
|
+
_exitBreadcrumbWritten = true;
|
|
1045
|
+
let rssBytes;
|
|
1046
|
+
try {
|
|
1047
|
+
rssBytes = process.memoryUsage().rss;
|
|
1048
|
+
} catch {
|
|
1049
|
+
}
|
|
1050
|
+
const info = {
|
|
1051
|
+
exitCode,
|
|
1052
|
+
reason,
|
|
1053
|
+
kind,
|
|
1054
|
+
ts: Date.now(),
|
|
1055
|
+
uptimeMs: Date.now() - _startedAt2,
|
|
1056
|
+
...rssBytes !== void 0 ? { rssBytes } : {},
|
|
1057
|
+
...extra
|
|
1058
|
+
};
|
|
1059
|
+
writeDaemonExitBreadcrumb(info);
|
|
1060
|
+
}
|
|
1061
|
+
function recordSelfHealBreadcrumb(lagMs, trigger) {
|
|
1062
|
+
const blk = _lastBlockingTimer && Date.now() - _lastBlockingTimer.ts < 6e4 ? _lastBlockingTimer : null;
|
|
1063
|
+
recordExitBreadcrumb("self_heal", 75, `self_heal_event_loop_lag:${trigger}`, {
|
|
1064
|
+
lagMs: Math.round(lagMs),
|
|
1065
|
+
...blk ? { timerName: blk.name, timerDurationMs: blk.durationMs } : {}
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
var SELF_HEAL_ACTION_DEPS = {
|
|
1069
|
+
writeBreadcrumb: recordSelfHealBreadcrumb,
|
|
1070
|
+
shutdown: (code) => {
|
|
1071
|
+
void shutdown(code);
|
|
1072
|
+
},
|
|
1073
|
+
exit: (code) => {
|
|
1074
|
+
process.exit(code);
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
977
1077
|
async function traceDaemonTimer(name, fn) {
|
|
978
1078
|
if (_timerInFlight.has(name)) {
|
|
979
1079
|
process.stderr.write(`[exed] Timer SKIPPED (overlap): ${name} \u2014 previous tick still running
|
|
@@ -988,6 +1088,7 @@ async function traceDaemonTimer(name, fn) {
|
|
|
988
1088
|
`);
|
|
989
1089
|
}
|
|
990
1090
|
const timeoutHandle = setTimeout(() => {
|
|
1091
|
+
_lastBlockingTimer = { name, durationMs: TIMER_TIMEOUT_MS, ts: Date.now() };
|
|
991
1092
|
process.stderr.write(
|
|
992
1093
|
`[exed] Timer TIMEOUT WARNING: ${name} has been running for >${TIMER_TIMEOUT_MS / 1e3}s \u2014 likely blocking the event loop
|
|
993
1094
|
`
|
|
@@ -1008,6 +1109,9 @@ async function traceDaemonTimer(name, fn) {
|
|
|
1008
1109
|
const span = measureSpan(probe);
|
|
1009
1110
|
const durationMs = Math.round(span.monoMs);
|
|
1010
1111
|
const slept = span.sleptMs > 1e3;
|
|
1112
|
+
if (!slept && durationMs >= TIMER_TIMEOUT_MS) {
|
|
1113
|
+
_lastBlockingTimer = { name, durationMs, ts: Date.now() };
|
|
1114
|
+
}
|
|
1011
1115
|
if (shouldTraceDaemonTimer(durationMs)) {
|
|
1012
1116
|
const sleepNote = slept ? ` (wall ${Math.round(span.wallMs)}ms \u2014 host slept/clock-stepped ${Math.round(span.sleptMs)}ms; not an event-loop block)` : "";
|
|
1013
1117
|
const msg = `[exed] Timer duration: ${name} ${durationMs}ms${sleepNote}`;
|
|
@@ -1166,9 +1270,6 @@ function isEventLoopBlockedNow(freshMs = EVENT_LOOP_BLOCKED_FRESH_MS) {
|
|
|
1166
1270
|
return false;
|
|
1167
1271
|
}
|
|
1168
1272
|
}
|
|
1169
|
-
function eventLoopHeartbeatPath() {
|
|
1170
|
-
return path3.join(os2.homedir(), ".exe-os", "session-cache", "event-loop-heartbeat");
|
|
1171
|
-
}
|
|
1172
1273
|
function touchEventLoopHeartbeat() {
|
|
1173
1274
|
try {
|
|
1174
1275
|
const p = eventLoopHeartbeatPath();
|
|
@@ -1438,7 +1539,7 @@ async function loadModel() {
|
|
|
1438
1539
|
void (async () => {
|
|
1439
1540
|
try {
|
|
1440
1541
|
if (_storeInitialized) {
|
|
1441
|
-
const { writeNotification } = await import("../notifications-
|
|
1542
|
+
const { writeNotification } = await import("../notifications-4UT53CDG.js");
|
|
1442
1543
|
await writeNotification({
|
|
1443
1544
|
agentId: "exe",
|
|
1444
1545
|
agentRole: "system",
|
|
@@ -1554,7 +1655,7 @@ function disableEmbeddingsForInferenceTimeouts() {
|
|
|
1554
1655
|
void (async () => {
|
|
1555
1656
|
try {
|
|
1556
1657
|
if (_storeInitialized) {
|
|
1557
|
-
const { writeNotification } = await import("../notifications-
|
|
1658
|
+
const { writeNotification } = await import("../notifications-4UT53CDG.js");
|
|
1558
1659
|
await writeNotification({
|
|
1559
1660
|
agentId: "exe",
|
|
1560
1661
|
agentRole: "system",
|
|
@@ -1723,10 +1824,12 @@ function checkIdle() {
|
|
|
1723
1824
|
_idleTimer.unref();
|
|
1724
1825
|
}
|
|
1725
1826
|
}
|
|
1726
|
-
async function shutdown(exitCode = 0) {
|
|
1827
|
+
async function shutdown(exitCode = 0, reason = null) {
|
|
1727
1828
|
if (_shuttingDown) return;
|
|
1728
1829
|
_shuttingDown = true;
|
|
1729
1830
|
_drainingWrites = true;
|
|
1831
|
+
const _exitKind = exitCode === 0 && !reason ? "clean" : reason ? "self_exit" : "restart-intent";
|
|
1832
|
+
recordExitBreadcrumb(_exitKind, exitCode, reason);
|
|
1730
1833
|
clearDaemonReady();
|
|
1731
1834
|
if (exitCode !== 0) {
|
|
1732
1835
|
recordDaemonCrash();
|
|
@@ -1765,12 +1868,58 @@ async function shutdown(exitCode = 0) {
|
|
|
1765
1868
|
}
|
|
1766
1869
|
}
|
|
1767
1870
|
try {
|
|
1768
|
-
const {
|
|
1769
|
-
|
|
1770
|
-
|
|
1871
|
+
const {
|
|
1872
|
+
createBackupAsync,
|
|
1873
|
+
enforceRetention,
|
|
1874
|
+
hasRecentBackup,
|
|
1875
|
+
preRestartDedupWindowMs,
|
|
1876
|
+
findActiveDb,
|
|
1877
|
+
shouldSkipBackupUnderMemoryPressure
|
|
1878
|
+
} = await import("../db-backup-W2QFSYQC.js");
|
|
1879
|
+
const PRE_RESTART_DEDUP_MS = preRestartDedupWindowMs();
|
|
1880
|
+
const PRE_RESTART_STORM_CAP = (() => {
|
|
1881
|
+
const v = Number(process.env.EXE_PRE_RESTART_STORM_CAP);
|
|
1882
|
+
return Number.isFinite(v) && v > 0 ? Math.floor(v) : 3;
|
|
1883
|
+
})();
|
|
1884
|
+
let stormSkip = false;
|
|
1885
|
+
try {
|
|
1886
|
+
const recentRestarts = restartBootsInWindow();
|
|
1887
|
+
if (recentRestarts >= PRE_RESTART_STORM_CAP) {
|
|
1888
|
+
stormSkip = true;
|
|
1889
|
+
process.stderr.write(
|
|
1890
|
+
`[exed] Pre-restart backup SKIPPED \u2014 restart storm (${recentRestarts} restarts in breaker window \u2265 cap ${PRE_RESTART_STORM_CAP}). Bounding total 1.7GB backup bytes; last snapshot + daily backups remain (data-safe).
|
|
1891
|
+
`
|
|
1892
|
+
);
|
|
1893
|
+
}
|
|
1894
|
+
} catch {
|
|
1895
|
+
}
|
|
1896
|
+
let memoryGateSkip = false;
|
|
1897
|
+
try {
|
|
1898
|
+
const dbPath = findActiveDb();
|
|
1899
|
+
let dbBytes = 0;
|
|
1900
|
+
try {
|
|
1901
|
+
dbBytes = dbPath ? statSync(dbPath).size : 0;
|
|
1902
|
+
} catch {
|
|
1903
|
+
}
|
|
1904
|
+
const { getAvailableMemoryBytesSync } = await import("../memory-pressure-watchdog-HN5X7AVN.js");
|
|
1905
|
+
const freeBytes = getAvailableMemoryBytesSync();
|
|
1906
|
+
if (shouldSkipBackupUnderMemoryPressure(freeBytes, dbBytes)) {
|
|
1907
|
+
memoryGateSkip = true;
|
|
1908
|
+
process.stderr.write(
|
|
1909
|
+
`[exed] Pre-restart backup SKIPPED under memory pressure \u2014 ${Math.round(freeBytes / 1024 / 1024)}MB free vs ${Math.round(dbBytes / 1024 / 1024)}MB DB. Skipping the copy is data-safe; OOM-killing the machine mid-copy is not.
|
|
1910
|
+
`
|
|
1911
|
+
);
|
|
1912
|
+
}
|
|
1913
|
+
} catch {
|
|
1914
|
+
}
|
|
1915
|
+
if (stormSkip) {
|
|
1916
|
+
enforceRetention("pre-restart");
|
|
1917
|
+
} else if (hasRecentBackup("pre-restart", PRE_RESTART_DEDUP_MS)) {
|
|
1771
1918
|
const deleted = enforceRetention("pre-restart");
|
|
1772
1919
|
process.stderr.write(`[exed] Pre-restart backup skipped \u2014 recent snapshot exists (crash-loop dedup)${deleted > 0 ? `; rotated ${deleted} old` : ""}.
|
|
1773
1920
|
`);
|
|
1921
|
+
} else if (memoryGateSkip) {
|
|
1922
|
+
enforceRetention("pre-restart");
|
|
1774
1923
|
} else {
|
|
1775
1924
|
const backupPath = await createBackupAsync("pre-restart");
|
|
1776
1925
|
if (backupPath) {
|
|
@@ -1796,12 +1945,12 @@ async function shutdown(exitCode = 0) {
|
|
|
1796
1945
|
`);
|
|
1797
1946
|
}
|
|
1798
1947
|
try {
|
|
1799
|
-
const { stopProjectionWorker } = await import("../projection-worker-
|
|
1948
|
+
const { stopProjectionWorker } = await import("../projection-worker-FZ7YSN3G.js");
|
|
1800
1949
|
stopProjectionWorker();
|
|
1801
1950
|
} catch {
|
|
1802
1951
|
}
|
|
1803
1952
|
try {
|
|
1804
|
-
const { disposeShards } = await import("../shard-manager-
|
|
1953
|
+
const { disposeShards } = await import("../shard-manager-35PWFR3B.js");
|
|
1805
1954
|
disposeShards();
|
|
1806
1955
|
} catch {
|
|
1807
1956
|
}
|
|
@@ -1862,7 +2011,7 @@ async function handleHealthCheck(socket, requestId) {
|
|
|
1862
2011
|
let pipelineStatus = "unknown";
|
|
1863
2012
|
if (dbConnected) {
|
|
1864
2013
|
try {
|
|
1865
|
-
await import("../pipeline-router-
|
|
2014
|
+
await import("../pipeline-router-LM53NMWJ.js");
|
|
1866
2015
|
pipelineStatus = "ok";
|
|
1867
2016
|
} catch {
|
|
1868
2017
|
pipelineStatus = "unavailable";
|
|
@@ -1967,6 +2116,18 @@ async function handleDbExecute(socket, requestId, sql, args) {
|
|
|
1967
2116
|
sendResponse(socket, { id: requestId, error: "DB not initialized" });
|
|
1968
2117
|
return;
|
|
1969
2118
|
}
|
|
2119
|
+
if (isOffloadableDaemonReadSql(sql)) {
|
|
2120
|
+
try {
|
|
2121
|
+
const { isDbReadWorkerReady, runReadQueryInWorkerSerialized } = await import("./db-read-worker-client.js");
|
|
2122
|
+
if (isDbReadWorkerReady()) {
|
|
2123
|
+
const serialized = await runReadQueryInWorkerSerialized(sql, args);
|
|
2124
|
+
_dbRequestsServed++;
|
|
2125
|
+
sendResponse(socket, { id: requestId, db: serialized });
|
|
2126
|
+
return;
|
|
2127
|
+
}
|
|
2128
|
+
} catch {
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
1970
2131
|
const { getClient } = await import("./database.js");
|
|
1971
2132
|
const client = getClient();
|
|
1972
2133
|
const deserializedArgs = deserializeArgs(args);
|
|
@@ -2258,7 +2419,7 @@ async function _writeMemoryRecordInner(entry) {
|
|
|
2258
2419
|
const vRow = await client.execute({ sql: "SELECT version FROM memories WHERE id = ?", args: [id] });
|
|
2259
2420
|
const version = Number(vRow.rows[0]?.version) || 0;
|
|
2260
2421
|
try {
|
|
2261
|
-
const { insertOntologyForMemory } = await import("../agentic-ontology-
|
|
2422
|
+
const { insertOntologyForMemory } = await import("../agentic-ontology-3FXYMHKW.js");
|
|
2262
2423
|
await insertOntologyForMemory({
|
|
2263
2424
|
id,
|
|
2264
2425
|
agent_id: record.agent_id,
|
|
@@ -2287,37 +2448,34 @@ function startMemoryQueueDrain() {
|
|
|
2287
2448
|
fired("memory_queue_drain");
|
|
2288
2449
|
if (!await ensureStoreForPolling()) return;
|
|
2289
2450
|
try {
|
|
2290
|
-
const { ackQueue, claimQueue, retryQueueEntries } = await import("../memory-queue-
|
|
2451
|
+
const { ackQueue, claimQueue, retryQueueEntries, processQueueEntries } = await import("../memory-queue-2UOOF27L.js");
|
|
2291
2452
|
const lease = claimQueue();
|
|
2292
2453
|
if (!lease || lease.entries.length === 0) return;
|
|
2293
2454
|
acted("memory_queue_drain");
|
|
2294
2455
|
const entries = lease.entries;
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
try {
|
|
2301
|
-
await writeMemoryRecord(entry);
|
|
2302
|
-
processed++;
|
|
2303
|
-
} catch (err) {
|
|
2304
|
-
retryEntries.push(entry);
|
|
2456
|
+
const result = await processQueueEntries(entries, (entry) => writeMemoryRecord(entry), {
|
|
2457
|
+
isDraining: () => _drainingWrites,
|
|
2458
|
+
batchSize: MEMORY_DRAIN_BATCH,
|
|
2459
|
+
yieldFn: yieldToEventLoop,
|
|
2460
|
+
onWriteError: (_entry, err) => {
|
|
2305
2461
|
process.stderr.write(
|
|
2306
2462
|
`[exed] Queue drain write error: ${err instanceof Error ? err.message : String(err)}
|
|
2463
|
+
`
|
|
2464
|
+
);
|
|
2465
|
+
},
|
|
2466
|
+
onShutdownPreserve: (count) => {
|
|
2467
|
+
process.stderr.write(
|
|
2468
|
+
`[exed] Queue drain interrupted by shutdown \u2014 ${count} entr${count === 1 ? "y" : "ies"} preserved in lease for replay after restart
|
|
2307
2469
|
`
|
|
2308
2470
|
);
|
|
2309
2471
|
}
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
await yieldToEventLoop();
|
|
2313
|
-
}
|
|
2314
|
-
}
|
|
2315
|
-
if (retryEntries.length === 0) {
|
|
2472
|
+
});
|
|
2473
|
+
if (result.retryEntries.length === 0) {
|
|
2316
2474
|
ackQueue(lease.leasePath);
|
|
2317
2475
|
} else {
|
|
2318
|
-
retryQueueEntries(lease.leasePath, retryEntries);
|
|
2476
|
+
retryQueueEntries(lease.leasePath, result.retryEntries);
|
|
2319
2477
|
}
|
|
2320
|
-
process.stderr.write(`[exed] Queue drain: processed ${processed}/${entries.length} memories
|
|
2478
|
+
process.stderr.write(`[exed] Queue drain: processed ${result.processed}/${entries.length} memories${result.preserved > 0 ? ` (${result.preserved} preserved for replay)` : ""}
|
|
2321
2479
|
`);
|
|
2322
2480
|
} catch (err) {
|
|
2323
2481
|
process.stderr.write(
|
|
@@ -2348,7 +2506,7 @@ function startMessageQueueDrain() {
|
|
|
2348
2506
|
fired("message_queue_drain");
|
|
2349
2507
|
if (!await ensureStoreForPolling()) return;
|
|
2350
2508
|
try {
|
|
2351
|
-
const { claimMessageQueue, ackMessageQueue } = await import("../message-queue-client-
|
|
2509
|
+
const { claimMessageQueue, ackMessageQueue } = await import("../message-queue-client-4EOQRUXW.js");
|
|
2352
2510
|
const lease = claimMessageQueue();
|
|
2353
2511
|
if (!lease || lease.entries.length === 0) return;
|
|
2354
2512
|
acted("message_queue_drain");
|
|
@@ -2994,7 +3152,7 @@ async function startMcpHttpServer() {
|
|
|
2994
3152
|
process.stderr.write("[exed] MCP HTTP: DB ready\n");
|
|
2995
3153
|
setBootPhase("db_ready");
|
|
2996
3154
|
_storeInitialized = true;
|
|
2997
|
-
const { initLicenseGate, getCachedLicenseGate } = await import("../license-gate-
|
|
3155
|
+
const { initLicenseGate, getCachedLicenseGate } = await import("../license-gate-QTRQHV4F.js");
|
|
2998
3156
|
const gateResult = await initLicenseGate();
|
|
2999
3157
|
if (!gateResult.hasKey) {
|
|
3000
3158
|
process.stderr.write(
|
|
@@ -3009,13 +3167,13 @@ async function startMcpHttpServer() {
|
|
|
3009
3167
|
let _cachedWrapTelemetry = null;
|
|
3010
3168
|
async function getWrapTelemetry() {
|
|
3011
3169
|
if (!_cachedWrapTelemetry) {
|
|
3012
|
-
const { wrapServerWithTelemetry } = await import("../tool-telemetry-
|
|
3170
|
+
const { wrapServerWithTelemetry } = await import("../tool-telemetry-KBXSBDTK.js");
|
|
3013
3171
|
_cachedWrapTelemetry = wrapServerWithTelemetry;
|
|
3014
3172
|
}
|
|
3015
3173
|
return _cachedWrapTelemetry;
|
|
3016
3174
|
}
|
|
3017
3175
|
Promise.all([
|
|
3018
|
-
import("../tool-capability-index-
|
|
3176
|
+
import("../tool-capability-index-VYF5GNJ2.js"),
|
|
3019
3177
|
import("../tool-gates-3IC7DK4R.js")
|
|
3020
3178
|
]).then(async ([{ getToolCapabilityIndex }, { TOOL_CATEGORIES }]) => {
|
|
3021
3179
|
const gateState = getCachedLicenseGate();
|
|
@@ -3077,9 +3235,11 @@ async function startMcpHttpServer() {
|
|
|
3077
3235
|
if (!header) return false;
|
|
3078
3236
|
const token = header.replace(/^Bearer\s+/i, "");
|
|
3079
3237
|
if (!token || token === header) return false;
|
|
3080
|
-
|
|
3238
|
+
const tokenBuf = Buffer.from(token);
|
|
3239
|
+
const expectedBuf = Buffer.from(_daemonToken);
|
|
3240
|
+
if (tokenBuf.length === expectedBuf.length && timingSafeEqual(tokenBuf, expectedBuf)) return true;
|
|
3081
3241
|
try {
|
|
3082
|
-
const { verifyAccessToken } = await import("../oauth-server-
|
|
3242
|
+
const { verifyAccessToken } = await import("../oauth-server-67YBDP32.js");
|
|
3083
3243
|
const result = verifyAccessToken(token);
|
|
3084
3244
|
return result.valid;
|
|
3085
3245
|
} catch {
|
|
@@ -3295,6 +3455,14 @@ async function startMcpHttpServer() {
|
|
|
3295
3455
|
version: PACKAGE_VERSION,
|
|
3296
3456
|
eventLoopLagMs: Math.round(elLag),
|
|
3297
3457
|
eventLoopBlockedNow: blockedNow,
|
|
3458
|
+
// Feature 9ddc55b2 (timer health dashboard): expose the names of the
|
|
3459
|
+
// timers executing RIGHT NOW. This is a plain read of the existing
|
|
3460
|
+
// in-memory overlap-guard Set (≤ ~96 short strings) on an existing
|
|
3461
|
+
// request handler — it adds ZERO work to the timer hot path. Without
|
|
3462
|
+
// it "is this timer in-flight?" is unanswerable from outside the
|
|
3463
|
+
// process: traceDaemonTimer writes tick *starts* to stderr only, never
|
|
3464
|
+
// durably. When a tick blocks the loop this is the field that names it.
|
|
3465
|
+
timersInFlight: [..._timerInFlight],
|
|
3298
3466
|
...blockedNow && { warning: "Event loop blocked marker is fresh \u2014 /mcp returning 503 Retry-After until marker clears (~10s)" },
|
|
3299
3467
|
...!blockedNow && degraded && { warning: `Event loop lag ${Math.round(elLag)}ms exceeds 5000ms threshold \u2014 daemon may be unresponsive` }
|
|
3300
3468
|
}));
|
|
@@ -3324,7 +3492,7 @@ async function startMcpHttpServer() {
|
|
|
3324
3492
|
return;
|
|
3325
3493
|
}
|
|
3326
3494
|
try {
|
|
3327
|
-
const { handleOAuthRoute } = await import("../oauth-server-
|
|
3495
|
+
const { handleOAuthRoute } = await import("../oauth-server-67YBDP32.js");
|
|
3328
3496
|
const handled = await handleOAuthRoute(req, res, url, MCP_HTTP_PORT);
|
|
3329
3497
|
if (handled) return;
|
|
3330
3498
|
} catch (err) {
|
|
@@ -3356,7 +3524,7 @@ async function startMcpHttpServer() {
|
|
|
3356
3524
|
for await (const chunk of req) chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
3357
3525
|
const rawBody = Buffer.concat(chunks);
|
|
3358
3526
|
try {
|
|
3359
|
-
const { loadWebhookConfig, verifyHmac, processWebhook } = await import("../webhook-pipe-
|
|
3527
|
+
const { loadWebhookConfig, verifyHmac, processWebhook } = await import("../webhook-pipe-LEXMUQ5B.js");
|
|
3360
3528
|
const webhookConfig = await loadWebhookConfig();
|
|
3361
3529
|
const serviceConfig = webhookConfig[serviceName];
|
|
3362
3530
|
if (!serviceConfig) {
|
|
@@ -3452,7 +3620,7 @@ async function startMcpHttpServer() {
|
|
|
3452
3620
|
contextPct: body.context_pct
|
|
3453
3621
|
});
|
|
3454
3622
|
if (body.context_pct !== void 0 && body.context_pct > 70) {
|
|
3455
|
-
void import("../orchestration-events-
|
|
3623
|
+
void import("../orchestration-events-WV4NWKZH.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
|
|
3456
3624
|
recordOE({
|
|
3457
3625
|
eventType: "context.pressure",
|
|
3458
3626
|
source: "exe-daemon.heartbeat",
|
|
@@ -3535,36 +3703,70 @@ async function startMcpHttpServer() {
|
|
|
3535
3703
|
}
|
|
3536
3704
|
const projectNameHeader = req.headers["x-project-name"] || "";
|
|
3537
3705
|
let sessionHint = req.headers["x-exe-session-name"] || req.headers["x-exe-session"] || "";
|
|
3538
|
-
if (sessionHint
|
|
3539
|
-
|
|
3706
|
+
if (sessionHint) {
|
|
3707
|
+
try {
|
|
3708
|
+
const { sanitizeSessionHintHeader, rejectForgedSessionHint } = await import("../mcp-session-identity-T7H2EKFQ.js");
|
|
3709
|
+
const rawHint = sessionHint;
|
|
3710
|
+
sessionHint = sanitizeSessionHintHeader(sessionHint);
|
|
3711
|
+
if (!sessionHint) {
|
|
3712
|
+
process.stderr.write(
|
|
3713
|
+
`[daemon] WARN: discarded malformed session identity header ${JSON.stringify(rawHint)} from agent "${agentId}"
|
|
3714
|
+
`
|
|
3715
|
+
);
|
|
3716
|
+
} else {
|
|
3717
|
+
try {
|
|
3718
|
+
const { listSessions: listRegistrySessions } = await import("./session-registry.js");
|
|
3719
|
+
const verdict = rejectForgedSessionHint({
|
|
3720
|
+
agentId,
|
|
3721
|
+
hint: sessionHint,
|
|
3722
|
+
registrySessions: listRegistrySessions()
|
|
3723
|
+
});
|
|
3724
|
+
if (verdict.rejected) {
|
|
3725
|
+
process.stderr.write(`[daemon] WARN: ${verdict.reason}
|
|
3726
|
+
`);
|
|
3727
|
+
sessionHint = "";
|
|
3728
|
+
}
|
|
3729
|
+
} catch {
|
|
3730
|
+
}
|
|
3731
|
+
}
|
|
3732
|
+
} catch {
|
|
3733
|
+
if (sessionHint.includes("$(") || sessionHint.includes("#{") || sessionHint.includes("tmux")) {
|
|
3734
|
+
sessionHint = "";
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3540
3737
|
}
|
|
3541
3738
|
const clientProvidedSessionHint = Boolean(sessionHint);
|
|
3542
3739
|
if (!sessionHint && agentId) {
|
|
3543
3740
|
try {
|
|
3544
3741
|
const liveSessions = await getTmuxSessionsAsync();
|
|
3545
|
-
const
|
|
3546
|
-
|
|
3547
|
-
|
|
3742
|
+
const paneCommands = await getPaneCommandsAsync();
|
|
3743
|
+
const { resolveMcpSessionHint } = await import("../mcp-session-identity-T7H2EKFQ.js");
|
|
3744
|
+
let registrySessions = [];
|
|
3745
|
+
try {
|
|
3746
|
+
const { listSessions: listRegistrySessions } = await import("./session-registry.js");
|
|
3747
|
+
registrySessions = listRegistrySessions();
|
|
3748
|
+
} catch {
|
|
3548
3749
|
}
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
const
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
}
|
|
3750
|
+
let isCoordinator = false;
|
|
3751
|
+
try {
|
|
3752
|
+
const { isCoordinatorName } = await import("./employees.js");
|
|
3753
|
+
isCoordinator = isCoordinatorName(agentId);
|
|
3754
|
+
} catch {
|
|
3755
|
+
}
|
|
3756
|
+
const resolution = resolveMcpSessionHint({
|
|
3757
|
+
agentId,
|
|
3758
|
+
isCoordinator,
|
|
3759
|
+
liveTmuxSessions: liveSessions,
|
|
3760
|
+
registrySessions,
|
|
3761
|
+
// Only count coordinators that still host a LIVE agent. Orphaned
|
|
3762
|
+
// coordinator shells (agent exited, tmux shell lingers) would otherwise
|
|
3763
|
+
// inflate the count forever and spam "cannot auto-resolve" (bug 6c46d301).
|
|
3764
|
+
coordinatorHasLiveAgent: (s) => coordinatorPaneHasLiveAgent(s, paneCommands)
|
|
3765
|
+
});
|
|
3766
|
+
sessionHint = resolution.sessionHint;
|
|
3767
|
+
if (resolution.warning) {
|
|
3768
|
+
process.stderr.write(`[daemon] WARN: ${resolution.warning}
|
|
3769
|
+
`);
|
|
3568
3770
|
}
|
|
3569
3771
|
} catch {
|
|
3570
3772
|
}
|
|
@@ -3662,6 +3864,54 @@ async function startMcpHttpServer() {
|
|
|
3662
3864
|
} catch (dbInitErr) {
|
|
3663
3865
|
process.stderr.write(`[exed] DB init on new session FAILED: ${dbInitErr instanceof Error ? dbInitErr.message : String(dbInitErr)}
|
|
3664
3866
|
`);
|
|
3867
|
+
}
|
|
3868
|
+
try {
|
|
3869
|
+
const { isManagementIdentity } = await import("./employees.js");
|
|
3870
|
+
if (isManagementIdentity(agentId)) {
|
|
3871
|
+
let bindRegistry = [];
|
|
3872
|
+
let bindLive = [];
|
|
3873
|
+
try {
|
|
3874
|
+
const { listSessions: listRegistrySessions } = await import("./session-registry.js");
|
|
3875
|
+
bindRegistry = listRegistrySessions();
|
|
3876
|
+
bindLive = await getTmuxSessionsAsync();
|
|
3877
|
+
} catch {
|
|
3878
|
+
}
|
|
3879
|
+
const { isLauncherCorroboratedIdentity } = await import("../mcp-session-identity-T7H2EKFQ.js");
|
|
3880
|
+
const corroborated = isLauncherCorroboratedIdentity({
|
|
3881
|
+
agentId,
|
|
3882
|
+
registrySessions: bindRegistry,
|
|
3883
|
+
liveTmuxSessions: bindLive
|
|
3884
|
+
});
|
|
3885
|
+
const assessment = assessInitialBindIdentity({
|
|
3886
|
+
agentId,
|
|
3887
|
+
privileged: true,
|
|
3888
|
+
corroborated,
|
|
3889
|
+
enforce: shouldEnforceSessionIdentity()
|
|
3890
|
+
});
|
|
3891
|
+
if (assessment.flagged) {
|
|
3892
|
+
process.stderr.write(`[exed] SECURITY: ${assessment.reason}
|
|
3893
|
+
`);
|
|
3894
|
+
recordMcpHttpEvent({
|
|
3895
|
+
level: "warn",
|
|
3896
|
+
message: assessment.reject ? "initial_bind_identity_rejected" : "initial_bind_identity_uncorroborated",
|
|
3897
|
+
method: req.method,
|
|
3898
|
+
agentId,
|
|
3899
|
+
agentRole,
|
|
3900
|
+
runtime
|
|
3901
|
+
});
|
|
3902
|
+
}
|
|
3903
|
+
if (assessment.reject) {
|
|
3904
|
+
sendJsonRpcError2(
|
|
3905
|
+
res,
|
|
3906
|
+
403,
|
|
3907
|
+
`Refusing to bind privileged identity "${agentId}" to a new MCP session: the X-Agent-Id header claims a management role but no launcher-written session-registry entry corroborates it (bug 2138232d). Launch the agent through exe-os, or set EXE_ENFORCE_SESSION_IDENTITY=0 for warn-only.`,
|
|
3908
|
+
getJsonRpcId2(parsedBody),
|
|
3909
|
+
{ agentId, agentRole }
|
|
3910
|
+
);
|
|
3911
|
+
return;
|
|
3912
|
+
}
|
|
3913
|
+
}
|
|
3914
|
+
} catch {
|
|
3665
3915
|
}
|
|
3666
3916
|
const initIsTransient = !clientProvidedSessionHint;
|
|
3667
3917
|
const initOwnerKey = mcpSessionOwnerKey2({ agentId, runtime, sessionHint, transient: initIsTransient });
|
|
@@ -3868,6 +4118,25 @@ async function startMcpHttpServer() {
|
|
|
3868
4118
|
effectiveSessionHint = stored.sessionHint;
|
|
3869
4119
|
}
|
|
3870
4120
|
}
|
|
4121
|
+
try {
|
|
4122
|
+
const { reconcileHintWithRegistryIdentity } = await import("../mcp-session-identity-T7H2EKFQ.js");
|
|
4123
|
+
const { listSessions: listRegistrySessions } = await import("./session-registry.js");
|
|
4124
|
+
const recon = reconcileHintWithRegistryIdentity({
|
|
4125
|
+
agentId,
|
|
4126
|
+
hint: effectiveSessionHint,
|
|
4127
|
+
clientProvided: clientProvidedSessionHint,
|
|
4128
|
+
registrySessions: listRegistrySessions(),
|
|
4129
|
+
liveTmuxSessions: await getTmuxSessionsAsync()
|
|
4130
|
+
});
|
|
4131
|
+
if (recon.message) process.stderr.write(`[daemon] ${recon.message}
|
|
4132
|
+
`);
|
|
4133
|
+
if (recon.corrected) {
|
|
4134
|
+
effectiveSessionHint = recon.sessionHint;
|
|
4135
|
+
const stored = activeRequestSessionId ? sessionDetails.get(activeRequestSessionId) : void 0;
|
|
4136
|
+
if (stored && recon.sessionHint) stored.sessionHint = recon.sessionHint;
|
|
4137
|
+
}
|
|
4138
|
+
} catch {
|
|
4139
|
+
}
|
|
3871
4140
|
try {
|
|
3872
4141
|
await runWithAgent({ agentId, agentRole, sessionHint: effectiveSessionHint, projectName: projectNameHeader || void 0 }, async () => {
|
|
3873
4142
|
if (wantsJsonOnly) {
|
|
@@ -3988,7 +4257,7 @@ async function startMcpHttpServer() {
|
|
|
3988
4257
|
`);
|
|
3989
4258
|
_boundMcpPort = MCP_HTTP_PORT;
|
|
3990
4259
|
writeDaemonReady({ pid: process.pid, port: MCP_HTTP_PORT });
|
|
3991
|
-
void import("../mcp-port-config-
|
|
4260
|
+
void import("../mcp-port-config-6HYY6J7K.js").then(({ persistMcpPortToConfig }) => persistMcpPortToConfig(String(MCP_HTTP_PORT))).catch(() => {
|
|
3992
4261
|
});
|
|
3993
4262
|
recordMcpHttpEvent({
|
|
3994
4263
|
level: "info",
|
|
@@ -4047,10 +4316,10 @@ async function ensureStoreForPolling() {
|
|
|
4047
4316
|
await initDatabase({ dbPath: config.dbPath, encryptionKey: masterKey.toString("hex") });
|
|
4048
4317
|
await ensureSchema();
|
|
4049
4318
|
try {
|
|
4050
|
-
const { isLedgerEnabled } = await import("../notification-ledger-
|
|
4319
|
+
const { isLedgerEnabled } = await import("../notification-ledger-SZEPGJQ7.js");
|
|
4051
4320
|
if (isLedgerEnabled()) {
|
|
4052
|
-
const { bumpBootGeneration } = await import("../boot-generation-
|
|
4053
|
-
const { setDaemonReadyGeneration } = await import("../daemon-ready-signal-
|
|
4321
|
+
const { bumpBootGeneration } = await import("../boot-generation-BL2ISK4U.js");
|
|
4322
|
+
const { setDaemonReadyGeneration } = await import("../daemon-ready-signal-LPAZWQOV.js");
|
|
4054
4323
|
const generation = await bumpBootGeneration();
|
|
4055
4324
|
setDaemonReadyGeneration(generation);
|
|
4056
4325
|
process.stderr.write(`[exed] notification ledger enabled \u2014 boot generation ${generation}
|
|
@@ -4079,13 +4348,13 @@ async function ensureStoreForPolling() {
|
|
|
4079
4348
|
}
|
|
4080
4349
|
}
|
|
4081
4350
|
async function startReviewPolling() {
|
|
4082
|
-
const polling = await import("../review-polling-
|
|
4351
|
+
const polling = await import("../review-polling-HXAFJZDA.js");
|
|
4083
4352
|
const state = {
|
|
4084
4353
|
lastIntercomSent: /* @__PURE__ */ new Map(),
|
|
4085
4354
|
lastNudgeSent: /* @__PURE__ */ new Map(),
|
|
4086
4355
|
intervalMs: REVIEW_POLL_INTERVAL_MS
|
|
4087
4356
|
};
|
|
4088
|
-
const { pollReviewNudge, createReviewNudgeRealDeps, loadNudgeState } = await import("../daemon-orchestration-
|
|
4357
|
+
const { pollReviewNudge, createReviewNudgeRealDeps, loadNudgeState } = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
4089
4358
|
const nudgeState = loadNudgeState();
|
|
4090
4359
|
const tick = async () => traceDaemonTimer("review_polling", async () => {
|
|
4091
4360
|
fired("review_polling");
|
|
@@ -4123,16 +4392,17 @@ async function startReviewPolling() {
|
|
|
4123
4392
|
}
|
|
4124
4393
|
var SESSION_TTL_INTERVAL_MS = 5 * 60 * 1e3;
|
|
4125
4394
|
var SESSION_REGISTRY_MAINTENANCE_INTERVAL_MS = 5 * 60 * 1e3;
|
|
4395
|
+
var _wedgeObservations = /* @__PURE__ */ new Map();
|
|
4126
4396
|
function startSessionTTL() {
|
|
4127
4397
|
const tick = async () => traceDaemonTimer("session_ttl", async () => {
|
|
4128
4398
|
fired("session_ttl");
|
|
4129
|
-
if (!await ensureStoreForPolling()) return;
|
|
4130
|
-
if (inPostRestartDestructiveGrace("session_ttl")) return;
|
|
4131
4399
|
try {
|
|
4400
|
+
if (!await ensureStoreForPolling()) return;
|
|
4401
|
+
if (inPostRestartDestructiveGrace("session_ttl")) return;
|
|
4132
4402
|
const { getClient } = await import("./database.js");
|
|
4133
|
-
const { checkSessionTTL, createSessionTTLRealDeps } = await import("../daemon-orchestration-
|
|
4403
|
+
const { checkSessionTTL, createSessionTTLRealDeps } = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
4134
4404
|
const deps = createSessionTTLRealDeps(getClient);
|
|
4135
|
-
const killed = await checkSessionTTL(deps);
|
|
4405
|
+
const killed = await checkSessionTTL(deps, _wedgeObservations);
|
|
4136
4406
|
if (killed.length > 0) acted("session_ttl");
|
|
4137
4407
|
} catch (err) {
|
|
4138
4408
|
process.stderr.write(`[exed] Session TTL error: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -4145,6 +4415,9 @@ function startSessionTTL() {
|
|
|
4145
4415
|
`);
|
|
4146
4416
|
}
|
|
4147
4417
|
var COO_RESTART_COOLDOWN_MS = 5 * 6e4;
|
|
4418
|
+
var _resolveNpmGlobalRoot = createMemoizedNpmGlobalRootResolver(
|
|
4419
|
+
(file, args, opts) => execFileAsync(file, args, opts)
|
|
4420
|
+
);
|
|
4148
4421
|
var _idleTickCounts = /* @__PURE__ */ new Map();
|
|
4149
4422
|
function startIdleKill() {
|
|
4150
4423
|
const tick = async () => traceDaemonTimer("idle_kill", async () => {
|
|
@@ -4179,7 +4452,7 @@ function startIdleKill() {
|
|
|
4179
4452
|
const cfg = await getCachedConfig();
|
|
4180
4453
|
if (!cfg) return;
|
|
4181
4454
|
const { getClient } = await import("./database.js");
|
|
4182
|
-
const { pollIdleKill, createIdleKillRealDeps } = await import("../daemon-orchestration-
|
|
4455
|
+
const { pollIdleKill, createIdleKillRealDeps } = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
4183
4456
|
const { sessions: liveSessions, paneCache, aliveSessions } = await getSharedOrchestrationCaches();
|
|
4184
4457
|
const realDeps = createIdleKillRealDeps(
|
|
4185
4458
|
getClient,
|
|
@@ -4252,7 +4525,7 @@ function startConsolidation() {
|
|
|
4252
4525
|
`);
|
|
4253
4526
|
}
|
|
4254
4527
|
try {
|
|
4255
|
-
const { createBackupAsync, enforceRetention } = await import("../db-backup-
|
|
4528
|
+
const { createBackupAsync, enforceRetention } = await import("../db-backup-W2QFSYQC.js");
|
|
4256
4529
|
const p = await createBackupAsync("pre-consolidation");
|
|
4257
4530
|
if (p) enforceRetention("pre-consolidation");
|
|
4258
4531
|
} catch (e) {
|
|
@@ -4485,7 +4758,7 @@ function startSkillRefinement() {
|
|
|
4485
4758
|
if (!shouldRunHeavyJob("skill_refinement")) return;
|
|
4486
4759
|
try {
|
|
4487
4760
|
if (!await ensureStoreForPolling()) return;
|
|
4488
|
-
const { runSkillRefinement } = await import("../skill-refinement-
|
|
4761
|
+
const { runSkillRefinement } = await import("../skill-refinement-DVSYXBBP.js");
|
|
4489
4762
|
const result = await runSkillRefinement();
|
|
4490
4763
|
if (result.reviewed > 0) {
|
|
4491
4764
|
acted("skill_refinement");
|
|
@@ -4511,8 +4784,8 @@ function startStaleBranchSweep() {
|
|
|
4511
4784
|
const tick = async () => {
|
|
4512
4785
|
fired("stale_branch_sweep");
|
|
4513
4786
|
try {
|
|
4514
|
-
const { discoverRepoPaths } = await import("../worktree-sweep-
|
|
4515
|
-
const {
|
|
4787
|
+
const { discoverRepoPaths } = await import("../worktree-sweep-WTK3MTKH.js");
|
|
4788
|
+
const { scanUnmergedBranchesCached } = await import("../branch-hygiene-TZWK6QCF.js");
|
|
4516
4789
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
4517
4790
|
for (const k of _staleBranchAlertedToday) {
|
|
4518
4791
|
if (!k.endsWith(today)) _staleBranchAlertedToday.delete(k);
|
|
@@ -4527,7 +4800,11 @@ function startStaleBranchSweep() {
|
|
|
4527
4800
|
await yieldToEventLoop();
|
|
4528
4801
|
let scan;
|
|
4529
4802
|
try {
|
|
4530
|
-
scan = await
|
|
4803
|
+
scan = await scanUnmergedBranchesCached(
|
|
4804
|
+
repo,
|
|
4805
|
+
{ staleHours: STALE_BRANCH_HOURS },
|
|
4806
|
+
{ forceRefresh: true }
|
|
4807
|
+
);
|
|
4531
4808
|
} catch {
|
|
4532
4809
|
continue;
|
|
4533
4810
|
}
|
|
@@ -4539,13 +4816,13 @@ function startStaleBranchSweep() {
|
|
|
4539
4816
|
if (!_storeInitialized) continue;
|
|
4540
4817
|
const stale = scan.branches.filter((b) => b.ageHours >= STALE_BRANCH_HOURS).slice(0, 5).map((b) => `${b.name} (+${b.ahead} commits, ${(b.ageHours / 24).toFixed(1)}d)`).join("; ");
|
|
4541
4818
|
try {
|
|
4542
|
-
const { writeNotification } = await import("../notifications-
|
|
4819
|
+
const { writeNotification } = await import("../notifications-4UT53CDG.js");
|
|
4543
4820
|
await writeNotification({
|
|
4544
4821
|
agentId: "exe",
|
|
4545
4822
|
agentRole: "system",
|
|
4546
4823
|
event: "error_spike",
|
|
4547
4824
|
project: repoName,
|
|
4548
|
-
summary: `${scan.staleCount} unmerged remote branch(es) in ${repoName} are >${STALE_BRANCH_HOURS}h old with unique work \u2014 check before starting new work to avoid redoing it. Oldest: ${stale}.
|
|
4825
|
+
summary: `${scan.staleCount} unmerged remote branch(es) in ${repoName} are >${STALE_BRANCH_HOURS}h old with unique work \u2014 check before starting new work to avoid redoing it. Oldest: ${stale}. List them with: git branch -r --no-merged origin/main`,
|
|
4549
4826
|
sessionScope: null
|
|
4550
4827
|
});
|
|
4551
4828
|
acted("stale_branch_sweep");
|
|
@@ -4578,7 +4855,7 @@ function startGraphExtraction() {
|
|
|
4578
4855
|
if (!await ensureStoreForPolling()) return;
|
|
4579
4856
|
const { getClient } = await import("./database.js");
|
|
4580
4857
|
const client = getClient();
|
|
4581
|
-
const { extractBatch } = await import("../graph-rag-
|
|
4858
|
+
const { extractBatch } = await import("../graph-rag-JZZAB7PC.js");
|
|
4582
4859
|
const result = await extractBatch(client, 50, config.selfQueryModel);
|
|
4583
4860
|
if (result.processed > 0) {
|
|
4584
4861
|
acted("graph_extraction");
|
|
@@ -4996,7 +5273,7 @@ function startReflectionSweep() {
|
|
|
4996
5273
|
);
|
|
4997
5274
|
let runReflection;
|
|
4998
5275
|
try {
|
|
4999
|
-
({ runReflection } = await import("../memory-reflection-
|
|
5276
|
+
({ runReflection } = await import("../memory-reflection-WVNFBJAA.js"));
|
|
5000
5277
|
} catch (importErr) {
|
|
5001
5278
|
_reflectionImportFailed = true;
|
|
5002
5279
|
process.stderr.write(`[exed] Reflection module unavailable (stale chunk hash?) \u2014 disabled until daemon restart: ${importErr instanceof Error ? importErr.message : String(importErr)}
|
|
@@ -5037,7 +5314,7 @@ function startReflectionSweep() {
|
|
|
5037
5314
|
if (memories > 100 && cards < memories * 0.1) {
|
|
5038
5315
|
process.stderr.write(`[exed] Memory cards sparse (${cards} cards / ${memories} memories) \u2014 running backfill...
|
|
5039
5316
|
`);
|
|
5040
|
-
const { insertMemoryCardsForBatch } = await import("../memory-cards-
|
|
5317
|
+
const { insertMemoryCardsForBatch } = await import("../memory-cards-ZRDW7QBX.js");
|
|
5041
5318
|
const batchSize = 500;
|
|
5042
5319
|
let offset = 0;
|
|
5043
5320
|
let totalCards = 0;
|
|
@@ -5076,13 +5353,25 @@ function startReflectionSweep() {
|
|
|
5076
5353
|
process.stderr.write(`[exed] Reflection sweep started (every 6h)
|
|
5077
5354
|
`);
|
|
5078
5355
|
}
|
|
5079
|
-
var
|
|
5356
|
+
var DB_BACKUP_TARGET_WINDOW_MS = Number(process.env.EXE_DB_BACKUP_TARGET_WINDOW_MS) || 6 * 60 * 60 * 1e3;
|
|
5357
|
+
var DB_BACKUP_INTERVAL_MS = Math.min(60 * 60 * 1e3, DB_BACKUP_TARGET_WINDOW_MS);
|
|
5080
5358
|
function startDatabaseBackup() {
|
|
5081
5359
|
const tick = async () => {
|
|
5082
5360
|
fired("db_backup");
|
|
5083
|
-
if (!shouldRunHeavyJob("db_backup")) return;
|
|
5084
5361
|
try {
|
|
5085
|
-
const { createBackupAsync, enforceRetention, hasBackupToday } = await import("../db-backup-
|
|
5362
|
+
const { createBackupAsync, enforceRetention, hasBackupToday, hasRecentBackup } = await import("../db-backup-W2QFSYQC.js");
|
|
5363
|
+
if (!hasRecentBackup("guaranteed", DB_BACKUP_TARGET_WINDOW_MS)) {
|
|
5364
|
+
const guaranteedPath = await createBackupAsync("guaranteed");
|
|
5365
|
+
if (guaranteedPath) {
|
|
5366
|
+
acted("db_backup");
|
|
5367
|
+
const deleted = enforceRetention("guaranteed");
|
|
5368
|
+
process.stderr.write(
|
|
5369
|
+
`[exed] DB backup guaranteed: ${guaranteedPath.split("/").pop()} (target window ${Math.round(DB_BACKUP_TARGET_WINDOW_MS / 36e5)}h)${deleted > 0 ? ` (rotated ${deleted} old)` : ""}
|
|
5370
|
+
`
|
|
5371
|
+
);
|
|
5372
|
+
}
|
|
5373
|
+
}
|
|
5374
|
+
if (!shouldRunHeavyJob("db_backup_daily")) return;
|
|
5086
5375
|
if (hasBackupToday("daily")) return;
|
|
5087
5376
|
const backupPath = await createBackupAsync("daily");
|
|
5088
5377
|
if (backupPath) {
|
|
@@ -5093,7 +5382,7 @@ function startDatabaseBackup() {
|
|
|
5093
5382
|
`
|
|
5094
5383
|
);
|
|
5095
5384
|
try {
|
|
5096
|
-
const { maybeVerifyDailyBackup } = await import("../backup-verify-
|
|
5385
|
+
const { maybeVerifyDailyBackup } = await import("../backup-verify-3Y2FHGZU.js");
|
|
5097
5386
|
const verdict = await maybeVerifyDailyBackup(backupPath);
|
|
5098
5387
|
if (verdict && !verdict.ok) {
|
|
5099
5388
|
process.stderr.write(
|
|
@@ -5117,8 +5406,10 @@ function startDatabaseBackup() {
|
|
|
5117
5406
|
tick();
|
|
5118
5407
|
const timer = setInterval(() => void traceDaemonTimer("db_backup", tick), DB_BACKUP_INTERVAL_MS);
|
|
5119
5408
|
timer.unref();
|
|
5120
|
-
process.stderr.write(
|
|
5121
|
-
`);
|
|
5409
|
+
process.stderr.write(
|
|
5410
|
+
`[exed] Database backup started (guaranteed every \u2264${Math.round(DB_BACKUP_TARGET_WINDOW_MS / 36e5)}h; daily verify window retained)
|
|
5411
|
+
`
|
|
5412
|
+
);
|
|
5122
5413
|
}
|
|
5123
5414
|
var PURGE_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
5124
5415
|
function startSoftDeletePurge() {
|
|
@@ -5168,7 +5459,7 @@ function startSessionEventsRetention() {
|
|
|
5168
5459
|
if (!await ensureStoreForPolling()) return;
|
|
5169
5460
|
try {
|
|
5170
5461
|
const { getClient } = await import("./database.js");
|
|
5171
|
-
const { sweepExpiredSessionEvents, DEFAULT_SESSION_EVENTS_RETENTION_DAYS } = await import("../session-events-
|
|
5462
|
+
const { sweepExpiredSessionEvents, DEFAULT_SESSION_EVENTS_RETENTION_DAYS } = await import("../session-events-O3BV56ZX.js");
|
|
5172
5463
|
const days = SESSION_EVENTS_RETENTION_DAYS ?? DEFAULT_SESSION_EVENTS_RETENTION_DAYS;
|
|
5173
5464
|
const count = await sweepExpiredSessionEvents(getClient(), days);
|
|
5174
5465
|
if (count > 0) {
|
|
@@ -5199,11 +5490,15 @@ function startIntercomQueueDrain() {
|
|
|
5199
5490
|
const tick = async () => traceDaemonTimer("intercom_queue_drain", async () => {
|
|
5200
5491
|
fired("intercom_queue_drain");
|
|
5201
5492
|
try {
|
|
5202
|
-
const { drainQueueAsync, readQueue } = await import("../intercom-queue-
|
|
5493
|
+
const { drainQueueAsync, readQueue } = await import("../intercom-queue-ZFEQALR3.js");
|
|
5203
5494
|
const {
|
|
5204
5495
|
sendIntercomAsync: centralSendIntercomAsync,
|
|
5205
|
-
|
|
5206
|
-
|
|
5496
|
+
countScopedPendingReviews,
|
|
5497
|
+
countScopedOpenTasks,
|
|
5498
|
+
dispositionWedgedSessionTask,
|
|
5499
|
+
decideDrainSend,
|
|
5500
|
+
offlineIfEmpty,
|
|
5501
|
+
paneHasPendingInput
|
|
5207
5502
|
} = await import("./tmux-routing.js");
|
|
5208
5503
|
const { baseAgentName, getCoordinatorName } = await import("./employees.js");
|
|
5209
5504
|
const agentsWithEmptyInbox = /* @__PURE__ */ new Set();
|
|
@@ -5236,6 +5531,18 @@ function startIntercomQueueDrain() {
|
|
|
5236
5531
|
if (count !== null) pendingReviewCounts.set(target, count);
|
|
5237
5532
|
}
|
|
5238
5533
|
}
|
|
5534
|
+
const openTaskCounts = /* @__PURE__ */ new Map();
|
|
5535
|
+
{
|
|
5536
|
+
const queue = readQueue();
|
|
5537
|
+
const taskTargets = new Set(
|
|
5538
|
+
queue.filter((q) => q.intercomReason === "nudge" || q.intercomReason === "signal" || !q.intercomReason).map((q) => q.targetSession)
|
|
5539
|
+
);
|
|
5540
|
+
for (const target of taskTargets) {
|
|
5541
|
+
const agent = baseAgentName(target.split("-")[0] ?? target);
|
|
5542
|
+
const count = await countScopedOpenTasks(target, agent);
|
|
5543
|
+
if (count !== null) openTaskCounts.set(target, count);
|
|
5544
|
+
}
|
|
5545
|
+
}
|
|
5239
5546
|
const result = await drainQueueAsync(
|
|
5240
5547
|
// Bug ddbfc3f6: async busy check via the shared async pane cache —
|
|
5241
5548
|
// no sync execFileSync("tmux") per queue item on the event loop.
|
|
@@ -5247,24 +5554,52 @@ function startIntercomQueueDrain() {
|
|
|
5247
5554
|
try {
|
|
5248
5555
|
const agentRaw = session.split("-")[0] ?? session;
|
|
5249
5556
|
const agent = baseAgentName(agentRaw);
|
|
5250
|
-
const
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5557
|
+
const pane = await capturePaneAsync(session, 8);
|
|
5558
|
+
return await decideDrainSend(item, {
|
|
5559
|
+
pane,
|
|
5560
|
+
paneState: classifyPaneState(pane),
|
|
5561
|
+
hasPendingInput: paneHasPendingInput(pane),
|
|
5562
|
+
nudgeState: {
|
|
5563
|
+
hasUnreadMessages: !agentsWithEmptyInbox.has(agent),
|
|
5564
|
+
pendingReviewCount: pendingReviewCounts.get(session) ?? null,
|
|
5565
|
+
openTaskCount: openTaskCounts.get(session) ?? null,
|
|
5566
|
+
hasInProgressTask: false
|
|
5567
|
+
},
|
|
5568
|
+
deliver: (s, reason) => centralSendIntercomAsync(s, { reason }),
|
|
5569
|
+
disposition: dispositionWedgedSessionTask
|
|
5262
5570
|
});
|
|
5263
|
-
return outcome === "delivered" || outcome === "debounced" || outcome === "skipped_exe";
|
|
5264
5571
|
} catch (e) {
|
|
5265
5572
|
process.stderr.write("[exe-daemon] intercom send to " + session + ": " + (e instanceof Error ? e.message : String(e)) + "\n");
|
|
5266
5573
|
return false;
|
|
5267
5574
|
}
|
|
5575
|
+
},
|
|
5576
|
+
void 0,
|
|
5577
|
+
// notifyExpiry — use the module default (notifyExpiredIntercom)
|
|
5578
|
+
10,
|
|
5579
|
+
// Terminal disposition (bug e9c19ffe + e7880e0e): a nudge that has
|
|
5580
|
+
// exhausted its retry budget (or TTL-expired) against a wedged EMPLOYEE
|
|
5581
|
+
// session routes that session's in_progress task to blocked. Pure DB
|
|
5582
|
+
// write — never a keystroke, never a buffer clear — so a human
|
|
5583
|
+
// mid-typing can never be clobbered. Round 4: an empty/uncapturable pane
|
|
5584
|
+
// is OFFLINE (⇒ wedged), and only a CONFIRMED "dispositioned" removes the
|
|
5585
|
+
// item; "error" returns false so drainQueueAsync keeps it for retry.
|
|
5586
|
+
async (item) => {
|
|
5587
|
+
try {
|
|
5588
|
+
const pane = await capturePaneAsync(item.targetSession, 8);
|
|
5589
|
+
const state = offlineIfEmpty(pane, classifyPaneState(pane));
|
|
5590
|
+
const hasPendingInput = paneHasPendingInput(pane);
|
|
5591
|
+
const outcome = await dispositionWedgedSessionTask(
|
|
5592
|
+
item.targetSession,
|
|
5593
|
+
`Auto-blocked: intercom (${item.intercomReason ?? "nudge"}) undeliverable after retry budget exhausted \u2014 session wedged (state=${state}, pendingInput=${hasPendingInput}; ${item.reason}). Re-dispatch after clearing the pane.`,
|
|
5594
|
+
{ state, hasPendingInput }
|
|
5595
|
+
);
|
|
5596
|
+
if (outcome === "dispositioned") return "dispositioned";
|
|
5597
|
+
if (outcome === "error") return "error";
|
|
5598
|
+
return "declined";
|
|
5599
|
+
} catch (e) {
|
|
5600
|
+
process.stderr.write("[exe-daemon] intercom disposition for " + item.targetSession + ": " + (e instanceof Error ? e.message : String(e)) + "\n");
|
|
5601
|
+
return "error";
|
|
5602
|
+
}
|
|
5268
5603
|
}
|
|
5269
5604
|
);
|
|
5270
5605
|
if (result.drained > 0 || result.failed > 0) {
|
|
@@ -5287,7 +5622,7 @@ function startLedgerDrain() {
|
|
|
5287
5622
|
const tick = async () => traceDaemonTimer("ledger_drain", async () => {
|
|
5288
5623
|
fired("ledger_drain");
|
|
5289
5624
|
try {
|
|
5290
|
-
const { isLedgerEnabled, drainLedger } = await import("../notification-ledger-
|
|
5625
|
+
const { isLedgerEnabled, drainLedger } = await import("../notification-ledger-SZEPGJQ7.js");
|
|
5291
5626
|
if (!isLedgerEnabled()) return;
|
|
5292
5627
|
const result = await drainLedger({
|
|
5293
5628
|
// Shadow "would-deliver": idle target = would-deliver, busy = retry.
|
|
@@ -5326,7 +5661,7 @@ function startOrphanReaper() {
|
|
|
5326
5661
|
const tick = async () => traceDaemonTimer("orphan_reaper", async () => {
|
|
5327
5662
|
fired("orphan_reaper");
|
|
5328
5663
|
try {
|
|
5329
|
-
const { reapOrphanedMcpProcesses, createOrphanReaperRealDepsAsync } = await import("../daemon-orchestration-
|
|
5664
|
+
const { reapOrphanedMcpProcesses, createOrphanReaperRealDepsAsync } = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
5330
5665
|
const deps = await createOrphanReaperRealDepsAsync();
|
|
5331
5666
|
const reaped = await reapOrphanedMcpProcesses(deps);
|
|
5332
5667
|
if (reaped.length > 0) acted("orphan_reaper");
|
|
@@ -5351,7 +5686,7 @@ function startZombieAgentReaper() {
|
|
|
5351
5686
|
const tick = async () => traceDaemonTimer("zombie_agent_reaper", async () => {
|
|
5352
5687
|
fired("zombie_agent_reaper");
|
|
5353
5688
|
try {
|
|
5354
|
-
const { reapZombieAgentProcesses, createZombieAgentReaperRealDepsAsync } = await import("../daemon-orchestration-
|
|
5689
|
+
const { reapZombieAgentProcesses, createZombieAgentReaperRealDepsAsync } = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
5355
5690
|
const deps = await createZombieAgentReaperRealDepsAsync();
|
|
5356
5691
|
const reaped = reapZombieAgentProcesses(deps);
|
|
5357
5692
|
if (reaped.length > 0) acted("zombie_agent_reaper");
|
|
@@ -5375,7 +5710,7 @@ async function startDaemonMemoryPressureWatchdog() {
|
|
|
5375
5710
|
try {
|
|
5376
5711
|
const cfg = await getCachedConfig();
|
|
5377
5712
|
if (!cfg) return;
|
|
5378
|
-
const { startMemoryPressureWatchdog: startWatchdog, MEMORY_PRESSURE_WATCHDOG_DEFAULTS } = await import("../memory-pressure-watchdog-
|
|
5713
|
+
const { startMemoryPressureWatchdog: startWatchdog, MEMORY_PRESSURE_WATCHDOG_DEFAULTS } = await import("../memory-pressure-watchdog-HN5X7AVN.js");
|
|
5379
5714
|
const watchdogCfg = {
|
|
5380
5715
|
...MEMORY_PRESSURE_WATCHDOG_DEFAULTS,
|
|
5381
5716
|
...cfg.memoryPressureWatchdog ?? {}
|
|
@@ -5406,7 +5741,7 @@ function startWorktreeReaper() {
|
|
|
5406
5741
|
const tick = async () => traceDaemonTimer("worktree_reaper", async () => {
|
|
5407
5742
|
fired("worktree_reaper");
|
|
5408
5743
|
try {
|
|
5409
|
-
const { reapOrphanedWorktrees, createWorktreeReaperRealDeps } = await import("../daemon-orchestration-
|
|
5744
|
+
const { reapOrphanedWorktrees, createWorktreeReaperRealDeps } = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
5410
5745
|
const deps = await createWorktreeReaperRealDeps();
|
|
5411
5746
|
const result = await reapOrphanedWorktrees(deps);
|
|
5412
5747
|
if (result.pruned.length > 0) {
|
|
@@ -5446,9 +5781,9 @@ function startWorktreeReaper() {
|
|
|
5446
5781
|
}
|
|
5447
5782
|
continue;
|
|
5448
5783
|
}
|
|
5449
|
-
const { cleanupAgentWorktree } = await import("../worktree-sweep-
|
|
5450
|
-
const {
|
|
5451
|
-
const repoRoot =
|
|
5784
|
+
const { cleanupAgentWorktree } = await import("../worktree-sweep-WTK3MTKH.js");
|
|
5785
|
+
const { getMainRepoRootAsync } = await import("../worktree-LL62PLQB.js");
|
|
5786
|
+
const repoRoot = await getMainRepoRootAsync(signal.worktreePath);
|
|
5452
5787
|
if (repoRoot && signal.agentId) {
|
|
5453
5788
|
const notes = await cleanupAgentWorktree(repoRoot, signal.agentId);
|
|
5454
5789
|
if (notes) {
|
|
@@ -5480,7 +5815,7 @@ function startAutoWake() {
|
|
|
5480
5815
|
if (!await ensureStoreForPolling()) return;
|
|
5481
5816
|
try {
|
|
5482
5817
|
const { getClient } = await import("./database.js");
|
|
5483
|
-
const { pollOrphanedTasks, createAutoWakeRealDeps } = await import("../daemon-orchestration-
|
|
5818
|
+
const { pollOrphanedTasks, createAutoWakeRealDeps } = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
5484
5819
|
const deps = createAutoWakeRealDeps(getClient, process.cwd(), getTmuxSessionsAsync);
|
|
5485
5820
|
const woken = await pollOrphanedTasks(deps);
|
|
5486
5821
|
if (woken.length > 0) acted("auto_wake");
|
|
@@ -5492,7 +5827,7 @@ function startAutoWake() {
|
|
|
5492
5827
|
const signalBase = path3.join(os2.homedir(), ".exe-os", "task-signals");
|
|
5493
5828
|
if (existsSync4(signalBase)) {
|
|
5494
5829
|
const { readdirSync: readdirSync2, statSync: statSyncFs } = await import("fs");
|
|
5495
|
-
const { sendIntercomAsync } = await import("./tmux-routing.js");
|
|
5830
|
+
const { sendIntercomAsync, extractRootExe } = await import("./tmux-routing.js");
|
|
5496
5831
|
const sessionCache = path3.join(os2.homedir(), ".exe-os", "session-cache");
|
|
5497
5832
|
const sessions = await getTmuxSessionsAsync();
|
|
5498
5833
|
const signalDirs = [];
|
|
@@ -5531,7 +5866,7 @@ function startAutoWake() {
|
|
|
5531
5866
|
if (age > 60 * 60 * 1e3) {
|
|
5532
5867
|
try {
|
|
5533
5868
|
unlinkSync2(signalPath);
|
|
5534
|
-
void import("../orchestration-events-
|
|
5869
|
+
void import("../orchestration-events-WV4NWKZH.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
|
|
5535
5870
|
recordOE({ eventType: "signal.stale", source: "exe-daemon.autoWake", severity: "warn", payload: { file, ageMinutes: Math.round(age / 6e4) } });
|
|
5536
5871
|
}).catch(() => {
|
|
5537
5872
|
});
|
|
@@ -5560,9 +5895,17 @@ function startAutoWake() {
|
|
|
5560
5895
|
`
|
|
5561
5896
|
);
|
|
5562
5897
|
} else {
|
|
5563
|
-
|
|
5564
|
-
|
|
5898
|
+
const nudgeScope = scope ?? extractRootExe(match) ?? null;
|
|
5899
|
+
const result = await sendIntercomAsync(match, { force: true, reason: "signal", callerSessionScope: nudgeScope });
|
|
5900
|
+
if (result === "failed") {
|
|
5901
|
+
process.stderr.write(
|
|
5902
|
+
`[exed] Signal-nudge: delivery FAILED to ${match} (signal age ${Math.round(age / 1e3)}s, scope=${nudgeScope ?? "none"}) \u2014 signal kept; will retry next tick
|
|
5903
|
+
`
|
|
5904
|
+
);
|
|
5905
|
+
} else {
|
|
5906
|
+
process.stderr.write(`[exed] Signal-nudge: ${result} intercom to ${match} (signal age ${Math.round(age / 1e3)}s)
|
|
5565
5907
|
`);
|
|
5908
|
+
}
|
|
5566
5909
|
}
|
|
5567
5910
|
}
|
|
5568
5911
|
}
|
|
@@ -5591,7 +5934,7 @@ function startWalCheckpoint() {
|
|
|
5591
5934
|
try {
|
|
5592
5935
|
const { getClient, runWalCheckpoint } = await import("./database.js");
|
|
5593
5936
|
const client = getClient();
|
|
5594
|
-
const { findActiveDb } = await import("../db-backup-
|
|
5937
|
+
const { findActiveDb } = await import("../db-backup-W2QFSYQC.js");
|
|
5595
5938
|
const dbPath = findActiveDb();
|
|
5596
5939
|
const started = Date.now();
|
|
5597
5940
|
const result = await runWalCheckpoint(client, dbPath, true);
|
|
@@ -5669,7 +6012,7 @@ function startStuckTaskRelease() {
|
|
|
5669
6012
|
createStuckTaskRealDeps,
|
|
5670
6013
|
escalateStuckBlockedTasks,
|
|
5671
6014
|
createStuckBlockedRealDeps
|
|
5672
|
-
} = await import("../daemon-orchestration-
|
|
6015
|
+
} = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
5673
6016
|
const deps = createStuckTaskRealDeps(getClient);
|
|
5674
6017
|
const released = await releaseStuckTasks(deps);
|
|
5675
6018
|
if (released.length > 0) {
|
|
@@ -5864,12 +6207,12 @@ function startTaskEnforcementScanner() {
|
|
|
5864
6207
|
const tick = async () => traceDaemonTimer("task_enforcement", async () => {
|
|
5865
6208
|
fired("task_enforcement");
|
|
5866
6209
|
try {
|
|
5867
|
-
const { runTaskEnforcementTick } = await import("../task-enforcement-
|
|
6210
|
+
const { runTaskEnforcementTick } = await import("../task-enforcement-IPIZX2MM.js");
|
|
5868
6211
|
const { getTransport } = await import("./transport.js");
|
|
5869
6212
|
const { loadAgentConfig } = await import("./agent-config.js");
|
|
5870
6213
|
const { getClient } = await import("./database.js");
|
|
5871
6214
|
const { loadEmployeesSync } = await import("./employees.js");
|
|
5872
|
-
const { sessionScopeFilter } = await import("../task-scope-
|
|
6215
|
+
const { sessionScopeFilter } = await import("../task-scope-FOIW25HR.js");
|
|
5873
6216
|
const transport = getTransport();
|
|
5874
6217
|
const { sessions: allSessions, paneCache, aliveSessions } = await getSharedOrchestrationCaches();
|
|
5875
6218
|
await yieldToEventLoop();
|
|
@@ -5880,10 +6223,10 @@ function startTaskEnforcementScanner() {
|
|
|
5880
6223
|
sendKeysLiteral: transport.sendKeysLiteral?.bind(transport),
|
|
5881
6224
|
isAlive: (session) => aliveSessions.has(session)
|
|
5882
6225
|
};
|
|
5883
|
-
const { checkAutoWakeGates } = await import("../daemon-orchestration-
|
|
5884
|
-
const { ensureEmployeeAsync, employeeSessionName } = await import("./tmux-routing.js");
|
|
6226
|
+
const { checkAutoWakeGates } = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
6227
|
+
const { ensureEmployeeAsync, employeeSessionName, sendIntercomAsync } = await import("./tmux-routing.js");
|
|
5885
6228
|
const { shouldAutoInstance } = await import("./employees.js");
|
|
5886
|
-
const { recordOrchestrationEventBestEffort } = await import("../orchestration-events-
|
|
6229
|
+
const { recordOrchestrationEventBestEffort } = await import("../orchestration-events-WV4NWKZH.js");
|
|
5887
6230
|
const projectDir = process.cwd();
|
|
5888
6231
|
await runTaskEnforcementTick({
|
|
5889
6232
|
transport: enforcementTransport,
|
|
@@ -5908,6 +6251,16 @@ function startTaskEnforcementScanner() {
|
|
|
5908
6251
|
`));
|
|
5909
6252
|
return { status: "intercom_unprocessed", sessionName: employeeSessionName(reviewerName, sessionScope) };
|
|
5910
6253
|
},
|
|
6254
|
+
// Bug 018aaf31: wake a LIVE-but-idle reviewer/coordinator that owns a
|
|
6255
|
+
// needs_review item. Same intercom funnel as the worker-nudge; reason
|
|
6256
|
+
// "completion" renders "An employee completed work — review it". The
|
|
6257
|
+
// input-buffer/busy/idle/debounce guards inside sendIntercom decide
|
|
6258
|
+
// whether to type, queue, or defer — so this never splices into a founder
|
|
6259
|
+
// keystroke and never piles onto a busy reviewer.
|
|
6260
|
+
reviewerNudge: (reviewerSession, sessionScope) => {
|
|
6261
|
+
void sendIntercomAsync(reviewerSession, { callerSessionScope: sessionScope, reason: "completion" }).catch((err) => process.stderr.write(`[exed] Reviewer nudge async failed for ${reviewerSession}: ${err instanceof Error ? err.message : String(err)}
|
|
6262
|
+
`));
|
|
6263
|
+
},
|
|
5911
6264
|
zombieWorkerRecover: async (session, agentName, sessionScope, reason) => {
|
|
5912
6265
|
const gateReason = checkAutoWakeGates(`mcp-zombie::${agentName}::${sessionScope || session}`, Date.now());
|
|
5913
6266
|
if (gateReason) {
|
|
@@ -6165,7 +6518,7 @@ function startBackgroundJobGuardrails() {
|
|
|
6165
6518
|
const tick = async () => traceDaemonTimer("background_job_guardrails", async () => {
|
|
6166
6519
|
fired("background_job_guardrails");
|
|
6167
6520
|
try {
|
|
6168
|
-
const { enforceBackgroundJobGuardrailsAsync } = await import("../background-jobs-
|
|
6521
|
+
const { enforceBackgroundJobGuardrailsAsync } = await import("../background-jobs-EXR5RVGG.js");
|
|
6169
6522
|
const actions = await enforceBackgroundJobGuardrailsAsync();
|
|
6170
6523
|
if (actions.length > 0) {
|
|
6171
6524
|
acted("background_job_guardrails");
|
|
@@ -6198,11 +6551,14 @@ function handleSignalShutdown() {
|
|
|
6198
6551
|
...signalAttribution
|
|
6199
6552
|
});
|
|
6200
6553
|
logShutdown(restartIntent ? "restart shutdown" : "graceful shutdown", "SIGTERM/SIGINT", signalAttribution);
|
|
6201
|
-
void shutdown(restartIntent ? 75 : 0);
|
|
6554
|
+
void shutdown(restartIntent ? 75 : 0, restartIntent ? reason ?? "restart-intent" : null);
|
|
6202
6555
|
}
|
|
6203
6556
|
process.on("SIGINT", handleSignalShutdown);
|
|
6204
6557
|
process.on("SIGTERM", handleSignalShutdown);
|
|
6205
6558
|
process.on("exit", (code) => {
|
|
6559
|
+
if (_bootPhase !== "ready" && code !== 0) {
|
|
6560
|
+
recordExitBreadcrumb("boot-abort", code, `boot_abort:${_bootPhase}`);
|
|
6561
|
+
}
|
|
6206
6562
|
if (_bootPhase === "ready") return;
|
|
6207
6563
|
try {
|
|
6208
6564
|
logDaemonHealth({
|
|
@@ -6320,7 +6676,7 @@ function startBugAutoFix() {
|
|
|
6320
6676
|
for (const exeSession of exeSessions) {
|
|
6321
6677
|
const ctoSession = `${ctoName}-${exeSession}`;
|
|
6322
6678
|
if (sessions.includes(ctoSession)) {
|
|
6323
|
-
await sendIntercomAsync(ctoSession);
|
|
6679
|
+
await sendIntercomAsync(ctoSession, { callerSessionScope: exeSession });
|
|
6324
6680
|
break;
|
|
6325
6681
|
}
|
|
6326
6682
|
}
|
|
@@ -6496,9 +6852,9 @@ function startAutoUpdateCheck() {
|
|
|
6496
6852
|
const effectiveChannel = updateChannel ?? "stable";
|
|
6497
6853
|
if (effectiveChannel === "pinned") return;
|
|
6498
6854
|
if (!autoInstall && !config.autoUpdate.checkOnBoot) return;
|
|
6499
|
-
const {
|
|
6855
|
+
const { checkForUpdateAsync, channelToInstallTag } = await import("../update-check-3FHAWIG2.js");
|
|
6500
6856
|
const packageRoot = new URL("../..", import.meta.url).pathname;
|
|
6501
|
-
const result =
|
|
6857
|
+
const result = await checkForUpdateAsync(packageRoot, effectiveChannel);
|
|
6502
6858
|
if (!result.updateAvailable) return;
|
|
6503
6859
|
acted("auto_update_check");
|
|
6504
6860
|
const channelLabel = effectiveChannel === "canary" ? " (canary)" : "";
|
|
@@ -6599,7 +6955,7 @@ if (process.platform === "darwin") {
|
|
|
6599
6955
|
logBoot({ socketPath: SOCKET_PATH, pidPath: PID_PATH });
|
|
6600
6956
|
void (async () => {
|
|
6601
6957
|
try {
|
|
6602
|
-
const { cleanupCrashDebris } = await import("../db-backup-
|
|
6958
|
+
const { cleanupCrashDebris } = await import("../db-backup-W2QFSYQC.js");
|
|
6603
6959
|
const removed = cleanupCrashDebris();
|
|
6604
6960
|
if (removed > 0) {
|
|
6605
6961
|
process.stderr.write(`[exed] Startup cleanup: pruned ${removed} crash-debris file(s) (backups/quarantine).
|
|
@@ -6745,9 +7101,7 @@ function startEventLoopLagDetector() {
|
|
|
6745
7101
|
const SELF_INFLICTED_ROLLING_WINDOW_MS = parseFloat(process.env.EXE_SELF_INFLICTED_ROLLING_WINDOW_MS ?? "") || 3e5;
|
|
6746
7102
|
const LAG_WARN_MS = 3e3;
|
|
6747
7103
|
const LAG_CRITICAL_MS = 1e4;
|
|
6748
|
-
const SELF_HEAL_SINGLE_MS
|
|
6749
|
-
const SELF_HEAL_CONSECUTIVE = parseInt(process.env.EXE_SELF_HEAL_CONSECUTIVE ?? "") || 3;
|
|
6750
|
-
const SELF_HEAL_THRESHOLD_MS = parseFloat(process.env.EXE_SELF_HEAL_THRESHOLD_MS ?? "") || 3e4;
|
|
7104
|
+
const { singleMs: SELF_HEAL_SINGLE_MS, consecutive: SELF_HEAL_CONSECUTIVE, thresholdMs: SELF_HEAL_THRESHOLD_MS } = resolveSelfHealThresholds();
|
|
6751
7105
|
let consecutiveSevereBlocks = 0;
|
|
6752
7106
|
let selfInflictedWindow = [];
|
|
6753
7107
|
touchEventLoopHeartbeat();
|
|
@@ -6775,7 +7129,7 @@ function startEventLoopLagDetector() {
|
|
|
6775
7129
|
const msg = `[exed] EVENT LOOP BLOCKED ${(lag / 1e3).toFixed(1)}s \u2014 MCP UNRESPONSIVE. Sessions will die.`;
|
|
6776
7130
|
process.stderr.write(msg + "\n");
|
|
6777
7131
|
logDaemonHealth({ event: "event_loop_blocked", pid: process.pid, message: msg, data: { lagMs: lag } });
|
|
6778
|
-
void import("../orchestration-events-
|
|
7132
|
+
void import("../orchestration-events-WV4NWKZH.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
|
|
6779
7133
|
recordOE({ eventType: "daemon.event_loop_blocked", source: "exe-daemon.lagDetector", severity: "error", durationMs: lag });
|
|
6780
7134
|
}).catch(() => {
|
|
6781
7135
|
});
|
|
@@ -6798,7 +7152,7 @@ function startEventLoopLagDetector() {
|
|
|
6798
7152
|
}
|
|
6799
7153
|
const load1m = os2.loadavg()[0] ?? 0;
|
|
6800
7154
|
const cpuCount = os2.cpus().length || 1;
|
|
6801
|
-
const starvationRatio =
|
|
7155
|
+
const starvationRatio = resolveSelfHealThresholds().starvationRatio;
|
|
6802
7156
|
const catchUpActive = inBootCatchUpGrace();
|
|
6803
7157
|
const decision = decideDaemonSelfHeal({
|
|
6804
7158
|
lagMs: lag,
|
|
@@ -6876,7 +7230,7 @@ function startEventLoopLagDetector() {
|
|
|
6876
7230
|
_lastSelfHealShutdownAtMs = Date.now();
|
|
6877
7231
|
process.stderr.write(healMsg + "\n");
|
|
6878
7232
|
logDaemonHealth({ event: "self_heal_restart", pid: process.pid, message: healMsg, data: { lagMs: lag, reason: "single_block" } });
|
|
6879
|
-
|
|
7233
|
+
dispatchSelfHealRestart(lag, "single_block", SELF_HEAL_ACTION_DEPS);
|
|
6880
7234
|
return;
|
|
6881
7235
|
}
|
|
6882
7236
|
if (decision.restart && decision.reason === "consecutive_blocks") {
|
|
@@ -6890,7 +7244,7 @@ function startEventLoopLagDetector() {
|
|
|
6890
7244
|
_lastSelfHealShutdownAtMs = Date.now();
|
|
6891
7245
|
process.stderr.write(healMsg + "\n");
|
|
6892
7246
|
logDaemonHealth({ event: "self_heal_restart", pid: process.pid, message: healMsg, data: { lagMs: lag, reason: "consecutive_blocks", count: consecutiveSevereBlocks } });
|
|
6893
|
-
|
|
7247
|
+
dispatchSelfHealRestart(lag, "consecutive_blocks", SELF_HEAL_ACTION_DEPS);
|
|
6894
7248
|
return;
|
|
6895
7249
|
}
|
|
6896
7250
|
} else if (lag > LAG_WARN_MS) {
|
|
@@ -6957,7 +7311,7 @@ function startTaskFileResync() {
|
|
|
6957
7311
|
});
|
|
6958
7312
|
if (Number(res.rowsAffected ?? 0) > 0) {
|
|
6959
7313
|
synced++;
|
|
6960
|
-
void import("../orchestration-events-
|
|
7314
|
+
void import("../orchestration-events-WV4NWKZH.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
|
|
6961
7315
|
recordOE({
|
|
6962
7316
|
eventType: "task_file.resynced",
|
|
6963
7317
|
source: "exe-daemon.taskFileResync",
|
|
@@ -6994,7 +7348,7 @@ function startTaskGroupBarriers() {
|
|
|
6994
7348
|
fired("task_group_barriers");
|
|
6995
7349
|
if (!await ensureStoreForPolling()) return;
|
|
6996
7350
|
try {
|
|
6997
|
-
const { pollTaskGroupBarriers } = await import("../daemon-orchestration-
|
|
7351
|
+
const { pollTaskGroupBarriers } = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
6998
7352
|
const firedCount = await pollTaskGroupBarriers();
|
|
6999
7353
|
if (firedCount > 0) {
|
|
7000
7354
|
acted("task_group_barriers");
|
|
@@ -7016,7 +7370,7 @@ function startCheckpointGc() {
|
|
|
7016
7370
|
fired("checkpoint_gc");
|
|
7017
7371
|
if (!await ensureStoreForPolling()) return;
|
|
7018
7372
|
try {
|
|
7019
|
-
const { gcStaleCheckpoints } = await import("../daemon-orchestration-
|
|
7373
|
+
const { gcStaleCheckpoints } = await import("../daemon-orchestration-FX4XZDR5.js");
|
|
7020
7374
|
const cleared = await gcStaleCheckpoints();
|
|
7021
7375
|
if (cleared > 0) {
|
|
7022
7376
|
acted("checkpoint_gc");
|
|
@@ -7047,7 +7401,7 @@ function startDaemonHeartbeat() {
|
|
|
7047
7401
|
function startDispatchAckCleanup() {
|
|
7048
7402
|
setInterval(async () => {
|
|
7049
7403
|
try {
|
|
7050
|
-
const { cleanStaleDispatchAcks } = await import("../dispatch-ack-
|
|
7404
|
+
const { cleanStaleDispatchAcks } = await import("../dispatch-ack-VYH3ONSS.js");
|
|
7051
7405
|
cleanStaleDispatchAcks();
|
|
7052
7406
|
} catch {
|
|
7053
7407
|
}
|
|
@@ -7056,14 +7410,14 @@ function startDispatchAckCleanup() {
|
|
|
7056
7410
|
function startProjectionWorkerDeferred() {
|
|
7057
7411
|
setTimeout(async () => {
|
|
7058
7412
|
try {
|
|
7059
|
-
const { startProjectionWorker } = await import("../projection-worker-
|
|
7413
|
+
const { startProjectionWorker } = await import("../projection-worker-FZ7YSN3G.js");
|
|
7060
7414
|
startProjectionWorker();
|
|
7061
7415
|
} catch {
|
|
7062
7416
|
}
|
|
7063
7417
|
}, 2e4);
|
|
7064
7418
|
}
|
|
7065
7419
|
async function startToolTelemetry() {
|
|
7066
|
-
const { startToolTelemetryFlush } = await import("../tool-telemetry-
|
|
7420
|
+
const { startToolTelemetryFlush } = await import("../tool-telemetry-KBXSBDTK.js");
|
|
7067
7421
|
startToolTelemetryFlush();
|
|
7068
7422
|
process.stderr.write("[exed] Tool telemetry started (flush every 5m)\n");
|
|
7069
7423
|
}
|
|
@@ -7229,7 +7583,7 @@ function startLocalFirstTimers() {
|
|
|
7229
7583
|
fired("orphan_task_cleanup");
|
|
7230
7584
|
try {
|
|
7231
7585
|
if (!await ensureStoreForPolling()) return;
|
|
7232
|
-
const { cleanOrphanedTaskFiles } = await import("../tasks-crud-
|
|
7586
|
+
const { cleanOrphanedTaskFiles } = await import("../tasks-crud-HBDKE6C5.js");
|
|
7233
7587
|
const count = await cleanOrphanedTaskFiles();
|
|
7234
7588
|
if (count > 0) {
|
|
7235
7589
|
acted("orphan_task_cleanup");
|
|
@@ -7245,7 +7599,7 @@ function startLocalFirstTimers() {
|
|
|
7245
7599
|
fired("task_file_consistency");
|
|
7246
7600
|
try {
|
|
7247
7601
|
if (!await ensureStoreForPolling()) return;
|
|
7248
|
-
const { checkTaskFileConsistency } = await import("../tasks-crud-
|
|
7602
|
+
const { checkTaskFileConsistency } = await import("../tasks-crud-HBDKE6C5.js");
|
|
7249
7603
|
const mismatches = await checkTaskFileConsistency();
|
|
7250
7604
|
if (mismatches > 0) {
|
|
7251
7605
|
acted("task_file_consistency");
|
|
@@ -7264,7 +7618,7 @@ function startLocalFirstTimers() {
|
|
|
7264
7618
|
const TELEMETRY_DAILY_MS = 24 * 60 * 60 * 1e3;
|
|
7265
7619
|
const telemetryDaily = async () => {
|
|
7266
7620
|
try {
|
|
7267
|
-
const { sendTelemetry, isTelemetryEnabled } = await import("../telemetry-upload-
|
|
7621
|
+
const { sendTelemetry, isTelemetryEnabled } = await import("../telemetry-upload-ZOXHRWR5.js");
|
|
7268
7622
|
if (!isTelemetryEnabled()) return;
|
|
7269
7623
|
const { upstream } = await sendTelemetry(24);
|
|
7270
7624
|
if (upstream.startsWith("sent")) {
|
|
@@ -7376,7 +7730,76 @@ function startLocalFirstTimers() {
|
|
|
7376
7730
|
}
|
|
7377
7731
|
}, 3e4);
|
|
7378
7732
|
}
|
|
7733
|
+
async function enterDegradedBreakerMode(crashCount) {
|
|
7734
|
+
const requestedHost = process.env.EXE_MCP_HOST || "127.0.0.1";
|
|
7735
|
+
const isRemote = !["127.0.0.1", "::1", "localhost"].includes(requestedHost);
|
|
7736
|
+
const allowRemote = /^(1|true|yes|on)$/i.test(process.env.EXE_MCP_ALLOW_REMOTE ?? "");
|
|
7737
|
+
const host = isRemote && !allowRemote ? "127.0.0.1" : requestedHost;
|
|
7738
|
+
let port = 48739;
|
|
7739
|
+
try {
|
|
7740
|
+
port = await resolveAndClaimPort();
|
|
7741
|
+
} catch {
|
|
7742
|
+
}
|
|
7743
|
+
const degradedBody = () => JSON.stringify({
|
|
7744
|
+
jsonrpc: "2.0",
|
|
7745
|
+
error: {
|
|
7746
|
+
code: -32002,
|
|
7747
|
+
message: `exe-os daemon is DEGRADED \u2014 restart circuit breaker OPEN after ${crashCount} crash restarts (bug 2fee6110). Heavy work is suspended to protect system memory. Recover: 'exe-os daemon reset-breaker' then relaunch. Details: 'exe-os daemon status'.`
|
|
7748
|
+
},
|
|
7749
|
+
id: null
|
|
7750
|
+
});
|
|
7751
|
+
const srv = createHttpServer((req, res) => {
|
|
7752
|
+
try {
|
|
7753
|
+
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1");
|
|
7754
|
+
const p = (req.url || "/").split("?")[0];
|
|
7755
|
+
if (req.method === "GET" && p === "/health") {
|
|
7756
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
7757
|
+
res.end(JSON.stringify({
|
|
7758
|
+
status: "degraded",
|
|
7759
|
+
reason: "restart_circuit_breaker_tripped",
|
|
7760
|
+
crashRestartsInWindow: crashCount,
|
|
7761
|
+
version: PACKAGE_VERSION,
|
|
7762
|
+
alert: readBreakerAlert() ?? void 0,
|
|
7763
|
+
recovery: "exe-os daemon reset-breaker"
|
|
7764
|
+
}));
|
|
7765
|
+
return;
|
|
7766
|
+
}
|
|
7767
|
+
res.writeHead(503, { "Content-Type": "application/json", "Retry-After": "300" });
|
|
7768
|
+
res.end(degradedBody());
|
|
7769
|
+
} catch {
|
|
7770
|
+
}
|
|
7771
|
+
});
|
|
7772
|
+
await new Promise((resolve) => {
|
|
7773
|
+
srv.once("error", (err) => {
|
|
7774
|
+
process.stderr.write(`[exed] Degraded health server bind failed (${err.code || err.message}) \u2014 staying alive without it.
|
|
7775
|
+
`);
|
|
7776
|
+
resolve();
|
|
7777
|
+
});
|
|
7778
|
+
srv.listen(port, host, () => {
|
|
7779
|
+
process.stderr.write(`[exed] DEGRADED health server on ${host}:${port} (breaker tripped \u2014 503 + /health only).
|
|
7780
|
+
`);
|
|
7781
|
+
resolve();
|
|
7782
|
+
});
|
|
7783
|
+
});
|
|
7784
|
+
setInterval(() => {
|
|
7785
|
+
process.stderr.write(
|
|
7786
|
+
`[exed] DEGRADED (breaker open, ${crashCount} crashes). No DB/backups/timers. Recover: 'exe-os daemon reset-breaker'. Alert: ${restartBreakerAlertPath()}
|
|
7787
|
+
`
|
|
7788
|
+
);
|
|
7789
|
+
}, 5 * 60 * 1e3);
|
|
7790
|
+
}
|
|
7379
7791
|
try {
|
|
7792
|
+
const breaker = recordDaemonRestart();
|
|
7793
|
+
process.stderr.write(
|
|
7794
|
+
`[exed] Boot classified as ${breaker.bootClass} (${breaker.reasonLabel}); crashes=${breaker.crashInWindow}/${5}, restarts=${breaker.restartsInWindow} in window.
|
|
7795
|
+
`
|
|
7796
|
+
);
|
|
7797
|
+
if (breaker.trip) {
|
|
7798
|
+
logRestartEvent("daemon_restart_breaker_tripped", { crash_in_window: breaker.crashInWindow, restarts_in_window: breaker.restartsInWindow });
|
|
7799
|
+
await enterDegradedBreakerMode(breaker.crashInWindow);
|
|
7800
|
+
await new Promise(() => {
|
|
7801
|
+
});
|
|
7802
|
+
}
|
|
7380
7803
|
const mcpRegPath = new URL("../mcp/register-tools.js", import.meta.url).href;
|
|
7381
7804
|
const { registerAllTools: regFn } = await import(
|
|
7382
7805
|
/* @vite-ignore */
|
|
@@ -7419,6 +7842,7 @@ try {
|
|
|
7419
7842
|
}
|
|
7420
7843
|
export {
|
|
7421
7844
|
decidePortHolderAction,
|
|
7845
|
+
getLastBlockingTimer,
|
|
7422
7846
|
injectRegisterAllTools,
|
|
7423
7847
|
isCrashLoopBreakerActive,
|
|
7424
7848
|
isEventLoopBlockedNow,
|