@askexenow/exe-os 0.9.312 → 0.9.313
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/deploy/compose/.env.askexe-control-plane.example +1 -1
- package/deploy/compose/.env.customer.example +11 -7
- package/deploy/compose/.env.default +4 -4
- package/deploy/compose/.env.example +7 -7
- package/deploy/compose/docker-compose.yml +43 -19
- package/deploy/compose/gateway.json +2 -2
- package/deploy/compose/init-db.sql +6 -20
- package/deploy/compose/setup.sh +74 -132
- package/deploy/compose/status.sh +5 -0
- package/deploy/stack-manifests/v0.9.json +21 -0
- package/dist/{active-agent-ORX47ZKW.js → active-agent-EWF2HJ3W.js} +6 -6
- package/dist/{active-agent-S5T2YMOR.js → active-agent-FFN5ARMC.js} +6 -6
- package/dist/{agentic-ontology-6KBAXLSJ.js → agentic-ontology-AAUATKUS.js} +1 -1
- package/dist/{backfill-metadata-FV7GX6AS.js → backfill-metadata-FBYFDOTH.js} +7 -7
- package/dist/{background-jobs-A2LV36UX.js → background-jobs-2QZ5IQKE.js} +5 -3
- package/dist/{behaviors-47CPEKJ7.js → behaviors-PQ77IPJR.js} +8 -8
- package/dist/bin/age-ontology-load.js +3 -3
- package/dist/bin/agentic-ontology-backfill.js +9 -9
- package/dist/bin/agentic-reflection-backfill.js +10 -10
- package/dist/bin/agentic-semantic-label.js +9 -9
- package/dist/bin/backfill-conversations.js +10 -10
- package/dist/bin/backfill-responses.js +10 -10
- package/dist/bin/backfill-vectors.js +13 -13
- package/dist/bin/bulk-sync-postgres.js +16 -16
- package/dist/bin/cc-doctor.js +9 -9
- package/dist/bin/cleanup-stale-review-tasks.js +15 -15
- package/dist/bin/cli.js +21 -21
- package/dist/bin/deferred-daemon-restart.js +1 -1
- package/dist/bin/exe-agent-config.js +6 -6
- package/dist/bin/exe-agent.js +14 -14
- package/dist/bin/exe-assign.js +12 -12
- package/dist/bin/exe-boot.js +78 -57
- package/dist/bin/exe-call.js +7 -7
- package/dist/bin/exe-cloud.js +17 -17
- package/dist/bin/exe-config-dump.js +7 -7
- package/dist/bin/exe-dispatch.js +15 -15
- package/dist/bin/exe-doctor.js +11 -2
- package/dist/bin/exe-export-behaviors.js +10 -10
- package/dist/bin/exe-forget.js +9 -9
- package/dist/bin/exe-gateway.js +10 -10
- package/dist/bin/exe-healthcheck.js +9 -9
- package/dist/bin/exe-heartbeat.js +15 -15
- package/dist/bin/exe-kill.js +18 -18
- package/dist/bin/exe-launch-agent.js +30 -28
- package/dist/bin/exe-new-employee.js +36 -15
- package/dist/bin/exe-pending-messages.js +16 -16
- package/dist/bin/exe-pending-notifications.js +15 -15
- package/dist/bin/exe-pending-reviews.js +15 -15
- package/dist/bin/exe-preflight.js +1 -1
- package/dist/bin/exe-rename.js +19 -29
- package/dist/bin/exe-review.js +17 -17
- package/dist/bin/exe-search.js +8 -8
- package/dist/bin/exe-session-cleanup.js +41 -20
- package/dist/bin/exe-settings.js +18 -18
- package/dist/bin/exe-start-codex.js +15 -15
- package/dist/bin/exe-start-opencode.js +11 -11
- package/dist/bin/exe-status.js +16 -16
- package/dist/bin/exe-support.js +5 -5
- package/dist/bin/exe-team.js +6 -6
- package/dist/bin/exe-watchdog.js +32 -3
- package/dist/bin/git-sweep.js +16 -16
- package/dist/bin/graph-backfill.js +8 -8
- package/dist/bin/graph-export.js +8 -8
- package/dist/bin/import-history.js +10 -10
- package/dist/bin/install-launchd.js +2 -2
- package/dist/bin/install.js +15 -15
- package/dist/bin/intercom-check.js +4 -4
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +7 -7
- package/dist/bin/postgres-agentic-reflection-backfill.js +5 -5
- package/dist/bin/postgres-agentic-semantic-backfill.js +4 -4
- package/dist/bin/pre-build-guard.js +12 -1
- package/dist/bin/scan-tasks.js +15 -15
- package/dist/bin/setup.js +3 -3
- package/dist/bin/shard-migrate.js +8 -8
- package/dist/bin/stack-update.js +8 -8
- package/dist/bin/verify-stack.js +3 -1
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/{branding-SC4BOPUY.js → branding-EDUC7TUP.js} +2 -2
- package/dist/{browser-session-store-DV5TDXXD.js → browser-session-store-CXQMOSEC.js} +1 -1
- package/dist/{capability-cards-WQVY7WSS.js → capability-cards-2U3XWCDP.js} +5 -5
- package/dist/{capacity-monitor-BUKYPSWR.js → capacity-monitor-ZRLW7TVL.js} +16 -16
- package/dist/{catchup-brief-X5IVQAOH.js → catchup-brief-FSBZVYPL.js} +18 -18
- package/dist/{chunk-PMEOSD6S.js → chunk-24BUDF3J.js} +9 -6
- package/dist/{chunk-2NVEKSSP.js → chunk-2FULKRDO.js} +56 -38
- package/dist/{chunk-QB5JOGPK.js → chunk-2PI6JBJL.js} +5 -4
- package/dist/{chunk-MTIJ2NXY.js → chunk-2PWRUIKZ.js} +1 -1
- package/dist/{chunk-NIZQ3CIS.js → chunk-3AMGSCRH.js} +1 -1
- package/dist/{chunk-7ODTYODO.js → chunk-3LGID56M.js} +10 -7
- package/dist/{chunk-GSY6HL3T.js → chunk-4JI54RHR.js} +5 -5
- package/dist/{chunk-ISILDO7P.js → chunk-4THK7IA4.js} +1 -1
- package/dist/{chunk-IRIPGGGL.js → chunk-4UHQYBMQ.js} +1 -1
- package/dist/{chunk-HQODUV3G.js → chunk-552IGUBB.js} +2 -2
- package/dist/{chunk-IRHNV4GY.js → chunk-5KLQCGI5.js} +72 -18
- package/dist/{chunk-SOT23KWW.js → chunk-63UEWYM3.js} +4 -4
- package/dist/{chunk-QE7UVQDP.js → chunk-6PR2RAKM.js} +1 -1
- package/dist/{chunk-ZZXADKAP.js → chunk-6SPUK67A.js} +2 -2
- package/dist/{chunk-RVXWGPD3.js → chunk-75TM3APG.js} +29 -6
- package/dist/{chunk-IZPO6IOZ.js → chunk-7QSXARI3.js} +1 -1
- package/dist/{chunk-A2YZG4AD.js → chunk-AIUXE3ZJ.js} +6 -6
- package/dist/{chunk-U63BZI2B.js → chunk-AJERMFD6.js} +3 -3
- package/dist/{chunk-BUOMSIXH.js → chunk-BMNX3YWX.js} +2 -2
- package/dist/{chunk-YUBTHJVV.js → chunk-BRSMAFBN.js} +1 -1
- package/dist/{chunk-JZW5AOWI.js → chunk-BSPALHIR.js} +2 -2
- package/dist/{chunk-VDYUKTNS.js → chunk-CLAYNAXC.js} +4 -5
- package/dist/{chunk-J3QZPDNH.js → chunk-CNQ25C4C.js} +1 -1
- package/dist/{chunk-GWPICNSO.js → chunk-CSTL7BMK.js} +49 -4
- package/dist/{chunk-5DPE7B7K.js → chunk-CTYHSVHP.js} +1 -1
- package/dist/{chunk-EM4EYF3P.js → chunk-CVTWQZOR.js} +13 -5
- package/dist/{chunk-JNARUXDC.js → chunk-CW3FPWUW.js} +2 -2
- package/dist/{chunk-V42BSVX6.js → chunk-CWACO2D4.js} +51 -4
- package/dist/{chunk-RPBTYQKJ.js → chunk-CWUCD7C7.js} +1 -1
- package/dist/{chunk-DFUCFLZH.js → chunk-D4EMVYI7.js} +2 -2
- package/dist/{chunk-W2J2RF5N.js → chunk-DIHMGQGV.js} +3 -3
- package/dist/{chunk-YB7U4WTY.js → chunk-DJ4RG3RK.js} +2 -2
- package/dist/{chunk-KSMITUGY.js → chunk-DR7QPGX4.js} +3 -3
- package/dist/{chunk-QNXM2HXW.js → chunk-ELFFRVNL.js} +1 -1
- package/dist/{chunk-QEGXNJGR.js → chunk-EV2SMRLF.js} +4 -4
- package/dist/{chunk-VFSYVQX4.js → chunk-F3QMXKKJ.js} +8 -2
- package/dist/{chunk-NCC3F6GM.js → chunk-F5XPKUPK.js} +2 -2
- package/dist/{chunk-43R2GILO.js → chunk-FIBL4JRZ.js} +2 -2
- package/dist/{chunk-B2J3BBJC.js → chunk-FQH4R6UG.js} +2 -2
- package/dist/{chunk-AC6DKMVS.js → chunk-FSAKWKWU.js} +1 -1
- package/dist/{chunk-GL5NU6IK.js → chunk-FXS5OFGH.js} +1 -1
- package/dist/{chunk-K7KBAJQL.js → chunk-GHJRLETI.js} +10 -10
- package/dist/{chunk-VQRTO7IS.js → chunk-H73TUI4Y.js} +9 -2
- package/dist/{chunk-IIHE3FNC.js → chunk-HSXWUZOD.js} +3 -3
- package/dist/{chunk-JV225JBX.js → chunk-I6RHLHVW.js} +2 -2
- package/dist/{chunk-S6HVQF27.js → chunk-IEDCQRGG.js} +88 -4
- package/dist/{chunk-4Q5VNQTV.js → chunk-IFSOVXGN.js} +3 -3
- package/dist/{chunk-JMHKK7A5.js → chunk-ITVMRPCQ.js} +1 -1
- package/dist/{chunk-VT6P7FV4.js → chunk-IU44MPY3.js} +1 -1
- package/dist/{chunk-6OD2RVIA.js → chunk-IXTDBQYU.js} +273 -397
- package/dist/{chunk-2NGPZCWX.js → chunk-JB7QUK3D.js} +3 -3
- package/dist/{chunk-VT2B5BHM.js → chunk-JBSCL2XT.js} +2 -1
- package/dist/{chunk-MPX3TRMQ.js → chunk-JD5S5AAV.js} +1 -1
- package/dist/{chunk-XYG722JW.js → chunk-JIJKUZIO.js} +3 -3
- package/dist/{chunk-KMIAYKIH.js → chunk-K5C6LC2G.js} +159 -39
- package/dist/{chunk-DAOHCXM2.js → chunk-KH6BCYLC.js} +1 -1
- package/dist/{chunk-4L4R6AQJ.js → chunk-KMI4TUTW.js} +1 -1
- package/dist/{chunk-PHFPIUWU.js → chunk-KWOAM7TA.js} +3 -0
- package/dist/{chunk-RZJ6DXVE.js → chunk-L6QI2NNG.js} +1 -1
- package/dist/{chunk-HED6D5KR.js → chunk-MMNMQNLD.js} +43 -29
- package/dist/{chunk-KAVUTP5G.js → chunk-N3CRJ2VW.js} +3 -3
- package/dist/{chunk-OBJXZII2.js → chunk-N7LBAQGK.js} +3 -3
- package/dist/{chunk-LMX7UKGX.js → chunk-OUAGTQC4.js} +17 -11
- package/dist/{chunk-WZBUKC5N.js → chunk-OUJI2ZTY.js} +2 -2
- package/dist/{chunk-YUGLOZOR.js → chunk-OXTZEKVA.js} +1 -1
- package/dist/{chunk-OR3TAZL3.js → chunk-P4ULFI2N.js} +1 -1
- package/dist/{chunk-6LNSZADA.js → chunk-PVC4RNHQ.js} +50 -11
- package/dist/{chunk-FM7XZDZI.js → chunk-R2WP3XIN.js} +1 -1
- package/dist/{chunk-IBDPPBFK.js → chunk-R5IPZ5ZC.js} +1 -1
- package/dist/{chunk-7WDIGRSO.js → chunk-R5TZ2FC3.js} +1 -1
- package/dist/{chunk-2UVN2NBN.js → chunk-RICNNGYH.js} +3 -3
- package/dist/{chunk-WBJXJ2R4.js → chunk-RLBVY5FE.js} +17 -14
- package/dist/{chunk-XXJRZ75E.js → chunk-RV634O2W.js} +5 -2
- package/dist/{chunk-3KH6GXXX.js → chunk-RYPFOZQH.js} +2 -2
- package/dist/{chunk-DNFU56ZS.js → chunk-SB7W6XI4.js} +1 -1
- package/dist/{chunk-PPXQE7AS.js → chunk-SE6MLUOK.js} +33 -34
- package/dist/{chunk-65DBIEM2.js → chunk-SHIICYJW.js} +7 -1
- package/dist/{chunk-KPVVTHPK.js → chunk-SRMNWAHN.js} +15 -10
- package/dist/chunk-T2DJR7ND.js +367 -0
- package/dist/{chunk-Z6H6Y4BS.js → chunk-TA22MGGN.js} +1 -1
- package/dist/{chunk-ZOVHXTGC.js → chunk-TN7SC2ZQ.js} +1 -1
- package/dist/{chunk-XV5HRIXG.js → chunk-TRPGNCVB.js} +8 -8
- package/dist/{chunk-4BANMHJ5.js → chunk-UDZP2SHJ.js} +3 -3
- package/dist/{chunk-GMZMBLHT.js → chunk-UM6WUSQ7.js} +2 -2
- package/dist/{chunk-2EJ636HI.js → chunk-UST3MKK7.js} +1 -1
- package/dist/{chunk-RQ7OVXUZ.js → chunk-V2CZVZUO.js} +2 -2
- package/dist/{chunk-4RJJ5FJ2.js → chunk-V4UKBUUA.js} +1 -1
- package/dist/{chunk-EOS7VPVT.js → chunk-VA2MDALR.js} +8 -8
- package/dist/{chunk-SCYWCWKY.js → chunk-VG4ZH2Z3.js} +24 -10
- package/dist/{chunk-255DIG4B.js → chunk-VHLI6CTD.js} +1 -1
- package/dist/{chunk-DFIOOK5R.js → chunk-WCES22KG.js} +4 -3
- package/dist/{chunk-5A6KTWQL.js → chunk-WOTKNUKK.js} +126 -2
- package/dist/{chunk-62UZWGFX.js → chunk-WZZBGGSD.js} +63 -2
- package/dist/{chunk-ELXR65AN.js → chunk-X2FHTDIU.js} +6 -3
- package/dist/{chunk-V4BW5HFQ.js → chunk-X5I5QRC2.js} +3 -3
- package/dist/{chunk-X4AFBL4N.js → chunk-XCORXJ3M.js} +1 -1
- package/dist/{chunk-66JPZELX.js → chunk-Y5CNGG4F.js} +24 -16
- package/dist/{chunk-SPOXL7HF.js → chunk-YEWNIBNA.js} +9 -9
- package/dist/{chunk-WJ2PZGRV.js → chunk-ZAA344BL.js} +29 -2
- package/dist/{chunk-TN2YCFQE.js → chunk-ZGLJ2VD7.js} +5 -5
- package/dist/{co-activation-WN25AJOC.js → co-activation-RH46OQ3N.js} +5 -5
- package/dist/{co-occurrence-YP2Q3OEA.js → co-occurrence-MJWERUWY.js} +5 -5
- package/dist/{code-context-index-ZWONKBKX.js → code-context-index-WFUBYGQT.js} +6 -6
- package/dist/{content-extractor-EYRVGD6O.js → content-extractor-RHITF2KM.js} +1 -1
- package/dist/{conversation-wiki-populator-XFUC7S5P.js → conversation-wiki-populator-SK233TL4.js} +1 -1
- package/dist/{crdt-sync-ZFIFL2QM.js → crdt-sync-4R7SXTNB.js} +1 -1
- package/dist/{crm-webhook-DGPHULOO.js → crm-webhook-YDXX5FDK.js} +2 -2
- package/dist/{cto-delegation-gate-OF2A3TSS.js → cto-delegation-gate-ZJHLPK4Y.js} +14 -14
- package/dist/{daemon-auth-N6P2MZAV.js → daemon-auth-5FCYVQIZ.js} +3 -3
- package/dist/{daemon-orchestration-G4RRTPP7.js → daemon-orchestration-NBU5RZ2O.js} +18 -18
- package/dist/{daemon-ready-signal-3L2MJT7C.js → daemon-ready-signal-KXLL6ZFL.js} +1 -1
- package/dist/{db-backup-EORG4LBO.js → db-backup-BTL2FBBL.js} +9 -3
- package/dist/{db-restore-events-3R7G4FP4.js → db-restore-events-3A57GMLW.js} +2 -2
- package/dist/{doc-graph-extractor-APZS3DFD.js → doc-graph-extractor-ADYRG7DB.js} +5 -5
- package/dist/documents-VWPZTDFA.js +56 -0
- package/dist/{dreaming-Q4E3WBGY.js → dreaming-76WKGTL6.js} +15 -15
- package/dist/embeddings-config-FANLORDH.js +21 -0
- package/dist/{exe-drift-CI5R6GUT.js → exe-drift-T3IO2SPX.js} +6 -6
- package/dist/{exe-export-HQIQASIT.js → exe-export-6YEHSJMP.js} +9 -9
- package/dist/{exe-import-ULZK56WC.js → exe-import-3NERK63O.js} +9 -9
- package/dist/{exe-key-ILNSBGRN.js → exe-key-RCMBMLSQ.js} +8 -8
- package/dist/{exe-org-WQWQZRLR.js → exe-org-KCOOLUTW.js} +3 -3
- package/dist/{exe-snapshot-RUZTWZOF.js → exe-snapshot-JIY7MNRI.js} +18 -18
- package/dist/{fast-db-init-KNJRL7T3.js → fast-db-init-PVJ72264.js} +1 -1
- package/dist/{founder-context-QCTMEK66.js → founder-context-A4VUEKDH.js} +4 -4
- package/dist/gateway/index.js +17 -17
- package/dist/{git-staleness-KIA5YI4H.js → git-staleness-IOAHAGBI.js} +5 -5
- package/dist/{git-task-sweep-WH6QE7HL.js → git-task-sweep-IGM5RILF.js} +17 -15
- package/dist/{global-procedures-SYZZCGDS.js → global-procedures-VZL2X4RK.js} +6 -6
- package/dist/{graph-auto-extract-J2TIWZEE.js → graph-auto-extract-TIXRGBC5.js} +5 -5
- package/dist/{hook-integrity-I6PWJQER.js → hook-integrity-XNPNCMAS.js} +1 -1
- package/dist/hooks/bug-report-worker.js +47 -17
- package/dist/hooks/codex-stop-task-finalizer.js +47 -17
- package/dist/hooks/commit-complete.js +18 -18
- package/dist/hooks/error-recall.js +11 -11
- package/dist/hooks/exe-heartbeat-hook.js +7 -7
- package/dist/hooks/ingest-worker.js +39 -9
- package/dist/hooks/ingest.js +17 -17
- package/dist/hooks/instructions-loaded.js +8 -8
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +8 -8
- package/dist/hooks/post-compact.js +17 -17
- package/dist/hooks/post-tool-combined.js +60 -7
- package/dist/hooks/pre-compact.js +23 -23
- package/dist/hooks/pre-tool-use.js +64 -34
- package/dist/hooks/prompt-submit.js +40 -32
- package/dist/hooks/session-end.js +29 -29
- package/dist/hooks/session-start.js +17 -17
- package/dist/hooks/stop.js +24 -24
- package/dist/hooks/subagent-stop.js +17 -17
- package/dist/hooks/summary-worker.js +55 -25
- package/dist/index.js +27 -27
- package/dist/{installer-PSDYMGN7.js → installer-D7D5O4KL.js} +10 -10
- package/dist/{installer-3NB3IBHF.js → installer-EQP2EMNZ.js} +10 -10
- package/dist/{installer-IIJFCTMH.js → installer-IWRYH55Z.js} +10 -10
- package/dist/{key-backup-status-FNSN3NXH.js → key-backup-status-ZNGDSPLT.js} +2 -2
- package/dist/lib/agent-config.js +3 -3
- package/dist/lib/cloud-sync.js +16 -16
- package/dist/lib/config.js +2 -2
- package/dist/lib/consolidation.js +8 -8
- package/dist/lib/database.js +7 -5
- package/dist/lib/db-daemon-client.js +6 -6
- package/dist/lib/db.js +7 -5
- package/dist/lib/device-registry.js +3 -3
- package/dist/lib/embed-worker.js +2 -2
- package/dist/lib/embedder.js +6 -6
- package/dist/lib/employee-templates.js +7 -7
- package/dist/lib/employees.js +5 -5
- package/dist/lib/exe-daemon-client.js +5 -5
- package/dist/lib/exe-daemon.js +449 -89
- package/dist/lib/hybrid-search.js +8 -8
- package/dist/lib/identity.js +5 -5
- package/dist/lib/license.js +4 -4
- package/dist/lib/messaging.js +15 -15
- package/dist/lib/post-tool-memory.js +2 -2
- package/dist/lib/reminders.js +6 -6
- package/dist/lib/schedules.js +8 -8
- package/dist/lib/session-registry.js +9 -7
- package/dist/lib/session-wrappers.js +1 -1
- package/dist/lib/skill-learning.js +9 -9
- package/dist/lib/store.js +7 -7
- package/dist/lib/task-router.js +6 -6
- package/dist/lib/tasks.js +16 -16
- package/dist/lib/tmux-routing.js +14 -14
- package/dist/lib/token-spend.js +6 -6
- package/dist/{license-gate-7SDHCJUO.js → license-gate-PZOP7S2S.js} +5 -5
- package/dist/mcp/register-tools.js +73 -72
- package/dist/mcp/server.js +74 -73
- package/dist/mcp/tools/complete-reminder.js +7 -7
- package/dist/mcp/tools/create-reminder.js +7 -7
- package/dist/mcp/tools/create-task.js +18 -18
- package/dist/mcp/tools/deactivate-behavior.js +10 -10
- package/dist/mcp/tools/list-reminders.js +7 -7
- package/dist/mcp/tools/list-tasks.js +18 -18
- package/dist/mcp/tools/send-message.js +17 -17
- package/dist/mcp/tools/update-task.js +17 -17
- package/dist/{mcp-http-config-QSOVFXHW.js → mcp-http-config-23DHJAU4.js} +7 -7
- package/dist/{mcp-port-config-AWWRZA22.js → mcp-port-config-FFAMMLLE.js} +2 -1
- package/dist/{memory-cards-II67WFL2.js → memory-cards-CNLMHSZC.js} +5 -5
- package/dist/{memory-graph-extractor-PM4Q2KJG.js → memory-graph-extractor-HIXP2BQS.js} +6 -6
- package/dist/{memory-poisoning-defense-ECXSX7HK.js → memory-poisoning-defense-YL53IBBF.js} +5 -5
- package/dist/{memory-queue-VAE6WMSS.js → memory-queue-3Q5P43AM.js} +3 -3
- package/dist/memory-queue-client-YP2QKX6J.js +16 -0
- package/dist/{memory-reflection-PXF6YFDU.js → memory-reflection-VHQRUZWK.js} +5 -5
- package/dist/{notifications-UP7WQGG4.js → notifications-Q5NEAP6K.js} +14 -14
- package/dist/{orchestration-events-PZLLPCKY.js → orchestration-events-7SNWRJYE.js} +6 -6
- package/dist/{orchestration-phase-SJOXDB7X.js → orchestration-phase-U45T4VG3.js} +3 -3
- package/dist/{orchestrator-PUT45J4O.js → orchestrator-XWLKNWUG.js} +16 -16
- package/dist/{pipeline-router-5CRWKESM.js → pipeline-router-5IBJBH7P.js} +6 -6
- package/dist/{plan-limits-SH2NDFNX.js → plan-limits-PBEZVHRQ.js} +8 -8
- package/dist/{preferences-YWBTKW3M.js → preferences-TYTGDXQZ.js} +2 -2
- package/dist/{project-boot-2TCPDZ4S.js → project-boot-OHEGJD2L.js} +2 -2
- package/dist/{projection-worker-HWY37MNC.js → projection-worker-HELRBNDR.js} +5 -5
- package/dist/{prospective-memory-FQSVMCGG.js → prospective-memory-N55XRGJP.js} +5 -5
- package/dist/{push-notifications-DK6XA5B3.js → push-notifications-PAFNP3EC.js} +3 -3
- package/dist/{reranker-AALRMGMM.js → reranker-MNJSTOPR.js} +3 -3
- package/dist/{retrieval-health-PNWJSJNG.js → retrieval-health-W4HNR3WX.js} +1 -1
- package/dist/{review-polling-65JZUE3T.js → review-polling-SRYZU2PI.js} +15 -15
- package/dist/runtime/index.js +22 -22
- package/dist/{session-events-EJ3OSAA6.js → session-events-L4DK5J6J.js} +15 -15
- package/dist/{session-kill-telemetry-3HGM7SNQ.js → session-kill-telemetry-U2YHKHCB.js} +15 -15
- package/dist/{session-scope-JGDYAMJO.js → session-scope-JTPHECAU.js} +14 -14
- package/dist/{setup-wizard-44LMFM2C.js → setup-wizard-IP5R66LR.js} +3 -3
- package/dist/{shard-manager-KUCJPLC6.js → shard-manager-RASGFMGS.js} +3 -3
- package/dist/{skill-refinement-DUOO6B7V.js → skill-refinement-VTYL4OMJ.js} +5 -5
- package/dist/{stack-release-XYMKU7NT.js → stack-release-TOCCJQOF.js} +244 -45
- package/dist/{stack-update-TUBZTY7Z.js → stack-update-MRNVHUZZ.js} +11 -5
- package/dist/{steward-gate-6NWRDLX2.js → steward-gate-JEVUDTBI.js} +6 -6
- package/dist/{task-enforcement-UOULTGFB.js → task-enforcement-VFSAAZUN.js} +14 -14
- package/dist/{task-scope-P5STKYAC.js → task-scope-P4VLIQNP.js} +14 -14
- package/dist/{tasks-crud-24HMTULR.js → tasks-crud-SC3ERIUR.js} +14 -14
- package/dist/{tasks-notify-LAIU7UUI.js → tasks-notify-WJYBUCIB.js} +15 -15
- package/dist/{tasks-review-AFJAU2DY.js → tasks-review-XPVPHCGD.js} +14 -14
- package/dist/{telemetry-upload-DWFGC2XJ.js → telemetry-upload-4QEYQROW.js} +10 -10
- package/dist/{token-budget-4RFZKWGH.js → token-budget-UBOP3HVE.js} +6 -6
- package/dist/{tool-capability-index-ZEXBWKUZ.js → tool-capability-index-SHYCBE2Z.js} +1 -1
- package/dist/{tool-telemetry-BS5JXM5M.js → tool-telemetry-CDNPES5B.js} +1 -1
- package/dist/tui/App.js +27 -27
- package/dist/{tui-data-UNO5B7PU.js → tui-data-HVYY7GRK.js} +14 -14
- package/dist/{worker-gate-C6CTTYMD.js → worker-gate-KQTODSUQ.js} +3 -3
- package/dist/{workflow-engine-4W2KYCDV.js → workflow-engine-OP2DQISD.js} +2 -2
- package/dist/{working-memory-FXHQCJJE.js → working-memory-PY4AG577.js} +22 -2
- package/dist/{worktree-2CXY6NEB.js → worktree-Z2G4CP4Z.js} +7 -7
- package/dist/{worktree-sweep-K3CJFSUL.js → worktree-sweep-LWSCAZW6.js} +8 -8
- package/package.json +2 -2
- package/release-notes.json +56 -113
- package/stack.release.json +7 -7
- package/dist/memory-queue-client-HLURQEV6.js +0 -16
- /package/dist/{chunk-J3SR5MGG.js → chunk-GIS4GBZE.js} +0 -0
- /package/dist/{chunk-AE74NOE6.js → chunk-NAPBIDGH.js} +0 -0
- /package/dist/{chunk-I3DPCSDG.js → chunk-OJS2H5HR.js} +0 -0
- /package/dist/{chunk-K4BKJJ4F.js → chunk-PCRRDXGL.js} +0 -0
- /package/dist/{chunk-MQCTK6EF.js → chunk-RRYJTPVW.js} +0 -0
- /package/dist/{chunk-2NS3QRMJ.js → chunk-ZIVUMDHA.js} +0 -0
- /package/dist/{core-memory-OC5ITKKV.js → core-memory-4JWCAGJI.js} +0 -0
- /package/dist/{entity-boost-NF3LE6OJ.js → entity-boost-AU342QRK.js} +0 -0
- /package/dist/{message-queue-client-4VDU6BZY.js → message-queue-client-IXYLJJVJ.js} +0 -0
- /package/dist/{oauth-server-EWUL7DMD.js → oauth-server-F4QWESK2.js} +0 -0
- /package/dist/{webhook-pipe-DHIGZHPW.js → webhook-pipe-S4CWK6H5.js} +0 -0
- /package/dist/{wiki-acl-CONNF6ES.js → wiki-acl-6GZHUA44.js} +0 -0
- /package/dist/{wiki-client-N6PT5P7W.js → wiki-client-CIJXRMKL.js} +0 -0
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
clearDaemonReady,
|
|
3
3
|
writeDaemonReady
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-RV634O2W.js";
|
|
5
5
|
import {
|
|
6
6
|
pushNotifyAsync
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-R5IPZ5ZC.js";
|
|
8
8
|
import {
|
|
9
9
|
getMcpToolFamily,
|
|
10
10
|
inferMcpRuntime,
|
|
11
11
|
recordMcpHttpEvent
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-WOTKNUKK.js";
|
|
13
13
|
import {
|
|
14
14
|
deserializeArgs,
|
|
15
15
|
serializeResultSet
|
|
@@ -18,17 +18,19 @@ import {
|
|
|
18
18
|
ensureDaemonToken,
|
|
19
19
|
reconcileSessionAgentIdentity,
|
|
20
20
|
shouldEnforceSessionIdentity
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-V2CZVZUO.js";
|
|
22
22
|
import {
|
|
23
23
|
findScopedDuplicate,
|
|
24
24
|
governMemoryRecord,
|
|
25
25
|
schedulePostWriteMemoryHygiene
|
|
26
|
-
} from "../chunk-
|
|
26
|
+
} from "../chunk-RRYJTPVW.js";
|
|
27
27
|
import "../chunk-Y25OJWOQ.js";
|
|
28
28
|
import {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
attributeSignalSource,
|
|
30
|
+
consumeRestartIntentDetail,
|
|
31
|
+
logRestartEvent,
|
|
32
|
+
requestRestart
|
|
33
|
+
} from "../chunk-75TM3APG.js";
|
|
32
34
|
import {
|
|
33
35
|
DAEMON_RSS_RESTART_DEBOUNCE,
|
|
34
36
|
DAEMON_RSS_STARTUP_GRACE_MS,
|
|
@@ -47,14 +49,14 @@ import {
|
|
|
47
49
|
} from "../chunk-7XGDTKHX.js";
|
|
48
50
|
import {
|
|
49
51
|
resolveEmbeddingsEnabled
|
|
50
|
-
} from "../chunk-
|
|
52
|
+
} from "../chunk-KWOAM7TA.js";
|
|
51
53
|
import {
|
|
52
54
|
logBoot,
|
|
53
55
|
logCrash,
|
|
54
56
|
logDaemonHealth,
|
|
55
57
|
logHeartbeat,
|
|
56
58
|
logShutdown
|
|
57
|
-
} from "../chunk-
|
|
59
|
+
} from "../chunk-H73TUI4Y.js";
|
|
58
60
|
import {
|
|
59
61
|
getEventLoopLagMs,
|
|
60
62
|
isEventLoopDegraded,
|
|
@@ -68,8 +70,8 @@ import {
|
|
|
68
70
|
EXE_AI_DIR,
|
|
69
71
|
MODELS_DIR,
|
|
70
72
|
resolveEmbedModelFile
|
|
71
|
-
} from "../chunk-
|
|
72
|
-
import "../chunk-
|
|
73
|
+
} from "../chunk-WCES22KG.js";
|
|
74
|
+
import "../chunk-SHIICYJW.js";
|
|
73
75
|
import "../chunk-MLKGABMK.js";
|
|
74
76
|
|
|
75
77
|
// src/lib/exe-daemon.ts
|
|
@@ -95,7 +97,11 @@ var DAEMON_ALLOWED_SCHEMA_SQL_RE = [
|
|
|
95
97
|
// Internal telemetry tables are created lazily from hooks and daemon helpers.
|
|
96
98
|
// Keep this allowlist narrow: idempotent CREATEs for known tables/indexes only.
|
|
97
99
|
/^\s*CREATE\s+TABLE\s+IF\s+NOT\s+EXISTS\s+session_events\s*\(/i,
|
|
98
|
-
|
|
100
|
+
// Bug 2417b0b1: idx_session_events_created_at (the retention-sweep index added
|
|
101
|
+
// in db9c95c8) was missing from this allowlist, so its idempotent CREATE INDEX
|
|
102
|
+
// was rejected on every session-event write — flooding daemon-health.log with
|
|
103
|
+
// "Blocked unsafe daemon SQL" db_errors. Added created_at to the alternation.
|
|
104
|
+
/^\s*CREATE\s+INDEX\s+IF\s+NOT\s+EXISTS\s+idx_session_events_(?:agent_time|session_index|scope_agent_time|created_at)\s+ON\s+session_events\s*\(/i,
|
|
99
105
|
/^\s*CREATE\s+TABLE\s+IF\s+NOT\s+EXISTS\s+orchestration_events\s*\(/i,
|
|
100
106
|
/^\s*CREATE\s+INDEX\s+IF\s+NOT\s+EXISTS\s+idx_orch_events_(?:ts|task|agent|type)\s+ON\s+orchestration_events\s*\(/i,
|
|
101
107
|
// Cloud sync metadata table — created lazily by getCloudReuploadRequired().
|
|
@@ -479,6 +485,7 @@ var _mcpSessionDetailsRef = null;
|
|
|
479
485
|
var _activeWrites = 0;
|
|
480
486
|
var _mcpHttpReady = Promise.resolve();
|
|
481
487
|
var _daemonToken = "";
|
|
488
|
+
var _boundMcpPort;
|
|
482
489
|
var _injectedRegisterAllTools = null;
|
|
483
490
|
function injectRegisterAllTools(fn) {
|
|
484
491
|
_injectedRegisterAllTools = fn;
|
|
@@ -585,6 +592,15 @@ async function capturePaneAsync(session, lines = 20) {
|
|
|
585
592
|
return "";
|
|
586
593
|
}
|
|
587
594
|
}
|
|
595
|
+
function classifyPaneState(pane) {
|
|
596
|
+
const busyPattern = /[✻✽✶✳·].*…|Running…|• Working|• Ran |• Explored|• Called|esc to interrupt/;
|
|
597
|
+
if (!pane.includes("\u276F") && !pane.includes("Claude Code") && !busyPattern.test(pane) && !/Running…/.test(pane)) {
|
|
598
|
+
if (/\$\s*$/.test(pane) || /% $/.test(pane.trimEnd())) return "no_claude";
|
|
599
|
+
}
|
|
600
|
+
if (/Running…/.test(pane)) return "tool";
|
|
601
|
+
if (busyPattern.test(pane)) return "thinking";
|
|
602
|
+
return "idle";
|
|
603
|
+
}
|
|
588
604
|
async function killTmuxSessionAsync(session, timeout = 3e3) {
|
|
589
605
|
try {
|
|
590
606
|
await execFileAsync("tmux", ["kill-session", "-t", session], { timeout });
|
|
@@ -692,20 +708,43 @@ var _startedAt2 = Date.now();
|
|
|
692
708
|
process.env.EXE_DAEMON_STARTED_AT_ISO ??= new Date(_startedAt2).toISOString();
|
|
693
709
|
var TIMER_TRACE_BOOT_WINDOW_MS = Number(process.env.EXE_TIMER_TRACE_BOOT_WINDOW_MS) || 10 * 60 * 1e3;
|
|
694
710
|
var TIMER_TRACE_SLOW_MS = Number(process.env.EXE_TIMER_TRACE_SLOW_MS) || 500;
|
|
711
|
+
var TIMER_TIMEOUT_MS = Number(process.env.EXE_TIMER_TIMEOUT_MS) || 1e4;
|
|
712
|
+
var _timerInFlight = /* @__PURE__ */ new Set();
|
|
695
713
|
function shouldTraceDaemonTimer(durationMs = 0) {
|
|
696
714
|
return Date.now() - _startedAt2 < TIMER_TRACE_BOOT_WINDOW_MS || durationMs >= TIMER_TRACE_SLOW_MS;
|
|
697
715
|
}
|
|
698
716
|
var yieldToEventLoop = () => new Promise((resolve) => setImmediate(resolve));
|
|
699
717
|
async function traceDaemonTimer(name, fn) {
|
|
718
|
+
if (_timerInFlight.has(name)) {
|
|
719
|
+
process.stderr.write(`[exed] Timer SKIPPED (overlap): ${name} \u2014 previous tick still running
|
|
720
|
+
`);
|
|
721
|
+
return void 0;
|
|
722
|
+
}
|
|
723
|
+
_timerInFlight.add(name);
|
|
700
724
|
const probe = captureClockProbe();
|
|
701
725
|
const traceStart = shouldTraceDaemonTimer();
|
|
702
726
|
if (traceStart) {
|
|
703
727
|
process.stderr.write(`[exed] Timer start: ${name}
|
|
704
728
|
`);
|
|
705
729
|
}
|
|
730
|
+
const timeoutHandle = setTimeout(() => {
|
|
731
|
+
process.stderr.write(
|
|
732
|
+
`[exed] Timer TIMEOUT WARNING: ${name} has been running for >${TIMER_TIMEOUT_MS / 1e3}s \u2014 likely blocking the event loop
|
|
733
|
+
`
|
|
734
|
+
);
|
|
735
|
+
logDaemonHealth({
|
|
736
|
+
event: "timer_timeout",
|
|
737
|
+
pid: process.pid,
|
|
738
|
+
message: `Timer ${name} exceeded ${TIMER_TIMEOUT_MS / 1e3}s budget`,
|
|
739
|
+
data: { timer: name, timeoutMs: TIMER_TIMEOUT_MS }
|
|
740
|
+
});
|
|
741
|
+
}, TIMER_TIMEOUT_MS);
|
|
742
|
+
timeoutHandle.unref();
|
|
706
743
|
try {
|
|
707
744
|
return await fn();
|
|
708
745
|
} finally {
|
|
746
|
+
clearTimeout(timeoutHandle);
|
|
747
|
+
_timerInFlight.delete(name);
|
|
709
748
|
const span = measureSpan(probe);
|
|
710
749
|
const durationMs = Math.round(span.monoMs);
|
|
711
750
|
const slept = span.sleptMs > 1e3;
|
|
@@ -722,7 +761,6 @@ async function traceDaemonTimer(name, fn) {
|
|
|
722
761
|
type: "timer_duration",
|
|
723
762
|
timer: name,
|
|
724
763
|
durationMs,
|
|
725
|
-
// monotonic — the value dashboards/alerts should trust
|
|
726
764
|
wallMs: Math.round(span.wallMs),
|
|
727
765
|
sleptMs: Math.round(span.sleptMs),
|
|
728
766
|
clockJump: slept,
|
|
@@ -868,6 +906,17 @@ function isEventLoopBlockedNow(freshMs = EVENT_LOOP_BLOCKED_FRESH_MS) {
|
|
|
868
906
|
return false;
|
|
869
907
|
}
|
|
870
908
|
}
|
|
909
|
+
function eventLoopHeartbeatPath() {
|
|
910
|
+
return path3.join(os2.homedir(), ".exe-os", "session-cache", "event-loop-heartbeat");
|
|
911
|
+
}
|
|
912
|
+
function touchEventLoopHeartbeat() {
|
|
913
|
+
try {
|
|
914
|
+
const p = eventLoopHeartbeatPath();
|
|
915
|
+
mkdirSync2(path3.dirname(p), { recursive: true });
|
|
916
|
+
writeFileSync3(p, String(Date.now()));
|
|
917
|
+
} catch {
|
|
918
|
+
}
|
|
919
|
+
}
|
|
871
920
|
function checkLaunchdPlistHealth() {
|
|
872
921
|
try {
|
|
873
922
|
if (process.platform !== "darwin") return;
|
|
@@ -1101,7 +1150,7 @@ async function loadModel() {
|
|
|
1101
1150
|
void (async () => {
|
|
1102
1151
|
try {
|
|
1103
1152
|
if (_storeInitialized) {
|
|
1104
|
-
const { writeNotification } = await import("../notifications-
|
|
1153
|
+
const { writeNotification } = await import("../notifications-Q5NEAP6K.js");
|
|
1105
1154
|
await writeNotification({
|
|
1106
1155
|
agentId: "exe",
|
|
1107
1156
|
agentRole: "system",
|
|
@@ -1217,7 +1266,7 @@ function disableEmbeddingsForInferenceTimeouts() {
|
|
|
1217
1266
|
void (async () => {
|
|
1218
1267
|
try {
|
|
1219
1268
|
if (_storeInitialized) {
|
|
1220
|
-
const { writeNotification } = await import("../notifications-
|
|
1269
|
+
const { writeNotification } = await import("../notifications-Q5NEAP6K.js");
|
|
1221
1270
|
await writeNotification({
|
|
1222
1271
|
agentId: "exe",
|
|
1223
1272
|
agentRole: "system",
|
|
@@ -1428,7 +1477,7 @@ async function shutdown(exitCode = 0) {
|
|
|
1428
1477
|
}
|
|
1429
1478
|
}
|
|
1430
1479
|
try {
|
|
1431
|
-
const { createBackupAsync, enforceRetention, hasRecentBackup } = await import("../db-backup-
|
|
1480
|
+
const { createBackupAsync, enforceRetention, hasRecentBackup } = await import("../db-backup-BTL2FBBL.js");
|
|
1432
1481
|
const PRE_RESTART_DEDUP_MS = 2 * 60 * 1e3;
|
|
1433
1482
|
if (hasRecentBackup("pre-restart", PRE_RESTART_DEDUP_MS)) {
|
|
1434
1483
|
const deleted = enforceRetention("pre-restart");
|
|
@@ -1459,12 +1508,12 @@ async function shutdown(exitCode = 0) {
|
|
|
1459
1508
|
`);
|
|
1460
1509
|
}
|
|
1461
1510
|
try {
|
|
1462
|
-
const { stopProjectionWorker } = await import("../projection-worker-
|
|
1511
|
+
const { stopProjectionWorker } = await import("../projection-worker-HELRBNDR.js");
|
|
1463
1512
|
stopProjectionWorker();
|
|
1464
1513
|
} catch {
|
|
1465
1514
|
}
|
|
1466
1515
|
try {
|
|
1467
|
-
const { disposeShards } = await import("../shard-manager-
|
|
1516
|
+
const { disposeShards } = await import("../shard-manager-RASGFMGS.js");
|
|
1468
1517
|
disposeShards();
|
|
1469
1518
|
} catch {
|
|
1470
1519
|
}
|
|
@@ -1525,7 +1574,7 @@ async function handleHealthCheck(socket, requestId) {
|
|
|
1525
1574
|
let pipelineStatus = "unknown";
|
|
1526
1575
|
if (dbConnected) {
|
|
1527
1576
|
try {
|
|
1528
|
-
await import("../pipeline-router-
|
|
1577
|
+
await import("../pipeline-router-5IBJBH7P.js");
|
|
1529
1578
|
pipelineStatus = "ok";
|
|
1530
1579
|
} catch {
|
|
1531
1580
|
pipelineStatus = "unavailable";
|
|
@@ -1921,7 +1970,7 @@ async function _writeMemoryRecordInner(entry) {
|
|
|
1921
1970
|
const vRow = await client.execute({ sql: "SELECT version FROM memories WHERE id = ?", args: [id] });
|
|
1922
1971
|
const version = Number(vRow.rows[0]?.version) || 0;
|
|
1923
1972
|
try {
|
|
1924
|
-
const { insertOntologyForMemory } = await import("../agentic-ontology-
|
|
1973
|
+
const { insertOntologyForMemory } = await import("../agentic-ontology-AAUATKUS.js");
|
|
1925
1974
|
await insertOntologyForMemory({
|
|
1926
1975
|
id,
|
|
1927
1976
|
agent_id: record.agent_id,
|
|
@@ -1944,18 +1993,20 @@ async function _writeMemoryRecordInner(entry) {
|
|
|
1944
1993
|
return id;
|
|
1945
1994
|
}
|
|
1946
1995
|
var MEMORY_DRAIN_INTERVAL_MS = 30 * 1e3;
|
|
1996
|
+
var MEMORY_DRAIN_BATCH = Math.max(1, Number(process.env.EXE_MEMORY_DRAIN_BATCH) || 25);
|
|
1947
1997
|
function startMemoryQueueDrain() {
|
|
1948
1998
|
const drain = async () => traceDaemonTimer("memory_queue_drain", async () => {
|
|
1949
1999
|
fired("memory_queue_drain");
|
|
1950
2000
|
if (!await ensureStoreForPolling()) return;
|
|
1951
2001
|
try {
|
|
1952
|
-
const { ackQueue, claimQueue, retryQueueEntries } = await import("../memory-queue-
|
|
2002
|
+
const { ackQueue, claimQueue, retryQueueEntries } = await import("../memory-queue-3Q5P43AM.js");
|
|
1953
2003
|
const lease = claimQueue();
|
|
1954
2004
|
if (!lease || lease.entries.length === 0) return;
|
|
1955
2005
|
acted("memory_queue_drain");
|
|
1956
2006
|
const entries = lease.entries;
|
|
1957
2007
|
let processed = 0;
|
|
1958
2008
|
const retryEntries = [];
|
|
2009
|
+
let sinceYield = 0;
|
|
1959
2010
|
for (const entry of entries) {
|
|
1960
2011
|
if (!entry.raw_text || entry.raw_text.length < 10) continue;
|
|
1961
2012
|
try {
|
|
@@ -1968,6 +2019,10 @@ function startMemoryQueueDrain() {
|
|
|
1968
2019
|
`
|
|
1969
2020
|
);
|
|
1970
2021
|
}
|
|
2022
|
+
if (++sinceYield >= MEMORY_DRAIN_BATCH) {
|
|
2023
|
+
sinceYield = 0;
|
|
2024
|
+
await yieldToEventLoop();
|
|
2025
|
+
}
|
|
1971
2026
|
}
|
|
1972
2027
|
if (retryEntries.length === 0) {
|
|
1973
2028
|
ackQueue(lease.leasePath);
|
|
@@ -2005,7 +2060,7 @@ function startMessageQueueDrain() {
|
|
|
2005
2060
|
fired("message_queue_drain");
|
|
2006
2061
|
if (!await ensureStoreForPolling()) return;
|
|
2007
2062
|
try {
|
|
2008
|
-
const { claimMessageQueue, ackMessageQueue } = await import("../message-queue-client-
|
|
2063
|
+
const { claimMessageQueue, ackMessageQueue } = await import("../message-queue-client-IXYLJJVJ.js");
|
|
2009
2064
|
const lease = claimMessageQueue();
|
|
2010
2065
|
if (!lease || lease.entries.length === 0) return;
|
|
2011
2066
|
acted("message_queue_drain");
|
|
@@ -2021,14 +2076,20 @@ function startMessageQueueDrain() {
|
|
|
2021
2076
|
const id = randomUUID2();
|
|
2022
2077
|
await client.execute({
|
|
2023
2078
|
sql: `INSERT INTO messages (id, source_agent, target_agent, content, priority, status, created_at)
|
|
2024
|
-
VALUES (?, ?, ?, ?, ?, '
|
|
2079
|
+
VALUES (?, ?, ?, ?, ?, 'pending_delivery', ?)`,
|
|
2025
2080
|
args: [id, entry.source_agent, entry.target_agent, entry.content, entry.priority, now]
|
|
2026
2081
|
});
|
|
2082
|
+
let delivered = false;
|
|
2027
2083
|
const exeSession = resolveExeSession();
|
|
2028
2084
|
if (exeSession) {
|
|
2029
2085
|
const sessionName = employeeSessionName(entry.target_agent, exeSession);
|
|
2030
|
-
await sendIntercomAsync(sessionName, { force: true });
|
|
2086
|
+
const result = await sendIntercomAsync(sessionName, { force: true });
|
|
2087
|
+
delivered = result !== "failed";
|
|
2031
2088
|
}
|
|
2089
|
+
await client.execute({
|
|
2090
|
+
sql: `UPDATE messages SET status = ? WHERE id = ?`,
|
|
2091
|
+
args: [delivered ? "delivered" : "pending_delivery", id]
|
|
2092
|
+
});
|
|
2032
2093
|
processed++;
|
|
2033
2094
|
} catch (err) {
|
|
2034
2095
|
retryEntries.push(entry);
|
|
@@ -2037,6 +2098,7 @@ function startMessageQueueDrain() {
|
|
|
2037
2098
|
`
|
|
2038
2099
|
);
|
|
2039
2100
|
}
|
|
2101
|
+
await yieldToEventLoop();
|
|
2040
2102
|
}
|
|
2041
2103
|
if (retryEntries.length === 0) {
|
|
2042
2104
|
ackMessageQueue(lease.leasePath);
|
|
@@ -2058,6 +2120,49 @@ function startMessageQueueDrain() {
|
|
|
2058
2120
|
process.stderr.write(`[exed] Message queue drain started (every ${MESSAGE_DRAIN_INTERVAL_MS / 1e3}s)
|
|
2059
2121
|
`);
|
|
2060
2122
|
}
|
|
2123
|
+
async function retryPendingMessages() {
|
|
2124
|
+
try {
|
|
2125
|
+
if (!await ensureStoreForPolling()) return;
|
|
2126
|
+
const { getClient: getDbClient } = await import("./database.js");
|
|
2127
|
+
const client = getDbClient();
|
|
2128
|
+
const { sendIntercomAsync, employeeSessionName, resolveExeSession } = await import("./tmux-routing.js");
|
|
2129
|
+
const rows = await client.execute({
|
|
2130
|
+
sql: `SELECT id, target_agent FROM messages WHERE status = 'pending_delivery' ORDER BY created_at ASC LIMIT 100`,
|
|
2131
|
+
args: []
|
|
2132
|
+
});
|
|
2133
|
+
if (!rows.rows || rows.rows.length === 0) return;
|
|
2134
|
+
process.stderr.write(`[exed] Retrying ${rows.rows.length} pending_delivery message(s) from previous daemon lifecycle...
|
|
2135
|
+
`);
|
|
2136
|
+
const exeSession = resolveExeSession();
|
|
2137
|
+
let retried = 0;
|
|
2138
|
+
for (const row of rows.rows) {
|
|
2139
|
+
const id = row.id;
|
|
2140
|
+
const targetAgent = row.target_agent;
|
|
2141
|
+
try {
|
|
2142
|
+
let delivered = false;
|
|
2143
|
+
if (exeSession) {
|
|
2144
|
+
const sessionName = employeeSessionName(targetAgent, exeSession);
|
|
2145
|
+
const result = await sendIntercomAsync(sessionName, { force: true });
|
|
2146
|
+
delivered = result !== "failed";
|
|
2147
|
+
}
|
|
2148
|
+
await client.execute({
|
|
2149
|
+
sql: `UPDATE messages SET status = ? WHERE id = ?`,
|
|
2150
|
+
args: [delivered ? "delivered" : "delivery_failed", id]
|
|
2151
|
+
});
|
|
2152
|
+
if (delivered) retried++;
|
|
2153
|
+
await yieldToEventLoop();
|
|
2154
|
+
} catch (err) {
|
|
2155
|
+
process.stderr.write(`[exed] Pending message retry error for ${id}: ${err instanceof Error ? err.message : String(err)}
|
|
2156
|
+
`);
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
if (retried > 0) process.stderr.write(`[exed] Pending message retry: ${retried}/${rows.rows.length} delivered successfully.
|
|
2160
|
+
`);
|
|
2161
|
+
} catch (err) {
|
|
2162
|
+
process.stderr.write(`[exed] Pending message retry sweep error: ${err instanceof Error ? err.message : String(err)}
|
|
2163
|
+
`);
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2061
2166
|
function startServer() {
|
|
2062
2167
|
mkdirSync2(path3.dirname(SOCKET_PATH), { recursive: true });
|
|
2063
2168
|
try {
|
|
@@ -2476,13 +2581,18 @@ async function startMcpHttpServer() {
|
|
|
2476
2581
|
}
|
|
2477
2582
|
return "unknown";
|
|
2478
2583
|
}, sendJsonRpcError2 = function(res, status, message, id, extra) {
|
|
2479
|
-
|
|
2584
|
+
const correlationId = randomUUID();
|
|
2585
|
+
const headers = {
|
|
2586
|
+
"Content-Type": "application/json",
|
|
2587
|
+
"X-Exe-Correlation-Id": correlationId
|
|
2588
|
+
};
|
|
2589
|
+
res.writeHead(status, headers);
|
|
2480
2590
|
res.end(JSON.stringify({
|
|
2481
2591
|
jsonrpc: "2.0",
|
|
2482
|
-
error: { code: -32e3, message },
|
|
2592
|
+
error: { code: -32e3, message, data: { correlationId } },
|
|
2483
2593
|
id
|
|
2484
2594
|
}));
|
|
2485
|
-
recordMcpHttpEvent({ level: "warn", message, status, ...extra });
|
|
2595
|
+
recordMcpHttpEvent({ level: "warn", message, status, correlationId, ...extra });
|
|
2486
2596
|
};
|
|
2487
2597
|
var parseDurationMs = parseDurationMs2, formatHostAuthority = formatHostAuthority2, formatOriginBase = formatOriginBase2, isAllowedHostAndOrigin = isAllowedHostAndOrigin2, closeMcpSession = closeMcpSession2, mcpSessionOwnerKey = mcpSessionOwnerKey2, resolveMcpSessionDetails = resolveMcpSessionDetails2, evictDuplicateMcpSessions = evictDuplicateMcpSessions2, pruneStaleRecoveryAliases = pruneStaleRecoveryAliases2, getRecoveredMcpSession = getRecoveredMcpSession2, awaitPendingMcpInit2 = awaitPendingMcpInit3, sweepStaleMcpSessions = sweepStaleMcpSessions2, getJsonRpcId = getJsonRpcId2, sendJsonRpcError = sendJsonRpcError2;
|
|
2488
2598
|
process.stderr.write("[exed] MCP HTTP: importing SDK modules...\n");
|
|
@@ -2549,7 +2659,7 @@ async function startMcpHttpServer() {
|
|
|
2549
2659
|
}
|
|
2550
2660
|
process.stderr.write("[exed] MCP HTTP: DB ready\n");
|
|
2551
2661
|
_storeInitialized = true;
|
|
2552
|
-
const { initLicenseGate, getCachedLicenseGate } = await import("../license-gate-
|
|
2662
|
+
const { initLicenseGate, getCachedLicenseGate } = await import("../license-gate-PZOP7S2S.js");
|
|
2553
2663
|
const gateResult = await initLicenseGate();
|
|
2554
2664
|
if (!gateResult.hasKey) {
|
|
2555
2665
|
process.stderr.write(
|
|
@@ -2564,13 +2674,13 @@ async function startMcpHttpServer() {
|
|
|
2564
2674
|
let _cachedWrapTelemetry = null;
|
|
2565
2675
|
async function getWrapTelemetry() {
|
|
2566
2676
|
if (!_cachedWrapTelemetry) {
|
|
2567
|
-
const { wrapServerWithTelemetry } = await import("../tool-telemetry-
|
|
2677
|
+
const { wrapServerWithTelemetry } = await import("../tool-telemetry-CDNPES5B.js");
|
|
2568
2678
|
_cachedWrapTelemetry = wrapServerWithTelemetry;
|
|
2569
2679
|
}
|
|
2570
2680
|
return _cachedWrapTelemetry;
|
|
2571
2681
|
}
|
|
2572
2682
|
Promise.all([
|
|
2573
|
-
import("../tool-capability-index-
|
|
2683
|
+
import("../tool-capability-index-SHYCBE2Z.js"),
|
|
2574
2684
|
import("../tool-gates-3IC7DK4R.js")
|
|
2575
2685
|
]).then(async ([{ getToolCapabilityIndex }, { TOOL_CATEGORIES }]) => {
|
|
2576
2686
|
const gateState = getCachedLicenseGate();
|
|
@@ -2634,7 +2744,7 @@ async function startMcpHttpServer() {
|
|
|
2634
2744
|
if (!token || token === header) return false;
|
|
2635
2745
|
if (token === _daemonToken) return true;
|
|
2636
2746
|
try {
|
|
2637
|
-
const { verifyAccessToken } = await import("../oauth-server-
|
|
2747
|
+
const { verifyAccessToken } = await import("../oauth-server-F4QWESK2.js");
|
|
2638
2748
|
const result = verifyAccessToken(token);
|
|
2639
2749
|
return result.valid;
|
|
2640
2750
|
} catch {
|
|
@@ -2837,8 +2947,8 @@ async function startMcpHttpServer() {
|
|
|
2837
2947
|
}
|
|
2838
2948
|
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1");
|
|
2839
2949
|
res.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS");
|
|
2840
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Agent-Id, X-Agent-Role, X-Exe-Session, X-Project-Name, Mcp-Session-Id");
|
|
2841
|
-
res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id");
|
|
2950
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Agent-Id, X-Agent-Role, X-Exe-Session, X-Exe-Session-Name, X-Project-Name, Mcp-Session-Id");
|
|
2951
|
+
res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id, X-Exe-Correlation-Id");
|
|
2842
2952
|
const url = new URL(req.url || "/", `http://${MCP_HTTP_HOST}:${MCP_HTTP_PORT}`);
|
|
2843
2953
|
if (req.method === "GET" && url.pathname === "/health") {
|
|
2844
2954
|
const elLag = getEventLoopLagMs();
|
|
@@ -2869,12 +2979,14 @@ async function startMcpHttpServer() {
|
|
|
2869
2979
|
return;
|
|
2870
2980
|
}
|
|
2871
2981
|
if (_drainingWrites) {
|
|
2872
|
-
|
|
2873
|
-
res.
|
|
2982
|
+
const correlationId = randomUUID();
|
|
2983
|
+
res.writeHead(503, { "Content-Type": "application/json", "X-Exe-Correlation-Id": correlationId });
|
|
2984
|
+
res.end(JSON.stringify({ error: "Server shutting down", correlationId }));
|
|
2985
|
+
recordMcpHttpEvent({ level: "warn", message: "Server shutting down", status: 503, method: req.method, correlationId });
|
|
2874
2986
|
return;
|
|
2875
2987
|
}
|
|
2876
2988
|
try {
|
|
2877
|
-
const { handleOAuthRoute } = await import("../oauth-server-
|
|
2989
|
+
const { handleOAuthRoute } = await import("../oauth-server-F4QWESK2.js");
|
|
2878
2990
|
const handled = await handleOAuthRoute(req, res, url, MCP_HTTP_PORT);
|
|
2879
2991
|
if (handled) return;
|
|
2880
2992
|
} catch (err) {
|
|
@@ -2906,7 +3018,7 @@ async function startMcpHttpServer() {
|
|
|
2906
3018
|
for await (const chunk of req) chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
2907
3019
|
const rawBody = Buffer.concat(chunks);
|
|
2908
3020
|
try {
|
|
2909
|
-
const { loadWebhookConfig, verifyHmac, processWebhook } = await import("../webhook-pipe-
|
|
3021
|
+
const { loadWebhookConfig, verifyHmac, processWebhook } = await import("../webhook-pipe-S4CWK6H5.js");
|
|
2910
3022
|
const webhookConfig = await loadWebhookConfig();
|
|
2911
3023
|
const serviceConfig = webhookConfig[serviceName];
|
|
2912
3024
|
if (!serviceConfig) {
|
|
@@ -3002,7 +3114,7 @@ async function startMcpHttpServer() {
|
|
|
3002
3114
|
contextPct: body.context_pct
|
|
3003
3115
|
});
|
|
3004
3116
|
if (body.context_pct !== void 0 && body.context_pct > 70) {
|
|
3005
|
-
void import("../orchestration-events-
|
|
3117
|
+
void import("../orchestration-events-7SNWRJYE.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
|
|
3006
3118
|
recordOE({
|
|
3007
3119
|
eventType: "context.pressure",
|
|
3008
3120
|
source: "exe-daemon.heartbeat",
|
|
@@ -3084,7 +3196,7 @@ async function startMcpHttpServer() {
|
|
|
3084
3196
|
agentRole = "employee";
|
|
3085
3197
|
}
|
|
3086
3198
|
const projectNameHeader = req.headers["x-project-name"] || "";
|
|
3087
|
-
let sessionHint = req.headers["x-exe-session"] || "";
|
|
3199
|
+
let sessionHint = req.headers["x-exe-session-name"] || req.headers["x-exe-session"] || "";
|
|
3088
3200
|
if (sessionHint.includes("$(") || sessionHint.includes("#{") || sessionHint.includes("tmux")) {
|
|
3089
3201
|
sessionHint = "";
|
|
3090
3202
|
}
|
|
@@ -3148,6 +3260,13 @@ async function startMcpHttpServer() {
|
|
|
3148
3260
|
});
|
|
3149
3261
|
return;
|
|
3150
3262
|
}
|
|
3263
|
+
const pingMethod = parsedBody?.method;
|
|
3264
|
+
if (req.method === "POST" && pingMethod === "ping") {
|
|
3265
|
+
const payload = JSON.stringify({ jsonrpc: "2.0", id: getJsonRpcId2(parsedBody), result: {} });
|
|
3266
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
3267
|
+
res.end(payload);
|
|
3268
|
+
return;
|
|
3269
|
+
}
|
|
3151
3270
|
const sessionId = req.headers["mcp-session-id"];
|
|
3152
3271
|
let transport;
|
|
3153
3272
|
let _thisRequestPendingInit;
|
|
@@ -3318,6 +3437,7 @@ async function startMcpHttpServer() {
|
|
|
3318
3437
|
sessionHint = details.sessionHint ?? "";
|
|
3319
3438
|
transport = recovered.transport;
|
|
3320
3439
|
req.headers["mcp-session-id"] = recovered.sessionId;
|
|
3440
|
+
if (!res.headersSent) res.setHeader("Mcp-Session-Id", recovered.sessionId);
|
|
3321
3441
|
} else if (sessionId && !transports.has(sessionId) && req.method === "DELETE") {
|
|
3322
3442
|
recordMcpHttpEvent({
|
|
3323
3443
|
level: "info",
|
|
@@ -3344,6 +3464,7 @@ async function startMcpHttpServer() {
|
|
|
3344
3464
|
transport = transports.get(adoptedSid);
|
|
3345
3465
|
sessionLastSeen.set(adoptedSid, Date.now());
|
|
3346
3466
|
req.headers["mcp-session-id"] = adoptedSid;
|
|
3467
|
+
if (!res.headersSent) res.setHeader("Mcp-Session-Id", adoptedSid);
|
|
3347
3468
|
recordMcpHttpEvent({
|
|
3348
3469
|
level: "info",
|
|
3349
3470
|
message: "missing_session_grace_recovered",
|
|
@@ -3481,8 +3602,9 @@ async function startMcpHttpServer() {
|
|
|
3481
3602
|
httpServer.listen(MCP_HTTP_PORT, MCP_HTTP_HOST, () => {
|
|
3482
3603
|
process.stderr.write(`[exed] MCP HTTP listening on ${MCP_HTTP_HOST}:${MCP_HTTP_PORT}
|
|
3483
3604
|
`);
|
|
3605
|
+
_boundMcpPort = MCP_HTTP_PORT;
|
|
3484
3606
|
writeDaemonReady({ pid: process.pid, port: MCP_HTTP_PORT });
|
|
3485
|
-
void import("../mcp-port-config-
|
|
3607
|
+
void import("../mcp-port-config-FFAMMLLE.js").then(({ persistMcpPortToConfig }) => persistMcpPortToConfig(String(MCP_HTTP_PORT))).catch(() => {
|
|
3486
3608
|
});
|
|
3487
3609
|
recordMcpHttpEvent({
|
|
3488
3610
|
level: "info",
|
|
@@ -3586,13 +3708,13 @@ async function ensureStoreForPolling() {
|
|
|
3586
3708
|
}
|
|
3587
3709
|
}
|
|
3588
3710
|
async function startReviewPolling() {
|
|
3589
|
-
const polling = await import("../review-polling-
|
|
3711
|
+
const polling = await import("../review-polling-SRYZU2PI.js");
|
|
3590
3712
|
const state = {
|
|
3591
3713
|
lastIntercomSent: /* @__PURE__ */ new Map(),
|
|
3592
3714
|
lastNudgeSent: /* @__PURE__ */ new Map(),
|
|
3593
3715
|
intervalMs: REVIEW_POLL_INTERVAL_MS
|
|
3594
3716
|
};
|
|
3595
|
-
const { pollReviewNudge, createReviewNudgeRealDeps, loadNudgeState } = await import("../daemon-orchestration-
|
|
3717
|
+
const { pollReviewNudge, createReviewNudgeRealDeps, loadNudgeState } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
3596
3718
|
const nudgeState = loadNudgeState();
|
|
3597
3719
|
const tick = async () => traceDaemonTimer("review_polling", async () => {
|
|
3598
3720
|
fired("review_polling");
|
|
@@ -3636,7 +3758,7 @@ function startSessionTTL() {
|
|
|
3636
3758
|
if (!await ensureStoreForPolling()) return;
|
|
3637
3759
|
try {
|
|
3638
3760
|
const { getClient } = await import("./database.js");
|
|
3639
|
-
const { checkSessionTTL, createSessionTTLRealDeps } = await import("../daemon-orchestration-
|
|
3761
|
+
const { checkSessionTTL, createSessionTTLRealDeps } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
3640
3762
|
const deps = createSessionTTLRealDeps(getClient);
|
|
3641
3763
|
const killed = await checkSessionTTL(deps);
|
|
3642
3764
|
if (killed.length > 0) acted("session_ttl");
|
|
@@ -3684,7 +3806,7 @@ function startIdleKill() {
|
|
|
3684
3806
|
const cfg = await getCachedConfig();
|
|
3685
3807
|
if (!cfg) return;
|
|
3686
3808
|
const { getClient } = await import("./database.js");
|
|
3687
|
-
const { pollIdleKill, createIdleKillRealDeps } = await import("../daemon-orchestration-
|
|
3809
|
+
const { pollIdleKill, createIdleKillRealDeps } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
3688
3810
|
const { sessions: liveSessions, paneCache, aliveSessions } = await getSharedOrchestrationCaches();
|
|
3689
3811
|
const realDeps = createIdleKillRealDeps(
|
|
3690
3812
|
getClient,
|
|
@@ -3753,7 +3875,7 @@ function startConsolidation() {
|
|
|
3753
3875
|
`);
|
|
3754
3876
|
}
|
|
3755
3877
|
try {
|
|
3756
|
-
const { createBackupAsync, enforceRetention } = await import("../db-backup-
|
|
3878
|
+
const { createBackupAsync, enforceRetention } = await import("../db-backup-BTL2FBBL.js");
|
|
3757
3879
|
const p = await createBackupAsync("pre-consolidation");
|
|
3758
3880
|
if (p) enforceRetention("pre-consolidation");
|
|
3759
3881
|
} catch (e) {
|
|
@@ -3937,7 +4059,7 @@ function startSkillRefinement() {
|
|
|
3937
4059
|
if (!shouldRunHeavyJob("skill_refinement")) return;
|
|
3938
4060
|
try {
|
|
3939
4061
|
if (!await ensureStoreForPolling()) return;
|
|
3940
|
-
const { runSkillRefinement } = await import("../skill-refinement-
|
|
4062
|
+
const { runSkillRefinement } = await import("../skill-refinement-VTYL4OMJ.js");
|
|
3941
4063
|
const result = await runSkillRefinement();
|
|
3942
4064
|
if (result.reviewed > 0) {
|
|
3943
4065
|
acted("skill_refinement");
|
|
@@ -3963,7 +4085,7 @@ function startStaleBranchSweep() {
|
|
|
3963
4085
|
const tick = async () => {
|
|
3964
4086
|
fired("stale_branch_sweep");
|
|
3965
4087
|
try {
|
|
3966
|
-
const { discoverRepoPaths } = await import("../worktree-sweep-
|
|
4088
|
+
const { discoverRepoPaths } = await import("../worktree-sweep-LWSCAZW6.js");
|
|
3967
4089
|
const { scanUnmergedBranches } = await import("../branch-hygiene-55TKIWAZ.js");
|
|
3968
4090
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3969
4091
|
for (const k of _staleBranchAlertedToday) {
|
|
@@ -3990,7 +4112,7 @@ function startStaleBranchSweep() {
|
|
|
3990
4112
|
if (!_storeInitialized) continue;
|
|
3991
4113
|
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("; ");
|
|
3992
4114
|
try {
|
|
3993
|
-
const { writeNotification } = await import("../notifications-
|
|
4115
|
+
const { writeNotification } = await import("../notifications-Q5NEAP6K.js");
|
|
3994
4116
|
await writeNotification({
|
|
3995
4117
|
agentId: "exe",
|
|
3996
4118
|
agentRole: "system",
|
|
@@ -4443,7 +4565,7 @@ function startReflectionSweep() {
|
|
|
4443
4565
|
);
|
|
4444
4566
|
let runReflection;
|
|
4445
4567
|
try {
|
|
4446
|
-
({ runReflection } = await import("../memory-reflection-
|
|
4568
|
+
({ runReflection } = await import("../memory-reflection-VHQRUZWK.js"));
|
|
4447
4569
|
} catch (importErr) {
|
|
4448
4570
|
_reflectionImportFailed = true;
|
|
4449
4571
|
process.stderr.write(`[exed] Reflection module unavailable (stale chunk hash?) \u2014 disabled until daemon restart: ${importErr instanceof Error ? importErr.message : String(importErr)}
|
|
@@ -4482,7 +4604,7 @@ function startReflectionSweep() {
|
|
|
4482
4604
|
if (memories > 100 && cards < memories * 0.1) {
|
|
4483
4605
|
process.stderr.write(`[exed] Memory cards sparse (${cards} cards / ${memories} memories) \u2014 running backfill...
|
|
4484
4606
|
`);
|
|
4485
|
-
const { insertMemoryCardsForBatch } = await import("../memory-cards-
|
|
4607
|
+
const { insertMemoryCardsForBatch } = await import("../memory-cards-CNLMHSZC.js");
|
|
4486
4608
|
const batchSize = 500;
|
|
4487
4609
|
let offset = 0;
|
|
4488
4610
|
let totalCards = 0;
|
|
@@ -4527,7 +4649,7 @@ function startDatabaseBackup() {
|
|
|
4527
4649
|
fired("db_backup");
|
|
4528
4650
|
if (!shouldRunHeavyJob("db_backup")) return;
|
|
4529
4651
|
try {
|
|
4530
|
-
const { createBackupAsync, enforceRetention, hasBackupToday } = await import("../db-backup-
|
|
4652
|
+
const { createBackupAsync, enforceRetention, hasBackupToday } = await import("../db-backup-BTL2FBBL.js");
|
|
4531
4653
|
if (hasBackupToday("daily")) return;
|
|
4532
4654
|
const backupPath = await createBackupAsync("daily");
|
|
4533
4655
|
if (backupPath) {
|
|
@@ -4596,7 +4718,7 @@ function startSessionEventsRetention() {
|
|
|
4596
4718
|
if (!await ensureStoreForPolling()) return;
|
|
4597
4719
|
try {
|
|
4598
4720
|
const { getClient } = await import("./database.js");
|
|
4599
|
-
const { sweepExpiredSessionEvents, DEFAULT_SESSION_EVENTS_RETENTION_DAYS } = await import("../session-events-
|
|
4721
|
+
const { sweepExpiredSessionEvents, DEFAULT_SESSION_EVENTS_RETENTION_DAYS } = await import("../session-events-L4DK5J6J.js");
|
|
4600
4722
|
const days = SESSION_EVENTS_RETENTION_DAYS ?? DEFAULT_SESSION_EVENTS_RETENTION_DAYS;
|
|
4601
4723
|
const count = await sweepExpiredSessionEvents(getClient(), days);
|
|
4602
4724
|
if (count > 0) {
|
|
@@ -4626,13 +4748,41 @@ function startIntercomQueueDrain() {
|
|
|
4626
4748
|
const tick = async () => traceDaemonTimer("intercom_queue_drain", async () => {
|
|
4627
4749
|
fired("intercom_queue_drain");
|
|
4628
4750
|
try {
|
|
4629
|
-
const { drainQueue } = await import("../intercom-queue-6M5IRX3Y.js");
|
|
4751
|
+
const { drainQueue, readQueue } = await import("../intercom-queue-6M5IRX3Y.js");
|
|
4630
4752
|
const { isSessionBusy } = await import("./tmux-routing.js");
|
|
4753
|
+
const { baseAgentName } = await import("./employees.js");
|
|
4754
|
+
const agentsWithEmptyInbox = /* @__PURE__ */ new Set();
|
|
4755
|
+
try {
|
|
4756
|
+
const queue = readQueue();
|
|
4757
|
+
const messageTargets = new Set(
|
|
4758
|
+
queue.filter((q) => q.intercomReason === "message").map((q) => baseAgentName(q.targetSession.split("-")[0] ?? q.targetSession))
|
|
4759
|
+
);
|
|
4760
|
+
if (messageTargets.size > 0) {
|
|
4761
|
+
const { countUnreadMessages } = await import("./messaging.js");
|
|
4762
|
+
for (const agentId of messageTargets) {
|
|
4763
|
+
try {
|
|
4764
|
+
const count = await countUnreadMessages(agentId);
|
|
4765
|
+
if (count === 0) agentsWithEmptyInbox.add(agentId);
|
|
4766
|
+
} catch {
|
|
4767
|
+
}
|
|
4768
|
+
}
|
|
4769
|
+
}
|
|
4770
|
+
} catch {
|
|
4771
|
+
}
|
|
4631
4772
|
const { sendIntercom: centralSendIntercom } = await import("./tmux-routing.js");
|
|
4632
4773
|
const result = drainQueue(
|
|
4633
4774
|
(session) => isSessionBusy(session),
|
|
4634
4775
|
(session, item) => {
|
|
4635
4776
|
try {
|
|
4777
|
+
if (item.intercomReason === "message") {
|
|
4778
|
+
const agentRaw = session.split("-")[0] ?? session;
|
|
4779
|
+
const agent = baseAgentName(agentRaw);
|
|
4780
|
+
if (agentsWithEmptyInbox.has(agent)) {
|
|
4781
|
+
process.stderr.write(`[exe-daemon] skipping stale message intercom for ${session} (inbox empty)
|
|
4782
|
+
`);
|
|
4783
|
+
return true;
|
|
4784
|
+
}
|
|
4785
|
+
}
|
|
4636
4786
|
const outcome = centralSendIntercom(session, {
|
|
4637
4787
|
reason: item.intercomReason ?? "nudge"
|
|
4638
4788
|
});
|
|
@@ -4664,7 +4814,7 @@ function startOrphanReaper() {
|
|
|
4664
4814
|
const tick = async () => traceDaemonTimer("orphan_reaper", async () => {
|
|
4665
4815
|
fired("orphan_reaper");
|
|
4666
4816
|
try {
|
|
4667
|
-
const { reapOrphanedMcpProcesses, createOrphanReaperRealDepsAsync } = await import("../daemon-orchestration-
|
|
4817
|
+
const { reapOrphanedMcpProcesses, createOrphanReaperRealDepsAsync } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
4668
4818
|
const deps = await createOrphanReaperRealDepsAsync();
|
|
4669
4819
|
const reaped = await reapOrphanedMcpProcesses(deps);
|
|
4670
4820
|
if (reaped.length > 0) acted("orphan_reaper");
|
|
@@ -4689,7 +4839,7 @@ function startZombieAgentReaper() {
|
|
|
4689
4839
|
const tick = async () => traceDaemonTimer("zombie_agent_reaper", async () => {
|
|
4690
4840
|
fired("zombie_agent_reaper");
|
|
4691
4841
|
try {
|
|
4692
|
-
const { reapZombieAgentProcesses, createZombieAgentReaperRealDepsAsync } = await import("../daemon-orchestration-
|
|
4842
|
+
const { reapZombieAgentProcesses, createZombieAgentReaperRealDepsAsync } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
4693
4843
|
const deps = await createZombieAgentReaperRealDepsAsync();
|
|
4694
4844
|
const reaped = reapZombieAgentProcesses(deps);
|
|
4695
4845
|
if (reaped.length > 0) acted("zombie_agent_reaper");
|
|
@@ -4713,7 +4863,7 @@ function startWorktreeReaper() {
|
|
|
4713
4863
|
const tick = async () => traceDaemonTimer("worktree_reaper", async () => {
|
|
4714
4864
|
fired("worktree_reaper");
|
|
4715
4865
|
try {
|
|
4716
|
-
const { reapOrphanedWorktrees, createWorktreeReaperRealDeps } = await import("../daemon-orchestration-
|
|
4866
|
+
const { reapOrphanedWorktrees, createWorktreeReaperRealDeps } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
4717
4867
|
const deps = await createWorktreeReaperRealDeps();
|
|
4718
4868
|
const result = await reapOrphanedWorktrees(deps);
|
|
4719
4869
|
if (result.pruned.length > 0) {
|
|
@@ -4753,8 +4903,8 @@ function startWorktreeReaper() {
|
|
|
4753
4903
|
}
|
|
4754
4904
|
continue;
|
|
4755
4905
|
}
|
|
4756
|
-
const { cleanupAgentWorktree } = await import("../worktree-sweep-
|
|
4757
|
-
const { getMainRepoRoot } = await import("../worktree-
|
|
4906
|
+
const { cleanupAgentWorktree } = await import("../worktree-sweep-LWSCAZW6.js");
|
|
4907
|
+
const { getMainRepoRoot } = await import("../worktree-Z2G4CP4Z.js");
|
|
4758
4908
|
const repoRoot = getMainRepoRoot(signal.worktreePath);
|
|
4759
4909
|
if (repoRoot && signal.agentId) {
|
|
4760
4910
|
const notes = cleanupAgentWorktree(repoRoot, signal.agentId);
|
|
@@ -4780,6 +4930,116 @@ function startWorktreeReaper() {
|
|
|
4780
4930
|
`);
|
|
4781
4931
|
}
|
|
4782
4932
|
var AUTO_WAKE_INTERVAL_MS = 60 * 1e3;
|
|
4933
|
+
function startAutoWake() {
|
|
4934
|
+
const tick = async () => traceDaemonTimer("auto_wake", async () => {
|
|
4935
|
+
fired("auto_wake");
|
|
4936
|
+
if (process.env.EXE_AUTO_WAKE === "0") return;
|
|
4937
|
+
if (!await ensureStoreForPolling()) return;
|
|
4938
|
+
try {
|
|
4939
|
+
const { getClient } = await import("./database.js");
|
|
4940
|
+
const { pollOrphanedTasks, createAutoWakeRealDeps } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
4941
|
+
const deps = createAutoWakeRealDeps(getClient, process.cwd());
|
|
4942
|
+
const woken = await pollOrphanedTasks(deps);
|
|
4943
|
+
if (woken.length > 0) acted("auto_wake");
|
|
4944
|
+
for (const agent of woken) {
|
|
4945
|
+
process.stderr.write(`[exed] Auto-wake: spawned ${agent}
|
|
4946
|
+
`);
|
|
4947
|
+
}
|
|
4948
|
+
try {
|
|
4949
|
+
const signalBase = path3.join(os2.homedir(), ".exe-os", "task-signals");
|
|
4950
|
+
if (existsSync3(signalBase)) {
|
|
4951
|
+
const { readdirSync: readdirSync2, statSync: statSyncFs } = await import("fs");
|
|
4952
|
+
const { sendIntercomAsync } = await import("./tmux-routing.js");
|
|
4953
|
+
const sessionCache = path3.join(os2.homedir(), ".exe-os", "session-cache");
|
|
4954
|
+
const sessions = await getTmuxSessionsAsync();
|
|
4955
|
+
const signalDirs = [];
|
|
4956
|
+
for (const entry of readdirSync2(signalBase, { withFileTypes: true })) {
|
|
4957
|
+
if (entry.isDirectory()) signalDirs.push({ dir: path3.join(signalBase, entry.name), scope: entry.name });
|
|
4958
|
+
}
|
|
4959
|
+
signalDirs.push({ dir: signalBase, scope: null });
|
|
4960
|
+
const _runtimeCache = /* @__PURE__ */ new Map();
|
|
4961
|
+
const runtimeFor = (sessionName) => {
|
|
4962
|
+
const cached = _runtimeCache.get(sessionName);
|
|
4963
|
+
if (cached && Date.now() - cached.ts < 3e4) return cached.runtime;
|
|
4964
|
+
try {
|
|
4965
|
+
const dispatchInfoPath = path3.join(sessionCache, `dispatch-info-${sessionName}.json`);
|
|
4966
|
+
if (!existsSync3(dispatchInfoPath)) {
|
|
4967
|
+
_runtimeCache.set(sessionName, { runtime: "claude", ts: Date.now() });
|
|
4968
|
+
return "claude";
|
|
4969
|
+
}
|
|
4970
|
+
const raw = JSON.parse(readFileSync3(dispatchInfoPath, "utf8"));
|
|
4971
|
+
const rt = raw.runtime ?? "claude";
|
|
4972
|
+
_runtimeCache.set(sessionName, { runtime: rt, ts: Date.now() });
|
|
4973
|
+
return rt;
|
|
4974
|
+
} catch {
|
|
4975
|
+
return "claude";
|
|
4976
|
+
}
|
|
4977
|
+
};
|
|
4978
|
+
for (const { dir, scope } of signalDirs) {
|
|
4979
|
+
let files = [];
|
|
4980
|
+
try {
|
|
4981
|
+
files = readdirSync2(dir).filter((f) => f.endsWith(".pending") && !f.includes("review-"));
|
|
4982
|
+
} catch {
|
|
4983
|
+
continue;
|
|
4984
|
+
}
|
|
4985
|
+
for (const file of files) {
|
|
4986
|
+
const signalPath = path3.join(dir, file);
|
|
4987
|
+
const age = Date.now() - statSyncFs(signalPath).mtimeMs;
|
|
4988
|
+
if (age > 60 * 60 * 1e3) {
|
|
4989
|
+
try {
|
|
4990
|
+
unlinkSync2(signalPath);
|
|
4991
|
+
void import("../orchestration-events-7SNWRJYE.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
|
|
4992
|
+
recordOE({ eventType: "signal.stale", source: "exe-daemon.autoWake", severity: "warn", payload: { file, ageMinutes: Math.round(age / 6e4) } });
|
|
4993
|
+
}).catch(() => {
|
|
4994
|
+
});
|
|
4995
|
+
} catch {
|
|
4996
|
+
}
|
|
4997
|
+
continue;
|
|
4998
|
+
}
|
|
4999
|
+
if (age > 5 * 60 * 1e3) continue;
|
|
5000
|
+
const agentId = file.includes(".") ? file.split(".")[0] : file.replace(".pending", "");
|
|
5001
|
+
const match = sessions.find((s) => {
|
|
5002
|
+
const agentPart = s.split("-")[0] ?? s;
|
|
5003
|
+
const base = agentPart.replace(/\d+$/, "");
|
|
5004
|
+
if (base !== agentId && s !== agentId) return false;
|
|
5005
|
+
if (!scope) return true;
|
|
5006
|
+
return s.endsWith(`-${scope}`);
|
|
5007
|
+
});
|
|
5008
|
+
if (!match) continue;
|
|
5009
|
+
const state = classifyPaneState(await capturePaneAsync(match, 5));
|
|
5010
|
+
if (state !== "idle") continue;
|
|
5011
|
+
const runtime = runtimeFor(match);
|
|
5012
|
+
if (runtime === "codex" || runtime === "opencode" || runtime === "exe-agent") {
|
|
5013
|
+
await killTmuxSessionAsync(match);
|
|
5014
|
+
acted("auto_wake");
|
|
5015
|
+
process.stderr.write(
|
|
5016
|
+
`[exed] Signal-wake: killed idle ${runtime} session ${match} for fresh task signal ${file}; auto-wake will respawn (signal age ${Math.round(age / 1e3)}s)
|
|
5017
|
+
`
|
|
5018
|
+
);
|
|
5019
|
+
} else {
|
|
5020
|
+
await sendIntercomAsync(match, { force: true, reason: "signal" });
|
|
5021
|
+
process.stderr.write(`[exed] Signal-nudge: sent intercom to ${match} (signal age ${Math.round(age / 1e3)}s)
|
|
5022
|
+
`);
|
|
5023
|
+
}
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
5026
|
+
}
|
|
5027
|
+
} catch (err) {
|
|
5028
|
+
process.stderr.write(`[exed] Signal-wake error: ${err instanceof Error ? err.message : String(err)}
|
|
5029
|
+
`);
|
|
5030
|
+
}
|
|
5031
|
+
} catch (err) {
|
|
5032
|
+
process.stderr.write(`[exed] Auto-wake error: ${err instanceof Error ? err.message : String(err)}
|
|
5033
|
+
`);
|
|
5034
|
+
}
|
|
5035
|
+
});
|
|
5036
|
+
setTimeout(() => {
|
|
5037
|
+
const timer = setInterval(() => void tick(), AUTO_WAKE_INTERVAL_MS);
|
|
5038
|
+
timer.unref();
|
|
5039
|
+
}, 15e3);
|
|
5040
|
+
process.stderr.write(`[exed] Auto-wake started (every ${AUTO_WAKE_INTERVAL_MS / 1e3}s, offset 15s)
|
|
5041
|
+
`);
|
|
5042
|
+
}
|
|
4783
5043
|
var WAL_CHECKPOINT_INTERVAL_MS = 5 * 60 * 1e3;
|
|
4784
5044
|
function startWalCheckpoint() {
|
|
4785
5045
|
const tick = async () => {
|
|
@@ -4788,7 +5048,7 @@ function startWalCheckpoint() {
|
|
|
4788
5048
|
try {
|
|
4789
5049
|
const { getClient, runWalCheckpoint } = await import("./database.js");
|
|
4790
5050
|
const client = getClient();
|
|
4791
|
-
const { findActiveDb } = await import("../db-backup-
|
|
5051
|
+
const { findActiveDb } = await import("../db-backup-BTL2FBBL.js");
|
|
4792
5052
|
const dbPath = findActiveDb();
|
|
4793
5053
|
const started = Date.now();
|
|
4794
5054
|
const result = await runWalCheckpoint(client, dbPath, true);
|
|
@@ -4860,7 +5120,7 @@ function startStuckTaskRelease() {
|
|
|
4860
5120
|
if (!await ensureStoreForPolling()) return;
|
|
4861
5121
|
try {
|
|
4862
5122
|
const { getClient } = await import("./database.js");
|
|
4863
|
-
const { releaseStuckTasks, createStuckTaskRealDeps } = await import("../daemon-orchestration-
|
|
5123
|
+
const { releaseStuckTasks, createStuckTaskRealDeps } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
4864
5124
|
const deps = createStuckTaskRealDeps(getClient);
|
|
4865
5125
|
const released = await releaseStuckTasks(deps);
|
|
4866
5126
|
if (released.length > 0) {
|
|
@@ -4914,8 +5174,9 @@ function startExternalRssWatchdog() {
|
|
|
4914
5174
|
const workerSource = `
|
|
4915
5175
|
import { workerData } from "node:worker_threads";
|
|
4916
5176
|
import { execFile } from "node:child_process";
|
|
4917
|
-
import { mkdirSync, writeFileSync } from "node:fs";
|
|
5177
|
+
import { mkdirSync, writeFileSync, statSync } from "node:fs";
|
|
4918
5178
|
import { dirname } from "node:path";
|
|
5179
|
+
import { loadavg, cpus } from "node:os";
|
|
4919
5180
|
|
|
4920
5181
|
const pid = Number(workerData.pid);
|
|
4921
5182
|
const restartBytes = Number(workerData.restartBytes);
|
|
@@ -4929,6 +5190,16 @@ function startExternalRssWatchdog() {
|
|
|
4929
5190
|
const debounceN = Number(workerData.debounceN) || 3;
|
|
4930
5191
|
const startupGraceMs = Number(workerData.startupGraceMs) || 0;
|
|
4931
5192
|
const startedAtMs = Number(workerData.startedAtMs) || Date.now();
|
|
5193
|
+
// Bugs 0b5ece29/459b9c5a/9a2e91a5: event-loop stall detection. The main loop
|
|
5194
|
+
// touches heartbeatPath every ~2s while alive. If its mtime goes stale beyond
|
|
5195
|
+
// stallMs, the loop is wedged on a synchronous op (SQLCipher scan) \u2014 RSS stays
|
|
5196
|
+
// healthy so the RSS path never fires. This worker thread has its OWN event
|
|
5197
|
+
// loop, so it keeps running and can terminate the daemon for a launchd respawn.
|
|
5198
|
+
const heartbeatPath = String(workerData.heartbeatPath || "");
|
|
5199
|
+
const stallMs = Number(workerData.stallMs) || 0;
|
|
5200
|
+
const stallMarkerPath = String(workerData.stallMarkerPath || markerPath);
|
|
5201
|
+
const starvationRatio = Number(workerData.starvationRatio);
|
|
5202
|
+
const cpuCount = cpus().length || 1;
|
|
4932
5203
|
let overCount = 0;
|
|
4933
5204
|
let terminating = false;
|
|
4934
5205
|
|
|
@@ -4940,6 +5211,44 @@ function startExternalRssWatchdog() {
|
|
|
4940
5211
|
});
|
|
4941
5212
|
}
|
|
4942
5213
|
|
|
5214
|
+
function terminateDaemon(reason) {
|
|
5215
|
+
if (terminating) return;
|
|
5216
|
+
terminating = true;
|
|
5217
|
+
try { process.stderr.write("[exed-watchdog] " + reason + " \u2014 terminating daemon PID " + pid + "\\n"); } catch {}
|
|
5218
|
+
// A wedged loop cannot run its SIGTERM handler, so escalate to SIGKILL after
|
|
5219
|
+
// a short grace (the in-process self-heal already WAL-checkpoints when it can;
|
|
5220
|
+
// this external path is the last resort precisely because the loop is stuck).
|
|
5221
|
+
try { process.kill(pid, "SIGTERM"); } catch {}
|
|
5222
|
+
setTimeout(() => { try { process.kill(pid, "SIGKILL"); } catch {} }, 5000).unref();
|
|
5223
|
+
}
|
|
5224
|
+
|
|
5225
|
+
// --- Event-loop stall watchdog (independent of RSS) ---
|
|
5226
|
+
if (heartbeatPath && stallMs > 0) {
|
|
5227
|
+
setInterval(() => {
|
|
5228
|
+
if (terminating) return;
|
|
5229
|
+
if (Date.now() - startedAtMs < startupGraceMs) return;
|
|
5230
|
+
let ageMs;
|
|
5231
|
+
try { ageMs = Date.now() - statSync(heartbeatPath).mtimeMs; }
|
|
5232
|
+
catch { return; } // heartbeat not yet written \u2014 main loop not up; do not act
|
|
5233
|
+
if (ageMs < stallMs) return;
|
|
5234
|
+
// Starvation-aware (bugs 459b9c5a/9a2e91a5): if the OS is CPU-starved the
|
|
5235
|
+
// lag is the scheduler, not an internal hang \u2014 restarting would not help and
|
|
5236
|
+
// risks WAL damage. Skip while load/core exceeds the ratio. starvationRatio<=0
|
|
5237
|
+
// disables this check (always treat a stale heartbeat as a real wedge).
|
|
5238
|
+
if (starvationRatio > 0) {
|
|
5239
|
+
const load1m = loadavg()[0] || 0;
|
|
5240
|
+
if (load1m > cpuCount * starvationRatio) {
|
|
5241
|
+
try { process.stderr.write("[exed-watchdog] event-loop heartbeat stale " + Math.round(ageMs/1000) + "s but load=" + load1m.toFixed(2) + "/" + cpuCount + " cpus (starved) \u2014 NOT restarting\\n"); } catch {}
|
|
5242
|
+
return;
|
|
5243
|
+
}
|
|
5244
|
+
}
|
|
5245
|
+
try { mkdirSync(dirname(stallMarkerPath), { recursive: true }); } catch {}
|
|
5246
|
+
try { writeFileSync(stallMarkerPath, "event-loop wedged (heartbeat stale " + Math.round(ageMs/1000) + "s) at " + new Date().toISOString() + " (external watchdog)\\n"); } catch {}
|
|
5247
|
+
terminateDaemon("EVENT LOOP WEDGED: heartbeat stale " + Math.round(ageMs/1000) + "s > " + Math.round(stallMs/1000) + "s threshold");
|
|
5248
|
+
}, checkMs).unref();
|
|
5249
|
+
}
|
|
5250
|
+
|
|
5251
|
+
// --- RSS watchdog (native leak outside V8 heap) ---
|
|
4943
5252
|
setInterval(() => {
|
|
4944
5253
|
if (terminating) return;
|
|
4945
5254
|
readRssBytes((rss) => {
|
|
@@ -4948,16 +5257,15 @@ function startExternalRssWatchdog() {
|
|
|
4948
5257
|
if (Date.now() - startedAtMs < startupGraceMs) return;
|
|
4949
5258
|
overCount += 1;
|
|
4950
5259
|
if (overCount < debounceN) return;
|
|
4951
|
-
terminating = true;
|
|
4952
5260
|
const rssMb = Math.round(rss / 1024 / 1024);
|
|
4953
5261
|
try { mkdirSync(dirname(markerPath), { recursive: true }); } catch {}
|
|
4954
5262
|
try { writeFileSync(markerPath, "RSS=" + rssMb + "MB at " + new Date().toISOString() + " (external watchdog, " + overCount + " consecutive)\\n"); } catch {}
|
|
4955
|
-
|
|
4956
|
-
try { process.kill(pid, "SIGTERM"); } catch {}
|
|
4957
|
-
setTimeout(() => { try { process.kill(pid, "SIGKILL"); } catch {} }, 5000).unref();
|
|
5263
|
+
terminateDaemon("RSS CRITICAL: " + rssMb + "MB for " + overCount + " consecutive samples");
|
|
4958
5264
|
});
|
|
4959
5265
|
}, checkMs).unref();
|
|
4960
5266
|
`;
|
|
5267
|
+
const stallMs = parseFloat(process.env.EXE_EVENT_LOOP_STALL_MS ?? "") || 15e4;
|
|
5268
|
+
const starvationRatio = parseFloat(process.env.EXE_STARVATION_LOAD_RATIO ?? "1.5");
|
|
4961
5269
|
const worker = new Worker(new URL(`data:text/javascript,${encodeURIComponent(workerSource)}`), {
|
|
4962
5270
|
workerData: {
|
|
4963
5271
|
pid: process.pid,
|
|
@@ -4969,12 +5277,16 @@ function startExternalRssWatchdog() {
|
|
|
4969
5277
|
// beyond the in-process debounce before terminating.
|
|
4970
5278
|
debounceN: DAEMON_RSS_RESTART_DEBOUNCE + 1,
|
|
4971
5279
|
startupGraceMs: DAEMON_RSS_STARTUP_GRACE_MS,
|
|
4972
|
-
startedAtMs: _daemonStartedAtMs
|
|
5280
|
+
startedAtMs: _daemonStartedAtMs,
|
|
5281
|
+
heartbeatPath: process.env.EXE_EVENT_LOOP_STALL_MS === "0" ? "" : eventLoopHeartbeatPath(),
|
|
5282
|
+
stallMs: process.env.EXE_EVENT_LOOP_STALL_MS === "0" ? 0 : stallMs,
|
|
5283
|
+
stallMarkerPath: eventLoopBlockedMarkerPath(),
|
|
5284
|
+
starvationRatio: Number.isFinite(starvationRatio) ? starvationRatio : 1.5
|
|
4973
5285
|
}
|
|
4974
5286
|
});
|
|
4975
5287
|
worker.unref();
|
|
4976
5288
|
worker.on("error", (err) => {
|
|
4977
|
-
process.stderr.write(`[exed] External
|
|
5289
|
+
process.stderr.write(`[exed] External watchdog error: ${err.message}
|
|
4978
5290
|
`);
|
|
4979
5291
|
_externalRssWatchdog = null;
|
|
4980
5292
|
});
|
|
@@ -4982,7 +5294,10 @@ function startExternalRssWatchdog() {
|
|
|
4982
5294
|
_externalRssWatchdog = null;
|
|
4983
5295
|
});
|
|
4984
5296
|
_externalRssWatchdog = worker;
|
|
4985
|
-
process.stderr.write(
|
|
5297
|
+
process.stderr.write(
|
|
5298
|
+
`[exed] External watchdog started (worker thread; survives main event-loop stalls; RSS restart + event-loop stall detection${process.env.EXE_EVENT_LOOP_STALL_MS === "0" ? " [stall OFF]" : ` @ ${Math.round(stallMs / 1e3)}s`}).
|
|
5299
|
+
`
|
|
5300
|
+
);
|
|
4986
5301
|
} catch (err) {
|
|
4987
5302
|
process.stderr.write(`[exed] External RSS watchdog failed to start: ${err instanceof Error ? err.message : String(err)}
|
|
4988
5303
|
`);
|
|
@@ -4992,12 +5307,12 @@ function startTaskEnforcementScanner() {
|
|
|
4992
5307
|
const tick = async () => traceDaemonTimer("task_enforcement", async () => {
|
|
4993
5308
|
fired("task_enforcement");
|
|
4994
5309
|
try {
|
|
4995
|
-
const { runTaskEnforcementTick } = await import("../task-enforcement-
|
|
5310
|
+
const { runTaskEnforcementTick } = await import("../task-enforcement-VFSAAZUN.js");
|
|
4996
5311
|
const { getTransport } = await import("./transport.js");
|
|
4997
5312
|
const { loadAgentConfig } = await import("./agent-config.js");
|
|
4998
5313
|
const { getClient } = await import("./database.js");
|
|
4999
5314
|
const { loadEmployeesSync } = await import("./employees.js");
|
|
5000
|
-
const { sessionScopeFilter } = await import("../task-scope-
|
|
5315
|
+
const { sessionScopeFilter } = await import("../task-scope-P4VLIQNP.js");
|
|
5001
5316
|
const transport = getTransport();
|
|
5002
5317
|
const { sessions: allSessions, paneCache, aliveSessions } = await getSharedOrchestrationCaches();
|
|
5003
5318
|
await yieldToEventLoop();
|
|
@@ -5008,10 +5323,10 @@ function startTaskEnforcementScanner() {
|
|
|
5008
5323
|
sendKeysLiteral: transport.sendKeysLiteral?.bind(transport),
|
|
5009
5324
|
isAlive: (session) => aliveSessions.has(session)
|
|
5010
5325
|
};
|
|
5011
|
-
const { checkAutoWakeGates } = await import("../daemon-orchestration-
|
|
5326
|
+
const { checkAutoWakeGates } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
5012
5327
|
const { ensureEmployeeAsync, employeeSessionName } = await import("./tmux-routing.js");
|
|
5013
5328
|
const { shouldAutoInstance } = await import("./employees.js");
|
|
5014
|
-
const { recordOrchestrationEventBestEffort } = await import("../orchestration-events-
|
|
5329
|
+
const { recordOrchestrationEventBestEffort } = await import("../orchestration-events-7SNWRJYE.js");
|
|
5015
5330
|
const projectDir = process.cwd();
|
|
5016
5331
|
await runTaskEnforcementTick({
|
|
5017
5332
|
transport: enforcementTransport,
|
|
@@ -5293,8 +5608,8 @@ function startBackgroundJobGuardrails() {
|
|
|
5293
5608
|
const tick = async () => traceDaemonTimer("background_job_guardrails", async () => {
|
|
5294
5609
|
fired("background_job_guardrails");
|
|
5295
5610
|
try {
|
|
5296
|
-
const {
|
|
5297
|
-
const actions =
|
|
5611
|
+
const { enforceBackgroundJobGuardrailsAsync } = await import("../background-jobs-2QZ5IQKE.js");
|
|
5612
|
+
const actions = await enforceBackgroundJobGuardrailsAsync();
|
|
5298
5613
|
if (actions.length > 0) {
|
|
5299
5614
|
acted("background_job_guardrails");
|
|
5300
5615
|
for (const action of actions) {
|
|
@@ -5316,18 +5631,56 @@ function startBackgroundJobGuardrails() {
|
|
|
5316
5631
|
}
|
|
5317
5632
|
function handleSignalShutdown() {
|
|
5318
5633
|
if (_shuttingDown) return;
|
|
5319
|
-
const restartIntent =
|
|
5320
|
-
|
|
5321
|
-
|
|
5634
|
+
const { intent: restartIntent, reason } = consumeRestartIntentDetail();
|
|
5635
|
+
const signalAttribution = attributeSignalSource(reason);
|
|
5636
|
+
logRestartEvent("daemon_signal_received", {
|
|
5637
|
+
platform: process.platform,
|
|
5638
|
+
fast_exit: false,
|
|
5639
|
+
restart_intent: restartIntent,
|
|
5640
|
+
uptime_s: Math.floor((Date.now() - _startedAt2) / 1e3),
|
|
5641
|
+
...signalAttribution
|
|
5642
|
+
});
|
|
5643
|
+
logShutdown(restartIntent ? "restart shutdown" : "graceful shutdown", "SIGTERM/SIGINT", signalAttribution);
|
|
5322
5644
|
void shutdown(restartIntent ? 75 : 0);
|
|
5323
5645
|
}
|
|
5324
5646
|
process.on("SIGINT", handleSignalShutdown);
|
|
5325
5647
|
process.on("SIGTERM", handleSignalShutdown);
|
|
5648
|
+
var _staleDistRe = /(?:ERR_MODULE_NOT_FOUND|Cannot find module)[^\n]*dist[\\/]/i;
|
|
5649
|
+
var _staleDistRestartRequested = false;
|
|
5650
|
+
function isStaleDistChunkError(reason) {
|
|
5651
|
+
try {
|
|
5652
|
+
if (reason && typeof reason === "object" && reason.code === "ERR_MODULE_NOT_FOUND") return true;
|
|
5653
|
+
const msg = reason instanceof Error ? reason.stack ?? reason.message : String(reason);
|
|
5654
|
+
return _staleDistRe.test(msg);
|
|
5655
|
+
} catch {
|
|
5656
|
+
return false;
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
function maybeSelfHealStaleDist(reason, source) {
|
|
5660
|
+
if (!isStaleDistChunkError(reason)) return;
|
|
5661
|
+
const msg = reason instanceof Error ? reason.stack ?? reason.message : String(reason);
|
|
5662
|
+
if (_staleDistRestartRequested) {
|
|
5663
|
+
process.stderr.write(`[exed] Stale-dist chunk error again (${source}) \u2014 restart already requested: ${msg}
|
|
5664
|
+
`);
|
|
5665
|
+
return;
|
|
5666
|
+
}
|
|
5667
|
+
_staleDistRestartRequested = true;
|
|
5668
|
+
process.stderr.write(`[exed] Stale dist chunk detected (${source}) \u2014 daemon is running against a swapped build; requesting restart: ${msg}
|
|
5669
|
+
`);
|
|
5670
|
+
logRestartEvent("daemon_self_exit", { trigger: "stale_dist_chunk", source, uptime_s: Math.floor((Date.now() - _startedAt2) / 1e3) });
|
|
5671
|
+
try {
|
|
5672
|
+
requestRestart("stale-dist-chunk-self-heal");
|
|
5673
|
+
} catch (err) {
|
|
5674
|
+
process.stderr.write(`[exed] requestRestart for stale-dist self-heal failed (non-fatal): ${err instanceof Error ? err.message : String(err)}
|
|
5675
|
+
`);
|
|
5676
|
+
}
|
|
5677
|
+
}
|
|
5326
5678
|
process.on("unhandledRejection", (reason) => {
|
|
5327
5679
|
const msg = reason instanceof Error ? reason.stack ?? reason.message : String(reason);
|
|
5328
5680
|
process.stderr.write(`[exed] Unhandled rejection (caught): ${msg}
|
|
5329
5681
|
`);
|
|
5330
5682
|
logCrash(reason instanceof Error ? reason : String(reason), "unhandled_rejection");
|
|
5683
|
+
maybeSelfHealStaleDist(reason, "unhandledRejection");
|
|
5331
5684
|
});
|
|
5332
5685
|
var BUG_AUTOFIX_INTERVAL_MS = 5 * 6e4;
|
|
5333
5686
|
var AUTOFIX_DEDUP_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
@@ -5425,6 +5778,7 @@ process.on("uncaughtException", (err) => {
|
|
|
5425
5778
|
`
|
|
5426
5779
|
);
|
|
5427
5780
|
logCrash(err, "uncaught_exception");
|
|
5781
|
+
maybeSelfHealStaleDist(err, "uncaughtException");
|
|
5428
5782
|
try {
|
|
5429
5783
|
pushNotifyAsync({ event: "daemon_crash", title: "Daemon crashed", body: err.message, priority: "urgent" });
|
|
5430
5784
|
} catch {
|
|
@@ -5650,7 +6004,7 @@ if (process.platform === "darwin") {
|
|
|
5650
6004
|
logBoot({ socketPath: SOCKET_PATH, pidPath: PID_PATH });
|
|
5651
6005
|
void (async () => {
|
|
5652
6006
|
try {
|
|
5653
|
-
const { cleanupCrashDebris } = await import("../db-backup-
|
|
6007
|
+
const { cleanupCrashDebris } = await import("../db-backup-BTL2FBBL.js");
|
|
5654
6008
|
const removed = cleanupCrashDebris();
|
|
5655
6009
|
if (removed > 0) {
|
|
5656
6010
|
process.stderr.write(`[exed] Startup cleanup: pruned ${removed} crash-debris file(s) (backups/quarantine).
|
|
@@ -5796,7 +6150,9 @@ function startEventLoopLagDetector() {
|
|
|
5796
6150
|
const SELF_HEAL_CONSECUTIVE = parseInt(process.env.EXE_SELF_HEAL_CONSECUTIVE ?? "") || 3;
|
|
5797
6151
|
const SELF_HEAL_THRESHOLD_MS = parseFloat(process.env.EXE_SELF_HEAL_THRESHOLD_MS ?? "") || 3e4;
|
|
5798
6152
|
let consecutiveSevereBlocks = 0;
|
|
6153
|
+
touchEventLoopHeartbeat();
|
|
5799
6154
|
const lagTimer = setInterval(() => {
|
|
6155
|
+
touchEventLoopHeartbeat();
|
|
5800
6156
|
const lag = monotonicElapsedMs(lastTick) - 2e3;
|
|
5801
6157
|
const clockJump = looksLikeClockJump(clockProbe);
|
|
5802
6158
|
lastTick = monotonicNowMs();
|
|
@@ -5815,7 +6171,7 @@ function startEventLoopLagDetector() {
|
|
|
5815
6171
|
const msg = `[exed] EVENT LOOP BLOCKED ${(lag / 1e3).toFixed(1)}s \u2014 MCP UNRESPONSIVE. Sessions will die.`;
|
|
5816
6172
|
process.stderr.write(msg + "\n");
|
|
5817
6173
|
logDaemonHealth({ event: "event_loop_blocked", pid: process.pid, message: msg, data: { lagMs: lag } });
|
|
5818
|
-
void import("../orchestration-events-
|
|
6174
|
+
void import("../orchestration-events-7SNWRJYE.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
|
|
5819
6175
|
recordOE({ eventType: "daemon.event_loop_blocked", source: "exe-daemon.lagDetector", severity: "error", durationMs: lag });
|
|
5820
6176
|
}).catch(() => {
|
|
5821
6177
|
});
|
|
@@ -5877,7 +6233,7 @@ function startEventLoopLagDetector() {
|
|
|
5877
6233
|
consecutiveSevereBlocks = 0;
|
|
5878
6234
|
} else {
|
|
5879
6235
|
consecutiveSevereBlocks = 0;
|
|
5880
|
-
writeDaemonReady({ pid: process.pid });
|
|
6236
|
+
writeDaemonReady({ pid: process.pid, port: _boundMcpPort });
|
|
5881
6237
|
}
|
|
5882
6238
|
}, 2e3);
|
|
5883
6239
|
lagTimer.unref();
|
|
@@ -5901,6 +6257,7 @@ function startTaskFileResync() {
|
|
|
5901
6257
|
const client = getClient();
|
|
5902
6258
|
const tasksRoot = path3.join(os2.homedir(), ".exe-os", "tasks");
|
|
5903
6259
|
let synced = 0;
|
|
6260
|
+
let fileCount = 0;
|
|
5904
6261
|
const walkAsync = async (dir) => {
|
|
5905
6262
|
let entries;
|
|
5906
6263
|
try {
|
|
@@ -5934,7 +6291,7 @@ function startTaskFileResync() {
|
|
|
5934
6291
|
});
|
|
5935
6292
|
if (Number(res.rowsAffected ?? 0) > 0) {
|
|
5936
6293
|
synced++;
|
|
5937
|
-
void import("../orchestration-events-
|
|
6294
|
+
void import("../orchestration-events-7SNWRJYE.js").then(({ recordOrchestrationEventBestEffort: recordOE }) => {
|
|
5938
6295
|
recordOE({
|
|
5939
6296
|
eventType: "task_file.resynced",
|
|
5940
6297
|
source: "exe-daemon.taskFileResync",
|
|
@@ -5952,6 +6309,7 @@ function startTaskFileResync() {
|
|
|
5952
6309
|
}
|
|
5953
6310
|
} catch {
|
|
5954
6311
|
}
|
|
6312
|
+
if (++fileCount % 10 === 0) await yieldToEventLoop();
|
|
5955
6313
|
}
|
|
5956
6314
|
};
|
|
5957
6315
|
await walkAsync(tasksRoot);
|
|
@@ -5970,7 +6328,7 @@ function startTaskGroupBarriers() {
|
|
|
5970
6328
|
fired("task_group_barriers");
|
|
5971
6329
|
if (!await ensureStoreForPolling()) return;
|
|
5972
6330
|
try {
|
|
5973
|
-
const { pollTaskGroupBarriers } = await import("../daemon-orchestration-
|
|
6331
|
+
const { pollTaskGroupBarriers } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
5974
6332
|
const firedCount = await pollTaskGroupBarriers();
|
|
5975
6333
|
if (firedCount > 0) {
|
|
5976
6334
|
acted("task_group_barriers");
|
|
@@ -5992,7 +6350,7 @@ function startCheckpointGc() {
|
|
|
5992
6350
|
fired("checkpoint_gc");
|
|
5993
6351
|
if (!await ensureStoreForPolling()) return;
|
|
5994
6352
|
try {
|
|
5995
|
-
const { gcStaleCheckpoints } = await import("../daemon-orchestration-
|
|
6353
|
+
const { gcStaleCheckpoints } = await import("../daemon-orchestration-NBU5RZ2O.js");
|
|
5996
6354
|
const cleared = await gcStaleCheckpoints();
|
|
5997
6355
|
if (cleared > 0) {
|
|
5998
6356
|
acted("checkpoint_gc");
|
|
@@ -6032,14 +6390,14 @@ function startDispatchAckCleanup() {
|
|
|
6032
6390
|
function startProjectionWorkerDeferred() {
|
|
6033
6391
|
setTimeout(async () => {
|
|
6034
6392
|
try {
|
|
6035
|
-
const { startProjectionWorker } = await import("../projection-worker-
|
|
6393
|
+
const { startProjectionWorker } = await import("../projection-worker-HELRBNDR.js");
|
|
6036
6394
|
startProjectionWorker();
|
|
6037
6395
|
} catch {
|
|
6038
6396
|
}
|
|
6039
6397
|
}, 2e4);
|
|
6040
6398
|
}
|
|
6041
6399
|
async function startToolTelemetry() {
|
|
6042
|
-
const { startToolTelemetryFlush } = await import("../tool-telemetry-
|
|
6400
|
+
const { startToolTelemetryFlush } = await import("../tool-telemetry-CDNPES5B.js");
|
|
6043
6401
|
startToolTelemetryFlush();
|
|
6044
6402
|
process.stderr.write("[exed] Tool telemetry started (flush every 5m)\n");
|
|
6045
6403
|
}
|
|
@@ -6067,11 +6425,13 @@ function startServerModeTimers() {
|
|
|
6067
6425
|
function startLocalFirstTimers() {
|
|
6068
6426
|
startMemoryQueueDrain();
|
|
6069
6427
|
startMessageQueueDrain();
|
|
6428
|
+
setTimeout(() => void retryPendingMessages(), 15e3);
|
|
6070
6429
|
void drainIngestOutbox();
|
|
6071
6430
|
startIntercomQueueDrain();
|
|
6072
6431
|
startReviewPolling();
|
|
6073
6432
|
startSessionTTL();
|
|
6074
6433
|
startTaskEnforcementScanner();
|
|
6434
|
+
startAutoWake();
|
|
6075
6435
|
startApiWatchdog();
|
|
6076
6436
|
startIdleKill();
|
|
6077
6437
|
startRssWatchdog();
|
|
@@ -6182,7 +6542,7 @@ function startLocalFirstTimers() {
|
|
|
6182
6542
|
fired("orphan_task_cleanup");
|
|
6183
6543
|
try {
|
|
6184
6544
|
if (!await ensureStoreForPolling()) return;
|
|
6185
|
-
const { cleanOrphanedTaskFiles } = await import("../tasks-crud-
|
|
6545
|
+
const { cleanOrphanedTaskFiles } = await import("../tasks-crud-SC3ERIUR.js");
|
|
6186
6546
|
const count = await cleanOrphanedTaskFiles();
|
|
6187
6547
|
if (count > 0) {
|
|
6188
6548
|
acted("orphan_task_cleanup");
|
|
@@ -6198,7 +6558,7 @@ function startLocalFirstTimers() {
|
|
|
6198
6558
|
fired("task_file_consistency");
|
|
6199
6559
|
try {
|
|
6200
6560
|
if (!await ensureStoreForPolling()) return;
|
|
6201
|
-
const { checkTaskFileConsistency } = await import("../tasks-crud-
|
|
6561
|
+
const { checkTaskFileConsistency } = await import("../tasks-crud-SC3ERIUR.js");
|
|
6202
6562
|
const mismatches = await checkTaskFileConsistency();
|
|
6203
6563
|
if (mismatches > 0) {
|
|
6204
6564
|
acted("task_file_consistency");
|
|
@@ -6217,7 +6577,7 @@ function startLocalFirstTimers() {
|
|
|
6217
6577
|
const TELEMETRY_DAILY_MS = 24 * 60 * 60 * 1e3;
|
|
6218
6578
|
const telemetryDaily = async () => {
|
|
6219
6579
|
try {
|
|
6220
|
-
const { sendTelemetry, isTelemetryEnabled } = await import("../telemetry-upload-
|
|
6580
|
+
const { sendTelemetry, isTelemetryEnabled } = await import("../telemetry-upload-4QEYQROW.js");
|
|
6221
6581
|
if (!isTelemetryEnabled()) return;
|
|
6222
6582
|
const { upstream } = await sendTelemetry(24);
|
|
6223
6583
|
if (upstream.startsWith("sent")) {
|