@askexenow/exe-os 0.9.340 → 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-EC6M7KTX.js → active-agent-PVGE57FY.js} +5 -5
- package/dist/{active-agent-WHIUCHLA.js → active-agent-TNIO6IY3.js} +5 -5
- package/dist/{agentic-ontology-RNSXGXW4.js → agentic-ontology-3FXYMHKW.js} +1 -1
- package/dist/{backfill-gate-J7UXFNXU.js → backfill-gate-65LSYVE5.js} +3 -3
- package/dist/{backfill-metadata-MFY6BHKE.js → backfill-metadata-ZSMZC45J.js} +8 -8
- package/dist/{background-jobs-STURKDCS.js → background-jobs-EXR5RVGG.js} +3 -3
- package/dist/backup-verify-3Y2FHGZU.js +425 -0
- package/dist/{behaviors-HLZUJSMP.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 +26 -24
- package/dist/bin/cli.js +111 -25
- package/dist/bin/customer-readiness.js +1 -1
- package/dist/bin/deferred-daemon-restart.js +97 -90
- package/dist/bin/exe-agent-config.js +9 -8
- package/dist/bin/exe-agent.js +20 -20
- package/dist/bin/exe-assign.js +12 -12
- package/dist/bin/exe-boot.js +201 -68
- 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 +26 -24
- 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 +29 -28
- package/dist/bin/exe-kill.js +31 -29
- package/dist/bin/exe-launch-agent.js +129 -68
- 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 +27 -25
- package/dist/bin/exe-pending-notifications.js +26 -24
- package/dist/bin/exe-pending-reviews.js +26 -24
- package/dist/bin/exe-rename.js +7 -7
- package/dist/bin/exe-review.js +30 -28
- package/dist/bin/exe-search.js +11 -9
- package/dist/bin/exe-session-cleanup.js +116 -86
- 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 +27 -25
- 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 +27 -25
- package/dist/bin/graph-backfill.js +9 -9
- package/dist/bin/graph-export.js +9 -9
- package/dist/bin/import-history.js +11 -11
- package/dist/bin/install.js +102 -95
- 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 +484 -0
- package/dist/bin/registry-proxy.js +1 -1
- package/dist/bin/scan-tasks.js +26 -24
- package/dist/bin/setup.js +6 -5
- package/dist/bin/shard-migrate.js +9 -9
- package/dist/bin/stack-update.js +15 -9
- package/dist/bin/update.js +1 -1
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/boot-generation-BL2ISK4U.js +22 -0
- 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-YOKVMMOL.js → capability-cards-DN5UIKVN.js} +4 -4
- package/dist/{capacity-monitor-S54IOWRL.js → capacity-monitor-ZG5GGFR2.js} +27 -25
- package/dist/{catchup-brief-DRRQCMKA.js → catchup-brief-D6HH6DWS.js} +32 -29
- package/dist/{support-outbox-MGUVVGHT.js → chunk-25X4JD2V.js} +28 -12
- package/dist/{chunk-IYB2NIW3.js → chunk-2KZNGDSW.js} +1 -1
- package/dist/{chunk-FUIIVSW6.js → chunk-2WAVZ5UJ.js} +1 -1
- package/dist/{chunk-K5WFKEXQ.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-VI7L43DC.js → chunk-4CMVFVFC.js} +173 -69
- package/dist/{chunk-BU2QQWBQ.js → chunk-4J4PMPXZ.js} +3 -2
- package/dist/{chunk-JD5S5AAV.js → chunk-4N2NRGCM.js} +2 -2
- package/dist/chunk-4QCFFW2H.js +378 -0
- package/dist/{chunk-7EA7LYW4.js → chunk-4VSV5P4D.js} +4 -4
- package/dist/{chunk-52KNOQMK.js → chunk-4ZCD2UWW.js} +39 -10
- package/dist/{chunk-DZ6OQM67.js → chunk-5ERDIOV3.js} +2 -2
- package/dist/chunk-5H47VHB7.js +30 -0
- package/dist/{chunk-UCQITDLM.js → chunk-5TY4FPH6.js} +1 -1
- package/dist/{chunk-R44Z32O2.js → chunk-6CH3TPHR.js} +2 -2
- package/dist/{chunk-WYLV4S6A.js → chunk-6WQ3NNCE.js} +3 -3
- package/dist/{chunk-HHIBOU3P.js → chunk-6XWTQUO4.js} +1 -1
- package/dist/chunk-76CJBM36.js +88 -0
- package/dist/{chunk-H2L4PHGH.js → chunk-7CTRGNLW.js} +2 -2
- package/dist/{chunk-XUKPALWT.js → chunk-7V4JADD6.js} +2 -2
- package/dist/{chunk-RMOBQ6A5.js → chunk-AD2VCHSS.js} +1 -1
- package/dist/{chunk-QXSBB26A.js → chunk-AJYCFKJR.js} +1 -1
- package/dist/chunk-AM7S2TY6.js +54 -0
- package/dist/{chunk-HEPR6QTL.js → chunk-AOHXREB7.js} +334 -66
- package/dist/{chunk-FNZR3B7U.js → chunk-ASAFVDVR.js} +1 -1
- package/dist/{chunk-TALWBVZE.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-XCTGRD4S.js → chunk-CE7F6RHG.js} +587 -77
- package/dist/{chunk-7WPOJDTA.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-AOO77BDE.js → chunk-EUS4QUKP.js} +1 -1
- package/dist/{chunk-RLRT2BVM.js → chunk-EV46QTD3.js} +1 -1
- package/dist/{chunk-PAEXYFMY.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-LMZISHSJ.js → chunk-FPFPLPUY.js} +6 -6
- package/dist/{chunk-7TS64TBG.js → chunk-G4RGKBCA.js} +8 -3
- package/dist/{chunk-4IYSBPX3.js → chunk-G5T6KDG4.js} +1 -1
- package/dist/{chunk-7WDXEKUL.js → chunk-GBTTBXAF.js} +4 -4
- package/dist/{chunk-6MRWJMI5.js → chunk-GDIJE6D7.js} +1 -1
- package/dist/{chunk-AVKXCSBI.js → chunk-GG5NDQNN.js} +2 -2
- package/dist/{chunk-I3XKO3KQ.js → chunk-GJ26DULE.js} +2 -2
- package/dist/chunk-GL57PO3K.js +104 -0
- package/dist/chunk-GWDSB25T.js +6 -0
- package/dist/{chunk-F55JF43M.js → chunk-H6BV5TKD.js} +39 -24
- package/dist/{chunk-HCJCW7X4.js → chunk-H7I47RS5.js} +34 -1
- package/dist/{chunk-65SVQELL.js → chunk-HA5R6USD.js} +31 -5
- package/dist/{chunk-VJHUVFIW.js → chunk-HAF2DJYV.js} +3 -3
- package/dist/chunk-HJ447YER.js +224 -0
- package/dist/chunk-HV4KESRY.js +395 -0
- package/dist/{chunk-B76TSEP3.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-MW2GJJ53.js → chunk-JGIPOUIK.js} +3 -3
- package/dist/{chunk-2233TQCA.js → chunk-JLZ4RYSD.js} +2 -2
- package/dist/{chunk-Q7L6G6KV.js → chunk-JMYHW3AL.js} +2 -2
- package/dist/{chunk-OJTJYEMX.js → chunk-JPUZPAAF.js} +4 -4
- package/dist/{chunk-XWHE4LZK.js → chunk-JTBIS4R5.js} +21 -2
- package/dist/{chunk-5Z5NATNS.js → chunk-K7KFGDWF.js} +1 -1
- package/dist/{chunk-UIV2WPBT.js → chunk-KGWRTRKC.js} +2 -2
- package/dist/{chunk-KTPG4XKI.js → chunk-KP3U5QGJ.js} +1 -1
- package/dist/{chunk-TLYAEISW.js → chunk-KW2SD2FL.js} +2 -2
- package/dist/{chunk-X7H3HMFH.js → chunk-KWZMQACA.js} +11 -7
- package/dist/{chunk-OFX5B2S7.js → chunk-L2R3LN2P.js} +1 -1
- package/dist/{chunk-T4KZ2Z2N.js → chunk-L4A5DL6Z.js} +3 -3
- package/dist/{chunk-X425OEYF.js → chunk-LU2FALL6.js} +3 -3
- package/dist/{chunk-6M36JFFD.js → chunk-MKYFAKDW.js} +4 -4
- package/dist/{chunk-I5RLNOFK.js → chunk-MOPUCPXK.js} +12 -4
- package/dist/{chunk-ZIVEA3NB.js → chunk-MR6LHP4F.js} +1 -1
- package/dist/chunk-MVYB76QG.js +341 -0
- package/dist/{chunk-2SG2UGCH.js → chunk-MZM6EJCU.js} +4 -4
- package/dist/{chunk-ZREGOV2Q.js → chunk-N7QJKQMX.js} +258 -14
- package/dist/{chunk-QLFRCA6I.js → chunk-NBZL5CGA.js} +93 -12
- package/dist/{chunk-QFPTDSY2.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-ATOU6CYR.js → chunk-OLMQ4UOF.js} +57 -11
- package/dist/{chunk-6HBURYON.js → chunk-OTF44GXL.js} +4 -4
- package/dist/{chunk-DILD54TU.js → chunk-OZEBAGKR.js} +277 -137
- package/dist/{chunk-DADMPMYX.js → chunk-P5HIWY2E.js} +1 -1
- package/dist/{chunk-EIF2LQHZ.js → chunk-PDWS3E22.js} +55 -4
- package/dist/{chunk-KTY7I7UH.js → chunk-PPCDBE6Z.js} +1 -1
- package/dist/{chunk-XACL67CS.js → chunk-PQIDGXSG.js} +13 -4
- package/dist/chunk-PWUFMX75.js +186 -0
- package/dist/{chunk-UPWE5NOG.js → chunk-QDGZJ653.js} +3 -3
- package/dist/{chunk-MQRFKSLI.js → chunk-QOO5RW3K.js} +6 -5
- package/dist/{chunk-KCC5A7YL.js → chunk-QQ4E2RYW.js} +95 -18
- package/dist/{chunk-BPC5LZ6Y.js → chunk-QRYVCDWS.js} +2 -2
- package/dist/{chunk-Z42MXYWW.js → chunk-QWVXN224.js} +110 -28
- package/dist/{chunk-542EWGY3.js → chunk-QYZJHTNE.js} +26 -27
- package/dist/{chunk-I7Z6KTGF.js → chunk-R2NN3JKH.js} +43 -6
- package/dist/{chunk-3OBWSCJN.js → chunk-RACAOE2Z.js} +14 -14
- package/dist/{chunk-5RACW3LX.js → chunk-RAXVPNMR.js} +1 -1
- package/dist/{chunk-2HZY3ECT.js → chunk-RHWZUUS4.js} +6 -6
- package/dist/{chunk-RNAYCUNM.js → chunk-S3THSOWV.js} +1 -1
- package/dist/{chunk-W7DHFGCB.js → chunk-S7QUM2UK.js} +2 -2
- package/dist/{chunk-SSTLTIF3.js → chunk-SKGMF2SO.js} +25 -2
- package/dist/{chunk-GN45PBWI.js → chunk-SQKXKV2Y.js} +2 -2
- package/dist/{chunk-QZLIZAS7.js → chunk-TLT7NZCW.js} +4 -4
- package/dist/chunk-TTCUG2CF.js +91 -0
- package/dist/chunk-UEA3LXOB.js +40 -0
- package/dist/{chunk-DRCRZIIJ.js → chunk-UNXQBELK.js} +1 -1
- package/dist/{chunk-PLRIJALF.js → chunk-UP75Z5X7.js} +921 -176
- package/dist/{chunk-TNJRWUCE.js → chunk-USSB56WK.js} +1 -1
- package/dist/{chunk-KMBEL7VB.js → chunk-UUEKJDK6.js} +90 -10
- package/dist/{chunk-XJI7Z6LZ.js → chunk-UUQBZPJJ.js} +1 -1
- package/dist/{chunk-RRWDYOQS.js → chunk-V3EEVY4L.js} +1 -1
- package/dist/{chunk-N5I7RL3I.js → chunk-VPZHJCKW.js} +2 -2
- package/dist/chunk-VRAQTFD6.js +265 -0
- package/dist/{chunk-H37HHX3E.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-YE7NH53A.js → chunk-X33NYQYJ.js} +2 -2
- package/dist/{chunk-UXBD22CD.js → chunk-XHK3FS3W.js} +3 -2
- package/dist/{chunk-3QDSCJ3F.js → chunk-XZXBB3TN.js} +2 -2
- package/dist/{chunk-JSKBHUR7.js → chunk-YCANDMI2.js} +2 -2
- package/dist/{chunk-JBSCL2XT.js → chunk-YLXTKI6M.js} +1 -1
- package/dist/{chunk-G7WO77Z2.js → chunk-YTCFACP4.js} +812 -896
- package/dist/{chunk-LTVCRHHD.js → chunk-Z6RSN7KS.js} +7 -6
- package/dist/{cleanup-graph-garbage-KUABW6LS.js → cleanup-graph-garbage-XWUFAMFO.js} +6 -6
- package/dist/{co-activation-XMPHKGHR.js → co-activation-ZCHPLLP6.js} +4 -4
- package/dist/{co-occurrence-SHKSJ6CV.js → co-occurrence-KG3LKALN.js} +4 -4
- package/dist/{code-context-index-EXXDY3QZ.js → code-context-index-WSOJQ72R.js} +5 -5
- package/dist/{content-extractor-RHITF2KM.js → content-extractor-NXYNEF5K.js} +2 -2
- package/dist/{conversation-wiki-populator-WU4HEQ7C.js → conversation-wiki-populator-WQN3IUU6.js} +1 -1
- package/dist/{crdt-sync-UJELKSNX.js → crdt-sync-4PFGPZXV.js} +8 -1
- package/dist/{crm-webhook-HHNBS7LY.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-7QB6QOXT.js → daemon-orchestration-FX4XZDR5.js} +46 -27
- package/dist/{daemon-ready-5XI5BIJD.js → daemon-ready-4JTSFKAY.js} +1 -1
- package/dist/{daemon-ready-signal-E7VMIQ6I.js → daemon-ready-signal-LPAZWQOV.js} +5 -1
- package/dist/daemon-restart-circuit-breaker-PEGEIP6H.js +35 -0
- package/dist/daemon-timer-report-NM44WQRH.js +25 -0
- package/dist/{db-backup-DLD4QZBO.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-3TRLGD7M.js → doc-graph-extractor-F6ODFIID.js} +4 -4
- package/dist/{documents-FHIBU7KJ.js → documents-23WX2FPQ.js} +12 -12
- package/dist/dreaming-NWD22UQ5.js +46 -0
- package/dist/{exe-drift-KY2KHZEL.js → exe-drift-CW72FBGE.js} +5 -5
- package/dist/{exe-export-SP6G3QF6.js → exe-export-AUJ7CV7G.js} +11 -11
- package/dist/{exe-import-KJU7FBVQ.js → exe-import-JX4I52VE.js} +11 -11
- package/dist/{exe-key-M6TYHNUW.js → exe-key-2N6LY2BU.js} +241 -226
- package/dist/{exe-org-BGZNNE4H.js → exe-org-X4CSNCKS.js} +3 -3
- package/dist/{exe-snapshot-ZNPGUKRZ.js → exe-snapshot-XZ7FVCYZ.js} +31 -29
- package/dist/{fast-db-init-QQB6IVWV.js → fast-db-init-4CWHSOOR.js} +1 -1
- package/dist/{founder-context-PQR3BUS7.js → founder-context-7L3CFPYN.js} +4 -4
- package/dist/gateway/index.js +14 -14
- 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-UGB5J3K7.js → git-staleness-CI2R4QOJ.js} +4 -4
- package/dist/{global-procedures-R7KRREEK.js → global-procedures-XQX3LUH6.js} +6 -6
- package/dist/{graph-auto-extract-LKIQ57PL.js → graph-auto-extract-OURWMGBS.js} +4 -4
- 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 +32 -28
- package/dist/hooks/codex-stop-task-finalizer.js +32 -28
- package/dist/hooks/commit-complete.js +29 -27
- 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 +28 -26
- package/dist/hooks/post-tool-combined.js +12 -12
- package/dist/hooks/pre-compact.js +29 -27
- package/dist/hooks/pre-tool-use.js +180 -47
- package/dist/hooks/prompt-submit.js +324 -273
- package/dist/hooks/session-end.js +35 -33
- package/dist/hooks/session-start.js +28 -21
- package/dist/hooks/stop.js +35 -33
- package/dist/hooks/subagent-stop.js +28 -26
- package/dist/hooks/summary-worker.js +36 -34
- package/dist/index.js +39 -37
- package/dist/{installer-SB2N5NKH.js → installer-G3JAO3NT.js} +9 -9
- package/dist/{installer-MZWWBXM6.js → installer-JND3RJ6Q.js} +9 -9
- package/dist/{installer-MNPXDLGG.js → installer-L7EVH5U5.js} +9 -9
- package/dist/{intercom-queue-VU2G6F5R.js → intercom-queue-ZFEQALR3.js} +25 -23
- 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 +9 -9
- 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 +651 -158
- 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 +28 -24
- 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 +29 -25
- package/dist/lib/tmux-routing.js +56 -25
- 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-BYDMFMFT.js → license-gate-QTRQHV4F.js} +5 -5
- package/dist/{license-sync-N3RNYVP2.js → license-sync-N3UJFWAW.js} +4 -4
- package/dist/mcp/register-tools.js +96 -89
- package/dist/mcp/server.js +98 -91
- 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 +37 -28
- 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 +35 -29
- package/dist/mcp/tools/send-message.js +28 -26
- package/dist/mcp/tools/update-task.js +34 -28
- package/dist/{mcp-http-config-EMAVS2JI.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-TQRLZI4D.js → memory-cards-ZRDW7QBX.js} +8 -8
- package/dist/{memory-graph-extractor-IWGNVAFU.js → memory-graph-extractor-QLXDMHRS.js} +5 -5
- package/dist/{memory-poisoning-defense-T4ITBGSG.js → memory-poisoning-defense-HJTXYCWH.js} +4 -4
- package/dist/{memory-pressure-watchdog-RRIAXPXQ.js → memory-pressure-watchdog-HN5X7AVN.js} +76 -37
- package/dist/{memory-queue-X2CSEAKE.js → memory-queue-2UOOF27L.js} +5 -3
- package/dist/{memory-queue-client-BKQHTYTH.js → memory-queue-client-O5U6F6XP.js} +6 -6
- package/dist/{memory-reflection-6N4J2FL7.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-SZEPGJQ7.js +409 -0
- package/dist/{notifications-KONB3C62.js → notifications-4UT53CDG.js} +25 -23
- package/dist/{orchestration-events-5SIJOE4H.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-O6HU7DKH.js → pipeline-router-LM53NMWJ.js} +5 -5
- package/dist/{plan-limits-GRNBOBB3.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-SD7GM24K.js → project-boot-4NUH5FRU.js} +2 -2
- package/dist/{projection-worker-ZVOFHTXT.js → projection-worker-FZ7YSN3G.js} +5 -5
- package/dist/{prospective-memory-W6S67LZZ.js → prospective-memory-6D2ASWM3.js} +4 -4
- package/dist/{push-notifications-W5JRXLKJ.js → push-notifications-U6FIBQRW.js} +3 -3
- package/dist/{reranker-QATGTAPC.js → reranker-GYYRPANK.js} +3 -3
- package/dist/{retrieval-health-TWHKYCRK.js → retrieval-health-4Z242P3B.js} +1 -1
- package/dist/{review-polling-PCMD5BFN.js → review-polling-HXAFJZDA.js} +26 -24
- package/dist/runtime/index.js +37 -35
- package/dist/{session-events-3LCVQEL7.js → session-events-O3BV56ZX.js} +26 -24
- package/dist/{session-kill-telemetry-CZSPN5V6.js → session-kill-telemetry-AELE4JDK.js} +26 -24
- package/dist/session-mcp-config-YKNXG5DW.js +50 -0
- package/dist/{session-scope-CFHVSVAQ.js → session-scope-5EAPUT45.js} +25 -23
- package/dist/setup-wizard-NB6R4QVS.js +14 -0
- package/dist/{shard-manager-MBWQEYNG.js → shard-manager-35PWFR3B.js} +3 -3
- package/dist/{skill-refinement-74T6VDFM.js → skill-refinement-DVSYXBBP.js} +5 -5
- package/dist/stack-promote-RSOWO6EY.js +130 -0
- package/dist/{stack-release-XXMV7SPX.js → stack-release-HGFFFCGC.js} +112 -22
- package/dist/{stack-update-E2TKHHSQ.js → stack-update-ATCJFOEK.js} +7 -5
- package/dist/{steward-gate-WT7WXQIE.js → steward-gate-3GQ5XKMJ.js} +5 -5
- package/dist/support-inbox-4L62P4EP.js +33 -0
- package/dist/support-outbox-WHGPUYL2.js +16 -0
- package/dist/task-enforcement-IPIZX2MM.js +90 -0
- package/dist/{task-scope-CQEG5SSJ.js → task-scope-FOIW25HR.js} +27 -23
- package/dist/{tasks-crud-UGK5A25L.js → tasks-crud-HBDKE6C5.js} +35 -23
- package/dist/tasks-notify-G2U2U2YA.js +53 -0
- package/dist/{tasks-review-JKBRACII.js → tasks-review-27SFX5XN.js} +27 -23
- package/dist/{telemetry-upload-7LBYGPCB.js → telemetry-upload-ZOXHRWR5.js} +9 -9
- package/dist/tmux-command-guard-KSJKIX3C.js +117 -0
- package/dist/{token-budget-QBRJR4M5.js → token-budget-5Y4YPDO3.js} +5 -5
- package/dist/{tool-capability-index-Q6YQDL7I.js → tool-capability-index-VYF5GNJ2.js} +1 -1
- package/dist/{tool-telemetry-ULIDUK3P.js → tool-telemetry-KBXSBDTK.js} +1 -1
- package/dist/tui/App.js +40 -38
- package/dist/{tui-data-NPTGKT37.js → tui-data-NLFMBIQI.js} +25 -23
- package/dist/{update-check-HFO4VHO4.js → update-check-3FHAWIG2.js} +7 -3
- package/dist/update-support-UVUSZG7R.js +355 -0
- 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-MXUQUG4M.js → worker-gate-3KUBAU32.js} +3 -3
- package/dist/{workflow-engine-EWCOLD47.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-ZAG3V24E.js → worktree-sweep-WTK3MTKH.js} +7 -7
- package/package.json +3 -2
- package/release-notes.json +86 -76
- package/dist/branch-hygiene-R5NVTRAY.js +0 -138
- package/dist/chunk-6IRVGOUL.js +0 -30
- package/dist/chunk-HMP5VT6A.js +0 -118
- package/dist/chunk-PVYR4FCQ.js +0 -113
- package/dist/chunk-UFAXZ2PY.js +0 -138
- package/dist/chunk-Y25OJWOQ.js +0 -45
- package/dist/chunk-YGAAZN3E.js +0 -47
- package/dist/cto-delegation-gate-DXNF5HVW.js +0 -290
- package/dist/dispatch-ack-4S44HBWB.js +0 -15
- package/dist/dreaming-OMFUEUCQ.js +0 -44
- package/dist/orchestrator-DUUX7FQV.js +0 -45
- package/dist/setup-wizard-TOFEJPLF.js +0 -13
- package/dist/tasks-notify-SMLDFBWM.js +0 -50
- package/dist/worktree-GVF2I5FP.js +0 -31
- /package/dist/{chunk-FLNSJ2TC.js → chunk-GIBYNT6W.js} +0 -0
- /package/dist/{chunk-NQBRGXYR.js → chunk-JRM4TAGS.js} +0 -0
- /package/dist/{chunk-WHRTDN5J.js → chunk-MGGOSFCR.js} +0 -0
- /package/dist/{chunk-D3QASX2W.js → chunk-QIFYLIUF.js} +0 -0
- /package/dist/{chunk-OADURIIN.js → chunk-WTH4CSAP.js} +0 -0
- /package/dist/{core-memory-VO5ZIBKH.js → core-memory-GAC6EWOQ.js} +0 -0
- /package/dist/{entity-boost-DNI4A5I7.js → entity-boost-NT6UO2Z3.js} +0 -0
- /package/dist/{message-queue-client-Q5BW3O5W.js → message-queue-client-4EOQRUXW.js} +0 -0
- /package/dist/{oauth-server-ROQFOEMM.js → oauth-server-67YBDP32.js} +0 -0
- /package/dist/{webhook-pipe-FZYLO6RR.js → webhook-pipe-LEXMUQ5B.js} +0 -0
- /package/dist/{wiki-acl-JA5UCQZ4.js → wiki-acl-74BLWG6J.js} +0 -0
- /package/dist/{wiki-client-VNDOBK63.js → wiki-client-EAN7F5LV.js} +0 -0
|
@@ -1,40 +1,42 @@
|
|
|
1
1
|
import {
|
|
2
|
+
createTask
|
|
3
|
+
} from "./chunk-QYZJHTNE.js";
|
|
4
|
+
import {
|
|
5
|
+
releaseDispatchClaim,
|
|
6
|
+
tryAcquireDispatchClaim,
|
|
2
7
|
writeDispatchFailed,
|
|
3
8
|
writeDispatchPending
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import {
|
|
6
|
-
createTask
|
|
7
|
-
} from "./chunk-542EWGY3.js";
|
|
9
|
+
} from "./chunk-O7LWR36Z.js";
|
|
8
10
|
import {
|
|
9
11
|
getActiveAgent
|
|
10
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-5ERDIOV3.js";
|
|
11
13
|
import {
|
|
12
|
-
|
|
14
|
+
ensureEmployeeAsync,
|
|
13
15
|
isValidSessionScope,
|
|
14
16
|
logTaskDispatch,
|
|
15
17
|
resolveExeSession
|
|
16
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-UP75Z5X7.js";
|
|
17
19
|
import {
|
|
18
20
|
recordOrchestrationEventBestEffort
|
|
19
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-2WAVZ5UJ.js";
|
|
20
22
|
import {
|
|
21
23
|
getAgentRuntime,
|
|
22
24
|
validateRuntimeModel
|
|
23
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-HA5R6USD.js";
|
|
24
26
|
import {
|
|
25
27
|
getLicenseSync
|
|
26
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-JGIPOUIK.js";
|
|
27
29
|
import {
|
|
28
30
|
getAgentContext
|
|
29
31
|
} from "./chunk-GJV3WDWM.js";
|
|
30
32
|
import {
|
|
31
33
|
isCoordinatorName
|
|
32
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-AOHXREB7.js";
|
|
33
35
|
|
|
34
36
|
// src/mcp/tools/create-task.ts
|
|
35
37
|
import { z } from "zod";
|
|
36
|
-
import { existsSync, readdirSync, readFileSync, statSync, writeFileSync, mkdirSync, unlinkSync } from "fs";
|
|
37
|
-
import { basename, join } from "path";
|
|
38
|
+
import { existsSync, readdirSync, readFileSync, realpathSync, statSync, writeFileSync, mkdirSync, unlinkSync } from "fs";
|
|
39
|
+
import { basename, dirname, isAbsolute, join, sep } from "path";
|
|
38
40
|
import { homedir } from "os";
|
|
39
41
|
function rootFromSessionName(sessionName) {
|
|
40
42
|
const raw = (sessionName ?? "").trim();
|
|
@@ -55,6 +57,20 @@ function isDirectory(pathname) {
|
|
|
55
57
|
function isGitRepoDir(pathname) {
|
|
56
58
|
return isDirectory(pathname) && existsSync(join(pathname, ".git"));
|
|
57
59
|
}
|
|
60
|
+
function realpathSafe(pathname) {
|
|
61
|
+
try {
|
|
62
|
+
return realpathSync(pathname);
|
|
63
|
+
} catch {
|
|
64
|
+
return pathname;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function isRealpathInside(candidate, scopedRoot) {
|
|
68
|
+
const rc = realpathSafe(candidate);
|
|
69
|
+
const rr = realpathSafe(scopedRoot);
|
|
70
|
+
if (rc === rr) return true;
|
|
71
|
+
const prefix = rr.endsWith(sep) ? rr : rr + sep;
|
|
72
|
+
return rc.startsWith(prefix);
|
|
73
|
+
}
|
|
58
74
|
function findNestedGitRepo(parentDir) {
|
|
59
75
|
const preferred = ["website", "app", "repo", "src"];
|
|
60
76
|
for (const child of preferred) {
|
|
@@ -74,34 +90,72 @@ function findNestedGitRepo(parentDir) {
|
|
|
74
90
|
function projectDirMatches(projectDir, projectName) {
|
|
75
91
|
const dirBasename = basename(projectDir).toLowerCase();
|
|
76
92
|
const normalizedProject = projectName.toLowerCase();
|
|
77
|
-
return dirBasename === normalizedProject || dirBasename === normalizedProject.replace(/^exe-/, "") || `exe-${dirBasename}` === normalizedProject
|
|
93
|
+
return dirBasename === normalizedProject || dirBasename === normalizedProject.replace(/^exe-/, "") || `exe-${dirBasename}` === normalizedProject;
|
|
94
|
+
}
|
|
95
|
+
function isSafeProjectName(projectName) {
|
|
96
|
+
if (typeof projectName !== "string") return false;
|
|
97
|
+
const name = projectName.trim();
|
|
98
|
+
if (name.length === 0 || name.length > 128) return false;
|
|
99
|
+
if (name === "." || name === "..") return false;
|
|
100
|
+
if (name.includes("\0")) return false;
|
|
101
|
+
if (isAbsolute(name)) return false;
|
|
102
|
+
if (name.includes("/") || name.includes("\\")) return false;
|
|
103
|
+
if (name.split(/[/\\]/).some((seg) => seg === "..")) return false;
|
|
104
|
+
return true;
|
|
78
105
|
}
|
|
79
106
|
function findProjectChildDir(parentDir, projectName) {
|
|
107
|
+
if (!isSafeProjectName(projectName)) return null;
|
|
80
108
|
if (!existsSync(parentDir)) return null;
|
|
81
109
|
const normalizedProject = projectName.toLowerCase();
|
|
82
110
|
const aliases = /* @__PURE__ */ new Set([
|
|
83
111
|
normalizedProject,
|
|
84
112
|
normalizedProject.replace(/^exe-/, "")
|
|
85
113
|
]);
|
|
114
|
+
const accept = (candidate) => {
|
|
115
|
+
if (!candidate) return null;
|
|
116
|
+
if (!isRealpathInside(candidate, parentDir)) {
|
|
117
|
+
process.stderr.write(
|
|
118
|
+
`[create-task] rejecting "${projectName}" candidate ${candidate}: symlink resolves outside scoped root ${parentDir}.
|
|
119
|
+
`
|
|
120
|
+
);
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
return candidate;
|
|
124
|
+
};
|
|
86
125
|
const exactCandidate = join(parentDir, projectName);
|
|
87
|
-
if (isGitRepoDir(exactCandidate))
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (nested) return nested;
|
|
126
|
+
if (isGitRepoDir(exactCandidate)) {
|
|
127
|
+
const ok = accept(exactCandidate);
|
|
128
|
+
if (ok) return ok;
|
|
91
129
|
}
|
|
130
|
+
const matches = /* @__PURE__ */ new Set();
|
|
131
|
+
const exactNested = isDirectory(exactCandidate) ? accept(findNestedGitRepo(exactCandidate)) : null;
|
|
132
|
+
if (exactNested) matches.add(exactNested);
|
|
92
133
|
try {
|
|
93
134
|
for (const entry of readdirSync(parentDir, { withFileTypes: true })) {
|
|
94
135
|
if (!entry.isDirectory()) continue;
|
|
95
136
|
const lower = entry.name.toLowerCase();
|
|
96
137
|
if (aliases.has(lower) || `exe-${lower}` === normalizedProject) {
|
|
97
138
|
const candidate = join(parentDir, entry.name);
|
|
98
|
-
if (isGitRepoDir(candidate))
|
|
99
|
-
|
|
100
|
-
|
|
139
|
+
if (isGitRepoDir(candidate)) {
|
|
140
|
+
const ok = accept(candidate);
|
|
141
|
+
if (ok) matches.add(ok);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const nested = accept(findNestedGitRepo(candidate));
|
|
145
|
+
if (nested) matches.add(nested);
|
|
101
146
|
}
|
|
102
147
|
}
|
|
103
148
|
} catch {
|
|
104
149
|
}
|
|
150
|
+
const sorted = [...matches].sort();
|
|
151
|
+
if (sorted.length === 1) return sorted[0];
|
|
152
|
+
if (sorted.length > 1) {
|
|
153
|
+
process.stderr.write(
|
|
154
|
+
`[create-task] ambiguous project resolution for "${projectName}" under ${parentDir}: ${sorted.length} candidates (${sorted.join(", ")}). Refusing to guess.
|
|
155
|
+
`
|
|
156
|
+
);
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
105
159
|
return null;
|
|
106
160
|
}
|
|
107
161
|
async function listCoordinatorRoots() {
|
|
@@ -212,6 +266,13 @@ function resolveDispatchRuntime(agentId, override) {
|
|
|
212
266
|
}
|
|
213
267
|
async function resolveProjectDir(projectName, callerSession) {
|
|
214
268
|
const home = homedir();
|
|
269
|
+
if (!isSafeProjectName(projectName)) {
|
|
270
|
+
process.stderr.write(
|
|
271
|
+
`[create-task] refusing to resolve unsafe project name "${String(projectName).slice(0, 80)}" (absolute path, path separator, or ".." segment). Rejecting.
|
|
272
|
+
`
|
|
273
|
+
);
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
215
276
|
if (callerSession) {
|
|
216
277
|
try {
|
|
217
278
|
const { listSessions } = await import("./lib/session-registry.js");
|
|
@@ -219,15 +280,31 @@ async function resolveProjectDir(projectName, callerSession) {
|
|
|
219
280
|
const coordName = callerSession.includes("-") ? callerSession.slice(callerSession.indexOf("-") + 1) : callerSession;
|
|
220
281
|
const coordSession = sessions.find((s) => s.windowName === coordName) ?? sessions.find((s) => s.windowName === callerSession);
|
|
221
282
|
if (coordSession?.projectDir && existsSync(coordSession.projectDir)) {
|
|
222
|
-
|
|
223
|
-
|
|
283
|
+
const coordDir = coordSession.projectDir;
|
|
284
|
+
if (projectDirMatches(coordDir, projectName)) {
|
|
285
|
+
return coordDir;
|
|
224
286
|
}
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
227
|
-
|
|
287
|
+
const childUnderCoord = findProjectChildDir(coordDir, projectName);
|
|
288
|
+
if (childUnderCoord) return childUnderCoord;
|
|
289
|
+
const workspaceRoot = dirname(coordDir);
|
|
290
|
+
if (workspaceRoot !== coordDir) {
|
|
291
|
+
const sibling = findProjectChildDir(workspaceRoot, projectName);
|
|
292
|
+
if (sibling) {
|
|
293
|
+
const owner = sessions.find(
|
|
294
|
+
(s) => s.windowName !== coordName && s.windowName !== callerSession && s.projectDir && isRealpathInside(sibling, s.projectDir)
|
|
295
|
+
);
|
|
296
|
+
if (owner) {
|
|
297
|
+
process.stderr.write(
|
|
298
|
+
`[create-task] REFUSING cross-scope resolution: project "${projectName}" -> ${sibling} is owned by coordinator scope "${owner.windowName}", not caller "${callerSession}". Returning null.
|
|
299
|
+
`
|
|
300
|
+
);
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
return sibling;
|
|
304
|
+
}
|
|
228
305
|
}
|
|
229
306
|
process.stderr.write(
|
|
230
|
-
`[create-task] project
|
|
307
|
+
`[create-task] project "${projectName}" not found within caller scope "${callerSession}" (coordinator dir "${coordDir}"). Not scanning other scopes.
|
|
231
308
|
`
|
|
232
309
|
);
|
|
233
310
|
}
|
|
@@ -237,36 +314,36 @@ async function resolveProjectDir(projectName, callerSession) {
|
|
|
237
314
|
`
|
|
238
315
|
);
|
|
239
316
|
}
|
|
317
|
+
process.stderr.write(
|
|
318
|
+
`[create-task] could not resolve project "${projectName}" within caller scope "${callerSession}". Returning null \u2014 dispatch will be refused (no $HOME/cwd fallback for a scoped caller).
|
|
319
|
+
`
|
|
320
|
+
);
|
|
321
|
+
return null;
|
|
240
322
|
}
|
|
241
323
|
try {
|
|
242
324
|
const ctx = getAgentContext();
|
|
243
|
-
if (ctx?.projectName) {
|
|
325
|
+
if (ctx?.projectName && isSafeProjectName(ctx.projectName)) {
|
|
244
326
|
const alsCandidate = join(home, ctx.projectName);
|
|
245
327
|
if (existsSync(alsCandidate)) return alsCandidate;
|
|
246
328
|
}
|
|
247
329
|
} catch {
|
|
248
330
|
}
|
|
249
|
-
const
|
|
250
|
-
join(home, projectName),
|
|
251
|
-
join(home, projectName.replace(/^exe-/, ""))
|
|
252
|
-
];
|
|
253
|
-
for (const candidate of candidates) {
|
|
331
|
+
for (const candidate of [join(home, projectName), join(home, projectName.replace(/^exe-/, ""))]) {
|
|
254
332
|
if (existsSync(candidate)) return candidate;
|
|
255
333
|
}
|
|
256
334
|
const cwd = process.cwd();
|
|
257
335
|
if (cwd !== home && existsSync(join(cwd, ".git"))) {
|
|
258
336
|
process.stderr.write(
|
|
259
|
-
`[create-task] WARN:
|
|
337
|
+
`[create-task] WARN: resolving project "${projectName}" to cwd (${cwd}) \u2014 no caller scope.
|
|
260
338
|
`
|
|
261
339
|
);
|
|
262
340
|
return cwd;
|
|
263
341
|
}
|
|
264
|
-
const fallback = join(home, projectName);
|
|
265
342
|
process.stderr.write(
|
|
266
|
-
`[create-task]
|
|
343
|
+
`[create-task] could not resolve an existing project dir for "${projectName}" (no caller scope). Returning null \u2014 dispatch will be refused.
|
|
267
344
|
`
|
|
268
345
|
);
|
|
269
|
-
return
|
|
346
|
+
return null;
|
|
270
347
|
}
|
|
271
348
|
function registerCreateTask(server) {
|
|
272
349
|
server.registerTool(
|
|
@@ -287,10 +364,15 @@ function registerCreateTask(server) {
|
|
|
287
364
|
budget_tokens: z.number().optional().describe("Max tokens allowed for this task (null = unlimited)"),
|
|
288
365
|
budget_fallback_model: z.string().optional().describe("Model to route to when budget is exhausted"),
|
|
289
366
|
spawn_runtime: z.string().optional().describe("Override runtime for spawned session (e.g., 'claude', 'codex', 'opencode')"),
|
|
290
|
-
spawn_model: z.string().optional().describe("Override model for spawned session (e.g., 'claude-sonnet-4.6', 'claude-haiku-4.5')")
|
|
367
|
+
spawn_model: z.string().optional().describe("Override model for spawned session (e.g., 'claude-sonnet-4.6', 'claude-haiku-4.5')"),
|
|
368
|
+
spawn_worktree: z.boolean().optional().describe(
|
|
369
|
+
"Worktree isolation for code-role agents. Default true (REQUIRED \u2014 a code-role agent that cannot get an isolated git worktree is refused, never spawned on main). Set false ONLY to dispatch a code-role agent into a NON-git 'automation' project (a plain folder with no repo to protect); the agent then runs in the project root and a loud worktree.bypassed event is logged. Genuine non-git projects are auto-detected, so this is rarely needed by hand."
|
|
370
|
+
),
|
|
371
|
+
idempotency_key: z.string().optional().describe("Idempotency key (bug c06a8803): retrying create_task with the SAME key returns the ORIGINAL task instead of creating a duplicate + duplicate spawn. Must be stable across the original call and its retry \u2014 do NOT embed a timestamp. Optional; when omitted no dedup is applied."),
|
|
372
|
+
idempotency_window: z.string().optional().describe("Optional nonce used to DERIVE an idempotency key when idempotency_key is not given (stable hash of assignee+title+project+session+window). Reuse the same window on a retry to dedup. When both this and idempotency_key are omitted, no dedup is applied.")
|
|
291
373
|
}
|
|
292
374
|
},
|
|
293
|
-
async ({ title, assigned_to, project_name, priority, complexity, context, blocked_by, parent_task_id, reviewer, budget_tokens, budget_fallback_model, spawn_runtime, spawn_model }) => {
|
|
375
|
+
async ({ title, assigned_to, project_name, priority, complexity, context, blocked_by, parent_task_id, reviewer, budget_tokens, budget_fallback_model, spawn_runtime, spawn_model, spawn_worktree, idempotency_key, idempotency_window }) => {
|
|
294
376
|
if (!isCoordinatorName(assigned_to)) {
|
|
295
377
|
const license = getLicenseSync();
|
|
296
378
|
if (license.plan === "free") {
|
|
@@ -399,6 +481,26 @@ function registerCreateTask(server) {
|
|
|
399
481
|
effectiveSpawnModel = validated.model;
|
|
400
482
|
}
|
|
401
483
|
const projectDir = await resolveProjectDir(project_name, callerRoot);
|
|
484
|
+
if (projectDir == null && process.env.VITEST !== "true" && process.env.NODE_ENV !== "test") {
|
|
485
|
+
const message = `BLOCKED: create_task could not resolve an existing project directory for "${project_name}" within the caller's coordinator scope. Refusing to create/dispatch into a fabricated or cross-scope path. Clone the project (or ensure the coordinator session registry points at it) and retry. If "${project_name}" is a non-git automation project, dispatch it from a session whose coordinator dir contains it.`;
|
|
486
|
+
process.stderr.write(`[create_task] ${message}
|
|
487
|
+
`);
|
|
488
|
+
recordOrchestrationEventBestEffort({
|
|
489
|
+
eventType: "dispatch.failed",
|
|
490
|
+
source: "create-task.mcp",
|
|
491
|
+
severity: "error",
|
|
492
|
+
agentId: assigned_to,
|
|
493
|
+
sessionScope: callerRoot || null,
|
|
494
|
+
projectName: project_name,
|
|
495
|
+
errorCode: "project_dir_unresolved",
|
|
496
|
+
payload: { priority, callerTmux, callerSource }
|
|
497
|
+
});
|
|
498
|
+
return {
|
|
499
|
+
content: [{ type: "text", text: message }],
|
|
500
|
+
isError: true
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
const resolvedProjectDir = projectDir ?? process.cwd();
|
|
402
504
|
let journalWarning = "";
|
|
403
505
|
try {
|
|
404
506
|
const orphans = findOrphanedDispatchIntents(callerRoot || null);
|
|
@@ -434,7 +536,7 @@ function registerCreateTask(server) {
|
|
|
434
536
|
assignedBy,
|
|
435
537
|
sessionScope: callerRoot || null,
|
|
436
538
|
callerSource,
|
|
437
|
-
projectDir
|
|
539
|
+
projectDir: resolvedProjectDir
|
|
438
540
|
}
|
|
439
541
|
);
|
|
440
542
|
} catch (journalErr) {
|
|
@@ -453,7 +555,7 @@ function registerCreateTask(server) {
|
|
|
453
555
|
priority,
|
|
454
556
|
complexity,
|
|
455
557
|
context,
|
|
456
|
-
baseDir:
|
|
558
|
+
baseDir: resolvedProjectDir,
|
|
457
559
|
blockedBy: blocked_by,
|
|
458
560
|
parentTaskId: parent_task_id,
|
|
459
561
|
reviewer: reviewer ?? assignedBy,
|
|
@@ -461,6 +563,11 @@ function registerCreateTask(server) {
|
|
|
461
563
|
budgetFallbackModel: budget_fallback_model,
|
|
462
564
|
spawnRuntime: spawn_runtime,
|
|
463
565
|
spawnModel: effectiveSpawnModel,
|
|
566
|
+
// Idempotency (bug c06a8803): thread the OPT-IN key/window through to
|
|
567
|
+
// createTaskCore so a retried tool call after a daemon transport error
|
|
568
|
+
// returns the original task instead of inserting a duplicate.
|
|
569
|
+
idempotencyKey: idempotency_key,
|
|
570
|
+
idempotencyWindow: idempotency_window,
|
|
464
571
|
// Pass the pre-resolved caller session to tasks-crud so it doesn't
|
|
465
572
|
// re-resolve independently (eliminates cross-session scope divergence).
|
|
466
573
|
callerSession: callerTmux || callerRoot || void 0,
|
|
@@ -532,7 +639,7 @@ function registerCreateTask(server) {
|
|
|
532
639
|
session_scope: sessionScope,
|
|
533
640
|
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
534
641
|
}), "utf-8");
|
|
535
|
-
const { recordOrchestrationEventBestEffort: recordOE } = await import("./orchestration-events-
|
|
642
|
+
const { recordOrchestrationEventBestEffort: recordOE } = await import("./orchestration-events-WV4NWKZH.js");
|
|
536
643
|
recordOE({
|
|
537
644
|
eventType: "signal.created",
|
|
538
645
|
source: "create-task.mcp",
|
|
@@ -545,7 +652,7 @@ function registerCreateTask(server) {
|
|
|
545
652
|
}
|
|
546
653
|
let dispatchStatus = "";
|
|
547
654
|
let dispatchOutcome = "ok";
|
|
548
|
-
if (task.status !== "blocked" && !process.env.VITEST) {
|
|
655
|
+
if (task.status !== "blocked" && !process.env.VITEST && !task.deduplicated) {
|
|
549
656
|
try {
|
|
550
657
|
const exeSession = task.sessionScope || callerRoot;
|
|
551
658
|
const dispatchRuntime = resolveDispatchRuntime(assigned_to, spawn_runtime ?? null);
|
|
@@ -565,7 +672,7 @@ function registerCreateTask(server) {
|
|
|
565
672
|
let projectConflictOpts = {};
|
|
566
673
|
try {
|
|
567
674
|
const { getClient } = await import("./lib/database.js");
|
|
568
|
-
const { sessionScopeFilter } = await import("./task-scope-
|
|
675
|
+
const { sessionScopeFilter } = await import("./task-scope-FOIW25HR.js");
|
|
569
676
|
const client = getClient();
|
|
570
677
|
const scope = sessionScopeFilter(task.sessionScope || callerRoot || exeSession || null);
|
|
571
678
|
const existing = await client.execute({
|
|
@@ -584,116 +691,142 @@ function registerCreateTask(server) {
|
|
|
584
691
|
}
|
|
585
692
|
} catch {
|
|
586
693
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
694
|
+
const claimedSpawn = tryAcquireDispatchClaim(task.id, assigned_to);
|
|
695
|
+
if (!claimedSpawn) {
|
|
696
|
+
dispatchStatus = `
|
|
697
|
+
Dispatched: deduped \u2014 another dispatch for task ${task.id} is already in flight`;
|
|
698
|
+
process.stderr.write(
|
|
699
|
+
`[create_task] DEDUPED spawn for ${assigned_to} task ${task.id} \u2014 a fresh dispatch is already in flight; not double-spawning
|
|
700
|
+
`
|
|
701
|
+
);
|
|
702
|
+
recordOrchestrationEventBestEffort({
|
|
703
|
+
eventType: "dispatch.deduped",
|
|
704
|
+
source: "create-task.mcp",
|
|
705
|
+
severity: "info",
|
|
706
|
+
taskId: task.id,
|
|
707
|
+
agentId: assigned_to,
|
|
708
|
+
sessionScope: task.sessionScope || callerRoot || exeSession,
|
|
709
|
+
projectName: project_name,
|
|
710
|
+
runtime: dispatchRuntime,
|
|
711
|
+
result: "deduped",
|
|
712
|
+
payload: { priority, reason: "fresh_dispatch_in_flight" }
|
|
713
|
+
});
|
|
714
|
+
} else {
|
|
715
|
+
const result = await ensureEmployeeAsync(assigned_to, exeSession, resolvedProjectDir, {
|
|
716
|
+
...autoOpts,
|
|
717
|
+
...projectConflictOpts,
|
|
718
|
+
runtimeOverride: spawn_runtime ?? void 0,
|
|
719
|
+
modelOverride: effectiveSpawnModel ?? void 0,
|
|
720
|
+
// Explicit worktree opt-out (bug b65135ee) — only when the caller
|
|
721
|
+
// passed spawn_worktree=false; undefined keeps the refuse-in-main
|
|
722
|
+
// default. Non-git automation projects auto-bypass downstream.
|
|
723
|
+
...spawn_worktree === false ? { spawnWorktree: false } : {}
|
|
724
|
+
});
|
|
725
|
+
switch (result.status) {
|
|
726
|
+
case "intercom_sent":
|
|
727
|
+
dispatchStatus = `
|
|
600
728
|
Dispatched: intercom sent to ${result.sessionName}`;
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
729
|
+
break;
|
|
730
|
+
case "intercom_unprocessed":
|
|
731
|
+
dispatchStatus = `
|
|
604
732
|
Dispatched: intercom delivered to ${result.sessionName}`;
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
733
|
+
break;
|
|
734
|
+
case "spawned":
|
|
735
|
+
dispatchStatus = `
|
|
608
736
|
Dispatched: spawned ${result.sessionName}`;
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
737
|
+
break;
|
|
738
|
+
case "failed":
|
|
739
|
+
dispatchStatus = `
|
|
612
740
|
Dispatch failed: ${result.error ?? "unknown"}`;
|
|
613
|
-
|
|
614
|
-
}
|
|
615
|
-
if (result.status === "failed") dispatchOutcome = "failed";
|
|
616
|
-
if (result.status === "failed") {
|
|
617
|
-
try {
|
|
618
|
-
writeDispatchFailed(task.id, assigned_to, result.error ?? "spawn failed", result.sessionName);
|
|
619
|
-
} catch {
|
|
741
|
+
break;
|
|
620
742
|
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
tmuxSession: result.sessionName || null,
|
|
631
|
-
runtime: dispatchRuntime,
|
|
632
|
-
result: result.status,
|
|
633
|
-
errorCode: result.status === "failed" ? "ensure_employee_failed" : null,
|
|
634
|
-
payload: { priority, error: result.error ?? null }
|
|
635
|
-
});
|
|
636
|
-
try {
|
|
637
|
-
const { sendIntercom: si } = await import("./lib/tmux-routing.js");
|
|
638
|
-
const { listTmuxSessions } = await import("./lib/tmux-status.js");
|
|
639
|
-
if (!autoOpts.autoInstance) {
|
|
640
|
-
const liveSessions = listTmuxSessions();
|
|
641
|
-
for (const s of liveSessions) {
|
|
642
|
-
const agentPart = s.split("-")[0]?.replace(/\d+$/, "") ?? "";
|
|
643
|
-
if (agentPart === assigned_to && s !== result.sessionName) {
|
|
644
|
-
si(s, { force: true });
|
|
645
|
-
}
|
|
743
|
+
if (result.status === "failed") dispatchOutcome = "failed";
|
|
744
|
+
if (result.status === "failed") {
|
|
745
|
+
try {
|
|
746
|
+
releaseDispatchClaim(task.id, assigned_to, result.error ?? "spawn failed");
|
|
747
|
+
} catch {
|
|
748
|
+
}
|
|
749
|
+
try {
|
|
750
|
+
writeDispatchFailed(task.id, assigned_to, result.error ?? "spawn failed", result.sessionName);
|
|
751
|
+
} catch {
|
|
646
752
|
}
|
|
647
753
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
754
|
+
recordOrchestrationEventBestEffort({
|
|
755
|
+
eventType: result.status === "failed" ? "dispatch.failed" : "dispatch.completed",
|
|
756
|
+
source: "create-task.mcp",
|
|
757
|
+
severity: result.status === "failed" ? "warn" : "info",
|
|
758
|
+
taskId: task.id,
|
|
759
|
+
agentId: assigned_to,
|
|
760
|
+
sessionScope: task.sessionScope || callerRoot || exeSession,
|
|
761
|
+
projectName: project_name,
|
|
762
|
+
tmuxSession: result.sessionName || null,
|
|
763
|
+
runtime: dispatchRuntime,
|
|
764
|
+
result: result.status,
|
|
765
|
+
errorCode: result.status === "failed" ? "ensure_employee_failed" : null,
|
|
766
|
+
payload: { priority, error: result.error ?? null }
|
|
767
|
+
});
|
|
651
768
|
try {
|
|
652
|
-
const {
|
|
653
|
-
await
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
769
|
+
const { sendIntercom: si } = await import("./lib/tmux-routing.js");
|
|
770
|
+
const { listTmuxSessions } = await import("./lib/tmux-status.js");
|
|
771
|
+
if (!autoOpts.autoInstance) {
|
|
772
|
+
const liveSessions = listTmuxSessions();
|
|
773
|
+
for (const s of liveSessions) {
|
|
774
|
+
const agentPart = s.split("-")[0]?.replace(/\d+$/, "") ?? "";
|
|
775
|
+
if (agentPart === assigned_to && s !== result.sessionName) {
|
|
776
|
+
si(s, { force: true });
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
} catch {
|
|
781
|
+
}
|
|
782
|
+
if (result.sessionName && result.status !== "failed") {
|
|
783
|
+
try {
|
|
784
|
+
const { getClient: gc } = await import("./lib/database.js");
|
|
785
|
+
await gc().execute({
|
|
786
|
+
// Audited 2026: intentionally unscoped PK update. The task was
|
|
787
|
+
// just created in this request, and WHERE id = ? binds one row.
|
|
788
|
+
sql: `UPDATE tasks
|
|
657
789
|
SET instance_id = ?,
|
|
658
790
|
assigned_tmux = CASE
|
|
659
791
|
WHEN assigned_tmux IS NULL OR assigned_tmux = 'unknown' THEN ?
|
|
660
792
|
ELSE assigned_tmux
|
|
661
793
|
END
|
|
662
794
|
WHERE id = ?`,
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
795
|
+
args: [result.sessionName, result.sessionName, task.id]
|
|
796
|
+
});
|
|
797
|
+
} catch {
|
|
798
|
+
}
|
|
799
|
+
try {
|
|
800
|
+
const sessionScope = task.sessionScope || callerRoot || "default";
|
|
801
|
+
const { taskSignalPath: getSignalPath } = await import("./signal-paths-4G53QTII.js");
|
|
802
|
+
const signalPath = getSignalPath(sessionScope, assigned_to, task.id);
|
|
803
|
+
writeFileSync(signalPath, JSON.stringify({
|
|
804
|
+
task_id: task.id,
|
|
805
|
+
title,
|
|
806
|
+
priority,
|
|
807
|
+
assigned_by: assignedBy,
|
|
808
|
+
session_scope: sessionScope,
|
|
809
|
+
instance_id: result.sessionName,
|
|
810
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
811
|
+
}), "utf-8");
|
|
812
|
+
} catch {
|
|
813
|
+
}
|
|
666
814
|
}
|
|
667
815
|
try {
|
|
668
|
-
|
|
669
|
-
const { taskSignalPath: getSignalPath } = await import("./signal-paths-4G53QTII.js");
|
|
670
|
-
const signalPath = getSignalPath(sessionScope, assigned_to, task.id);
|
|
671
|
-
writeFileSync(signalPath, JSON.stringify({
|
|
672
|
-
task_id: task.id,
|
|
673
|
-
title,
|
|
674
|
-
priority,
|
|
675
|
-
assigned_by: assignedBy,
|
|
676
|
-
session_scope: sessionScope,
|
|
677
|
-
instance_id: result.sessionName,
|
|
678
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
679
|
-
}), "utf-8");
|
|
816
|
+
writeDispatchPending(task.id, assigned_to, result.sessionName);
|
|
680
817
|
} catch {
|
|
681
818
|
}
|
|
819
|
+
logTaskDispatch({
|
|
820
|
+
taskId: task.id,
|
|
821
|
+
assignedTo: assigned_to,
|
|
822
|
+
callerRoot,
|
|
823
|
+
exeSession,
|
|
824
|
+
callerSource,
|
|
825
|
+
dispatchResult: result.status,
|
|
826
|
+
sessionName: result.sessionName,
|
|
827
|
+
error: result.error
|
|
828
|
+
});
|
|
682
829
|
}
|
|
683
|
-
try {
|
|
684
|
-
writeDispatchPending(task.id, assigned_to, result.sessionName);
|
|
685
|
-
} catch {
|
|
686
|
-
}
|
|
687
|
-
logTaskDispatch({
|
|
688
|
-
taskId: task.id,
|
|
689
|
-
assignedTo: assigned_to,
|
|
690
|
-
callerRoot,
|
|
691
|
-
exeSession,
|
|
692
|
-
callerSource,
|
|
693
|
-
dispatchResult: result.status,
|
|
694
|
-
sessionName: result.sessionName,
|
|
695
|
-
error: result.error
|
|
696
|
-
});
|
|
697
830
|
} else {
|
|
698
831
|
const noSessionMsg = `Dispatch skipped: no coordinator session resolved (callerTmux="${callerTmux}", callerSource="${callerSource}"). Task ${task.id} created but agent ${assigned_to} was NOT spawned. Auto-wake will retry.`;
|
|
699
832
|
process.stderr.write(`[create_task] ${noSessionMsg}
|
|
@@ -716,6 +849,10 @@ Dispatch deferred: no coordinator session \u2014 auto-wake will spawn ${assigned
|
|
|
716
849
|
}
|
|
717
850
|
} catch (dispatchErr) {
|
|
718
851
|
dispatchOutcome = "failed";
|
|
852
|
+
try {
|
|
853
|
+
releaseDispatchClaim(task.id, assigned_to, "dispatch exception");
|
|
854
|
+
} catch {
|
|
855
|
+
}
|
|
719
856
|
recordOrchestrationEventBestEffort({
|
|
720
857
|
eventType: "dispatch.failed",
|
|
721
858
|
source: "create-task.mcp",
|
|
@@ -734,8 +871,8 @@ ${dispatchErr instanceof Error ? dispatchErr.stack : ""}
|
|
|
734
871
|
}
|
|
735
872
|
let dupWarning = "";
|
|
736
873
|
try {
|
|
737
|
-
const { findMatchingBranches } = await import("./branch-hygiene-
|
|
738
|
-
const matches = await findMatchingBranches(
|
|
874
|
+
const { findMatchingBranches } = await import("./branch-hygiene-TZWK6QCF.js");
|
|
875
|
+
const matches = await findMatchingBranches(resolvedProjectDir, { title });
|
|
739
876
|
if (matches.length > 0) {
|
|
740
877
|
const top = matches.slice(0, 3).map((m) => {
|
|
741
878
|
const age = m.ageHours >= 24 ? `${(m.ageHours / 24).toFixed(1)}d` : `${m.ageHours.toFixed(0)}h`;
|
|
@@ -783,11 +920,14 @@ Warning: ${task.warning}`;
|
|
|
783
920
|
}
|
|
784
921
|
|
|
785
922
|
export {
|
|
923
|
+
isSafeProjectName,
|
|
924
|
+
findProjectChildDir,
|
|
786
925
|
DISPATCH_JOURNAL_ORPHAN_AGE_MS,
|
|
787
926
|
dispatchJournalDir,
|
|
788
927
|
journalDispatchIntent,
|
|
789
928
|
updateDispatchJournalEntry,
|
|
790
929
|
clearDispatchJournalEntry,
|
|
791
930
|
findOrphanedDispatchIntents,
|
|
931
|
+
resolveProjectDir,
|
|
792
932
|
registerCreateTask
|
|
793
933
|
};
|