@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,621 @@
|
|
|
1
|
+
// src/lib/git-main-guard.ts
|
|
2
|
+
import { execFileSync } from "child_process";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var MAIN_GUARD_OVERRIDE_TOKEN = "EXE_FORCE_ALLOW_MAIN_HISTORY_REWRITE=1";
|
|
5
|
+
var MAIN_GUARD_OVERRIDE_ENV = "EXE_FORCE_ALLOW_MAIN_HISTORY_REWRITE";
|
|
6
|
+
var GIT_TIMEOUT_MS = (() => {
|
|
7
|
+
const raw = process.env.EXE_GIT_GUARD_TIMEOUT_MS;
|
|
8
|
+
const n = raw ? Number.parseInt(raw, 10) : Number.NaN;
|
|
9
|
+
return Number.isFinite(n) && n > 0 ? n : 1e4;
|
|
10
|
+
})();
|
|
11
|
+
function runGit(cwd, args) {
|
|
12
|
+
try {
|
|
13
|
+
const out = execFileSync("git", args, {
|
|
14
|
+
cwd,
|
|
15
|
+
encoding: "utf8",
|
|
16
|
+
timeout: GIT_TIMEOUT_MS,
|
|
17
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
18
|
+
});
|
|
19
|
+
return { status: "ok", stdout: out.trim() };
|
|
20
|
+
} catch (err) {
|
|
21
|
+
const e = err;
|
|
22
|
+
return typeof e.status === "number" ? { status: "nonzero" } : { status: "unavailable" };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function gitOut(cwd, args) {
|
|
26
|
+
const r = runGit(cwd, args);
|
|
27
|
+
return r.status === "ok" ? r.stdout : null;
|
|
28
|
+
}
|
|
29
|
+
function tokenizeShell(command) {
|
|
30
|
+
const tokens = [];
|
|
31
|
+
let cur = "";
|
|
32
|
+
let curStarted = false;
|
|
33
|
+
let inSingle = false;
|
|
34
|
+
let inDouble = false;
|
|
35
|
+
let hasShellControl = false;
|
|
36
|
+
const push = () => {
|
|
37
|
+
if (curStarted) tokens.push(cur);
|
|
38
|
+
cur = "";
|
|
39
|
+
curStarted = false;
|
|
40
|
+
};
|
|
41
|
+
for (let i = 0; i < command.length; i++) {
|
|
42
|
+
const ch = command[i];
|
|
43
|
+
const next = command[i + 1];
|
|
44
|
+
if (inSingle) {
|
|
45
|
+
if (ch === "'") inSingle = false;
|
|
46
|
+
else {
|
|
47
|
+
cur += ch;
|
|
48
|
+
curStarted = true;
|
|
49
|
+
}
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (inDouble) {
|
|
53
|
+
if (ch === '"') inDouble = false;
|
|
54
|
+
else {
|
|
55
|
+
if (ch === "`" || ch === "$" && next === "(") hasShellControl = true;
|
|
56
|
+
cur += ch;
|
|
57
|
+
curStarted = true;
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
switch (ch) {
|
|
62
|
+
case "'":
|
|
63
|
+
inSingle = true;
|
|
64
|
+
curStarted = true;
|
|
65
|
+
continue;
|
|
66
|
+
case '"':
|
|
67
|
+
inDouble = true;
|
|
68
|
+
curStarted = true;
|
|
69
|
+
continue;
|
|
70
|
+
case " ":
|
|
71
|
+
case " ":
|
|
72
|
+
push();
|
|
73
|
+
continue;
|
|
74
|
+
case "\n":
|
|
75
|
+
case "\r":
|
|
76
|
+
hasShellControl = true;
|
|
77
|
+
push();
|
|
78
|
+
continue;
|
|
79
|
+
case "\\":
|
|
80
|
+
if (next !== void 0) {
|
|
81
|
+
cur += next;
|
|
82
|
+
curStarted = true;
|
|
83
|
+
i++;
|
|
84
|
+
}
|
|
85
|
+
continue;
|
|
86
|
+
case "&":
|
|
87
|
+
case "|":
|
|
88
|
+
case ";":
|
|
89
|
+
case "<":
|
|
90
|
+
case ">":
|
|
91
|
+
case "`":
|
|
92
|
+
hasShellControl = true;
|
|
93
|
+
push();
|
|
94
|
+
continue;
|
|
95
|
+
case "$":
|
|
96
|
+
if (next === "(" || next === "{") hasShellControl = true;
|
|
97
|
+
cur += ch;
|
|
98
|
+
curStarted = true;
|
|
99
|
+
continue;
|
|
100
|
+
case "(":
|
|
101
|
+
case ")":
|
|
102
|
+
hasShellControl = true;
|
|
103
|
+
push();
|
|
104
|
+
continue;
|
|
105
|
+
case "#":
|
|
106
|
+
if (!curStarted) {
|
|
107
|
+
hasShellControl = true;
|
|
108
|
+
i = command.length;
|
|
109
|
+
push();
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
cur += ch;
|
|
113
|
+
curStarted = true;
|
|
114
|
+
continue;
|
|
115
|
+
default:
|
|
116
|
+
cur += ch;
|
|
117
|
+
curStarted = true;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (inSingle || inDouble) hasShellControl = true;
|
|
122
|
+
push();
|
|
123
|
+
return { tokens, hasShellControl };
|
|
124
|
+
}
|
|
125
|
+
var SHELLS = /* @__PURE__ */ new Set(["sh", "bash", "zsh", "dash", "ksh"]);
|
|
126
|
+
function basename(tok) {
|
|
127
|
+
return tok.split("/").pop() ?? tok;
|
|
128
|
+
}
|
|
129
|
+
function isGitProgram(tok) {
|
|
130
|
+
return tok === "git" || /(?:^|\/)git$/.test(tok);
|
|
131
|
+
}
|
|
132
|
+
function isShellProgram(tok) {
|
|
133
|
+
return SHELLS.has(basename(tok));
|
|
134
|
+
}
|
|
135
|
+
function isDashC(tok) {
|
|
136
|
+
return /^-[a-z]*c[a-z]*$/i.test(tok) && tok.includes("c");
|
|
137
|
+
}
|
|
138
|
+
function isLeadingAssignment(tok) {
|
|
139
|
+
return /^[A-Za-z_][A-Za-z0-9_]*=/.test(tok);
|
|
140
|
+
}
|
|
141
|
+
var FORCE_PUSH_FLAGS = /* @__PURE__ */ new Set(["-f", "--force"]);
|
|
142
|
+
function isForcePushFlag(t) {
|
|
143
|
+
return FORCE_PUSH_FLAGS.has(t) || /^--force-with-lease(=.*)?$/.test(t) || t === "--force-if-includes";
|
|
144
|
+
}
|
|
145
|
+
function isDeleteFlag(t) {
|
|
146
|
+
return t === "--delete" || t === "-d";
|
|
147
|
+
}
|
|
148
|
+
function refShortName(ref) {
|
|
149
|
+
let r = ref.replace(/^\+/, "");
|
|
150
|
+
r = r.replace(/^refs\/heads\//, "").replace(/^heads\//, "");
|
|
151
|
+
return r;
|
|
152
|
+
}
|
|
153
|
+
function isMainName(name) {
|
|
154
|
+
return name === "main" || name === "master";
|
|
155
|
+
}
|
|
156
|
+
function destHeadShortName(dst) {
|
|
157
|
+
if (dst.startsWith("refs/remotes/")) return null;
|
|
158
|
+
if (dst.startsWith("refs/tags/")) return null;
|
|
159
|
+
if (dst.startsWith("refs/heads/")) return dst.slice("refs/heads/".length);
|
|
160
|
+
if (dst.startsWith("heads/")) return dst.slice("heads/".length);
|
|
161
|
+
if (dst.startsWith("refs/")) return null;
|
|
162
|
+
return dst;
|
|
163
|
+
}
|
|
164
|
+
function headTargetsMainOrGlob(head) {
|
|
165
|
+
return head.includes("*") || isMainName(head);
|
|
166
|
+
}
|
|
167
|
+
function refspecDestTargetsMainHead(spec) {
|
|
168
|
+
const bare = spec.replace(/^\+/, "");
|
|
169
|
+
const colon = bare.indexOf(":");
|
|
170
|
+
const dst = colon >= 0 ? bare.slice(colon + 1) : bare;
|
|
171
|
+
const head = destHeadShortName(dst);
|
|
172
|
+
return head !== null && headTargetsMainOrGlob(head);
|
|
173
|
+
}
|
|
174
|
+
function tokensFromVerb(tokens, verb) {
|
|
175
|
+
const i = tokens.indexOf(verb);
|
|
176
|
+
return i === -1 ? [] : tokens.slice(i);
|
|
177
|
+
}
|
|
178
|
+
function hasDestructiveVerbTokens(tokens) {
|
|
179
|
+
const has = (t) => tokens.includes(t);
|
|
180
|
+
if (has("reset") && (has("--hard") || has("--mixed"))) return true;
|
|
181
|
+
if (has("push") && (tokens.some((t) => isForcePushFlag(t) || isDeleteFlag(t)) || has("--mirror") || tokens.some((t) => /^\+/.test(t) || /^:/.test(t)))) return true;
|
|
182
|
+
if (has("fetch") && tokens.some((t) => t.includes(":"))) return true;
|
|
183
|
+
for (const verb of ["checkout", "switch"]) {
|
|
184
|
+
if (has(verb) && tokensFromVerb(tokens, verb).some((t) => /^-[BC]/.test(t) || /^--force-create(=|$)/.test(t))) return true;
|
|
185
|
+
}
|
|
186
|
+
if (has("branch") && tokensFromVerb(tokens, "branch").some(
|
|
187
|
+
(t) => t === "-f" || t === "--force" || t === "-D" || t === "-M" || t === "--move" || t === "--copy" || t === "--delete" || t === "-C" || t === "-m" || t === "-c" || t === "-d"
|
|
188
|
+
)) return true;
|
|
189
|
+
if (has("worktree") && has("add") && tokens.some((t) => /^-B/.test(t))) return true;
|
|
190
|
+
if (has("update-ref")) return true;
|
|
191
|
+
if (has("rebase")) return true;
|
|
192
|
+
if (has("filter-branch") || has("filter-repo")) return true;
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
function splitShellSegments(command) {
|
|
196
|
+
const segments = [];
|
|
197
|
+
let cur = "";
|
|
198
|
+
let inSingle = false;
|
|
199
|
+
let inDouble = false;
|
|
200
|
+
for (let i = 0; i < command.length; i++) {
|
|
201
|
+
const ch = command[i];
|
|
202
|
+
const next = command[i + 1];
|
|
203
|
+
if (inSingle) {
|
|
204
|
+
if (ch === "'") inSingle = false;
|
|
205
|
+
cur += ch;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (inDouble) {
|
|
209
|
+
if (ch === '"' && command[i - 1] !== "\\") inDouble = false;
|
|
210
|
+
cur += ch;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (ch === "'") {
|
|
214
|
+
inSingle = true;
|
|
215
|
+
cur += ch;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (ch === '"') {
|
|
219
|
+
inDouble = true;
|
|
220
|
+
cur += ch;
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (ch === ";" || ch === "\n" || ch === "\r" || ch === "|" || ch === "&") {
|
|
224
|
+
if ((ch === "|" || ch === "&") && next === ch) i++;
|
|
225
|
+
segments.push(cur);
|
|
226
|
+
cur = "";
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
cur += ch;
|
|
230
|
+
}
|
|
231
|
+
segments.push(cur);
|
|
232
|
+
return segments.filter((s) => s.trim().length > 0);
|
|
233
|
+
}
|
|
234
|
+
function containsDestructiveGitCandidate(command, depth = 0) {
|
|
235
|
+
if (depth > 3) return true;
|
|
236
|
+
const { tokens } = tokenizeShell(command);
|
|
237
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
238
|
+
if (isShellProgram(tokens[i]) && tokens[i + 1] && isDashC(tokens[i + 1])) {
|
|
239
|
+
const script = tokens[i + 2];
|
|
240
|
+
if (script && containsDestructiveGitCandidate(script, depth + 1)) return true;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (!tokens.some(isGitProgram)) return false;
|
|
244
|
+
const segments = splitShellSegments(command);
|
|
245
|
+
if (segments.length > 1) {
|
|
246
|
+
for (const seg of segments) {
|
|
247
|
+
const segTokens = tokenizeShell(seg).tokens;
|
|
248
|
+
if (!segTokens.some(isGitProgram)) continue;
|
|
249
|
+
if (segTokens.some((t) => /^alias\./.test(t))) return true;
|
|
250
|
+
if (hasDestructiveVerbTokens(segTokens)) return true;
|
|
251
|
+
}
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
if (tokens.some((t) => /^alias\./.test(t))) return true;
|
|
255
|
+
return hasDestructiveVerbTokens(tokens);
|
|
256
|
+
}
|
|
257
|
+
var PUSH_VALUE_OPTS = /* @__PURE__ */ new Set(["-o", "--push-option", "--repo", "--receive-pack", "--exec", "--recurse-submodules"]);
|
|
258
|
+
var REBASE_VALUE_OPTS = /* @__PURE__ */ new Set(["--onto", "-s", "--strategy", "-X", "--strategy-option", "--exec", "-x", "--whitespace"]);
|
|
259
|
+
function parseSingleGitCommand(tokens) {
|
|
260
|
+
if (tokens[0] !== "git") {
|
|
261
|
+
return { kind: "unparseable", reason: `command does not begin with a bare 'git' (saw "${tokens[0] ?? ""}")` };
|
|
262
|
+
}
|
|
263
|
+
let i = 1;
|
|
264
|
+
let contextDir = null;
|
|
265
|
+
let cCount = 0;
|
|
266
|
+
while (i < tokens.length) {
|
|
267
|
+
const t = tokens[i];
|
|
268
|
+
if (!t.startsWith("-")) break;
|
|
269
|
+
if (t === "-C") {
|
|
270
|
+
const p = tokens[i + 1];
|
|
271
|
+
if (p === void 0) return { kind: "unparseable", reason: "-C without a path" };
|
|
272
|
+
contextDir = p;
|
|
273
|
+
cCount++;
|
|
274
|
+
i += 2;
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
if (/^-C./.test(t)) {
|
|
278
|
+
contextDir = t.slice(2);
|
|
279
|
+
cCount++;
|
|
280
|
+
i++;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
return { kind: "unparseable", reason: `unsupported git global option "${t}" \u2014 target repo cannot be verified` };
|
|
284
|
+
}
|
|
285
|
+
if (cCount > 1) return { kind: "unparseable", reason: "multiple -C options \u2014 composed repo path cannot be verified" };
|
|
286
|
+
const sub = tokens[i];
|
|
287
|
+
if (sub === void 0) return { kind: "none", contextDir };
|
|
288
|
+
const args = tokens.slice(i + 1);
|
|
289
|
+
switch (sub) {
|
|
290
|
+
case "reset":
|
|
291
|
+
return args.includes("--hard") || args.includes("--mixed") ? { kind: "reset-hard", contextDir } : { kind: "none", contextDir };
|
|
292
|
+
case "checkout":
|
|
293
|
+
case "switch": {
|
|
294
|
+
for (let k = 0; k < args.length; k++) {
|
|
295
|
+
const a = args[k];
|
|
296
|
+
let target;
|
|
297
|
+
if (a === "-B" || a === "-C" || a === "--force-create") target = args[k + 1];
|
|
298
|
+
else if (/^-[BC]./.test(a)) target = a.slice(2);
|
|
299
|
+
else if (a.startsWith("--force-create=")) target = a.slice("--force-create=".length);
|
|
300
|
+
if (target !== void 0 && isMainName(refShortName(target))) {
|
|
301
|
+
return { kind: "move-main", verb: `${sub} ${a} main`, contextDir };
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return { kind: "none", contextDir };
|
|
305
|
+
}
|
|
306
|
+
case "branch": {
|
|
307
|
+
const has = (t) => args.includes(t);
|
|
308
|
+
const positionals = args.filter((a) => !a.startsWith("-"));
|
|
309
|
+
const force = has("-f") || has("--force");
|
|
310
|
+
const forceMove = has("-M") || (has("--move") || has("-m")) && force;
|
|
311
|
+
const forceCopy = has("-C") || (has("--copy") || has("-c")) && force;
|
|
312
|
+
const forceDelete = has("-D") || (has("--delete") || has("-d")) && force;
|
|
313
|
+
if (forceMove || forceCopy) {
|
|
314
|
+
const dest = positionals[positionals.length - 1];
|
|
315
|
+
if (dest && isMainName(refShortName(dest))) return { kind: "move-main", verb: "branch move/copy \u2192 main", contextDir };
|
|
316
|
+
}
|
|
317
|
+
if (forceDelete) {
|
|
318
|
+
if (positionals.some((p) => isMainName(refShortName(p)))) return { kind: "move-main", verb: "branch -D main", contextDir };
|
|
319
|
+
}
|
|
320
|
+
if (force && !forceMove && !forceCopy && !forceDelete) {
|
|
321
|
+
const target = positionals[0];
|
|
322
|
+
if (target && isMainName(refShortName(target))) return { kind: "move-main", verb: "branch -f main", contextDir };
|
|
323
|
+
}
|
|
324
|
+
return { kind: "none", contextDir };
|
|
325
|
+
}
|
|
326
|
+
case "update-ref": {
|
|
327
|
+
if (args.includes("--stdin")) {
|
|
328
|
+
return { kind: "unparseable", reason: "update-ref --stdin \u2014 ref targets are read from stdin and cannot be verified" };
|
|
329
|
+
}
|
|
330
|
+
const operands = [];
|
|
331
|
+
for (let k = 0; k < args.length; k++) {
|
|
332
|
+
const a = args[k];
|
|
333
|
+
if (a === "-m") {
|
|
334
|
+
k++;
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (a.startsWith("-")) continue;
|
|
338
|
+
operands.push(a);
|
|
339
|
+
}
|
|
340
|
+
const target = operands[0];
|
|
341
|
+
if (target && (target === "refs/heads/main" || target === "refs/heads/master")) {
|
|
342
|
+
return { kind: "move-main", verb: "update-ref refs/heads/main", contextDir };
|
|
343
|
+
}
|
|
344
|
+
return { kind: "none", contextDir };
|
|
345
|
+
}
|
|
346
|
+
case "worktree": {
|
|
347
|
+
if (args[0] === "add") {
|
|
348
|
+
for (let k = 1; k < args.length; k++) {
|
|
349
|
+
const a = args[k];
|
|
350
|
+
let target;
|
|
351
|
+
if (a === "-B") target = args[k + 1];
|
|
352
|
+
else if (/^-B./.test(a)) target = a.slice(2);
|
|
353
|
+
if (target !== void 0 && isMainName(refShortName(target))) {
|
|
354
|
+
return { kind: "move-main", verb: "worktree add -B main", contextDir };
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return { kind: "none", contextDir };
|
|
359
|
+
}
|
|
360
|
+
case "fetch": {
|
|
361
|
+
const refspecs = args.filter((a) => !a.startsWith("-") && a.includes(":"));
|
|
362
|
+
if (refspecs.some(refspecDestTargetsMainHead)) return { kind: "move-main", verb: "fetch <src>:<main-or-glob head>", contextDir };
|
|
363
|
+
return { kind: "none", contextDir };
|
|
364
|
+
}
|
|
365
|
+
case "filter-branch":
|
|
366
|
+
case "filter-repo":
|
|
367
|
+
return { kind: "move-main", verb: sub, contextDir };
|
|
368
|
+
case "rebase": {
|
|
369
|
+
if (args.includes("--abort") || args.includes("--quit")) return { kind: "none", contextDir };
|
|
370
|
+
const operands = [];
|
|
371
|
+
for (let k = 0; k < args.length; k++) {
|
|
372
|
+
const a = args[k];
|
|
373
|
+
if (a.startsWith("-")) {
|
|
374
|
+
if (REBASE_VALUE_OPTS.has(a)) k++;
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
operands.push(a);
|
|
378
|
+
}
|
|
379
|
+
if (operands.length >= 2) {
|
|
380
|
+
const branch = operands[operands.length - 1];
|
|
381
|
+
return isMainName(refShortName(branch)) ? { kind: "move-main", verb: "rebase \u2026 main", contextDir } : { kind: "none", contextDir };
|
|
382
|
+
}
|
|
383
|
+
return { kind: "reset-hard", contextDir };
|
|
384
|
+
}
|
|
385
|
+
case "push":
|
|
386
|
+
return parsePush(args, contextDir);
|
|
387
|
+
default:
|
|
388
|
+
return { kind: "none", contextDir };
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function parsePush(args, contextDir) {
|
|
392
|
+
let force = false;
|
|
393
|
+
let del = false;
|
|
394
|
+
let mirror = false;
|
|
395
|
+
const positionals = [];
|
|
396
|
+
for (let k = 0; k < args.length; k++) {
|
|
397
|
+
const a = args[k];
|
|
398
|
+
if (a.startsWith("-") && a !== "-") {
|
|
399
|
+
if (isForcePushFlag(a)) {
|
|
400
|
+
force = true;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
if (isDeleteFlag(a)) {
|
|
404
|
+
del = true;
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
if (a === "--mirror") {
|
|
408
|
+
mirror = true;
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
if (PUSH_VALUE_OPTS.has(a)) {
|
|
412
|
+
k++;
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
if (/^(-o|--push-option|--repo|--receive-pack|--exec|--recurse-submodules)=/.test(a)) continue;
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
positionals.push(a);
|
|
419
|
+
}
|
|
420
|
+
if (mirror) return { kind: "force-remote", verb: "push --mirror", contextDir };
|
|
421
|
+
const refspecs = positionals.length > 1 ? positionals.slice(1) : [];
|
|
422
|
+
let targetsMain = false;
|
|
423
|
+
let needsUpstream = false;
|
|
424
|
+
for (const spec of refspecs) {
|
|
425
|
+
if (/^\+/.test(spec)) force = true;
|
|
426
|
+
if (/^\+?:/.test(spec)) del = true;
|
|
427
|
+
const bare = spec.replace(/^\+/, "");
|
|
428
|
+
const colon = bare.indexOf(":");
|
|
429
|
+
const dst = colon >= 0 ? bare.slice(colon + 1) : bare;
|
|
430
|
+
if (dst === "HEAD") {
|
|
431
|
+
needsUpstream = true;
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (refspecDestTargetsMainHead(spec)) targetsMain = true;
|
|
435
|
+
}
|
|
436
|
+
if (refspecs.length === 0) needsUpstream = true;
|
|
437
|
+
const destructive = force || del;
|
|
438
|
+
return { kind: "push", destructive, targetsMain, needsUpstream, contextDir };
|
|
439
|
+
}
|
|
440
|
+
function resolveRepoStateOnce(cwd) {
|
|
441
|
+
const root = runGit(cwd, ["rev-parse", "--show-toplevel"]);
|
|
442
|
+
if (root.status === "unavailable") return { ok: false, reason: "unverifiable" };
|
|
443
|
+
if (root.status === "nonzero") return { ok: false, reason: "not-a-repo" };
|
|
444
|
+
const repoRoot = root.stdout;
|
|
445
|
+
const head = runGit(repoRoot, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
446
|
+
if (head.status === "unavailable") return { ok: false, reason: "unverifiable" };
|
|
447
|
+
const currentBranch = head.status === "ok" && head.stdout !== "HEAD" ? head.stdout : null;
|
|
448
|
+
const mainRef = runGit(repoRoot, ["show-ref", "--verify", "--quiet", "refs/heads/main"]);
|
|
449
|
+
if (mainRef.status === "unavailable") return { ok: false, reason: "unverifiable" };
|
|
450
|
+
let mainBranch = mainRef.status === "ok" ? "main" : null;
|
|
451
|
+
if (!mainBranch) {
|
|
452
|
+
const masterRef = runGit(repoRoot, ["show-ref", "--verify", "--quiet", "refs/heads/master"]);
|
|
453
|
+
if (masterRef.status === "unavailable") return { ok: false, reason: "unverifiable" };
|
|
454
|
+
mainBranch = masterRef.status === "ok" ? "master" : null;
|
|
455
|
+
}
|
|
456
|
+
if (!mainBranch) return { ok: true, currentBranch, mainBranch: null, mainAhead: 0, aheadCommits: [] };
|
|
457
|
+
const originRef = runGit(repoRoot, ["show-ref", "--verify", "--quiet", `refs/remotes/origin/${mainBranch}`]);
|
|
458
|
+
if (originRef.status === "unavailable") return { ok: false, reason: "unverifiable" };
|
|
459
|
+
if (originRef.status === "nonzero") return { ok: true, currentBranch, mainBranch, mainAhead: 0, aheadCommits: [] };
|
|
460
|
+
const aheadRes = runGit(repoRoot, ["rev-list", "--count", `origin/${mainBranch}..${mainBranch}`]);
|
|
461
|
+
if (aheadRes.status !== "ok") return { ok: false, reason: "unverifiable" };
|
|
462
|
+
const ahead = Number.parseInt(aheadRes.stdout, 10);
|
|
463
|
+
if (!Number.isFinite(ahead)) return { ok: false, reason: "unverifiable" };
|
|
464
|
+
let aheadCommits = [];
|
|
465
|
+
if (ahead > 0) {
|
|
466
|
+
const log = runGit(repoRoot, ["log", "--oneline", "--decorate=short", "-5", `origin/${mainBranch}..${mainBranch}`]);
|
|
467
|
+
aheadCommits = log.status === "ok" ? log.stdout.split("\n").filter(Boolean) : [];
|
|
468
|
+
}
|
|
469
|
+
return { ok: true, currentBranch, mainBranch, mainAhead: ahead, aheadCommits };
|
|
470
|
+
}
|
|
471
|
+
function resolveRepoState(cwd) {
|
|
472
|
+
const first = resolveRepoStateOnce(cwd);
|
|
473
|
+
if (first.ok || first.reason !== "unverifiable") return first;
|
|
474
|
+
return resolveRepoStateOnce(cwd);
|
|
475
|
+
}
|
|
476
|
+
function resolvePushTargetOnce(cwd) {
|
|
477
|
+
for (const rev of ["@{push}", "@{upstream}"]) {
|
|
478
|
+
const r = runGit(cwd, ["rev-parse", "--abbrev-ref", "--symbolic-full-name", rev]);
|
|
479
|
+
if (r.status === "unavailable") return { status: "unavailable" };
|
|
480
|
+
if (r.status === "ok" && r.stdout) {
|
|
481
|
+
const seg = r.stdout.split("/").pop();
|
|
482
|
+
if (seg) return { status: "resolved", branch: seg };
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return { status: "none" };
|
|
486
|
+
}
|
|
487
|
+
function resolvePushTargetBranch(cwd) {
|
|
488
|
+
const first = resolvePushTargetOnce(cwd);
|
|
489
|
+
if (first.status !== "unavailable") return first;
|
|
490
|
+
return resolvePushTargetOnce(cwd);
|
|
491
|
+
}
|
|
492
|
+
function getLocalMainAheadInfo(cwd = process.cwd()) {
|
|
493
|
+
const state = resolveRepoState(cwd);
|
|
494
|
+
if (!state.ok || !state.mainBranch || state.mainAhead <= 0) return null;
|
|
495
|
+
const repoRoot = gitOut(cwd, ["rev-parse", "--show-toplevel"]) ?? cwd;
|
|
496
|
+
return { repoRoot, branch: state.mainBranch, ahead: state.mainAhead, commits: state.aheadCommits };
|
|
497
|
+
}
|
|
498
|
+
function getCurrentBranch(cwd) {
|
|
499
|
+
const state = resolveRepoState(cwd);
|
|
500
|
+
return state.ok ? state.currentBranch : null;
|
|
501
|
+
}
|
|
502
|
+
function hasEmergencyOverride(command, env = process.env) {
|
|
503
|
+
if (env[MAIN_GUARD_OVERRIDE_ENV] === "1") return true;
|
|
504
|
+
return new RegExp(String.raw`^\s*${MAIN_GUARD_OVERRIDE_ENV}=1\s+git\b`).test(command);
|
|
505
|
+
}
|
|
506
|
+
function normalizeCleanGit(tokens) {
|
|
507
|
+
const first = tokens[0];
|
|
508
|
+
if (first === void 0) return { ok: false, reason: "empty command" };
|
|
509
|
+
if (isLeadingAssignment(first)) return { ok: false, reason: "leading environment assignment before git" };
|
|
510
|
+
if (isShellProgram(first)) return { ok: false, reason: `command runs a shell ("${first}") whose script cannot be verified` };
|
|
511
|
+
if (!isGitProgram(first)) return { ok: false, reason: `git is wrapped or embedded (program is "${first}", not a bare 'git')` };
|
|
512
|
+
return { ok: true, tokens: ["git", ...tokens.slice(1)] };
|
|
513
|
+
}
|
|
514
|
+
function evaluateMainGuard(command, opts = {}) {
|
|
515
|
+
const env = opts.env ?? process.env;
|
|
516
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
517
|
+
if (hasEmergencyOverride(command, env)) return { block: false, overridden: true };
|
|
518
|
+
if (!containsDestructiveGitCandidate(command)) return { block: false };
|
|
519
|
+
const { tokens, hasShellControl } = tokenizeShell(command);
|
|
520
|
+
if (hasShellControl) {
|
|
521
|
+
return { block: true, message: formatUnverifiableBlockMessage("the command is compound or uses shell control operators (&&, ||, ;, |, newline, backtick, $(), redirection, or a comment)") };
|
|
522
|
+
}
|
|
523
|
+
const clean = normalizeCleanGit(tokens);
|
|
524
|
+
if (!clean.ok) {
|
|
525
|
+
return { block: true, message: formatUnverifiableBlockMessage(clean.reason) };
|
|
526
|
+
}
|
|
527
|
+
const parsed = parseSingleGitCommand(clean.tokens);
|
|
528
|
+
if (parsed.kind === "unparseable") return { block: true, message: formatUnverifiableBlockMessage(parsed.reason) };
|
|
529
|
+
if (parsed.kind === "none") return { block: false };
|
|
530
|
+
const resolveState = opts.stateResolver ?? resolveRepoState;
|
|
531
|
+
const resolvePush = opts.pushTargetResolver ?? resolvePushTargetBranch;
|
|
532
|
+
const ctxDir = parsed.contextDir !== null ? path.resolve(cwd, parsed.contextDir) : cwd;
|
|
533
|
+
if (parsed.kind === "force-remote") {
|
|
534
|
+
return { block: true, message: formatForcePushBlockMessage(parsed.verb) };
|
|
535
|
+
}
|
|
536
|
+
if (parsed.kind === "reset-hard") {
|
|
537
|
+
const state = resolveState(ctxDir);
|
|
538
|
+
if (!state.ok) {
|
|
539
|
+
return state.reason === "not-a-repo" ? { block: false } : { block: true, message: formatStateUnverifiableBlockMessage(ctxDir) };
|
|
540
|
+
}
|
|
541
|
+
if (state.currentBranch === null) return { block: false };
|
|
542
|
+
if (state.currentBranch !== state.mainBranch) return { block: false };
|
|
543
|
+
if (!state.mainBranch || state.mainAhead <= 0) return { block: false };
|
|
544
|
+
return { block: true, message: formatMainAheadBlockMessage({ repoRoot: ctxDir, branch: state.mainBranch, ahead: state.mainAhead, commits: state.aheadCommits }, "rewrite of main (reset/rebase)") };
|
|
545
|
+
}
|
|
546
|
+
if (parsed.kind === "move-main") {
|
|
547
|
+
const state = resolveState(ctxDir);
|
|
548
|
+
if (!state.ok) {
|
|
549
|
+
return state.reason === "not-a-repo" ? { block: false } : { block: true, message: formatStateUnverifiableBlockMessage(ctxDir) };
|
|
550
|
+
}
|
|
551
|
+
if (!state.mainBranch) return { block: false };
|
|
552
|
+
if (state.mainAhead <= 0) return { block: false };
|
|
553
|
+
return { block: true, message: formatMainAheadBlockMessage({ repoRoot: ctxDir, branch: state.mainBranch, ahead: state.mainAhead, commits: state.aheadCommits }, parsed.verb) };
|
|
554
|
+
}
|
|
555
|
+
if (!parsed.destructive) return { block: false };
|
|
556
|
+
let targetsMain = parsed.targetsMain;
|
|
557
|
+
if (!targetsMain && parsed.needsUpstream) {
|
|
558
|
+
const state = resolveState(ctxDir);
|
|
559
|
+
if (!state.ok) {
|
|
560
|
+
return state.reason === "not-a-repo" ? { block: false } : { block: true, message: formatStateUnverifiableBlockMessage(ctxDir) };
|
|
561
|
+
}
|
|
562
|
+
const pt = resolvePush(ctxDir);
|
|
563
|
+
if (pt.status === "unavailable") return { block: true, message: formatStateUnverifiableBlockMessage(ctxDir) };
|
|
564
|
+
const targetBranch = pt.status === "resolved" ? pt.branch : state.currentBranch;
|
|
565
|
+
if (targetBranch && isMainName(targetBranch)) targetsMain = true;
|
|
566
|
+
}
|
|
567
|
+
if (!targetsMain) return { block: false };
|
|
568
|
+
return { block: true, message: formatForcePushBlockMessage("force/delete push to main") };
|
|
569
|
+
}
|
|
570
|
+
var OVERRIDE_LINE = `OVERRIDE (genuine emergency, loud + auditable): run it as a SINGLE, non-compound git invocation prefixed with the env assignment ${MAIN_GUARD_OVERRIDE_TOKEN}`;
|
|
571
|
+
function formatMainAheadBlockMessage(info, verb) {
|
|
572
|
+
const commitList = info.commits.length > 0 ? info.commits.map((c) => ` \u2022 ${c}`).join("\n") : " \u2022 (commit list unavailable)";
|
|
573
|
+
return `\u{1F6AB} BLOCKED: ${verb ? `\`${verb}\` ` : "this destructive git operation "}would rewrite local ${info.branch}, but ${info.branch} has ${info.ahead} unpushed commit${info.ahead === 1 ? "" : "s"} ahead of origin/${info.branch} that would be orphaned:
|
|
574
|
+
${commitList}
|
|
575
|
+
WHY: those commits exist only here \u2014 rewriting ${info.branch} discards them (bug 47986655).
|
|
576
|
+
SAFE ALTERNATIVES:
|
|
577
|
+
\u2022 Preserve first: git branch backup-${info.branch} ${info.branch}
|
|
578
|
+
\u2022 Or push them: git push origin ${info.branch}
|
|
579
|
+
\u2022 Resetting a NON-${info.branch} branch onto its own ancestor is allowed \u2014 check that branch out first (git checkout -B <branch> <sha>); this guard only fires when ${info.branch} itself moves.
|
|
580
|
+
${OVERRIDE_LINE}`;
|
|
581
|
+
}
|
|
582
|
+
function formatForcePushBlockMessage(verb = "force/delete push to main") {
|
|
583
|
+
return `\u{1F6AB} BLOCKED: ${verb} would overwrite SHARED history on origin \u2014 it can silently discard commits other people (and other agents) pushed.
|
|
584
|
+
WHY: --force / --force-with-lease / --mirror / +refspec / --delete rewrites the remote branch everyone builds on (bug 6aaea78f).
|
|
585
|
+
SAFE ALTERNATIVES:
|
|
586
|
+
\u2022 Push your work on a feature branch and open a PR instead of force-pushing main.
|
|
587
|
+
\u2022 If you must correct main, do it with a forward commit (git revert), not a force-push.
|
|
588
|
+
\u2022 Force-pushing a FEATURE branch is allowed; only main/master is guarded.
|
|
589
|
+
${OVERRIDE_LINE}`;
|
|
590
|
+
}
|
|
591
|
+
function formatUnverifiableBlockMessage(reason) {
|
|
592
|
+
return `\u{1F6AB} BLOCKED: this git command could rewrite main/master and the guard CANNOT verify its target \u2014 ${reason}.
|
|
593
|
+
WHY: exe-os fails CLOSED here \u2014 a compound/wrapped command can move HEAD before a check runs, so an unverifiable destructive-git command is denied rather than parsed permissively (bug 6aaea78f).
|
|
594
|
+
SAFE ALTERNATIVE: run the git command as a SINGLE, non-compound invocation with a bare 'git' program (no sh -c, no wrapper, no path), no shell operators, no comment, at most one -C, and no --git-dir/--work-tree. Then the guard can verify whether it touches main and allow it if it does not.
|
|
595
|
+
${OVERRIDE_LINE}`;
|
|
596
|
+
}
|
|
597
|
+
function formatStateUnverifiableBlockMessage(dir) {
|
|
598
|
+
return `\u23F3 BLOCKED (could not verify): the guard could not read the repo state in "${dir}" within ${GIT_TIMEOUT_MS}ms \u2014 most likely git was slow to spawn under machine load. This does NOT mean the command is dangerous; the guard just could not confirm it is safe.
|
|
599
|
+
WHAT TO DO: simply RE-RUN the command (the guard already retried once internally) \u2014 this usually clears immediately. If it persists, the repo may be in an unusual state or on a stalled filesystem.
|
|
600
|
+
${OVERRIDE_LINE}`;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
export {
|
|
604
|
+
MAIN_GUARD_OVERRIDE_TOKEN,
|
|
605
|
+
MAIN_GUARD_OVERRIDE_ENV,
|
|
606
|
+
tokenizeShell,
|
|
607
|
+
isGitProgram,
|
|
608
|
+
splitShellSegments,
|
|
609
|
+
containsDestructiveGitCandidate,
|
|
610
|
+
parseSingleGitCommand,
|
|
611
|
+
resolveRepoState,
|
|
612
|
+
resolvePushTargetBranch,
|
|
613
|
+
getLocalMainAheadInfo,
|
|
614
|
+
getCurrentBranch,
|
|
615
|
+
hasEmergencyOverride,
|
|
616
|
+
evaluateMainGuard,
|
|
617
|
+
formatMainAheadBlockMessage,
|
|
618
|
+
formatForcePushBlockMessage,
|
|
619
|
+
formatUnverifiableBlockMessage,
|
|
620
|
+
formatStateUnverifiableBlockMessage
|
|
621
|
+
};
|