@askexenow/exe-os 0.9.372 → 0.9.374
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deploy/compose/.env.customer.example +45 -10
- package/deploy/compose/.env.example +46 -9
- package/deploy/compose/docker-compose.yml +136 -18
- package/deploy/compose/generate-env.ts +142 -34
- package/deploy/compose/sso-edge/default.conf.template +78 -7
- package/deploy/compose/sso-edge/sso-redirect.conf +109 -13
- package/deploy/stack-manifests/v0.9.30-apps.json +1 -1
- package/deploy/stack-manifests/v0.9.json +4 -4
- package/dist/.dist-verified.json +3 -3
- package/dist/{active-agent-GRT5MKD5.js → active-agent-ONPPEWQV.js} +7 -6
- package/dist/{active-agent-L2ZSSXDK.js → active-agent-UJKMG7LJ.js} +7 -6
- package/dist/{agent-defs-generator-M4ZNYIVX.js → agent-defs-generator-ZWI6DXOE.js} +6 -5
- package/dist/{agent-loop-FOK2IRZQ.js → agent-loop-OYHJKNYH.js} +1 -1
- package/dist/{agentic-ontology-DMPRDEUX.js → agentic-ontology-WHFJ3QFS.js} +1 -1
- package/dist/{artifact-backup-767STHSW.js → artifact-backup-WXZNB7KE.js} +2 -1
- package/dist/{backfill-gate-VX2RZTQV.js → backfill-gate-KWJQ35YX.js} +3 -2
- package/dist/{backfill-metadata-ZMEHJQ5M.js → backfill-metadata-3OUSQD5V.js} +8 -7
- package/dist/{background-jobs-LTPWCMA3.js → background-jobs-6VMD55PK.js} +3 -2
- package/dist/{backup-verify-EX2K732J.js → backup-verify-ZKTUYLTA.js} +4 -3
- package/dist/{behavior-injection-22AGMS25.js → behavior-injection-M6UYZCMW.js} +17 -15
- package/dist/{behaviors-DVFXAWF5.js → behaviors-ZJ45TFBJ.js} +21 -13
- package/dist/bin/age-ontology-load.js +3 -2
- package/dist/bin/agentic-ontology-backfill.js +10 -9
- package/dist/bin/agentic-reflection-backfill.js +11 -10
- package/dist/bin/agentic-semantic-label.js +10 -9
- package/dist/bin/backfill-conversations.js +13 -11
- package/dist/bin/backfill-responses.js +13 -11
- package/dist/bin/backfill-vectors.js +17 -15
- package/dist/bin/bulk-sync-postgres.js +22 -20
- package/dist/bin/cc-doctor.js +10 -9
- package/dist/bin/cleanup-stale-review-tasks.js +29 -26
- package/dist/bin/cli.js +36 -26
- package/dist/bin/deferred-daemon-restart.js +114 -110
- package/dist/bin/exe-agent-config.js +6 -5
- package/dist/bin/exe-agent.js +127 -33
- package/dist/bin/exe-assign.js +15 -13
- package/dist/bin/exe-boot.js +57 -54
- package/dist/bin/exe-call.js +8 -7
- package/dist/bin/exe-cloud.js +24 -22
- package/dist/bin/exe-config-dump.js +6 -5
- package/dist/bin/exe-dispatch.js +30 -27
- package/dist/bin/exe-doctor.js +14 -10
- package/dist/bin/exe-export-behaviors.js +19 -17
- package/dist/bin/exe-forget.js +10 -9
- package/dist/bin/exe-gateway.js +199 -19
- package/dist/bin/exe-grant.js +5 -5
- package/dist/bin/exe-healthcheck.js +10 -9
- package/dist/bin/exe-heartbeat.js +35 -32
- package/dist/bin/exe-kill.js +34 -31
- package/dist/bin/exe-launch-agent.js +126 -54
- package/dist/bin/exe-mcp.js +6 -5
- package/dist/bin/exe-memory-reads.js +8 -7
- package/dist/bin/exe-new-employee.js +12 -11
- package/dist/bin/exe-os-mcp-proxy.js +6 -5
- package/dist/bin/exe-pending-messages.js +30 -27
- package/dist/bin/exe-pending-notifications.js +29 -26
- package/dist/bin/exe-pending-reviews.js +30 -27
- package/dist/bin/exe-rename.js +8 -7
- package/dist/bin/exe-repo-truth.js +1 -1
- package/dist/bin/exe-review.js +33 -30
- package/dist/bin/exe-search.js +9 -8
- package/dist/bin/exe-session-cleanup.js +35 -32
- package/dist/bin/exe-settings.js +24 -22
- package/dist/bin/exe-start-codex.js +137 -55
- package/dist/bin/exe-start-opencode.js +121 -23
- package/dist/bin/exe-status.js +31 -28
- package/dist/bin/exe-support.js +5 -4
- package/dist/bin/exe-team.js +7 -6
- package/dist/bin/exe-watchdog.js +31 -11
- package/dist/bin/generate-hook-manifest.js +44 -7
- package/dist/bin/git-sweep.js +31 -28
- package/dist/bin/graph-backfill.js +89 -35
- package/dist/bin/graph-export.js +9 -8
- package/dist/bin/import-history.js +14 -13
- package/dist/bin/install.js +137 -113
- package/dist/bin/intercom-check.js +5 -5
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +7 -6
- package/dist/bin/postgres-agentic-reflection-backfill.js +5 -4
- package/dist/bin/postgres-agentic-semantic-backfill.js +4 -3
- package/dist/bin/pre-publish.js +1 -1
- package/dist/bin/reconcile-backlog.js +2 -2
- package/dist/bin/registry-proxy.js +1 -1
- package/dist/bin/scan-tasks.js +29 -26
- package/dist/bin/setup.js +5 -4
- package/dist/bin/shard-migrate.js +9 -8
- package/dist/bin/stack-update.js +40 -9
- package/dist/bin/verify-stack.js +2 -2
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/{boot-generation-OHXH4YC5.js → boot-generation-JKVZ4ZAT.js} +6 -5
- package/dist/{boot-review-sections-N5IXIGSS.js → boot-review-sections-2M6BTG73.js} +28 -25
- package/dist/{branch-hygiene-KCGXRAWP.js → branch-hygiene-U5GFRSTP.js} +31 -7
- package/dist/{branding-GH43W3PU.js → branding-I6KIMB7F.js} +3 -2
- package/dist/budget-fallback-XJRPMP2D.js +11 -0
- package/dist/build-manifest.json +1318 -1233
- package/dist/{capability-cards-4PXVLIVS.js → capability-cards-5IMJT6J7.js} +5 -4
- package/dist/{capacity-monitor-FKMQXORX.js → capacity-monitor-SAXCQK7O.js} +30 -27
- package/dist/{catchup-brief-SN5EKO4N.js → catchup-brief-U2TXBLHD.js} +34 -31
- package/dist/{chunk-CNC57JCS.js → chunk-23MVDXLY.js} +4 -4
- package/dist/{chunk-V4XAKXXF.js → chunk-2AJGV5UL.js} +1 -1
- package/dist/{chunk-FBYAXTDM.js → chunk-2ZOEC4KC.js} +10 -2
- package/dist/{chunk-ELXFSIIM.js → chunk-32YV32VA.js} +2 -2
- package/dist/{chunk-44C7QNZS.js → chunk-3KDCORDO.js} +1 -1
- package/dist/{chunk-JTB5V6BV.js → chunk-3SXHEQ7X.js} +1 -1
- package/dist/{chunk-HDW4XPDV.js → chunk-3UUX5OY4.js} +1 -1
- package/dist/{chunk-7PSLK36P.js → chunk-44TLJZJ5.js} +1 -1
- package/dist/{chunk-JTWTBX2M.js → chunk-4EN3IZ3Q.js} +2 -1
- package/dist/{chunk-KPMC7PY7.js → chunk-4HKTO2SV.js} +1 -1
- package/dist/{chunk-CDUB5Q6J.js → chunk-4IK2K3B3.js} +1 -1
- package/dist/{chunk-GH6YJOOC.js → chunk-4SJ4LK4V.js} +6 -6
- package/dist/{chunk-PVEM537A.js → chunk-4YLBKEL5.js} +2 -2
- package/dist/chunk-4YNA3CM6.js +872 -0
- package/dist/{chunk-KYFFVTGO.js → chunk-55BEFF4V.js} +3 -3
- package/dist/{chunk-SEP5ITFQ.js → chunk-636LKCKE.js} +2 -2
- package/dist/{chunk-QTI4QAWA.js → chunk-6EZQUNE6.js} +338 -5
- package/dist/{chunk-WAEKYKTK.js → chunk-6RKKVPYF.js} +1 -1
- package/dist/{chunk-VX2F4ZUY.js → chunk-6SCGLHJ7.js} +3 -3
- package/dist/{chunk-MEGRQ53A.js → chunk-6VHOQ3IM.js} +51 -6
- package/dist/{chunk-HIIXCAEE.js → chunk-6YVUR3OU.js} +3 -3
- package/dist/{chunk-L6ZNURWN.js → chunk-7GE2EQ23.js} +1 -1
- package/dist/{chunk-2CWS374F.js → chunk-7RI2CNXJ.js} +1 -1
- package/dist/{chunk-OL3QP3AU.js → chunk-7TSBV3SD.js} +1 -1
- package/dist/{chunk-DSOQUQTV.js → chunk-A27Q27CT.js} +27 -0
- package/dist/{chunk-5AHRZI3R.js → chunk-AETLDRZB.js} +1 -1
- package/dist/{chunk-RNLF3CBB.js → chunk-AKLJ4JH3.js} +1 -1
- package/dist/{chunk-XHYHX6F7.js → chunk-AKLQSC6W.js} +329 -164
- package/dist/chunk-ANLFH23R.js +261 -0
- package/dist/{chunk-QLA3RTH4.js → chunk-AWWKRZMB.js} +5 -5
- package/dist/{chunk-ERVQTR7P.js → chunk-BBSIEYF5.js} +17 -3
- package/dist/{chunk-IPMUWYRQ.js → chunk-BJ7AVSY6.js} +2 -2
- package/dist/{chunk-HV6Y6F4X.js → chunk-C2L622QJ.js} +89 -3
- package/dist/{chunk-TX3Q2GIL.js → chunk-C5HUMAA7.js} +24 -1
- package/dist/{chunk-QTYJPWJN.js → chunk-CBCGDEJA.js} +7 -7
- package/dist/{chunk-XXSNLM6R.js → chunk-DB55JZHU.js} +1 -1
- package/dist/{chunk-LAZKEJMS.js → chunk-DIXXEE3S.js} +840 -607
- package/dist/{chunk-FB343XQX.js → chunk-DJ7YXOTU.js} +2 -2
- package/dist/{chunk-YFCNWQAM.js → chunk-DJOIMFKV.js} +2 -2
- package/dist/{chunk-UTDMTQNH.js → chunk-DSJI76XL.js} +92 -14
- package/dist/{chunk-EEXX4UMQ.js → chunk-DZKPOSFD.js} +1 -1
- package/dist/{chunk-WSOA3WMC.js → chunk-E426DOSY.js} +161 -4
- package/dist/{chunk-ZISQOOER.js → chunk-EKE37MO4.js} +3 -3
- package/dist/{chunk-RIECV7SR.js → chunk-EKYYMIVT.js} +1 -1
- package/dist/{chunk-HIVZ53YB.js → chunk-EXTZSNWL.js} +2 -2
- package/dist/{chunk-YYA5LXCT.js → chunk-FNEZ4BWT.js} +1 -1
- package/dist/chunk-FTZET5YX.js +313 -0
- package/dist/chunk-GHR4ZPJ7.js +70 -0
- package/dist/{chunk-MINXPXAB.js → chunk-GJI77VDO.js} +3 -3
- package/dist/{chunk-AAMGHW5W.js → chunk-GLQEJOXE.js} +1 -0
- package/dist/{chunk-ADNBOKYZ.js → chunk-GM7TLYOK.js} +60 -18
- package/dist/{chunk-RUWWES2K.js → chunk-GNUAL43X.js} +2 -2
- package/dist/{chunk-QZL6E4UB.js → chunk-GOMQ7PVQ.js} +2 -2
- package/dist/{chunk-GB3AHV5F.js → chunk-GQOEWNVM.js} +1 -1
- package/dist/{chunk-NQZUSEAR.js → chunk-GS7LIT34.js} +246 -17
- package/dist/{chunk-XTWHNLGD.js → chunk-GZOG2MAX.js} +1 -1
- package/dist/{chunk-E5HAY3DQ.js → chunk-HDLAB7W3.js} +1 -1
- package/dist/{chunk-E5QQZDQN.js → chunk-HNWS7YHN.js} +358 -136
- package/dist/{chunk-VV5EZZNT.js → chunk-HTBEVCO2.js} +1 -1
- package/dist/{chunk-OZBII5E3.js → chunk-I4DNJFDR.js} +4 -4
- package/dist/{chunk-SI5SZAJA.js → chunk-IBS2FAI4.js} +21 -4
- package/dist/{chunk-J5EYOBFF.js → chunk-IHXW4VUI.js} +1 -1
- package/dist/{chunk-RUVO3NJC.js → chunk-IN6CAM4F.js} +9 -3
- package/dist/{chunk-53PYNYTW.js → chunk-IRVOXUSK.js} +5 -5
- package/dist/{chunk-THM7J6UI.js → chunk-JHI5WMK5.js} +5 -5
- package/dist/{chunk-3KTQWMHI.js → chunk-JSMDRKPJ.js} +12 -4
- package/dist/chunk-JTVIANUB.js +131 -0
- package/dist/{chunk-2ADYTOHQ.js → chunk-K4ESASPL.js} +1 -1
- package/dist/{chunk-YWUQVHDL.js → chunk-KTCXJWJG.js} +1 -1
- package/dist/{chunk-RGUDGC6A.js → chunk-KTU3EAWK.js} +5 -5
- package/dist/{chunk-DKBPCOU4.js → chunk-L6RXG36J.js} +2 -2
- package/dist/{chunk-T4EK56WI.js → chunk-LDNYSMPZ.js} +1 -1
- package/dist/{chunk-RIK5GRWI.js → chunk-LGS2V2XD.js} +3 -3
- package/dist/{chunk-JKXZGRWR.js → chunk-LP4GB656.js} +2 -2
- package/dist/{chunk-H74466TM.js → chunk-M7O7TGGU.js} +1 -1
- package/dist/chunk-MJCSEIFI.js +54 -0
- package/dist/{chunk-IDZPQG2D.js → chunk-MOGA4Q7F.js} +2 -2
- package/dist/{chunk-OYQNNKNS.js → chunk-MXPNVSXI.js} +37 -14
- package/dist/{chunk-UVW7YFAF.js → chunk-N7VEP5B3.js} +4 -4
- package/dist/{chunk-HHE2HV3V.js → chunk-NBXDXKLC.js} +1 -1
- package/dist/{chunk-LDL3S7AC.js → chunk-NKETJCB5.js} +7 -3
- package/dist/{chunk-ECHLVLA7.js → chunk-NMH5ZQPU.js} +1 -1
- package/dist/{chunk-U3XLRMJD.js → chunk-NT7W4RXD.js} +1 -1
- package/dist/{chunk-UQUUNGTP.js → chunk-NUK7EEN5.js} +11 -9
- package/dist/{chunk-GBNB4EWD.js → chunk-ORM7ZFKC.js} +16 -0
- package/dist/{chunk-O4ZFRK6W.js → chunk-OVEQE6YS.js} +244 -49
- package/dist/{chunk-4ZJ5BPY6.js → chunk-PB5S7YOF.js} +2 -2
- package/dist/{chunk-JR23BL74.js → chunk-PDVXWXTL.js} +4 -4
- package/dist/{chunk-3CIMDFXG.js → chunk-PFQ3VEEM.js} +1 -1
- package/dist/{chunk-SBJV2PCU.js → chunk-PHBU4LGO.js} +1 -1
- package/dist/{chunk-W25RLOQ2.js → chunk-PLZSZOZN.js} +3 -3
- package/dist/{chunk-THIJIOE2.js → chunk-PY3FOMRN.js} +18 -6
- package/dist/{chunk-AAUWFXOX.js → chunk-Q3AXXKDF.js} +3 -3
- package/dist/{chunk-VKXS2YGN.js → chunk-QHJR7IMX.js} +2 -2
- package/dist/chunk-QLZ46RCK.js +45 -0
- package/dist/{chunk-UHPMK6QZ.js → chunk-R3CZWFFC.js} +10 -2
- package/dist/{chunk-6XEYELCA.js → chunk-R4CBHKZ2.js} +1 -1
- package/dist/{chunk-5APCDDJZ.js → chunk-R522MWAR.js} +9 -9
- package/dist/chunk-RH4AH3YB.js +80 -0
- package/dist/{chunk-AMKSDKMK.js → chunk-S2WBS6BG.js} +22 -35
- package/dist/{chunk-WUKQVNLP.js → chunk-SEQIPGLU.js} +1 -1
- package/dist/{chunk-7WQRFSZI.js → chunk-SL6KQYDU.js} +26 -6
- package/dist/chunk-SLLLOOEI.js +103 -0
- package/dist/{chunk-5N4SG5NB.js → chunk-T35RCQFE.js} +3 -3
- package/dist/{chunk-7V6M3QUS.js → chunk-T3QUKNLI.js} +1 -1
- package/dist/{chunk-CW2UCKHS.js → chunk-TADAO3HV.js} +2 -2
- package/dist/{chunk-5DCCKHDY.js → chunk-TAMDAOCU.js} +109 -13
- package/dist/{chunk-ZXB56YR2.js → chunk-TFKCERAK.js} +101 -23
- package/dist/{chunk-RBYHJDAT.js → chunk-TQAZTRQ3.js} +3 -3
- package/dist/{chunk-OKGIOWOB.js → chunk-U6SUKSZR.js} +2 -2
- package/dist/{chunk-23QKEUF6.js → chunk-U73AC5AN.js} +34 -12
- package/dist/{chunk-PM6WSWVU.js → chunk-UBK7HK3J.js} +3 -3
- package/dist/{chunk-H37FSTF2.js → chunk-UBMZ3YQU.js} +1 -1
- package/dist/{chunk-JJUGI2YL.js → chunk-UCFC2AEI.js} +1 -1
- package/dist/{chunk-6IWLAQ7O.js → chunk-UCUOGVDX.js} +4 -0
- package/dist/{chunk-E7UCDSUE.js → chunk-UKLN57Q5.js} +2 -2
- package/dist/{chunk-ZYCLSEZT.js → chunk-ULIBLJ6W.js} +33 -11
- package/dist/{chunk-RLR6VVKV.js → chunk-UM3N6VND.js} +4 -4
- package/dist/{chunk-ZNUJFX7L.js → chunk-UQGSBM3U.js} +1 -1
- package/dist/{chunk-ZZXMB5F2.js → chunk-UZDF6FLJ.js} +1 -1
- package/dist/{chunk-LNOS24GV.js → chunk-V3WLC5TJ.js} +2 -95
- package/dist/{chunk-UXLO7VHX.js → chunk-VI4ATC6I.js} +1 -1
- package/dist/{chunk-77JP3LK4.js → chunk-VKJGHAZT.js} +92 -21
- package/dist/{chunk-7R73IAHU.js → chunk-VMTZ4RUW.js} +67 -150
- package/dist/{chunk-TGPQMMQP.js → chunk-VYQ7B7DI.js} +30 -17
- package/dist/{chunk-E2WEFZOR.js → chunk-W75GTHR3.js} +1 -1
- package/dist/{chunk-UKLF7F3Z.js → chunk-WJG344NC.js} +9 -9
- package/dist/{chunk-MBNIJXKI.js → chunk-WMEYJT4R.js} +18 -4
- package/dist/{chunk-R6FLELV6.js → chunk-XFTEX77S.js} +3 -3
- package/dist/{chunk-MDGYXUOV.js → chunk-XH7YL7JM.js} +1 -1
- package/dist/{chunk-JOO35RHR.js → chunk-XL5MFGMR.js} +3 -3
- package/dist/{chunk-OW5RZIDW.js → chunk-XNNECNDL.js} +95 -33
- package/dist/{chunk-5AHDQCTB.js → chunk-XXFKSJYA.js} +6 -6
- package/dist/{chunk-TGEPLJ66.js → chunk-XXOPG4BW.js} +3 -3
- package/dist/{chunk-PGLPUP37.js → chunk-XZ65ST2I.js} +1 -1
- package/dist/{chunk-3TTKAT6V.js → chunk-YKC7QDZH.js} +9 -4
- package/dist/{chunk-KXYFBBZR.js → chunk-YMP2QSOP.js} +20 -3
- package/dist/{chunk-TK4MI6F6.js → chunk-YSLGFPWX.js} +6 -6
- package/dist/{chunk-X2P43TB2.js → chunk-YTSXPJUQ.js} +1 -1
- package/dist/{chunk-HECXZGGZ.js → chunk-ZCERWHY2.js} +33 -35
- package/dist/{chunk-IVU3WN7S.js → chunk-ZG62LIK3.js} +74 -4
- package/dist/{chunk-GU62SNDH.js → chunk-ZGYNKA3O.js} +744 -111
- package/dist/{chunk-QMSEL5YS.js → chunk-ZIG7VPJV.js} +28 -76
- package/dist/{chunk-WZJVGA5I.js → chunk-ZL4AGWAH.js} +258 -13
- package/dist/{chunk-QR624DER.js → chunk-ZSODLMFV.js} +2 -2
- package/dist/{cleanup-graph-garbage-IPYDS5OX.js → cleanup-graph-garbage-DPJGO52H.js} +11 -10
- package/dist/{cloud-sync-command-JLNVG7H4.js → cloud-sync-command-JPNTT4OQ.js} +2 -2
- package/dist/{cloud-sync-db-init-JXUF6GI3.js → cloud-sync-db-init-V2LWIUQU.js} +1 -1
- package/dist/{cloud-sync-shutdown-Z4SBP6PL.js → cloud-sync-shutdown-BNALPWGX.js} +5 -4
- package/dist/{co-activation-74RDFTKS.js → co-activation-CMNSWS6B.js} +5 -4
- package/dist/{co-occurrence-CN3TBYVR.js → co-occurrence-WRI2NAN6.js} +9 -8
- package/dist/{code-context-index-D4MJ4VFX.js → code-context-index-NOJSHLPN.js} +12 -6
- package/dist/code-context-watcher-VZNZU3BO.js +118 -0
- package/dist/{codex-consolidation-PPXNBXCV.js → codex-consolidation-SH4UKFBQ.js} +2 -1
- package/dist/{conversation-entity-extractor-QGTLH4BP.js → conversation-entity-extractor-74252CAO.js} +4 -4
- package/dist/{conversation-wiki-populator-EBUZXYEU.js → conversation-wiki-populator-OS4C6W54.js} +1 -1
- package/dist/conversations-retention-C4BLKFEL.js +54 -0
- package/dist/coordinator-notice-MHUY7AQB.js +55 -0
- package/dist/{crdt-sync-7T4WCOKD.js → crdt-sync-B3JN6AIV.js} +1 -1
- package/dist/{crm-webhook-FTW3XZTO.js → crm-webhook-GYWQRFET.js} +2 -2
- package/dist/{cto-delegation-gate-SZCE34LB.js → cto-delegation-gate-LQHVLEMW.js} +29 -26
- package/dist/{daemon-auth-SSPY5ODS.js → daemon-auth-QZHEO7IQ.js} +3 -2
- package/dist/{daemon-orchestration-IGPHVNFR.js → daemon-orchestration-5HIQALZH.js} +36 -34
- package/dist/{daemon-ready-OT2VQLS7.js → daemon-ready-P2BR2XP5.js} +1 -1
- package/dist/{db-integrity-events-5DTASXJF.js → db-integrity-events-2DTFO37N.js} +3 -2
- package/dist/{db-restore-events-2FI4ZMKA.js → db-restore-events-G6NOQOVE.js} +2 -1
- package/dist/{destructive-data-guard-6I5MDFVD.js → destructive-data-guard-BVFWPPIS.js} +1 -1
- package/dist/doc-graph-extractor-PQHDHQPQ.js +367 -0
- package/dist/{documents-URULIXGM.js → documents-C4SSPJMC.js} +15 -13
- package/dist/{dreaming-VIZO3QDO.js → dreaming-XAO3FCBV.js} +33 -30
- package/dist/{employee-boot-brief-XLOG4ULP.js → employee-boot-brief-W4OHUMRQ.js} +37 -34
- package/dist/{exe-drift-TLQM3IHD.js → exe-drift-AG2KMKD5.js} +6 -5
- package/dist/{exe-export-7YWYWJHY.js → exe-export-IC5BT335.js} +17 -15
- package/dist/{exe-import-DW6VAUKW.js → exe-import-A35ZLDPG.js} +17 -15
- package/dist/{exe-key-TLJP2B4Y.js → exe-key-TCMJNYLA.js} +116 -112
- package/dist/{exe-org-LU46N36E.js → exe-org-JXCR3JYZ.js} +24 -23
- package/dist/{exe-snapshot-QHUZRS62.js → exe-snapshot-SV6SRIG6.js} +36 -33
- package/dist/{fast-db-init-SCTOOIUT.js → fast-db-init-L2RGKJWH.js} +1 -1
- package/dist/{founder-context-ZFZC4UHO.js → founder-context-D4HFIESJ.js} +4 -3
- package/dist/{founder-monitor-envelope-5KTKNL5G.js → founder-monitor-envelope-TFKRGCFE.js} +5 -4
- package/dist/{fts-integrity-LKAZEZJE.js → fts-integrity-4YB34KWX.js} +3 -2
- package/dist/gateway/index.js +19 -17
- package/dist/{git-main-guard-TN27QBAI.js → git-main-guard-VTW4N3CM.js} +7 -1
- package/dist/{git-staleness-GSGP344N.js → git-staleness-TN7CYGFG.js} +5 -4
- package/dist/{global-procedures-YAR7G4C6.js → global-procedures-YFDEIOG7.js} +7 -6
- package/dist/{graph-auto-extract-GNQS64F5.js → graph-auto-extract-3YR3TYRW.js} +9 -8
- package/dist/{graph-rag-RMSFLUOB.js → graph-rag-Z2KCJTPK.js} +6 -4
- package/dist/{hook-integrity-CF567MVN.js → hook-integrity-KGAV6ZC2.js} +14 -4
- package/dist/{hook-prefetch-36BK4F7U.js → hook-prefetch-K5DN3TOQ.js} +29 -26
- package/dist/hooks/bug-report-worker.js +34 -30
- package/dist/hooks/codex-stop-task-finalizer.js +36 -32
- package/dist/hooks/commit-complete.js +33 -30
- package/dist/hooks/error-recall.js +12 -11
- package/dist/hooks/exe-heartbeat-hook.js +8 -7
- package/dist/hooks/ingest-worker.js +23 -11
- package/dist/hooks/ingest.js +18 -17
- package/dist/hooks/instructions-loaded.js +10 -9
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +9 -8
- package/dist/hooks/post-compact.js +8 -7
- package/dist/hooks/post-tool-combined.js +26 -15
- package/dist/hooks/pre-compact.js +33 -30
- package/dist/hooks/pre-tool-use.js +404 -46
- package/dist/hooks/prompt-submit.js +57 -47
- package/dist/hooks/session-end.js +40 -41
- package/dist/hooks/session-start.js +21 -20
- package/dist/hooks/stop.js +40 -37
- package/dist/hooks/subagent-stop.js +38 -35
- package/dist/hooks/summary-worker.js +39 -36
- package/dist/hyde-MP4QNMU5.js +80 -0
- package/dist/index.js +44 -39
- package/dist/{installer-LUN4HQIC.js → installer-54HTN5RE.js} +8 -7
- package/dist/{installer-OC5VXNC7.js → installer-LK35OX6R.js} +8 -7
- package/dist/{installer-MPRFUQJE.js → installer-LLWKZI2S.js} +8 -7
- package/dist/intercom-ack-VCW755TN.js +13 -0
- package/dist/{intercom-queue-6DZ7BANV.js → intercom-queue-5NOT2RKI.js} +28 -25
- package/dist/{key-backup-status-6L2ARCXW.js → key-backup-status-LQPINQ3W.js} +2 -1
- package/dist/lib/agent-config.js +3 -2
- package/dist/lib/cloud-sync.js +26 -20
- package/dist/lib/config.js +2 -1
- package/dist/lib/consolidation.js +17 -10
- package/dist/lib/database.js +7 -4
- package/dist/lib/db-backup.js +17 -2
- package/dist/lib/db-daemon-client.js +8 -6
- package/dist/lib/db-write-worker-client.js +3 -1
- package/dist/lib/db-write-worker.js +20 -3
- package/dist/lib/db.js +7 -4
- package/dist/lib/device-registry.js +3 -2
- package/dist/lib/embed-worker.js +2 -1
- package/dist/lib/embedder.js +8 -6
- package/dist/lib/employee-templates.js +8 -7
- package/dist/lib/employees.js +5 -4
- package/dist/lib/exe-daemon-client.js +7 -5
- package/dist/lib/exe-daemon.js +467 -221
- package/dist/lib/hybrid-search.js +11 -8
- package/dist/lib/identity.js +5 -4
- package/dist/lib/license.js +4 -3
- package/dist/lib/messaging.js +29 -26
- package/dist/lib/post-tool-memory.js +16 -2
- package/dist/lib/registry-proxy.js +3 -1
- package/dist/lib/reminders.js +6 -5
- package/dist/lib/schedules.js +9 -8
- package/dist/lib/session-registry.js +7 -6
- package/dist/lib/skill-learning.js +16 -14
- package/dist/lib/stack-invariants.js +17 -1
- package/dist/lib/status-brief.js +5 -4
- package/dist/lib/store.js +10 -7
- package/dist/lib/task-router.js +6 -5
- package/dist/lib/tasks.js +31 -27
- package/dist/lib/tmux-routing.js +40 -25
- package/dist/lib/tmux-status.js +3 -1
- package/dist/lib/tmux-transport.js +2 -1
- package/dist/lib/token-spend.js +6 -5
- package/dist/lib/transport.js +3 -2
- package/dist/{license-gate-ESER24PJ.js → license-gate-JVMB6OFD.js} +5 -4
- package/dist/{license-sync-JVG5KNIY.js → license-sync-5VYS2F2W.js} +4 -3
- package/dist/mcp/register-tools.js +113 -109
- package/dist/mcp/server.js +118 -114
- package/dist/mcp/tools/complete-reminder.js +7 -6
- package/dist/mcp/tools/create-reminder.js +7 -6
- package/dist/mcp/tools/create-task.js +34 -30
- package/dist/mcp/tools/deactivate-behavior.js +18 -16
- package/dist/mcp/tools/list-reminders.js +7 -6
- package/dist/mcp/tools/list-tasks.js +34 -30
- package/dist/mcp/tools/send-message.js +32 -29
- package/dist/mcp/tools/update-task.js +32 -28
- package/dist/mcp-child-registry-OTG4MWO7.js +25 -0
- package/dist/{mcp-http-config-6K6IKH5F.js → mcp-http-config-DQWL7U2Z.js} +6 -5
- package/dist/{mcp-session-identity-LRC6WJSD.js → mcp-session-identity-277GASTQ.js} +28 -25
- package/dist/{memory-cards-V3OZHIYP.js → memory-cards-3S2ZQPR7.js} +17 -8
- package/dist/{memory-graph-extractor-JC2Z64L4.js → memory-graph-extractor-A6DFEFIN.js} +10 -9
- package/dist/{memory-poisoning-defense-YM4QJHCX.js → memory-poisoning-defense-ZVP4H6DY.js} +5 -4
- package/dist/{memory-pressure-watchdog-6F6KEQHN.js → memory-pressure-watchdog-6W5F6R7H.js} +29 -26
- package/dist/{memory-queue-QJNWKWKG.js → memory-queue-YF7IDSFY.js} +3 -2
- package/dist/{memory-queue-client-COA4ABEV.js → memory-queue-client-ADSDP6OX.js} +9 -7
- package/dist/{memory-reflection-QXHJPYPC.js → memory-reflection-BKB2YOE6.js} +52 -6
- package/dist/{monitor-grants-BW2WL4IU.js → monitor-grants-EV747HMW.js} +4 -3
- package/dist/{notification-ledger-6QRLQW4Q.js → notification-ledger-CLGM7ODF.js} +30 -27
- package/dist/{notifications-7B6D7Y5C.js → notifications-MACUZPYP.js} +28 -25
- package/dist/{oauth-server-TZFNQAFS.js → oauth-server-AYM37SQ4.js} +25 -4
- package/dist/{orchestration-events-GY5VP5LU.js → orchestration-events-N7LYMUGA.js} +6 -5
- package/dist/{orchestration-phase-UDS24CVQ.js → orchestration-phase-T2WD45UA.js} +3 -2
- package/dist/{orchestrator-JVPVOYWA.js → orchestrator-4X24EWHV.js} +30 -27
- package/dist/{org-brief-session-GRV5R5E3.js → org-brief-session-FZOFMO5U.js} +13 -12
- package/dist/{org-consent-policy-3FHHSYXV.js → org-consent-policy-O5E6HXBL.js} +1 -1
- package/dist/{org-join-BY4PV6UO.js → org-join-POWUG25F.js} +8 -7
- package/dist/{org-key-admin-WSCPT2CZ.js → org-key-admin-E7EMDOZZ.js} +9 -8
- package/dist/{org-key-pin-5WUSPGVN.js → org-key-pin-WHWHVWUO.js} +4 -3
- package/dist/{org-membership-ESALTLLN.js → org-membership-WRT2IHJK.js} +5 -4
- package/dist/{org-partner-config-YKHPDPZR.js → org-partner-config-B7T4CL2T.js} +7 -6
- package/dist/{org-partner-runtime-UJDGECZ4.js → org-partner-runtime-FODONVTM.js} +13 -12
- package/dist/{org-row-visibility-V5DXIHTE.js → org-row-visibility-VX4AVV5Q.js} +1 -1
- package/dist/{pipeline-router-YY5FQKTY.js → pipeline-router-6GGT2ZW3.js} +6 -5
- package/dist/{plan-limits-OVX6SN6B.js → plan-limits-FUN76LYY.js} +8 -7
- package/dist/{platform-procedures-I57ITMDC.js → platform-procedures-7YSCLF4Z.js} +1 -1
- package/dist/{postinstall-failure-B2JHNFPM.js → postinstall-failure-O6TSSNJB.js} +3 -2
- package/dist/{project-boot-LXLU2J32.js → project-boot-3Q65LCIP.js} +2 -1
- package/dist/project-name-LJVFMYTQ.js +30 -0
- package/dist/{projection-worker-D2472IOD.js → projection-worker-4OANGP5K.js} +5 -4
- package/dist/{prospective-memory-JXO2A6PL.js → prospective-memory-KR3P4T6N.js} +5 -4
- package/dist/{push-notifications-HR3FZRDI.js → push-notifications-NCZLH6DI.js} +29 -26
- package/dist/ref-provenance-gate-M4AQO4OT.js +269 -0
- package/dist/{reproject-worktree-memories-OSS3PGRF.js → reproject-worktree-memories-PWYKPB2U.js} +106 -23
- package/dist/{reranker-IMZRPYJ2.js → reranker-6V3C2AO4.js} +3 -2
- package/dist/resolve-image-labels-ZI6UBW5W.js +15 -0
- package/dist/{retrieval-health-W7OD44FE.js → retrieval-health-5D7O6VH6.js} +4 -3
- package/dist/{review-polling-2INP7H6M.js → review-polling-QW3LJ4KN.js} +29 -26
- package/dist/runtime/index.js +38 -34
- package/dist/{session-events-G4XUPVWV.js → session-events-T45SSTMF.js} +31 -26
- package/dist/{session-kill-telemetry-W7MHWJTQ.js → session-kill-telemetry-QSPVJGBF.js} +29 -26
- package/dist/{session-mcp-config-F7KATWOF.js → session-mcp-config-SC5BLWZG.js} +3 -2
- package/dist/{session-scope-LG2J4EMQ.js → session-scope-KRWE54C4.js} +28 -25
- package/dist/{setup-wizard-YQJI3SVM.js → setup-wizard-GP3TBTPF.js} +5 -4
- package/dist/{shard-manager-UROHZE46.js → shard-manager-OE36A4MY.js} +3 -2
- package/dist/{skill-refinement-RA37U756.js → skill-refinement-C7JTMLJG.js} +6 -5
- package/dist/stack-generate-manifest-MFMDWRUP.js +810 -0
- package/dist/{stack-promote-IYBRXHTA.js → stack-promote-EKSCYY63.js} +8 -6
- package/dist/{stack-release-OXWLVVG6.js → stack-release-2GZAAFO4.js} +8 -6
- package/dist/{stack-update-2CZEROPK.js → stack-update-J6JXSTAZ.js} +51 -5
- package/dist/{steward-gate-LTNFB3FY.js → steward-gate-BFCCMCSW.js} +6 -5
- package/dist/{subagent-brief-injection-OHLWLECQ.js → subagent-brief-injection-ED36PLYY.js} +44 -36
- package/dist/{subagent-spawn-ledger-USYZXU3M.js → subagent-spawn-ledger-E6U3OY6Z.js} +3 -2
- package/dist/{supervisor-handoff-CSJQMI53.js → supervisor-handoff-SGLEPOCY.js} +12 -3
- package/dist/{support-inbox-4KCEPAZQ.js → support-inbox-YW47SYJF.js} +20 -5
- package/dist/{task-enforcement-LGXWXGVZ.js → task-enforcement-CECTQX4U.js} +29 -26
- package/dist/{task-request-inbox-WHCOSUCP.js → task-request-inbox-Q5T4N5K7.js} +1 -1
- package/dist/{task-scope-KXF7Y6KA.js → task-scope-ERVEUEYU.js} +28 -25
- package/dist/{tasks-crud-5EM55WRZ.js → tasks-crud-ZRQNJXQ2.js} +28 -25
- package/dist/{tasks-notify-VFMAURTN.js → tasks-notify-MIZH4C2O.js} +29 -26
- package/dist/{tasks-review-MHGMBHUZ.js → tasks-review-Z7J2P6DG.js} +28 -25
- package/dist/{telemetry-upload-6NRTN7QJ.js → telemetry-upload-LVQUQYFP.js} +10 -9
- package/dist/{token-budget-LZPOYTRP.js → token-budget-BU4NOVZF.js} +6 -5
- package/dist/{tool-capability-index-ED5OAPMW.js → tool-capability-index-7F42MOJT.js} +1 -1
- package/dist/{tool-gates-7PLIOLAL.js → tool-gates-JWVSAYTW.js} +1 -1
- package/dist/{tool-gates-2OZY3GZM.js → tool-gates-VXITVRFQ.js} +1 -1
- package/dist/{tool-telemetry-ZX7VSAXK.js → tool-telemetry-O27EVMBR.js} +1 -1
- package/dist/tui/App.js +43 -40
- package/dist/{tui-data-CC5POSUV.js → tui-data-TPWWBIUQ.js} +28 -25
- package/dist/{update-support-KH6NSQON.js → update-support-F2F5537B.js} +22 -20
- package/dist/{whatsapp-QW3X7OCN.js → whatsapp-YM4A2CSK.js} +3 -1
- package/dist/{work-claims-MNK7PEPW.js → work-claims-B73X5NE7.js} +6 -5
- package/dist/{work-state-heartbeat-YEWT5NMZ.js → work-state-heartbeat-P4YX6E2R.js} +1 -1
- package/dist/{worker-gate-BOQSIU2Z.js → worker-gate-BEEIIVWA.js} +3 -2
- package/dist/{workflow-engine-MUUD7ZEX.js → workflow-engine-5X46PFCW.js} +4 -2
- package/dist/{worktree-GOGT2LZP.js → worktree-W47CIMJ6.js} +9 -6
- package/dist/worktree-ownership-guard-OUWJROW2.js +88 -0
- package/dist/{worktree-sweep-46VWPVQT.js → worktree-sweep-BNBD4RFX.js} +8 -7
- package/package.json +14 -5
- package/release-notes.json +5 -5
- package/src/commands/exe/call.md +1 -1
- package/stack.release.json +6 -0
- package/dist/chunk-KZXMP6JG.js +0 -319
- package/dist/chunk-TCTED52S.js +0 -120
- package/dist/chunk-W2IRQJ6R.js +0 -67
- package/dist/doc-graph-extractor-VPTRIEKN.js +0 -149
- package/dist/project-name-ILJTETUE.js +0 -14
- /package/dist/{chunk-3Y5THOU6.js → chunk-6WIFPD2P.js} +0 -0
- /package/dist/{chunk-7XGXRD22.js → chunk-AISULNGL.js} +0 -0
- /package/dist/{chunk-3F2UB4IQ.js → chunk-DN4YVV4Z.js} +0 -0
- /package/dist/{chunk-WV3TOOL7.js → chunk-KQ6RJWRW.js} +0 -0
- /package/dist/{chunk-HR2R2QER.js → chunk-M4IRPXSZ.js} +0 -0
- /package/dist/{chunk-ORA5BWCV.js → chunk-NRG7KZIP.js} +0 -0
- /package/dist/{chunk-7UTJA6HF.js → chunk-VZAFWPAY.js} +0 -0
- /package/dist/{chunk-VJSDGDNS.js → chunk-WSQASFLP.js} +0 -0
- /package/dist/{chunk-FZQWVQJG.js → chunk-YO4BO2CL.js} +0 -0
- /package/dist/{core-memory-6WBNT2HL.js → core-memory-7I7RE2SJ.js} +0 -0
- /package/dist/{entity-boost-MT336PI3.js → entity-boost-3UWGXG5O.js} +0 -0
- /package/dist/{memory-isolation-EJ45IXBH.js → memory-isolation-2TUZ7Z4K.js} +0 -0
- /package/dist/{message-queue-client-MVBTYCSV.js → message-queue-client-XQN7QABL.js} +0 -0
- /package/dist/{webhook-pipe-UQSEHFPO.js → webhook-pipe-W2FVXY7M.js} +0 -0
- /package/dist/{wiki-acl-WXRJGZ5Q.js → wiki-acl-IBQLLBTS.js} +0 -0
- /package/dist/{wiki-client-AXNM5FWY.js → wiki-client-W65IOSWF.js} +0 -0
|
@@ -1,40 +1,89 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// IMAGE PINS — DERIVED FROM THE SIGNED MANIFEST. NEVER HAND-TYPED.
|
|
5
|
+
//
|
|
6
|
+
// .env used to be an INDEPENDENT source of pins: a block of hand-edited
|
|
7
|
+
// `*_RELEASE_TAG` constants that had to be "kept in sync" with
|
|
8
|
+
// deploy/stack-manifests/v0.9.json. It was not kept in sync. On 2026-08-20 the
|
|
9
|
+
// manifest, /opt/exe-stack/.env and the compose fallback defaults disagreed on
|
|
10
|
+
// 5 of 7 apps in production.
|
|
11
|
+
//
|
|
12
|
+
// One direction only: each repo cuts a release -> the manifest is generated
|
|
13
|
+
// from those releases -> .env is DERIVED from the manifest -> the VPS pulls what
|
|
14
|
+
// .env says. The version AND digest of every pin below now come from the
|
|
15
|
+
// manifest and nowhere else, so drift is unrepresentable rather than merely
|
|
16
|
+
// discouraged.
|
|
17
|
+
//
|
|
18
|
+
// The registry HOST is deployment topology, not a pin: .env.example targets
|
|
19
|
+
// GHCR so local simulation runs without private update.askexe.com credentials,
|
|
20
|
+
// while the same tag@digest is served by the pull-through proxy. Re-hosting
|
|
21
|
+
// preserves the digest, so the artifact is identical either way.
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
2
23
|
const REGISTRY = "ghcr.io/askexe";
|
|
3
24
|
// exe-auth (the shared SSO sign-in/sign-up SPA) ships only from the private
|
|
4
25
|
// update.askexe.com registry — it is not mirrored to GHCR — so it carries its
|
|
5
26
|
// own registry constant rather than reusing REGISTRY (bug 58840873).
|
|
6
27
|
const AUTH_REGISTRY = "update.askexe.com/askexe";
|
|
7
28
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
const MANIFEST_PATH = new URL("../stack-manifests/v0.9.json", import.meta.url);
|
|
30
|
+
|
|
31
|
+
type ManifestFile = {
|
|
32
|
+
latest: string;
|
|
33
|
+
stacks: Record<string, { services?: Record<string, { image?: string }> }>;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function loadManifestServices(): Record<string, { image?: string }> {
|
|
37
|
+
const manifest = JSON.parse(readFileSync(MANIFEST_PATH, "utf8")) as ManifestFile;
|
|
38
|
+
const services = manifest.stacks?.[manifest.latest]?.services;
|
|
39
|
+
if (!services) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`generate-env: stack manifest ${MANIFEST_PATH.pathname} has no services for latest="${manifest.latest}". ` +
|
|
42
|
+
`Refusing to generate a .env with no pins — that is exactly the silent-substitution failure ` +
|
|
43
|
+
`the manifest-as-single-source-of-truth change exists to prevent.`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return services;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const MANIFEST_SERVICES = loadManifestServices();
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The manifest's pin for a service, re-hosted onto `registry`. FAILS LOUDLY
|
|
53
|
+
* when the manifest does not govern the service, or governs it without a
|
|
54
|
+
* digest: a missing pin must abort generation, never fall back to a literal.
|
|
55
|
+
*/
|
|
56
|
+
function pin(serviceKey: string, registry: string, imageName: string): string {
|
|
57
|
+
const image = MANIFEST_SERVICES[serviceKey]?.image;
|
|
58
|
+
if (!image) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`generate-env: the stack manifest does not pin "${serviceKey}". Every service .env pins must be ` +
|
|
61
|
+
`manifest-governed — add it to the manifest (exe-os stack-generate-manifest) rather than ` +
|
|
62
|
+
`hard-coding a version here.`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
const at = image.indexOf("@");
|
|
66
|
+
if (at === -1) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
`generate-env: the manifest pin for "${serviceKey}" (${image}) carries no @sha256 digest. ` +
|
|
69
|
+
`Tags move, digests do not — refusing to emit an unpinned .env value.`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const digest = image.slice(at + 1);
|
|
73
|
+
const beforeDigest = image.slice(0, at);
|
|
74
|
+
const colon = beforeDigest.lastIndexOf(":");
|
|
75
|
+
const slash = beforeDigest.lastIndexOf("/");
|
|
76
|
+
const tag = colon > slash ? beforeDigest.slice(colon + 1) : "";
|
|
77
|
+
return tag ? `${registry}/${imageName}:${tag}@${digest}` : `${registry}/${imageName}@${digest}`;
|
|
78
|
+
}
|
|
30
79
|
|
|
31
80
|
const POSTGRES_USER = "exe";
|
|
32
81
|
const POSTGRES_DB = "exedb";
|
|
33
82
|
const CLICKHOUSE_DB = "default";
|
|
34
83
|
const CLICKHOUSE_USER = "exe";
|
|
35
|
-
export const CRM_IMAGE_TAG =
|
|
84
|
+
export const CRM_IMAGE_TAG = pin("crm", REGISTRY, "exe-crm");
|
|
36
85
|
const CRM_HOST_PORT = "3000";
|
|
37
|
-
export const WIKI_IMAGE_TAG =
|
|
86
|
+
export const WIKI_IMAGE_TAG = pin("wiki", REGISTRY, "exe-wiki");
|
|
38
87
|
// Bug 2a8d3003: the wiki's data lives in `public` and generated .env files must say
|
|
39
88
|
// so. This constant used to be "wiki", which meant every freshly generated stack
|
|
40
89
|
// pinned the wiki to an empty schema — Prisma bootstraps it silently rather than
|
|
@@ -42,13 +91,22 @@ export const WIKI_IMAGE_TAG = `${REGISTRY}/exe-wiki:${WIKI_RELEASE_TAG}`;
|
|
|
42
91
|
const WIKI_DB_SCHEMA = "public";
|
|
43
92
|
const WIKI_VECTOR_DB = "exeOsMcp";
|
|
44
93
|
const WIKI_HOST_PORT = "3001";
|
|
45
|
-
export const EXE_OS_IMAGE_TAG =
|
|
46
|
-
export const GATEWAY_IMAGE_TAG =
|
|
47
|
-
export const MONITOR_AGENT_IMAGE_TAG =
|
|
48
|
-
export const MONITOR_HUB_IMAGE_TAG =
|
|
49
|
-
export const ERP_IMAGE_TAG =
|
|
50
|
-
|
|
51
|
-
|
|
94
|
+
export const EXE_OS_IMAGE_TAG = pin("exe-os", REGISTRY, "exe-os");
|
|
95
|
+
export const GATEWAY_IMAGE_TAG = pin("gateway", REGISTRY, "exe-gateway");
|
|
96
|
+
export const MONITOR_AGENT_IMAGE_TAG = pin("monitorAgent", REGISTRY, "exe-monitor-agent");
|
|
97
|
+
export const MONITOR_HUB_IMAGE_TAG = pin("monitorHub", REGISTRY, "exe-monitor-hub");
|
|
98
|
+
export const ERP_IMAGE_TAG = pin("erp", REGISTRY, "exe-erp");
|
|
99
|
+
// exe-build is control-plane only (not part of the customer stack), so the
|
|
100
|
+
// manifest does not govern it and there is nothing to derive. It is emitted
|
|
101
|
+
// as an opt-in for askexe-control-plane hosts.
|
|
102
|
+
export const EXE_BUILD_IMAGE_TAG = `${REGISTRY}/exe-build:v0.1.0`;
|
|
103
|
+
export const AUTH_IMAGE_TAG = pin("auth", AUTH_REGISTRY, "exe-auth");
|
|
104
|
+
// Infra pins. Compose no longer carries fallback defaults for these either, so
|
|
105
|
+
// the generated .env must state them — derived from the manifest like the rest.
|
|
106
|
+
// Third-party artifacts are served from the same pull-through proxy the manifest
|
|
107
|
+
// names, so they are NOT re-hosted onto GHCR.
|
|
108
|
+
export const EXE_DB_IMAGE = pin("exe-db", "update.askexe.com/askexe", "pgvector");
|
|
109
|
+
export const OTEL_COLLECTOR_IMAGE = pin("exe-otel-collector", "update.askexe.com/askexe", "otel-collector-contrib");
|
|
52
110
|
const GATEWAY_HTTP_HOST_PORT = "3100";
|
|
53
111
|
const GATEWAY_WS_HOST_PORT = "3101";
|
|
54
112
|
const RANDOM_SECRET_16 = 16;
|
|
@@ -172,8 +230,8 @@ export function generateEnv(options: GenerateEnvOptions): string {
|
|
|
172
230
|
"# http://gotrue:9999 and can reject browser tokens as iss-mismatch.",
|
|
173
231
|
`GOTRUE_JWT_ISSUER=https://auth.${normalizedDomain}`,
|
|
174
232
|
"# SSO redirect allow-list (bug 66f8e10a): app origins the gateway may bounce",
|
|
175
|
-
"# users back to via ?redirect=. Required for unified SSO across crm/wiki/erp.",
|
|
176
|
-
`GOTRUE_URI_ALLOW_LIST=https://crm.${normalizedDomain},https://wiki.${normalizedDomain},https://erp.${normalizedDomain}`,
|
|
233
|
+
"# users back to via ?redirect=. Required for unified SSO across crm/wiki/erp/dashboard/gateway (bug 2d2de534).",
|
|
234
|
+
`GOTRUE_URI_ALLOW_LIST=https://crm.${normalizedDomain},https://wiki.${normalizedDomain},https://erp.${normalizedDomain},https://dashboard.${normalizedDomain},https://gateway.${normalizedDomain}`,
|
|
177
235
|
"# Bug 0327b017: scope the session cookie to the PARENT apex domain so it is",
|
|
178
236
|
"# shared across crm/wiki/erp/auth subdomains → true SSO (no re-login).",
|
|
179
237
|
`GOTRUE_COOKIE_DOMAIN=.${normalizedDomain}`,
|
|
@@ -201,6 +259,14 @@ export function generateEnv(options: GenerateEnvOptions): string {
|
|
|
201
259
|
"SMTP_USER=",
|
|
202
260
|
"SMTP_PASS=",
|
|
203
261
|
"",
|
|
262
|
+
"# --- Dashboard (exe-dashboard — customer dashboard at dashboard.<domain>) ---",
|
|
263
|
+
"# OPT-IN: the exe-dashboard compose service sits behind `profiles: [dashboard]`.",
|
|
264
|
+
"# No default is written here on purpose — the pin comes from the signed stack",
|
|
265
|
+
"# manifest (services.dashboard.image), so .env stays derived rather than",
|
|
266
|
+
"# becoming a competing source of truth that outranks it once it goes stale.",
|
|
267
|
+
"#DASHBOARD_IMAGE_TAG=update.askexe.com/askexe/exe-dashboard:vX.Y.Z@sha256:...",
|
|
268
|
+
"#DASHBOARD_PORT=3301",
|
|
269
|
+
"",
|
|
204
270
|
"# --- Auth gateway (exe-auth — shared SSO sign-in UI at auth.<domain>) ---",
|
|
205
271
|
"# Bug 58840873: pin the auth image in .env so compose never falls back to its",
|
|
206
272
|
"# stale hardcoded default tag. Keep in sync with the manifest AUTH_IMAGE_TAG.",
|
|
@@ -262,6 +328,11 @@ export function generateEnv(options: GenerateEnvOptions): string {
|
|
|
262
328
|
"",
|
|
263
329
|
"# --- exe-os ---",
|
|
264
330
|
`EXE_OS_IMAGE_TAG=${EXE_OS_IMAGE_TAG}`,
|
|
331
|
+
"",
|
|
332
|
+
"# Infra image pins — manifest-derived. Compose has no fallback default for",
|
|
333
|
+
"# these: a missing pin ABORTS the deploy instead of substituting an old image.",
|
|
334
|
+
`EXE_DB_IMAGE=${EXE_DB_IMAGE}`,
|
|
335
|
+
`OTEL_COLLECTOR_IMAGE=${OTEL_COLLECTOR_IMAGE}`,
|
|
265
336
|
`EXED_MCP_TOKEN=${randomSecret(RANDOM_SECRET_48)}`,
|
|
266
337
|
`EXED_DEVICE_ID=vps-${normalizedClientName}`,
|
|
267
338
|
`EXE_MCP_HOST_BIND=${DEFAULT_EXE_MCP_HOST_BIND}`,
|
|
@@ -466,7 +537,7 @@ export function generateExampleEnv(): string {
|
|
|
466
537
|
"# Bug 51086951: JWT issuer pinned to the public auth URL so signer + consumers agree.",
|
|
467
538
|
"GOTRUE_JWT_ISSUER=https://auth.CHANGEME_DOMAIN",
|
|
468
539
|
"# SSO redirect allow-list (bug 66f8e10a) — app origins for unified SSO.",
|
|
469
|
-
"GOTRUE_URI_ALLOW_LIST=https://crm.CHANGEME_DOMAIN,https://wiki.CHANGEME_DOMAIN,https://erp.CHANGEME_DOMAIN",
|
|
540
|
+
"GOTRUE_URI_ALLOW_LIST=https://crm.CHANGEME_DOMAIN,https://wiki.CHANGEME_DOMAIN,https://erp.CHANGEME_DOMAIN,https://dashboard.CHANGEME_DOMAIN,https://gateway.CHANGEME_DOMAIN",
|
|
470
541
|
"# Bug 0327b017: parent-domain cookie → session shared across all subdomains.",
|
|
471
542
|
"GOTRUE_COOKIE_DOMAIN=.CHANGEME_DOMAIN",
|
|
472
543
|
"GOTRUE_COOKIE_KEY=exe-auth",
|
|
@@ -483,6 +554,21 @@ export function generateExampleEnv(): string {
|
|
|
483
554
|
"SMTP_USER=",
|
|
484
555
|
"SMTP_PASS=",
|
|
485
556
|
"",
|
|
557
|
+
"# --- Dashboard (exe-dashboard — customer dashboard at dashboard.<domain>) ---",
|
|
558
|
+
"# OPT-IN: the exe-dashboard compose service sits behind `profiles: [dashboard]`",
|
|
559
|
+
"# and is off unless you run `docker compose --profile dashboard ...`.",
|
|
560
|
+
"# DELIBERATELY UNSET AND COMMENTED OUT. Unlike the older *_IMAGE_TAG lines",
|
|
561
|
+
"# above/below, this one carries no hardcoded literal: a pinned default here is",
|
|
562
|
+
"# a second source of truth that silently outranks the manifest the moment it",
|
|
563
|
+
"# goes stale. Take the value from the signed stack manifest",
|
|
564
|
+
"# (deploy/stack-manifests/v0.9.json -> services.dashboard.image), digest and all.",
|
|
565
|
+
"# Leave it unset and compose refuses the dashboard loudly (\"has neither an image",
|
|
566
|
+
"# nor a build context specified\") instead of booting something arbitrary.",
|
|
567
|
+
"#DASHBOARD_IMAGE_TAG=update.askexe.com/askexe/exe-dashboard:vX.Y.Z@sha256:...",
|
|
568
|
+
"# Host port for the dashboard container (bound to 127.0.0.1; the tunnel and the",
|
|
569
|
+
"# SSO edge reach it over the docker network, not this port).",
|
|
570
|
+
"#DASHBOARD_PORT=3301",
|
|
571
|
+
"",
|
|
486
572
|
"# --- Auth gateway (exe-auth — shared SSO sign-in UI at auth.<domain>) ---",
|
|
487
573
|
"# Bug 58840873: pin the auth image so compose never falls back to its stale",
|
|
488
574
|
"# hardcoded default tag. Keep in sync with the manifest AUTH_IMAGE_TAG. exe-auth",
|
|
@@ -502,6 +588,23 @@ export function generateExampleEnv(): string {
|
|
|
502
588
|
"# the sign-up UI/route instead of showing a form that always fails.",
|
|
503
589
|
"AUTH_DISABLE_SIGNUP=true",
|
|
504
590
|
"",
|
|
591
|
+
"# --- Session cookie contract (exe-auth v0.6.0) \u2014 INFORMATIONAL, not settings ---",
|
|
592
|
+
"# Recorded here because operators reason about XSS blast radius from this file,",
|
|
593
|
+
"# and an earlier draft of these notes described the OPPOSITE of what ships.",
|
|
594
|
+
"# exe-auth performs the GoTrue token exchange server-side in njs and sets:",
|
|
595
|
+
"# exe_sess HttpOnly Secure SameSite=Lax \u2014 the real access token",
|
|
596
|
+
"# exe_sess_refresh HttpOnly Secure SameSite=Lax \u2014 the real refresh token",
|
|
597
|
+
"# exe_access_token JS-readable, value literally \"1\" \u2014 presence sentinel only",
|
|
598
|
+
"# All three are scoped to the apex (AUTH_COOKIE_DOMAIN) so they are shared",
|
|
599
|
+
"# across product subdomains.",
|
|
600
|
+
"#",
|
|
601
|
+
"# The credentials are HttpOnly ON PURPOSE (security bug 368bf916): page",
|
|
602
|
+
"# JavaScript CANNOT read them, so an XSS on any subdomain cannot exfiltrate a",
|
|
603
|
+
"# session token from document.cookie. The only JS-readable cookie is the",
|
|
604
|
+
"# sentinel, whose value is the constant \"1\" and is not a credential.",
|
|
605
|
+
"# Apps must NOT read a token from document.cookie \u2014 send credentialed",
|
|
606
|
+
"# same-site requests and let the HttpOnly cookie ride along.",
|
|
607
|
+
"",
|
|
505
608
|
...MANAGED_PERMS_ENV_BLOCK,
|
|
506
609
|
"",
|
|
507
610
|
"# --- CRM ---",
|
|
@@ -542,6 +645,11 @@ export function generateExampleEnv(): string {
|
|
|
542
645
|
"",
|
|
543
646
|
"# --- exe-os ---",
|
|
544
647
|
`EXE_OS_IMAGE_TAG=${EXE_OS_IMAGE_TAG}`,
|
|
648
|
+
"",
|
|
649
|
+
"# Infra image pins — manifest-derived. Compose has no fallback default for",
|
|
650
|
+
"# these: a missing pin ABORTS the deploy instead of substituting an old image.",
|
|
651
|
+
`EXE_DB_IMAGE=${EXE_DB_IMAGE}`,
|
|
652
|
+
`OTEL_COLLECTOR_IMAGE=${OTEL_COLLECTOR_IMAGE}`,
|
|
545
653
|
"EXED_MCP_TOKEN=CHANGEME_EXED_MCP_TOKEN",
|
|
546
654
|
"EXED_DEVICE_ID=vps-default",
|
|
547
655
|
`EXE_MCP_HOST_BIND=${DEFAULT_EXE_MCP_HOST_BIND}`,
|
|
@@ -37,15 +37,86 @@ map $request_uri $sso_uri_access_token {
|
|
|
37
37
|
"~[?&]access_token=(?<tok>[^&]+)" $tok;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
# Extract the shared
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
40
|
+
# Extract the shared apex SSO cookie from the Cookie header.
|
|
41
|
+
#
|
|
42
|
+
# THE COOKIE IS `exe_access_token` (bug 21ae2388). This map previously matched
|
|
43
|
+
# `exe-auth` — a name NOTHING has ever set. That made the cross-app-logout arm
|
|
44
|
+
# below fire on every single request, so any visitor holding a valid app-native
|
|
45
|
+
# session was bounced back to auth forever. It is the FOURTH instance of one
|
|
46
|
+
# recurring bug class: gating on a cookie name nothing mints. The first three
|
|
47
|
+
# all gated on the retired `exe_sso_token` — exe-wiki f1bb40d8, exe-crm
|
|
48
|
+
# 9f60e8e6, exe-erp 3938ac3d. See .github/workflows/sso-cookie-contract-monitor.yml.
|
|
49
|
+
#
|
|
50
|
+
# THE REAL CONTRACT (exe-auth v0.6.0, auth.njs.js setSessionCookies):
|
|
51
|
+
# exe_sess HttpOnly Secure SameSite=Lax — the real access_token
|
|
52
|
+
# exe_sess_refresh HttpOnly Secure SameSite=Lax — the real refresh_token
|
|
53
|
+
# exe_access_token JS-readable, value literally "1" — presence sentinel
|
|
54
|
+
# All three are scoped to the registrable apex (".${DOMAIN}") via
|
|
55
|
+
# AUTH_COOKIE_DOMAIN, so they are presented across every product subdomain.
|
|
56
|
+
# The two credentials are HttpOnly deliberately (security bug 368bf916) and are
|
|
57
|
+
# therefore unusable as an edge signal; the sentinel is the one that is visible
|
|
58
|
+
# here and is exactly what a presence gate needs.
|
|
59
|
+
#
|
|
60
|
+
# Cross-app logout: exe-auth's logout handler (clearSessionCookies) expires
|
|
61
|
+
# exe_access_token on the apex, so its absence alongside a live app-native
|
|
62
|
+
# cookie means the session was revoked on another app — the edge forces re-auth
|
|
63
|
+
# (return 401 → login redirect).
|
|
64
|
+
#
|
|
65
|
+
# PRESENCE SIGNAL ONLY. The value is the literal "1", not a token. Never treat
|
|
66
|
+
# it as a bearer credential and never forward it as one — the gate below tests
|
|
67
|
+
# only whether it is empty. Token validation is step 3's GoTrue /user call.
|
|
46
68
|
map $http_cookie $sso_gotrue_cookie {
|
|
47
69
|
default "";
|
|
48
|
-
"~(?:^|;\s*)
|
|
70
|
+
"~(?:^|;\s*)exe_access_token=([^\s;]+)" $1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# Static-asset exemption for the gate (see sso-redirect.conf step 0). Exempting
|
|
74
|
+
# assets is required for the SPA to boot at all: the app sets its session cookie
|
|
75
|
+
# only after its JS runs, so gating app.js hands a session-bearing document auth
|
|
76
|
+
# HTML in place of its script -> blank page.
|
|
77
|
+
#
|
|
78
|
+
# MAPS OVER $request_uri, NOT $uri (bug 06a3daae). Same trap the token map
|
|
79
|
+
# above documents: $sso_is_static is read inside the auth_request subrequest,
|
|
80
|
+
# where $uri is the gate's own path `/_sso_gate` — never the original request
|
|
81
|
+
# path — so an extension regex over $uri can never match and this exemption was
|
|
82
|
+
# completely inert from the day it shipped. $request_uri IS inherited, but it
|
|
83
|
+
# carries the query string, so the anchor admits `?`/`#` as well as end-of-
|
|
84
|
+
# string — without that, /assets/app.js?v=abc would fall back into the gate.
|
|
85
|
+
#
|
|
86
|
+
# SCOPED BY PATH PREFIX, NOT BY BARE EXTENSION (P0 review of PR #874). A bare
|
|
87
|
+
# extension test over $request_uri exempts ANY URL shaped like an asset, and the
|
|
88
|
+
# app locations are catch-all proxies, so `/uploads/customer.png` and
|
|
89
|
+
# `/api/export.js` would walk straight past the gate — the gate returns 204
|
|
90
|
+
# before it ever looks at a cookie. The allow arms below are anchored at `^/`
|
|
91
|
+
# on the build-output directories the SPAs actually boot from; everything else
|
|
92
|
+
# — including every proxied application path — falls to `default ""` and stays
|
|
93
|
+
# gated. This is now a path test AND an extension test, not a URL-shape test.
|
|
94
|
+
#
|
|
95
|
+
# nginx takes the FIRST matching regex in a map, so the deny arms are listed
|
|
96
|
+
# first and win unconditionally over the allow arms.
|
|
97
|
+
map $request_uri $sso_is_static {
|
|
98
|
+
default "";
|
|
99
|
+
|
|
100
|
+
# ── DENY (evaluated first, wins over everything below) ───────────────────
|
|
101
|
+
# Proxied application surface: API, user uploads and app-served files can
|
|
102
|
+
# never be exempt, whatever extension or query string they are dressed in.
|
|
103
|
+
"~*^/(?:api|uploads?|files|private|attachments|media|desk|app|method|admin)(?:[/?#]|$)" "";
|
|
104
|
+
# Traversal, raw or percent-encoded. $request_uri is the RAW request line:
|
|
105
|
+
# `/assets/../api/secret.js` is a prefix match here but normalizes to
|
|
106
|
+
# `/api/secret.js` before it reaches the app, so it must never be exempt.
|
|
107
|
+
"~\.\." "";
|
|
108
|
+
"~*%2e" "";
|
|
109
|
+
"~*%2f" "";
|
|
110
|
+
"~*%5c" "";
|
|
111
|
+
|
|
112
|
+
# ── ALLOW ────────────────────────────────────────────────────────────────
|
|
113
|
+
# Build-output directories only: Vite/Frappe `/assets/`, CRA/Twenty
|
|
114
|
+
# `/static/`, Next `/_next/static/`, Nuxt `/_nuxt/`, Vite-in-subdir
|
|
115
|
+
# `/build/assets/`. `[^?#]*` keeps the extension test on the PATH, so a
|
|
116
|
+
# query string can never supply the matching extension.
|
|
117
|
+
"~*^/(?:_next/static|_nuxt|assets|static|build/assets)/[^?#]*\.(?:js|mjs|css|map|png|jpe?g|gif|svg|ico|webp|woff2?|ttf)(?:[?#]|$)" "static";
|
|
118
|
+
# Root icons the browser requests on its own before any app code runs.
|
|
119
|
+
"~*^/(?:favicon\.(?:ico|svg|png)|apple-touch-icon(?:-precomposed)?\.png)(?:[?#]|$)" "static";
|
|
49
120
|
}
|
|
50
121
|
|
|
51
122
|
map $http_upgrade $sso_conn_upgrade {
|
|
@@ -7,13 +7,17 @@
|
|
|
7
7
|
# advertised "single front door" does not exist.
|
|
8
8
|
#
|
|
9
9
|
# ── How it works ────────────────────────────────────────────────────────────
|
|
10
|
-
#
|
|
10
|
+
# 0. Static assets (JS/CSS/images/fonts, via the $sso_is_static map) are
|
|
11
|
+
# exempted from the gate and answered 204 — see step 0 inside /_sso_gate
|
|
12
|
+
# for why gating them deadlocks first page load.
|
|
13
|
+
# 1. Every other request runs the edge auth gate (auth_request → /_sso_gate).
|
|
11
14
|
# 2. If the app session cookie is present the request passes (the app validates
|
|
12
15
|
# its own session server-side — the cookie name differs per app; set it via
|
|
13
16
|
# $sso_session_cookie below). Cross-app logout: the edge also checks for the
|
|
14
|
-
# shared
|
|
15
|
-
#
|
|
16
|
-
# the
|
|
17
|
+
# shared apex SSO cookie `exe_access_token` (set on .${DOMAIN} by exe-auth's
|
|
18
|
+
# njs handlers — a NON-CREDENTIAL presence sentinel whose value is literally
|
|
19
|
+
# "1"); if the app cookie is present but that sentinel is gone, the session
|
|
20
|
+
# was revoked on another app and the edge forces re-auth.
|
|
17
21
|
# 3. If the request carries ?access_token= (the SSO callback), the edge
|
|
18
22
|
# VALIDATES the token against the shared GoTrue (`GET /user` with
|
|
19
23
|
# `Authorization: Bearer <token>`) before letting it through. P0 bug
|
|
@@ -22,6 +26,8 @@
|
|
|
22
26
|
# trusted — only a token GoTrue accepts passes.
|
|
23
27
|
# 4. Anything else 401s inside the gate and is 302-redirected to:
|
|
24
28
|
# https://auth.<domain>/?product=<App>&redirect=https://<app>.<domain><uri>
|
|
29
|
+
# A 403 from the GoTrue /user validation subrequest is mapped to the same
|
|
30
|
+
# login redirect, so it is never leaked raw to the browser.
|
|
25
31
|
# 5. The gateway authenticates against the shared GoTrue and bounces the user
|
|
26
32
|
# back to the app URL with ?access_token=<jwt>&refresh_token=<...>. The app
|
|
27
33
|
# consumes the token and sets its session cookie — subsequent requests carry
|
|
@@ -31,7 +37,7 @@
|
|
|
31
37
|
# These are templated values — replace before installing, or render with envsubst
|
|
32
38
|
# (DOMAIN, APP_NAME, APP_SUBDOMAIN, APP_SESSION_COOKIE):
|
|
33
39
|
#
|
|
34
|
-
# #
|
|
40
|
+
# # FOUR http-context declarations MUST exist once per nginx config (the
|
|
35
41
|
# # compose edge ships them in sso-edge/default.conf.template; host-nginx
|
|
36
42
|
# # installs add them next to their `include`s — see sso-redirect.README.md):
|
|
37
43
|
# #
|
|
@@ -45,6 +51,34 @@
|
|
|
45
51
|
# default "";
|
|
46
52
|
# "~[?&]access_token=(?<tok>[^&]+)" $tok;
|
|
47
53
|
# }
|
|
54
|
+
# # 3. The shared apex SSO cookie — the cross-app-logout signal. The name is
|
|
55
|
+
# # `exe_access_token` (bug 21ae2388: this used to read a nonexistent
|
|
56
|
+
# # `exe-auth`, which 401'd every authenticated request). Presence only —
|
|
57
|
+
# # the value is the literal "1", never a bearer token:
|
|
58
|
+
# map $http_cookie $sso_gotrue_cookie {
|
|
59
|
+
# default "";
|
|
60
|
+
# "~(?:^|;\s*)exe_access_token=([^\s;]+)" $1;
|
|
61
|
+
# }
|
|
62
|
+
# # 4. The static-asset exemption (see step 0 inside /_sso_gate). Like #2
|
|
63
|
+
# # this MUST map over $request_uri: inside the auth_request subrequest
|
|
64
|
+
# # $uri is `/_sso_gate`, so a map over $uri never matches and the
|
|
65
|
+
# # exemption is silently inert (bug 06a3daae). $request_uri includes the
|
|
66
|
+
# # query string, hence the `[?#]` anchor instead of a bare `$`.
|
|
67
|
+
# # It must ALSO be anchored to the build-output PATH PREFIXES: a bare
|
|
68
|
+
# # extension test exempts any URL shaped like an asset, and since the app
|
|
69
|
+
# # location is a catch-all proxy that hands `/uploads/customer.png` and
|
|
70
|
+
# # `/api/export.js` straight past the gate. Deny arms come first because
|
|
71
|
+
# # nginx takes the FIRST matching regex in a map:
|
|
72
|
+
# map $request_uri $sso_is_static {
|
|
73
|
+
# default "";
|
|
74
|
+
# "~*^/(?:api|uploads?|files|private|attachments|media|desk|app|method|admin)(?:[/?#]|$)" "";
|
|
75
|
+
# "~\.\." "";
|
|
76
|
+
# "~*%2e" "";
|
|
77
|
+
# "~*%2f" "";
|
|
78
|
+
# "~*%5c" "";
|
|
79
|
+
# "~*^/(?:_next/static|_nuxt|assets|static|build/assets)/[^?#]*\.(?:js|mjs|css|map|png|jpe?g|gif|svg|ico|webp|woff2?|ttf)(?:[?#]|$)" "static";
|
|
80
|
+
# "~*^/(?:favicon\.(?:ico|svg|png)|apple-touch-icon(?:-precomposed)?\.png)(?:[?#]|$)" "static";
|
|
81
|
+
# }
|
|
48
82
|
#
|
|
49
83
|
# server {
|
|
50
84
|
# server_name crm.${DOMAIN};
|
|
@@ -70,9 +104,47 @@
|
|
|
70
104
|
# are app-native sessions the edge cannot verify against GoTrue); each app fully
|
|
71
105
|
# validates its own session server-side. The edge gate's job is the login funnel
|
|
72
106
|
# plus never letting an unvalidated bearer token skip it (bug 462d3273).
|
|
73
|
-
# Cross-app logout adds a
|
|
74
|
-
# but the shared
|
|
75
|
-
# on another app and the app-native cookie is
|
|
107
|
+
# Cross-app logout adds a sentinel-cookie check: if the app-native cookie is
|
|
108
|
+
# present but the shared apex `exe_access_token` sentinel is absent, the edge
|
|
109
|
+
# 401s — the session was revoked on another app and the app-native cookie is
|
|
110
|
+
# stale. This is ALWAYS ON; it is the mechanism that makes "log out once, out
|
|
111
|
+
# everywhere" real across crm/wiki/erp/dashboard.
|
|
112
|
+
#
|
|
113
|
+
# ── SCOPE OF THE STATIC-ASSET EXEMPTION ──────────────────────────────────────
|
|
114
|
+
# Step 0 exempts a request from the gate BEFORE any cookie check, matching on
|
|
115
|
+
# $request_uri (bug 06a3daae — $uri is `/_sso_gate` inside the subrequest).
|
|
116
|
+
#
|
|
117
|
+
# The exemption is scoped by PATH PREFIX **and** extension, never by extension
|
|
118
|
+
# alone. An extension-only test is a pure URL-shape test, and because each app
|
|
119
|
+
# location is a catch-all `proxy_pass`, it would hand `/uploads/customer.png`
|
|
120
|
+
# or `/api/export.js` a 204 from the gate and proxy them to the app with no SSO
|
|
121
|
+
# at all. Only these prefixes can ever be exempt:
|
|
122
|
+
#
|
|
123
|
+
# /_next/static/ /_nuxt/ /assets/ /static/ /build/assets/
|
|
124
|
+
# /favicon.{ico,svg,png} /apple-touch-icon[-precomposed].png
|
|
125
|
+
#
|
|
126
|
+
# and only when the PATH (not the query string) also ends in a known asset
|
|
127
|
+
# extension. Deny arms listed FIRST in the map — nginx takes the first matching
|
|
128
|
+
# regex — make it explicit that /api/, /uploads/, /files/, /private/, /media/,
|
|
129
|
+
# /attachments/, /desk, /app, /method and /admin can NEVER be exempt whatever
|
|
130
|
+
# their extension or query string, and reject traversal forms (`..`, %2e, %2f,
|
|
131
|
+
# %5c) so a raw `/assets/../api/secret.js` cannot prefix-match here and then
|
|
132
|
+
# normalize into the API before it reaches the app.
|
|
133
|
+
#
|
|
134
|
+
# What is still true of anything that IS exempt: it is a URL test, not a
|
|
135
|
+
# content test. If an app serves user content out of one of those build-output
|
|
136
|
+
# prefixes, that content is reachable unauthenticated at the edge. Two reasons
|
|
137
|
+
# that is acceptable:
|
|
138
|
+
# 1. Every app validates its own session server-side. The edge gate is the
|
|
139
|
+
# LOGIN FUNNEL, not the authorization boundary — an exempted request still
|
|
140
|
+
# reaches an app that will refuse to serve it to an unauthenticated user.
|
|
141
|
+
# 2. Without the exemption the stack does not work at all: the SPA only sets
|
|
142
|
+
# its session cookie after its JS runs, so gating app.js returns auth HTML
|
|
143
|
+
# in place of the script and the app never boots (blank page).
|
|
144
|
+
#
|
|
145
|
+
# The limit of that reasoning: never serve private content from one of the
|
|
146
|
+
# prefixes above, and do not rely on the edge gate for an app that does no
|
|
147
|
+
# authorization of its own.
|
|
76
148
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
77
149
|
|
|
78
150
|
# Run the gate for every request on this vhost. The gate is a zero-cost local
|
|
@@ -82,6 +154,11 @@
|
|
|
82
154
|
# official nginx / nginx:alpine builds).
|
|
83
155
|
auth_request /_sso_gate;
|
|
84
156
|
error_page 401 = @sso_login;
|
|
157
|
+
# A 403 from the gate's GoTrue /user validation must funnel to login too, not
|
|
158
|
+
# leak raw to the browser. Safe: proxy_intercept_errors is not enabled on the
|
|
159
|
+
# app proxy_pass blocks, so a genuine 403 from an upstream app is NOT converted
|
|
160
|
+
# — only the auth_request subrequest's own status reaches this mapping.
|
|
161
|
+
error_page 403 = @sso_login;
|
|
85
162
|
|
|
86
163
|
location = /_sso_gate {
|
|
87
164
|
internal;
|
|
@@ -93,12 +170,31 @@ location = /_sso_gate {
|
|
|
93
170
|
# which auth_request rejects ("auth request unexpected status: 302").
|
|
94
171
|
error_page 401 = @sso_gate_deny;
|
|
95
172
|
|
|
173
|
+
# 0. Static assets (JS/CSS/images/fonts via the $sso_is_static http-context
|
|
174
|
+
# map) pass BEFORE any cookie check. Assets are non-sensitive — all SPA
|
|
175
|
+
# data flows only via the authenticated APIs, which stay fully gated —
|
|
176
|
+
# and gating them deadlocks first page load: the SPA sets its session
|
|
177
|
+
# cookie only AFTER it boots, so answering app.js with the auth HTML
|
|
178
|
+
# leaves a session-bearing document that can never boot (blank page).
|
|
179
|
+
# See the SCOPE note in the header: the map is path-prefix scoped, so
|
|
180
|
+
# only build-output directories can reach this 204 — /api/* and
|
|
181
|
+
# /uploads/* stay gated no matter what extension they carry.
|
|
182
|
+
# The map MUST be over $request_uri, not $uri: in here $uri is
|
|
183
|
+
# `/_sso_gate`, so a $uri-based map never matches (bug 06a3daae).
|
|
184
|
+
if ($sso_is_static) {
|
|
185
|
+
return 204;
|
|
186
|
+
}
|
|
187
|
+
|
|
96
188
|
# 1. App session cookie present → check for cross-app logout.
|
|
97
|
-
# The
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
# app cookie
|
|
189
|
+
# The shared apex cookie is `exe_access_token` (domain .${DOMAIN}), set
|
|
190
|
+
# by exe-auth's njs login handler and expired by its logout handler. It
|
|
191
|
+
# is a NON-CREDENTIAL presence sentinel — its value is literally "1", so
|
|
192
|
+
# only its presence is meaningful and it is never used as a bearer token.
|
|
193
|
+
# If the app-native cookie is present but the sentinel is gone, the
|
|
194
|
+
# session was revoked on another app — force re-auth instead of trusting
|
|
195
|
+
# the stale app cookie.
|
|
196
|
+
# Bug 21ae2388: this arm matched a cookie named `exe-auth` that nothing
|
|
197
|
+
# has ever minted, so it fired unconditionally and 401'd every request.
|
|
102
198
|
set $sso_auth_check "";
|
|
103
199
|
if ($sso_session_cookie) {
|
|
104
200
|
set $sso_auth_check "app";
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"env": "ERP_IMAGE_TAG",
|
|
53
53
|
"composeService": "exe-erp",
|
|
54
54
|
"healthUrl": "http://127.0.0.1:8069/api/method/ping",
|
|
55
|
-
"healthHost": "erp.
|
|
55
|
+
"healthHost": "${ERP_SITE_NAME:-erp.localhost}",
|
|
56
56
|
"required": false,
|
|
57
57
|
"category": "app",
|
|
58
58
|
"description": "Enterprise Resource Planning"
|
|
@@ -2752,13 +2752,13 @@
|
|
|
2752
2752
|
"gitSha": "10660eb4abdeffbcba2aad13549aa58e208ac7a3"
|
|
2753
2753
|
},
|
|
2754
2754
|
"auth": {
|
|
2755
|
-
"image": "update.askexe.com/askexe/exe-auth:v0.6.
|
|
2755
|
+
"image": "update.askexe.com/askexe/exe-auth:v0.6.1@sha256:89670a15bc59255299be695525863e66f949694eec1dd8886038dc3659a4a941",
|
|
2756
2756
|
"env": "AUTH_IMAGE_TAG",
|
|
2757
2757
|
"composeService": "exe-auth",
|
|
2758
2758
|
"healthUrl": "http://127.0.0.1:3300/api/health",
|
|
2759
2759
|
"category": "auth",
|
|
2760
|
-
"description": "exe-auth v0.6.
|
|
2761
|
-
"gitSha": "
|
|
2760
|
+
"description": "exe-auth v0.6.1 — the v0.6.0 hardening (GoTrue admin API no longer public; nginx 404s /api/admin|invite; query strings redacted from access + error logs) PLUS the four fixes that merged after v0.6.0 was tagged and had never been built into any image (bug 9e054a59): /api/recover CORS + method restriction (0f9fbebe); a recovery link can no longer mint a session and link hashes are sent as token_hash (056abf8d, c9b62c91); the Secure cookie flag fails closed and HSTS is set (bb99ceda); the session token is kept out of upstream request lines, shape-checked, and a service_role JWT is refused (bff591fe). Verified inside this exact digest, not from a green badge.",
|
|
2761
|
+
"gitSha": "633e7a4d9930aad8b0ce6783a1b3bc2f96b454a8"
|
|
2762
2762
|
},
|
|
2763
2763
|
"erp": {
|
|
2764
2764
|
"image": "update.askexe.com/askexe/exe-erp:v2026.08.07-d185286-stamped@sha256:1c655f3f7819c797afd13c79561354f0276cf337403f32aee3e406a497e8827b",
|
|
@@ -2809,6 +2809,6 @@
|
|
|
2809
2809
|
"signature": {
|
|
2810
2810
|
"keyId": "exe-stack-1",
|
|
2811
2811
|
"alg": "ed25519",
|
|
2812
|
-
"signature": "
|
|
2812
|
+
"signature": "zJx3MxMUaco9bPRAPvmMs8qFXScuuAS9xWXSQBgtzKJB3ERe5aNvb+f6O39jWjxAvoPUQUObPjCuhwbu0aD8AQ=="
|
|
2813
2813
|
}
|
|
2814
2814
|
}
|
package/dist/.dist-verified.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
|
-
"verified_at": "2026-08-
|
|
4
|
-
"manifest_sha256": "
|
|
5
|
-
"package_version": "0.9.
|
|
3
|
+
"verified_at": "2026-08-20T18:51:08.214Z",
|
|
4
|
+
"manifest_sha256": "185d088d5d3a1b4d1f2d293248438af3df4498155f42a6f9cfc35521103d5b70",
|
|
5
|
+
"package_version": "0.9.374"
|
|
6
6
|
}
|
|
@@ -7,22 +7,23 @@ import {
|
|
|
7
7
|
resolveAgentAttribution,
|
|
8
8
|
resolveAgentForPayload,
|
|
9
9
|
writeActiveAgent
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-55BEFF4V.js";
|
|
11
|
+
import "./chunk-K4ESASPL.js";
|
|
12
12
|
import "./chunk-CVYC6DUW.js";
|
|
13
13
|
import "./chunk-GJV3WDWM.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-TKDITWDN.js";
|
|
14
|
+
import "./chunk-TAMDAOCU.js";
|
|
16
15
|
import "./chunk-BBMTVAE3.js";
|
|
16
|
+
import "./chunk-TKDITWDN.js";
|
|
17
17
|
import "./chunk-5YEUPUV4.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-DSJI76XL.js";
|
|
19
19
|
import "./chunk-YYB5PMTK.js";
|
|
20
20
|
import "./chunk-NJFJWQNN.js";
|
|
21
21
|
import "./chunk-V3W3SATA.js";
|
|
22
22
|
import "./chunk-JY5GAZYC.js";
|
|
23
23
|
import "./chunk-FXU7JOXK.js";
|
|
24
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-ZIG7VPJV.js";
|
|
25
25
|
import "./chunk-HSGBZSCA.js";
|
|
26
|
+
import "./chunk-RH4AH3YB.js";
|
|
26
27
|
import "./chunk-JKKZGDLP.js";
|
|
27
28
|
import "./chunk-MLKGABMK.js";
|
|
28
29
|
export {
|
|
@@ -8,22 +8,23 @@ import {
|
|
|
8
8
|
resolveAgentAttribution,
|
|
9
9
|
resolveAgentForPayload,
|
|
10
10
|
writeActiveAgent
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-55BEFF4V.js";
|
|
12
|
+
import "./chunk-K4ESASPL.js";
|
|
13
13
|
import "./chunk-CVYC6DUW.js";
|
|
14
14
|
import "./chunk-GJV3WDWM.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-TKDITWDN.js";
|
|
15
|
+
import "./chunk-TAMDAOCU.js";
|
|
17
16
|
import "./chunk-BBMTVAE3.js";
|
|
17
|
+
import "./chunk-TKDITWDN.js";
|
|
18
18
|
import "./chunk-5YEUPUV4.js";
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-DSJI76XL.js";
|
|
20
20
|
import "./chunk-YYB5PMTK.js";
|
|
21
21
|
import "./chunk-NJFJWQNN.js";
|
|
22
22
|
import "./chunk-V3W3SATA.js";
|
|
23
23
|
import "./chunk-JY5GAZYC.js";
|
|
24
24
|
import "./chunk-FXU7JOXK.js";
|
|
25
|
-
import "./chunk-
|
|
25
|
+
import "./chunk-ZIG7VPJV.js";
|
|
26
26
|
import "./chunk-HSGBZSCA.js";
|
|
27
|
+
import "./chunk-RH4AH3YB.js";
|
|
27
28
|
import "./chunk-JKKZGDLP.js";
|
|
28
29
|
import "./chunk-MLKGABMK.js";
|
|
29
30
|
export {
|