@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
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import {
|
|
2
|
+
supportCommitSchema,
|
|
3
|
+
supportIdSchema,
|
|
4
|
+
supportProductSchema,
|
|
5
|
+
supportTaskIdSchema,
|
|
6
|
+
supportVersionSchema
|
|
7
|
+
} from "./chunk-5H47VHB7.js";
|
|
8
|
+
import {
|
|
9
|
+
SUPPORT_PRODUCTS,
|
|
10
|
+
sanitizeProductFilter,
|
|
11
|
+
sanitizeUpstreamId,
|
|
12
|
+
sanitizedUpstreamBody
|
|
13
|
+
} from "./chunk-4QCFFW2H.js";
|
|
14
|
+
import {
|
|
15
|
+
loadLicense,
|
|
16
|
+
readCachedLicenseToken
|
|
17
|
+
} from "./chunk-PQIDGXSG.js";
|
|
18
|
+
|
|
19
|
+
// src/mcp/tools/support-inbox.ts
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
import { readFileSync } from "fs";
|
|
22
|
+
import { join } from "path";
|
|
23
|
+
import { homedir } from "os";
|
|
24
|
+
var DEFAULT_ENDPOINT = "https://api.askexe.com/admin/support/bug-reports";
|
|
25
|
+
var DEFAULT_OWNER_ENDPOINT = "https://api.askexe.com/v1/support/bug-reports";
|
|
26
|
+
var STATUS = z.enum(["open", "triaged", "fixed", "closed", "wontfix"]);
|
|
27
|
+
function adminToken() {
|
|
28
|
+
if (process.env.ASKEXE_SUPPORT_ADMIN_TOKEN) return process.env.ASKEXE_SUPPORT_ADMIN_TOKEN;
|
|
29
|
+
if (process.env.EXE_SUPPORT_ADMIN_TOKEN) return process.env.EXE_SUPPORT_ADMIN_TOKEN;
|
|
30
|
+
try {
|
|
31
|
+
const configPath = join(process.env.EXE_OS_DIR ?? join(homedir(), ".exe-os"), "config.json");
|
|
32
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
33
|
+
return config.support?.adminToken || config.support?.admin_token;
|
|
34
|
+
} catch {
|
|
35
|
+
return void 0;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function endpoint() {
|
|
39
|
+
return (process.env.ASKEXE_SUPPORT_ADMIN_ENDPOINT || DEFAULT_ENDPOINT).replace(/\/+$/, "");
|
|
40
|
+
}
|
|
41
|
+
function ownerEndpoint() {
|
|
42
|
+
const routerUrl = process.env.API_ROUTER_URL?.replace(/\/+$/, "");
|
|
43
|
+
let configured;
|
|
44
|
+
try {
|
|
45
|
+
const configPath = join(process.env.EXE_OS_DIR ?? join(homedir(), ".exe-os"), "config.json");
|
|
46
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
47
|
+
configured = config.support?.bugReportEndpoint;
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
const base = configured || process.env.EXE_BUG_REPORT_ENDPOINT || (routerUrl ? `${routerUrl}/v1/support/bug-reports` : DEFAULT_OWNER_ENDPOINT);
|
|
51
|
+
return base.replace(/\/+$/, "");
|
|
52
|
+
}
|
|
53
|
+
function ownerAuthHeaders() {
|
|
54
|
+
let cloudApiKey;
|
|
55
|
+
try {
|
|
56
|
+
const configPath = join(process.env.EXE_OS_DIR ?? join(homedir(), ".exe-os"), "config.json");
|
|
57
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
58
|
+
cloudApiKey = config.cloud?.apiKey;
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
const licenseKey = loadLicense() || process.env.EXE_LICENSE_KEY || cloudApiKey;
|
|
62
|
+
const licenseToken = readCachedLicenseToken();
|
|
63
|
+
const headers = {};
|
|
64
|
+
if (licenseKey) {
|
|
65
|
+
headers["x-exe-license-key"] = licenseKey;
|
|
66
|
+
headers.authorization = `Bearer ${licenseKey}`;
|
|
67
|
+
}
|
|
68
|
+
if (licenseToken) headers["x-exe-license-token"] = licenseToken;
|
|
69
|
+
return headers;
|
|
70
|
+
}
|
|
71
|
+
function assertInternal() {
|
|
72
|
+
const token = adminToken();
|
|
73
|
+
if (!token) throw new Error("AskExe support admin token not configured");
|
|
74
|
+
return token;
|
|
75
|
+
}
|
|
76
|
+
async function requestJson(url, init) {
|
|
77
|
+
const token = assertInternal();
|
|
78
|
+
const res = await fetch(url, {
|
|
79
|
+
...init,
|
|
80
|
+
headers: {
|
|
81
|
+
"content-type": "application/json",
|
|
82
|
+
authorization: `Bearer ${token}`,
|
|
83
|
+
...init?.headers ?? {}
|
|
84
|
+
},
|
|
85
|
+
signal: AbortSignal.timeout(1e4)
|
|
86
|
+
});
|
|
87
|
+
const text = await res.text();
|
|
88
|
+
let data = text;
|
|
89
|
+
try {
|
|
90
|
+
data = text ? JSON.parse(text) : {};
|
|
91
|
+
} catch {
|
|
92
|
+
}
|
|
93
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}: ${typeof data === "string" ? data : JSON.stringify(data)}`);
|
|
94
|
+
return data;
|
|
95
|
+
}
|
|
96
|
+
async function fetchJson(url, headers, init) {
|
|
97
|
+
const res = await fetch(url, {
|
|
98
|
+
...init,
|
|
99
|
+
headers: { "content-type": "application/json", ...headers, ...init?.headers ?? {} },
|
|
100
|
+
signal: AbortSignal.timeout(1e4)
|
|
101
|
+
});
|
|
102
|
+
const text = await res.text();
|
|
103
|
+
let data = text;
|
|
104
|
+
try {
|
|
105
|
+
data = text ? JSON.parse(text) : {};
|
|
106
|
+
} catch {
|
|
107
|
+
}
|
|
108
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}: ${typeof data === "string" ? data : JSON.stringify(data)}`);
|
|
109
|
+
return data;
|
|
110
|
+
}
|
|
111
|
+
async function commentRequestJson(bugId, init) {
|
|
112
|
+
const token = adminToken();
|
|
113
|
+
if (token) {
|
|
114
|
+
const url2 = `${endpoint()}/${encodeURIComponent(sanitizeUpstreamId(bugId))}/comments`;
|
|
115
|
+
return fetchJson(url2, { authorization: `Bearer ${token}` }, init);
|
|
116
|
+
}
|
|
117
|
+
const ownerHeaders = ownerAuthHeaders();
|
|
118
|
+
if (!ownerHeaders.authorization && !ownerHeaders["x-exe-license-token"]) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
"Not authenticated for support comments. Run `exe-os login` (GoTrue) or set a license key, or configure an AskExe admin token (ASKEXE_SUPPORT_ADMIN_TOKEN)."
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
const url = `${ownerEndpoint()}/${encodeURIComponent(sanitizeUpstreamId(bugId))}/comments`;
|
|
124
|
+
return fetchJson(url, ownerHeaders, init);
|
|
125
|
+
}
|
|
126
|
+
function registerListBugReports(server) {
|
|
127
|
+
server.registerTool(
|
|
128
|
+
"list_bug_reports",
|
|
129
|
+
{
|
|
130
|
+
title: "List Bug Reports",
|
|
131
|
+
description: "AskExe-internal only: list incoming customer bug reports from the support inbox.",
|
|
132
|
+
inputSchema: {
|
|
133
|
+
status: z.enum(["all", "open", "triaged", "fixed", "closed", "wontfix"]).default("open"),
|
|
134
|
+
severity: z.enum(["p0", "p1", "p2", "p3"]).optional(),
|
|
135
|
+
// Round 8: constrain to the known enum at the schema — a `product` filter is
|
|
136
|
+
// NOT free text, and it was sent raw as a query param.
|
|
137
|
+
product: z.enum(SUPPORT_PRODUCTS).optional().describe("Filter by product"),
|
|
138
|
+
limit: z.number().int().min(1).max(500).default(25),
|
|
139
|
+
offset: z.number().int().min(0).default(0).describe("Number of results to skip for pagination. Use next_offset from a prior response.")
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
async ({ status, severity, product, limit, offset }) => {
|
|
143
|
+
const url = new URL(endpoint());
|
|
144
|
+
url.searchParams.set("status", status);
|
|
145
|
+
url.searchParams.set("limit", String(limit));
|
|
146
|
+
url.searchParams.set("offset", String(offset));
|
|
147
|
+
if (severity) url.searchParams.set("severity", severity);
|
|
148
|
+
const safeProduct = sanitizeProductFilter(product);
|
|
149
|
+
if (safeProduct) url.searchParams.set("product", safeProduct);
|
|
150
|
+
const data = await requestJson(url.toString());
|
|
151
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
function parseComments(row) {
|
|
156
|
+
if (!row || typeof row !== "object") return [];
|
|
157
|
+
const raw = row.progress_log;
|
|
158
|
+
if (typeof raw !== "string" || !raw.trim()) return [];
|
|
159
|
+
try {
|
|
160
|
+
const parsed = JSON.parse(raw);
|
|
161
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
162
|
+
} catch {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function registerGetBugReport(server) {
|
|
167
|
+
server.registerTool(
|
|
168
|
+
"get_bug_report",
|
|
169
|
+
{
|
|
170
|
+
title: "Get Bug Report",
|
|
171
|
+
description: "AskExe-internal only: fetch one customer bug report with full markdown payload and comments thread.",
|
|
172
|
+
inputSchema: { id: supportIdSchema }
|
|
173
|
+
},
|
|
174
|
+
async ({ id }) => {
|
|
175
|
+
const data = await requestJson(`${endpoint()}/${encodeURIComponent(sanitizeUpstreamId(id))}`);
|
|
176
|
+
const comments = parseComments(data);
|
|
177
|
+
const enriched = data && typeof data === "object" ? { ...data, comments } : { id, comments };
|
|
178
|
+
return { content: [{ type: "text", text: JSON.stringify(enriched, null, 2) }] };
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
function registerAddBugReportComment(server) {
|
|
183
|
+
server.registerTool(
|
|
184
|
+
"add_bug_report_comment",
|
|
185
|
+
{
|
|
186
|
+
title: "Add Bug Report Comment",
|
|
187
|
+
description: "AskExe-internal only: append a comment to a bug report's thread (POST /comments). Non-destructive \u2014 does not touch triage_notes or status.",
|
|
188
|
+
inputSchema: {
|
|
189
|
+
id: supportIdSchema,
|
|
190
|
+
comment: z.string().min(1).describe("Comment text to append to the bug report thread")
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
async ({ id, comment }) => {
|
|
194
|
+
const data = await commentRequestJson(id, {
|
|
195
|
+
method: "POST",
|
|
196
|
+
body: sanitizedUpstreamBody({ comment }, "support-inbox:add_comment")
|
|
197
|
+
});
|
|
198
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
function registerGetBugReportComments(server) {
|
|
203
|
+
server.registerTool(
|
|
204
|
+
"get_bug_report_comments",
|
|
205
|
+
{
|
|
206
|
+
title: "Get Bug Report Comments",
|
|
207
|
+
description: "AskExe-internal only: list the comments thread on a bug report (GET /comments).",
|
|
208
|
+
inputSchema: { id: supportIdSchema }
|
|
209
|
+
},
|
|
210
|
+
async ({ id }) => {
|
|
211
|
+
const data = await commentRequestJson(id);
|
|
212
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
213
|
+
}
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
function registerTriageBugReport(server) {
|
|
217
|
+
server.registerTool(
|
|
218
|
+
"triage_bug_report",
|
|
219
|
+
{
|
|
220
|
+
title: "Triage Bug Report",
|
|
221
|
+
description: "AskExe-internal only: update bug report status and link task/commit/release metadata.",
|
|
222
|
+
inputSchema: {
|
|
223
|
+
id: supportIdSchema,
|
|
224
|
+
status: STATUS.optional(),
|
|
225
|
+
triage_notes: z.string().optional(),
|
|
226
|
+
add_note: z.string().optional().describe("Append a timestamped progress note without changing status or replacing triage_notes"),
|
|
227
|
+
linked_task_id: supportTaskIdSchema.optional(),
|
|
228
|
+
linked_commit: supportCommitSchema.optional(),
|
|
229
|
+
fixed_version: supportVersionSchema.optional(),
|
|
230
|
+
product: supportProductSchema.optional().describe("Re-label this bug's product: exe-os, exe-create, exe-wiki, exe-gateway, exe-crm, exe-build, exe-chat, exe-auth, exe-monitor, exe-db, exe-erp")
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
async ({ id, status, triage_notes, add_note, linked_task_id, linked_commit, fixed_version, product }) => {
|
|
234
|
+
const effectiveStatus = fixed_version && !status ? "closed" : status;
|
|
235
|
+
const data = await requestJson(`${endpoint()}/${encodeURIComponent(sanitizeUpstreamId(id))}`, {
|
|
236
|
+
method: "PATCH",
|
|
237
|
+
body: sanitizedUpstreamBody({ status: effectiveStatus, triage_notes, add_note, linked_task_id, linked_commit, fixed_version, product }, "support-inbox:triage_bug")
|
|
238
|
+
});
|
|
239
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
240
|
+
}
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
var FEATURE_STATUS = z.enum(["open", "planned", "in_progress", "shipped", "closed", "wontdo"]);
|
|
244
|
+
function featureEndpoint() {
|
|
245
|
+
return endpoint().replace(/\/bug-reports\/?$/, "/feature-requests");
|
|
246
|
+
}
|
|
247
|
+
function registerListFeatureRequests(server) {
|
|
248
|
+
server.registerTool(
|
|
249
|
+
"list_feature_requests",
|
|
250
|
+
{
|
|
251
|
+
title: "List Feature Requests",
|
|
252
|
+
description: "AskExe-internal only: list incoming customer feature requests from the support inbox.",
|
|
253
|
+
inputSchema: {
|
|
254
|
+
status: z.enum(["all", "open", "planned", "in_progress", "shipped", "closed", "wontdo"]).default("open"),
|
|
255
|
+
priority: z.enum(["p0", "p1", "p2", "p3"]).optional(),
|
|
256
|
+
product: z.string().optional().describe("Filter by product: exe-os, exe-create, exe-wiki, exe-gateway, exe-crm, exe-build, exe-chat, exe-auth, exe-monitor, exe-db, exe-erp"),
|
|
257
|
+
limit: z.number().int().min(1).max(500).default(25),
|
|
258
|
+
offset: z.number().int().min(0).default(0).describe("Number of results to skip for pagination. Use next_offset from a prior response.")
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
async ({ status, priority, product, limit, offset }) => {
|
|
262
|
+
const url = new URL(featureEndpoint());
|
|
263
|
+
url.searchParams.set("status", status);
|
|
264
|
+
url.searchParams.set("limit", String(limit));
|
|
265
|
+
url.searchParams.set("offset", String(offset));
|
|
266
|
+
if (priority) url.searchParams.set("priority", priority);
|
|
267
|
+
const safeProduct = sanitizeProductFilter(product);
|
|
268
|
+
if (safeProduct) url.searchParams.set("product", safeProduct);
|
|
269
|
+
const data = await requestJson(url.toString());
|
|
270
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
271
|
+
}
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
function registerGetFeatureRequest(server) {
|
|
275
|
+
server.registerTool(
|
|
276
|
+
"get_feature_request",
|
|
277
|
+
{
|
|
278
|
+
title: "Get Feature Request",
|
|
279
|
+
description: "AskExe-internal only: fetch one customer feature request with full payload.",
|
|
280
|
+
inputSchema: { id: supportIdSchema }
|
|
281
|
+
},
|
|
282
|
+
async ({ id }) => {
|
|
283
|
+
const data = await requestJson(`${featureEndpoint()}/${encodeURIComponent(sanitizeUpstreamId(id))}`);
|
|
284
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
285
|
+
}
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
function registerTriageFeatureRequest(server) {
|
|
289
|
+
server.registerTool(
|
|
290
|
+
"triage_feature_request",
|
|
291
|
+
{
|
|
292
|
+
title: "Triage Feature Request",
|
|
293
|
+
description: "AskExe-internal only: update feature request status, response notes, and version metadata.",
|
|
294
|
+
inputSchema: {
|
|
295
|
+
id: supportIdSchema,
|
|
296
|
+
status: FEATURE_STATUS.optional(),
|
|
297
|
+
response_notes: z.string().optional(),
|
|
298
|
+
add_note: z.string().optional().describe("Append a timestamped progress note without changing status or replacing response_notes"),
|
|
299
|
+
target_version: supportVersionSchema.optional(),
|
|
300
|
+
shipped_version: supportVersionSchema.optional(),
|
|
301
|
+
// bug b8e990ed: allow admin re-label of a feature's product. Typed with the
|
|
302
|
+
// strict product schema (round 10 ingress validation), not a loose string.
|
|
303
|
+
product: supportProductSchema.optional().describe("Re-label this feature's product: exe-os, exe-create, exe-wiki, exe-gateway, exe-crm, exe-build, exe-chat, exe-auth, exe-monitor, exe-db, exe-erp")
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
async ({ id, status, response_notes, add_note, target_version, shipped_version, product }) => {
|
|
307
|
+
const effectiveStatus = shipped_version && !status ? "shipped" : status;
|
|
308
|
+
const data = await requestJson(`${featureEndpoint()}/${encodeURIComponent(sanitizeUpstreamId(id))}`, {
|
|
309
|
+
method: "PATCH",
|
|
310
|
+
body: sanitizedUpstreamBody({ status: effectiveStatus, response_notes, add_note, target_version, shipped_version, product }, "support-inbox:triage_feature")
|
|
311
|
+
});
|
|
312
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
313
|
+
}
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
var REVIEW_STATUS = z.enum(["open", "in_review", "approved", "merged", "closed", "rejected"]);
|
|
317
|
+
function reviewEndpoint() {
|
|
318
|
+
return endpoint().replace(/\/bug-reports\/?$/, "/reviews");
|
|
319
|
+
}
|
|
320
|
+
function registerListReviews(server) {
|
|
321
|
+
server.registerTool(
|
|
322
|
+
"list_reviews",
|
|
323
|
+
{
|
|
324
|
+
title: "List Reviews",
|
|
325
|
+
description: "AskExe-internal only: list incoming review requests from the support inbox.",
|
|
326
|
+
inputSchema: {
|
|
327
|
+
status: z.enum(["all", "open", "in_review", "approved", "merged", "closed", "rejected"]).default("open"),
|
|
328
|
+
priority: z.enum(["p0", "p1", "p2", "p3"]).optional(),
|
|
329
|
+
limit: z.number().int().min(1).max(500).default(25),
|
|
330
|
+
offset: z.number().int().min(0).default(0).describe("Number of results to skip for pagination. Use next_offset from a prior response.")
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
async ({ status, priority, limit, offset }) => {
|
|
334
|
+
const url = new URL(reviewEndpoint());
|
|
335
|
+
url.searchParams.set("status", status);
|
|
336
|
+
url.searchParams.set("limit", String(limit));
|
|
337
|
+
url.searchParams.set("offset", String(offset));
|
|
338
|
+
if (priority) url.searchParams.set("priority", priority);
|
|
339
|
+
const data = await requestJson(url.toString());
|
|
340
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
341
|
+
}
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
function registerGetReview(server) {
|
|
345
|
+
server.registerTool(
|
|
346
|
+
"get_review",
|
|
347
|
+
{
|
|
348
|
+
title: "Get Review",
|
|
349
|
+
description: "AskExe-internal only: fetch one review with full payload.",
|
|
350
|
+
inputSchema: { id: supportIdSchema }
|
|
351
|
+
},
|
|
352
|
+
async ({ id }) => {
|
|
353
|
+
const data = await requestJson(`${reviewEndpoint()}/${encodeURIComponent(sanitizeUpstreamId(id))}`);
|
|
354
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
355
|
+
}
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
function registerTriageReview(server) {
|
|
359
|
+
server.registerTool(
|
|
360
|
+
"triage_review",
|
|
361
|
+
{
|
|
362
|
+
title: "Triage Review",
|
|
363
|
+
description: "AskExe-internal only: update review status, response notes, and resolution.",
|
|
364
|
+
inputSchema: {
|
|
365
|
+
id: supportIdSchema,
|
|
366
|
+
status: REVIEW_STATUS.optional(),
|
|
367
|
+
response_notes: z.string().optional(),
|
|
368
|
+
add_note: z.string().optional().describe("Append a timestamped progress note without changing status or replacing response_notes"),
|
|
369
|
+
resolution: z.string().optional(),
|
|
370
|
+
pr_url: z.string().optional()
|
|
371
|
+
}
|
|
372
|
+
},
|
|
373
|
+
async ({ id, status, response_notes, add_note, resolution, pr_url }) => {
|
|
374
|
+
const data = await requestJson(`${reviewEndpoint()}/${encodeURIComponent(sanitizeUpstreamId(id))}`, {
|
|
375
|
+
method: "PATCH",
|
|
376
|
+
body: sanitizedUpstreamBody({ status, response_notes, add_note, resolution, pr_url }, "support-inbox:triage_review")
|
|
377
|
+
});
|
|
378
|
+
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
|
|
379
|
+
}
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export {
|
|
384
|
+
registerListBugReports,
|
|
385
|
+
registerGetBugReport,
|
|
386
|
+
registerAddBugReportComment,
|
|
387
|
+
registerGetBugReportComments,
|
|
388
|
+
registerTriageBugReport,
|
|
389
|
+
registerListFeatureRequests,
|
|
390
|
+
registerGetFeatureRequest,
|
|
391
|
+
registerTriageFeatureRequest,
|
|
392
|
+
registerListReviews,
|
|
393
|
+
registerGetReview,
|
|
394
|
+
registerTriageReview
|
|
395
|
+
};
|
|
@@ -1,12 +1,73 @@
|
|
|
1
1
|
import {
|
|
2
2
|
recordOrchestrationEventBestEffort
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2WAVZ5UJ.js";
|
|
4
4
|
|
|
5
5
|
// src/lib/worktree.ts
|
|
6
|
-
import { execSync } from "child_process";
|
|
7
|
-
import {
|
|
6
|
+
import { execFile, execSync } from "child_process";
|
|
7
|
+
import { promisify } from "util";
|
|
8
|
+
import { existsSync, readFileSync, appendFileSync, mkdirSync, realpathSync, statSync } from "fs";
|
|
8
9
|
import path from "path";
|
|
9
10
|
var GIT_TIMEOUT_MS = 1e4;
|
|
11
|
+
var execFileAsync = promisify(execFile);
|
|
12
|
+
async function gitAsync(args, cwd) {
|
|
13
|
+
const { stdout } = await execFileAsync("git", args, {
|
|
14
|
+
cwd,
|
|
15
|
+
encoding: "utf-8",
|
|
16
|
+
timeout: GIT_TIMEOUT_MS
|
|
17
|
+
});
|
|
18
|
+
return String(stdout ?? "");
|
|
19
|
+
}
|
|
20
|
+
function classifyGitFailure(err) {
|
|
21
|
+
if (!err || typeof err !== "object") return "unavailable";
|
|
22
|
+
const e = err;
|
|
23
|
+
if (e.killed === true) return "unavailable";
|
|
24
|
+
if (typeof e.signal === "string" && e.signal.length > 0) return "unavailable";
|
|
25
|
+
if (e.code === "ETIMEDOUT" || e.code === "ENOENT") return "unavailable";
|
|
26
|
+
if (typeof e.status === "number") return "definitive";
|
|
27
|
+
if (typeof e.code === "number") return "definitive";
|
|
28
|
+
return "unavailable";
|
|
29
|
+
}
|
|
30
|
+
async function resolveGitWithRetryAsync(run) {
|
|
31
|
+
for (let attempt = 0; ; attempt++) {
|
|
32
|
+
try {
|
|
33
|
+
return await run();
|
|
34
|
+
} catch (err) {
|
|
35
|
+
if (classifyGitFailure(err) === "definitive") return null;
|
|
36
|
+
if (attempt >= 1) return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function resolveGitWithRetrySync(run) {
|
|
41
|
+
for (let attempt = 0; ; attempt++) {
|
|
42
|
+
try {
|
|
43
|
+
return run();
|
|
44
|
+
} catch (err) {
|
|
45
|
+
if (classifyGitFailure(err) === "definitive") return null;
|
|
46
|
+
if (attempt >= 1) return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function isInsideGitRepo(dir) {
|
|
51
|
+
let cur;
|
|
52
|
+
try {
|
|
53
|
+
cur = path.resolve(dir);
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
for (let i = 0; i < 128; i++) {
|
|
58
|
+
try {
|
|
59
|
+
statSync(path.join(cur, ".git"));
|
|
60
|
+
return true;
|
|
61
|
+
} catch (err) {
|
|
62
|
+
const code = err?.code;
|
|
63
|
+
if (code !== "ENOENT" && code !== "ENOTDIR") return true;
|
|
64
|
+
}
|
|
65
|
+
const parent = path.dirname(cur);
|
|
66
|
+
if (parent === cur) break;
|
|
67
|
+
cur = parent;
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
10
71
|
function getGitRoot(dir) {
|
|
11
72
|
try {
|
|
12
73
|
const root = execSync("git rev-parse --show-toplevel", {
|
|
@@ -20,17 +81,31 @@ function getGitRoot(dir) {
|
|
|
20
81
|
return null;
|
|
21
82
|
}
|
|
22
83
|
}
|
|
23
|
-
function
|
|
84
|
+
async function getGitRootAsync(dir) {
|
|
24
85
|
try {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
{ cwd: dir, encoding: "utf-8", timeout: GIT_TIMEOUT_MS, stdio: ["pipe", "pipe", "pipe"] }
|
|
28
|
-
).trim();
|
|
29
|
-
return realpath(path.dirname(commonDir));
|
|
86
|
+
const root = (await gitAsync(["rev-parse", "--show-toplevel"], dir)).trim();
|
|
87
|
+
return realpath(root);
|
|
30
88
|
} catch {
|
|
31
89
|
return null;
|
|
32
90
|
}
|
|
33
91
|
}
|
|
92
|
+
function getMainRepoRoot(dir) {
|
|
93
|
+
const commonDir = resolveGitWithRetrySync(
|
|
94
|
+
() => execSync(
|
|
95
|
+
"git rev-parse --path-format=absolute --git-common-dir",
|
|
96
|
+
{ cwd: dir, encoding: "utf-8", timeout: GIT_TIMEOUT_MS, stdio: ["pipe", "pipe", "pipe"] }
|
|
97
|
+
).trim()
|
|
98
|
+
);
|
|
99
|
+
if (commonDir == null) return null;
|
|
100
|
+
return realpath(path.dirname(commonDir));
|
|
101
|
+
}
|
|
102
|
+
async function getMainRepoRootAsync(dir) {
|
|
103
|
+
const commonDir = await resolveGitWithRetryAsync(
|
|
104
|
+
async () => (await gitAsync(["rev-parse", "--path-format=absolute", "--git-common-dir"], dir)).trim()
|
|
105
|
+
);
|
|
106
|
+
if (commonDir == null) return null;
|
|
107
|
+
return realpath(path.dirname(commonDir));
|
|
108
|
+
}
|
|
34
109
|
function worktreePath(repoRoot, employeeName, instance) {
|
|
35
110
|
const label = instanceLabel(employeeName, instance);
|
|
36
111
|
return path.join(repoRoot, ".worktrees", label);
|
|
@@ -165,6 +240,107 @@ function ensureWorktree(projectDir, employeeName, instance) {
|
|
|
165
240
|
return null;
|
|
166
241
|
}
|
|
167
242
|
}
|
|
243
|
+
async function ensureWorktreeAsync(projectDir, employeeName, instance) {
|
|
244
|
+
const repoRoot = await getMainRepoRootAsync(projectDir);
|
|
245
|
+
if (!repoRoot) return null;
|
|
246
|
+
const wtPath = worktreePath(repoRoot, employeeName, instance);
|
|
247
|
+
const branch = worktreeBranch(employeeName, instance);
|
|
248
|
+
if (existsSync(path.join(wtPath, ".git"))) {
|
|
249
|
+
const currentBranch = await getWorktreeCurrentBranchAsync(wtPath);
|
|
250
|
+
if (currentBranch !== branch) {
|
|
251
|
+
recordOrchestrationEventBestEffort({
|
|
252
|
+
eventType: "worktree.branch_mismatch",
|
|
253
|
+
source: "worktree.ensureWorktreeAsync",
|
|
254
|
+
severity: "warn",
|
|
255
|
+
agentId: employeeName,
|
|
256
|
+
instanceId: instance != null ? String(instance) : null,
|
|
257
|
+
payload: { expectedBranch: branch, actualBranch: currentBranch }
|
|
258
|
+
});
|
|
259
|
+
if (await isWorktreeDirtyAsync(wtPath)) {
|
|
260
|
+
process.stderr.write(
|
|
261
|
+
`[worktree] Refusing to reuse ${wtPath}: expected branch ${branch}, found ${currentBranch ?? "unknown"} with uncommitted changes
|
|
262
|
+
`
|
|
263
|
+
);
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
try {
|
|
267
|
+
await gitAsync(["worktree", "remove", wtPath], repoRoot);
|
|
268
|
+
} catch (err) {
|
|
269
|
+
process.stderr.write(
|
|
270
|
+
`[worktree] Failed to repair branch mismatch for ${employeeName}: ${err instanceof Error ? err.message : String(err)}
|
|
271
|
+
`
|
|
272
|
+
);
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
} else {
|
|
276
|
+
recordOrchestrationEventBestEffort({
|
|
277
|
+
eventType: "worktree.reused",
|
|
278
|
+
source: "worktree.ensureWorktreeAsync",
|
|
279
|
+
agentId: employeeName,
|
|
280
|
+
instanceId: instance != null ? String(instance) : null,
|
|
281
|
+
payload: { branch }
|
|
282
|
+
});
|
|
283
|
+
return wtPath;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (existsSync(path.join(wtPath, ".git")) && await getWorktreeCurrentBranchAsync(wtPath) === branch) {
|
|
287
|
+
recordOrchestrationEventBestEffort({
|
|
288
|
+
eventType: "worktree.reused",
|
|
289
|
+
source: "worktree.ensureWorktreeAsync",
|
|
290
|
+
agentId: employeeName,
|
|
291
|
+
instanceId: instance != null ? String(instance) : null,
|
|
292
|
+
payload: { branch }
|
|
293
|
+
});
|
|
294
|
+
return wtPath;
|
|
295
|
+
}
|
|
296
|
+
mkdirSync(path.join(repoRoot, ".worktrees"), { recursive: true });
|
|
297
|
+
ensureGitignoreEntry(repoRoot, "/.worktrees/");
|
|
298
|
+
try {
|
|
299
|
+
await gitAsync(["worktree", "prune"], repoRoot);
|
|
300
|
+
} catch {
|
|
301
|
+
}
|
|
302
|
+
const branchExists = await branchExistsLocallyAsync(repoRoot, branch);
|
|
303
|
+
try {
|
|
304
|
+
if (branchExists) {
|
|
305
|
+
await gitAsync(["worktree", "add", wtPath, branch], repoRoot);
|
|
306
|
+
} else {
|
|
307
|
+
await gitAsync(["worktree", "add", wtPath, "-b", branch, "HEAD"], repoRoot);
|
|
308
|
+
}
|
|
309
|
+
recordOrchestrationEventBestEffort({
|
|
310
|
+
eventType: "worktree.created",
|
|
311
|
+
source: "worktree.ensureWorktreeAsync",
|
|
312
|
+
agentId: employeeName,
|
|
313
|
+
instanceId: instance != null ? String(instance) : null,
|
|
314
|
+
payload: { branch, reusedBranch: branchExists }
|
|
315
|
+
});
|
|
316
|
+
return wtPath;
|
|
317
|
+
} catch (err) {
|
|
318
|
+
if (existsSync(path.join(wtPath, ".git")) && await getWorktreeCurrentBranchAsync(wtPath) === branch) {
|
|
319
|
+
recordOrchestrationEventBestEffort({
|
|
320
|
+
eventType: "worktree.reused",
|
|
321
|
+
source: "worktree.ensureWorktreeAsync",
|
|
322
|
+
agentId: employeeName,
|
|
323
|
+
instanceId: instance != null ? String(instance) : null,
|
|
324
|
+
payload: { branch, raced: true }
|
|
325
|
+
});
|
|
326
|
+
return wtPath;
|
|
327
|
+
}
|
|
328
|
+
recordOrchestrationEventBestEffort({
|
|
329
|
+
eventType: "worktree.failed",
|
|
330
|
+
source: "worktree.ensureWorktreeAsync",
|
|
331
|
+
severity: "warn",
|
|
332
|
+
agentId: employeeName,
|
|
333
|
+
instanceId: instance != null ? String(instance) : null,
|
|
334
|
+
errorCode: err instanceof Error ? err.name : "worktree_create_failed",
|
|
335
|
+
payload: { branch }
|
|
336
|
+
});
|
|
337
|
+
process.stderr.write(
|
|
338
|
+
`[worktree] Failed to create worktree for ${employeeName}: ${err instanceof Error ? err.message : String(err)}
|
|
339
|
+
`
|
|
340
|
+
);
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
168
344
|
function isWorktreeDirty(wtPath) {
|
|
169
345
|
try {
|
|
170
346
|
const status = execSync("git status --porcelain", {
|
|
@@ -178,6 +354,13 @@ function isWorktreeDirty(wtPath) {
|
|
|
178
354
|
return true;
|
|
179
355
|
}
|
|
180
356
|
}
|
|
357
|
+
async function isWorktreeDirtyAsync(wtPath) {
|
|
358
|
+
try {
|
|
359
|
+
return (await gitAsync(["status", "--porcelain"], wtPath)).trim().length > 0;
|
|
360
|
+
} catch {
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
181
364
|
function cleanupWorktree(projectDir, employeeName, instance) {
|
|
182
365
|
const repoRoot = getMainRepoRoot(projectDir);
|
|
183
366
|
if (!repoRoot) return { cleaned: false, reason: "not a git repo" };
|
|
@@ -277,6 +460,14 @@ function branchExistsLocally(repoRoot, branch) {
|
|
|
277
460
|
return false;
|
|
278
461
|
}
|
|
279
462
|
}
|
|
463
|
+
async function branchExistsLocallyAsync(repoRoot, branch) {
|
|
464
|
+
try {
|
|
465
|
+
await gitAsync(["rev-parse", "--verify", `refs/heads/${branch}`], repoRoot);
|
|
466
|
+
return true;
|
|
467
|
+
} catch {
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
280
471
|
function getWorktreeCurrentBranch(wtPath) {
|
|
281
472
|
try {
|
|
282
473
|
const branch = execSync("git branch --show-current", {
|
|
@@ -290,6 +481,14 @@ function getWorktreeCurrentBranch(wtPath) {
|
|
|
290
481
|
return null;
|
|
291
482
|
}
|
|
292
483
|
}
|
|
484
|
+
async function getWorktreeCurrentBranchAsync(wtPath) {
|
|
485
|
+
try {
|
|
486
|
+
const branch = (await gitAsync(["branch", "--show-current"], wtPath)).trim();
|
|
487
|
+
return branch.length > 0 ? branch : null;
|
|
488
|
+
} catch {
|
|
489
|
+
return null;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
293
492
|
function detectMainBranch(repoRoot) {
|
|
294
493
|
for (const candidate of ["main", "master"]) {
|
|
295
494
|
if (branchExistsLocally(repoRoot, candidate)) return candidate;
|
|
@@ -333,12 +532,20 @@ ${entry}
|
|
|
333
532
|
}
|
|
334
533
|
|
|
335
534
|
export {
|
|
535
|
+
classifyGitFailure,
|
|
536
|
+
resolveGitWithRetryAsync,
|
|
537
|
+
resolveGitWithRetrySync,
|
|
538
|
+
isInsideGitRepo,
|
|
336
539
|
getGitRoot,
|
|
540
|
+
getGitRootAsync,
|
|
337
541
|
getMainRepoRoot,
|
|
542
|
+
getMainRepoRootAsync,
|
|
338
543
|
worktreePath,
|
|
339
544
|
worktreeBranch,
|
|
340
545
|
parseInstanceLabel,
|
|
341
546
|
ensureWorktree,
|
|
547
|
+
ensureWorktreeAsync,
|
|
342
548
|
isWorktreeDirty,
|
|
549
|
+
isWorktreeDirtyAsync,
|
|
343
550
|
cleanupWorktree
|
|
344
551
|
};
|