@askexenow/exe-os 0.9.362 → 0.9.365
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 +46 -2
- package/deploy/compose/.env.example +49 -2
- package/deploy/compose/cloudflared/config.yml.example +15 -8
- package/deploy/compose/docker-compose.yml +240 -34
- package/deploy/compose/generate-env.ts +88 -2
- package/deploy/compose/status.sh +30 -0
- package/deploy/compose/uptime-check.sh +39 -2
- package/deploy/compose/wiki-schema-guard.sh +302 -0
- package/deploy/stack-manifests/v0.9.json +232 -2
- package/dist/.dist-verified.json +3 -3
- package/dist/{active-agent-BPNEBKHI.js → active-agent-C6DPH43L.js} +10 -5
- package/dist/{active-agent-3FV5V7SS.js → active-agent-MGF7J3HB.js} +10 -5
- package/dist/agent-defs-generator-X7TVMPVB.js +240 -0
- package/dist/{agentic-ontology-RCVCJ6WB.js → agentic-ontology-CARDCG37.js} +1 -1
- package/dist/artifact-backup-767STHSW.js +209 -0
- package/dist/artifact-provenance-C7HQ267L.js +13 -0
- package/dist/{backfill-gate-LRX77SUD.js → backfill-gate-VX2RZTQV.js} +2 -2
- package/dist/{backfill-metadata-Y3DGVCK5.js → backfill-metadata-ANCJA6LA.js} +7 -7
- package/dist/{background-jobs-Z6KHCWES.js → background-jobs-LTPWCMA3.js} +2 -2
- package/dist/{backup-verify-TZPPUCLU.js → backup-verify-F7BHVEF7.js} +27 -14
- package/dist/{behavior-injection-JMGGWCWG.js → behavior-injection-XQ4B7DCF.js} +13 -12
- package/dist/{behaviors-TT6CMEKC.js → behaviors-R2IE3PEN.js} +12 -11
- package/dist/bin/age-ontology-load.js +2 -2
- package/dist/bin/agentic-ontology-backfill.js +9 -9
- package/dist/bin/agentic-reflection-backfill.js +10 -10
- package/dist/bin/agentic-semantic-label.js +9 -9
- package/dist/bin/backfill-conversations.js +10 -9
- package/dist/bin/backfill-responses.js +10 -9
- package/dist/bin/backfill-vectors.js +14 -13
- package/dist/bin/bulk-sync-postgres.js +23 -19
- package/dist/bin/cc-doctor.js +11 -8
- package/dist/bin/cleanup-stale-review-tasks.js +26 -24
- package/dist/bin/cli.js +29 -102
- package/dist/bin/customer-readiness.js +3 -1
- package/dist/bin/deferred-daemon-restart.js +115 -103
- package/dist/bin/exe-agent-config.js +5 -5
- package/dist/bin/exe-agent.js +14 -14
- package/dist/bin/exe-assign.js +12 -11
- package/dist/bin/exe-boot.js +60 -51
- package/dist/bin/exe-call.js +7 -7
- package/dist/bin/exe-cloud.js +26 -22
- package/dist/bin/exe-config-dump.js +5 -5
- package/dist/bin/exe-dispatch.js +30 -24
- package/dist/bin/exe-doctor.js +10 -9
- package/dist/bin/exe-export-behaviors.js +14 -13
- package/dist/bin/exe-forget.js +9 -9
- package/dist/bin/exe-gateway.js +9 -9
- package/dist/bin/exe-grant.js +5 -5
- package/dist/bin/exe-healthcheck.js +13 -8
- package/dist/bin/exe-heartbeat.js +36 -29
- package/dist/bin/exe-kill.js +30 -28
- package/dist/bin/exe-launch-agent.js +41 -37
- package/dist/bin/exe-mcp.js +5 -5
- package/dist/bin/exe-memory-reads.js +7 -7
- package/dist/bin/exe-new-employee.js +12 -11
- package/dist/bin/exe-os-mcp-proxy.js +5 -5
- 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 +27 -25
- package/dist/bin/exe-rename.js +7 -7
- package/dist/bin/exe-review.js +29 -27
- package/dist/bin/exe-search.js +8 -8
- package/dist/bin/exe-session-cleanup.js +31 -29
- package/dist/bin/exe-settings.js +24 -20
- package/dist/bin/exe-start-codex.js +36 -21
- package/dist/bin/exe-start-opencode.js +15 -14
- package/dist/bin/exe-status.js +28 -25
- package/dist/bin/exe-support.js +5 -4
- package/dist/bin/exe-team.js +12 -6
- package/dist/bin/exe-verify-running-images.js +145 -0
- package/dist/bin/exe-watchdog.js +16 -6
- package/dist/bin/git-sweep.js +27 -25
- package/dist/bin/graph-backfill.js +10 -9
- package/dist/bin/graph-export.js +8 -8
- package/dist/bin/import-history.js +13 -11
- package/dist/bin/install.js +119 -107
- package/dist/bin/intercom-check.js +5 -5
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +6 -6
- package/dist/bin/postgres-agentic-reflection-backfill.js +4 -4
- package/dist/bin/postgres-agentic-semantic-backfill.js +3 -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 +26 -24
- package/dist/bin/setup.js +4 -3
- package/dist/bin/shard-migrate.js +8 -8
- package/dist/bin/stack-update.js +87 -38
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/{boot-generation-XABYKF5P.js → boot-generation-X45BSVZY.js} +5 -5
- package/dist/{boot-review-sections-2X5TFIGU.js → boot-review-sections-OBVRXXSF.js} +25 -23
- package/dist/{branch-hygiene-Z4IBWAOX.js → branch-hygiene-HFJ3HA62.js} +17 -10
- package/dist/{branding-7MZDHTKN.js → branding-GH43W3PU.js} +2 -2
- package/dist/build-manifest.json +1189 -1049
- package/dist/{capability-cards-O5UXDOOA.js → capability-cards-57FURUMR.js} +4 -4
- package/dist/{capacity-monitor-IPXM726A.js → capacity-monitor-QEL62JDO.js} +27 -25
- package/dist/{catchup-brief-EBIGDXOK.js → catchup-brief-PMXTCASA.js} +30 -28
- package/dist/{chunk-UO5QJ2RX.js → chunk-22YQBVMO.js} +4 -4
- package/dist/chunk-2ADYTOHQ.js +189 -0
- package/dist/{chunk-NO5KHKKB.js → chunk-2CWS374F.js} +1 -1
- package/dist/{chunk-NAHCSQWT.js → chunk-2ESB5SDP.js} +19 -7
- package/dist/{chunk-CY5NVDTH.js → chunk-2FYIMTQE.js} +9 -5
- package/dist/{chunk-SC6WDF3Q.js → chunk-2RQT7TED.js} +2 -2
- package/dist/{chunk-UWEFIIEG.js → chunk-3CIMDFXG.js} +1 -1
- package/dist/{chunk-E7PL3T2U.js → chunk-3JNVB5LG.js} +1 -1
- package/dist/{chunk-7SY2NOMQ.js → chunk-3THNS2T7.js} +1 -1
- package/dist/{chunk-XJIRUTGJ.js → chunk-45EQTS7B.js} +1 -1
- package/dist/{chunk-YZUHSV24.js → chunk-4LWBC7CM.js} +1 -1
- package/dist/{chunk-DKRDU2AX.js → chunk-4QKKLK3C.js} +14 -14
- package/dist/{chunk-WP2TGH5R.js → chunk-52TIQJEQ.js} +2 -2
- package/dist/{chunk-LG37UBBE.js → chunk-5CBGH6RA.js} +5 -5
- package/dist/{chunk-W3LKIQJ2.js → chunk-6GQYPJPG.js} +22 -16
- package/dist/{chunk-I3SF6QGV.js → chunk-6Q263OZE.js} +1 -1
- package/dist/{chunk-XSYQ5EPE.js → chunk-7C4FUNVO.js} +11 -11
- package/dist/{chunk-P7CV4SHQ.js → chunk-7Y6AQWVT.js} +21 -10
- package/dist/{chunk-NGDXBN3M.js → chunk-A6PDF4BO.js} +2 -2
- package/dist/chunk-A7XLR3K7.js +45 -0
- package/dist/{chunk-7H3AZNQ7.js → chunk-AGQAGOQN.js} +9 -9
- package/dist/{chunk-VDMFVUSY.js → chunk-ANPE3TT3.js} +3 -3
- package/dist/{chunk-NE4QI2GX.js → chunk-BATQKSLI.js} +2 -2
- package/dist/{chunk-AOMFYUPT.js → chunk-BEHLIRRJ.js} +2 -2
- package/dist/{chunk-6EM6USV7.js → chunk-BNHAZ65R.js} +42 -50
- package/dist/{chunk-HLU52KTO.js → chunk-BRLS5OLZ.js} +257 -36
- package/dist/{chunk-QCJT265O.js → chunk-BY7WWPRM.js} +1 -1
- package/dist/{chunk-Z67DIJKT.js → chunk-C3UAQ3JG.js} +1 -1
- package/dist/{chunk-MZYNW5OY.js → chunk-CDUB5Q6J.js} +1 -1
- package/dist/{chunk-5H3RHWRE.js → chunk-CKG6CVKI.js} +1 -1
- package/dist/{chunk-WH2VVEGD.js → chunk-CMBF5WCL.js} +56 -2
- package/dist/{chunk-JYKZVAS6.js → chunk-CPILYY2K.js} +1 -1
- package/dist/{chunk-XTGR3LMF.js → chunk-CW2UCKHS.js} +2 -2
- package/dist/{chunk-32FEF5BW.js → chunk-CWBFOAGM.js} +2 -2
- package/dist/{chunk-V5I5N7NC.js → chunk-DEFSN2FQ.js} +3 -3
- package/dist/{chunk-HAXCUCJC.js → chunk-DJK45U7B.js} +1 -1
- package/dist/{chunk-MZZN5GFC.js → chunk-DQ5KHWFD.js} +1 -1
- package/dist/{chunk-SLBOKYYQ.js → chunk-DWAQOEXL.js} +2 -2
- package/dist/{chunk-T2RZU7JA.js → chunk-DYWGIPVP.js} +7 -7
- package/dist/{chunk-6DTALXOA.js → chunk-E5HAY3DQ.js} +1 -1
- package/dist/{chunk-D5CY4E7I.js → chunk-EHHMNKOA.js} +1 -1
- package/dist/{chunk-54USDN5Q.js → chunk-EJ4522YM.js} +1 -1
- package/dist/{chunk-URNVIZXU.js → chunk-EKVTRI3N.js} +52 -6
- package/dist/{chunk-KID6T2A4.js → chunk-EMZHB767.js} +44 -35
- package/dist/{chunk-KBI4FVBZ.js → chunk-EPDNWY5P.js} +111 -22
- package/dist/{chunk-AQO3BT3I.js → chunk-EPNWEOOE.js} +13 -13
- package/dist/{chunk-5C6ZIJ7J.js → chunk-ESTR7QUP.js} +1 -1
- package/dist/{chunk-Q2VQNAPU.js → chunk-EVPBYX2Z.js} +2 -2
- package/dist/{chunk-CVYDJ2TW.js → chunk-EWCEUO65.js} +1 -1
- package/dist/{chunk-RNSAVQEU.js → chunk-EWZYFG5Q.js} +8 -3
- package/dist/{chunk-R7F6HKTH.js → chunk-EXDW3E2R.js} +3 -1
- package/dist/{chunk-TY4JLBFO.js → chunk-F2S3M5MB.js} +3 -3
- package/dist/{chunk-BT2PUK3S.js → chunk-FXPAUDCZ.js} +1 -1
- package/dist/{chunk-3C7NE4JE.js → chunk-G2EAYH4U.js} +1 -1
- package/dist/{chunk-WDA2KAV7.js → chunk-GSJLB6JI.js} +1 -1
- package/dist/{chunk-M67ARGXY.js → chunk-H37FSTF2.js} +1 -1
- package/dist/{chunk-ZR4CQBAP.js → chunk-H74466TM.js} +1 -1
- package/dist/{chunk-3BAGFZFN.js → chunk-HHGOCBVQ.js} +9 -9
- package/dist/{working-memory-BACVOAIV.js → chunk-HSFBNCNC.js} +3 -3
- package/dist/{chunk-PF7EQSE5.js → chunk-IIZITKBV.js} +6 -6
- package/dist/{chunk-2FA4PYYX.js → chunk-IM2I7OOS.js} +1 -1
- package/dist/{chunk-DSKEYEL2.js → chunk-IXEFO6HD.js} +3 -3
- package/dist/{chunk-TN2E6ZCM.js → chunk-J4U5Z7VX.js} +214 -58
- package/dist/{chunk-PU7UYQRC.js → chunk-J5EYOBFF.js} +1 -1
- package/dist/{chunk-RWKX2TK5.js → chunk-J6I7X272.js} +1 -1
- package/dist/{chunk-BDLRTLXY.js → chunk-JITNFE4W.js} +6 -2
- package/dist/{chunk-PUMH7JSB.js → chunk-JNVQGLPX.js} +3 -3
- package/dist/{chunk-VAOUB2TK.js → chunk-JTB5V6BV.js} +1 -1
- package/dist/{chunk-QYRI25IP.js → chunk-JUOZLXLH.js} +2 -2
- package/dist/{chunk-RYRNY6IF.js → chunk-JYFYIGYK.js} +2 -2
- package/dist/{chunk-2PRAXZWM.js → chunk-KOYGRP2L.js} +10 -5
- package/dist/{chunk-4AFD4R35.js → chunk-KRUYQFSH.js} +5 -5
- package/dist/chunk-L25OAFOU.js +93 -0
- package/dist/{chunk-FUQ2OSDV.js → chunk-L2VZBPJJ.js} +25 -8
- package/dist/{chunk-LCDW2HUL.js → chunk-LHOKWZKL.js} +1 -1
- package/dist/{chunk-BN26LSME.js → chunk-LKYGSJ2E.js} +13 -2
- package/dist/chunk-LNOS24GV.js +214 -0
- package/dist/{chunk-O32HTNRX.js → chunk-LZKYVMBY.js} +13 -4
- package/dist/{chunk-35FD67ZB.js → chunk-M7EES2KM.js} +3 -3
- package/dist/chunk-MBBFL2SP.js +45 -0
- package/dist/{chunk-4R2WD6T3.js → chunk-MPQXQ5IE.js} +2 -2
- package/dist/{chunk-QQMYD4M7.js → chunk-MXEIZUXG.js} +1 -1
- package/dist/{chunk-6QJXFLNN.js → chunk-MZJBUAC3.js} +5 -5
- package/dist/chunk-NEHOQ3P2.js +19 -0
- package/dist/{chunk-BRZR76TS.js → chunk-NJFJWQNN.js} +49 -14
- package/dist/{chunk-Q7J2SQJ6.js → chunk-NO3M2AFM.js} +100 -32
- package/dist/{gotrue-session-2IT7MDGW.js → chunk-NUTZJZKW.js} +7 -8
- package/dist/{chunk-6UZDGEGQ.js → chunk-NV6A5HDN.js} +71 -1
- package/dist/{chunk-ZI3HA3XW.js → chunk-O2MEBF23.js} +3 -3
- package/dist/{chunk-V6YLIDLK.js → chunk-ODBRU6BF.js} +577 -230
- package/dist/{chunk-6N3HUOV3.js → chunk-OFGFRT5J.js} +2 -2
- package/dist/{chunk-HKQ7UTSE.js → chunk-OPNROU5B.js} +1 -1
- package/dist/{chunk-SQM4ZTL2.js → chunk-ORNCMRIX.js} +60 -33
- package/dist/{chunk-RUUX2ZST.js → chunk-P47MPWNU.js} +1 -1
- package/dist/{org-key-admin-4W6LZ5KZ.js → chunk-P5XTVIEC.js} +62 -17
- package/dist/{chunk-OZNCAMS3.js → chunk-POPRJKAY.js} +122 -20
- package/dist/{chunk-SRFRUN66.js → chunk-PPGPCWRC.js} +5 -5
- package/dist/{chunk-B6PFGUYJ.js → chunk-PVEM537A.js} +46 -5
- package/dist/{chunk-QJBX3MBV.js → chunk-Q7BU5Q6I.js} +3 -3
- package/dist/{chunk-SXKIGBNF.js → chunk-QFIVK3G5.js} +1 -1
- package/dist/{chunk-BRIZ6OZ3.js → chunk-QMSEL5YS.js} +81 -23
- package/dist/{chunk-BJEQBKGH.js → chunk-QYJANQWC.js} +8 -8
- package/dist/{chunk-4U56FZ7B.js → chunk-R7RM766N.js} +3 -3
- package/dist/{chunk-QI25QRUP.js → chunk-RD4E5G3B.js} +2 -2
- package/dist/{chunk-QP53XLC5.js → chunk-RHX6MNWY.js} +1 -1
- package/dist/chunk-RIECV7SR.js +234 -0
- package/dist/{chunk-3YBJ36UX.js → chunk-RLDMUSRM.js} +2 -2
- package/dist/{chunk-CXQ724WH.js → chunk-RVWALVDT.js} +2 -2
- package/dist/{chunk-VWTUKKUF.js → chunk-RZIKSE6N.js} +10 -4
- package/dist/chunk-SBAU735L.js +328 -0
- package/dist/{chunk-XRCX6R5S.js → chunk-SBJV2PCU.js} +1 -1
- package/dist/chunk-SO7KTH3Q.js +27 -0
- package/dist/{chunk-327Q53AS.js → chunk-SP37DONS.js} +17 -6
- package/dist/{chunk-KA4WVDLX.js → chunk-T6S45OLV.js} +4 -4
- package/dist/chunk-TCTED52S.js +120 -0
- package/dist/{chunk-HLQ4MS42.js → chunk-TO6TB75E.js} +4 -4
- package/dist/{chunk-465RCKVI.js → chunk-U373MEF5.js} +6 -6
- package/dist/{chunk-AL4HXKDJ.js → chunk-VGE6IHZB.js} +10 -10
- package/dist/{chunk-WBG7XYVR.js → chunk-VHJVD3MZ.js} +8 -0
- package/dist/{chunk-ZZEKOI2M.js → chunk-VMJ2UH4S.js} +1 -1
- package/dist/{chunk-3ICF4IAZ.js → chunk-VS4LPG66.js} +1 -1
- package/dist/{chunk-E3YI6FVJ.js → chunk-VV5EZZNT.js} +1 -1
- package/dist/{chunk-OPU3NYOO.js → chunk-W2IRQJ6R.js} +12 -0
- package/dist/{chunk-PV5BIXT6.js → chunk-WR75WUEP.js} +1 -1
- package/dist/{chunk-XUB4GFPN.js → chunk-WYLFDSIE.js} +144 -99
- package/dist/{chunk-4L33OFU4.js → chunk-X2P43TB2.js} +6 -3
- package/dist/chunk-X2X3IGZU.js +215 -0
- package/dist/{chunk-KIKB6FY3.js → chunk-X6A2VWVJ.js} +2 -2
- package/dist/chunk-XMVSLLED.js +38 -0
- package/dist/{chunk-KDMVVHZH.js → chunk-XTWHNLGD.js} +95 -23
- package/dist/{chunk-QY3TM2T3.js → chunk-YMJOLEPE.js} +4 -4
- package/dist/{chunk-RFKRCVGW.js → chunk-YYA5LXCT.js} +1 -1
- package/dist/{chunk-HSKABJE6.js → chunk-ZDUO6QBH.js} +5 -10
- package/dist/{chunk-PDJWHL63.js → chunk-ZEKCHV43.js} +4 -4
- package/dist/{chunk-23KWUA7Z.js → chunk-ZNEBZCZR.js} +53 -2
- package/dist/chunk-ZNUJFX7L.js +135 -0
- package/dist/{chunk-TP7RXGMP.js → chunk-ZRKEUCUZ.js} +315 -67
- package/dist/{chunk-6Y3KUO7Q.js → chunk-ZSZPMUNX.js} +244 -21
- package/dist/{chunk-4P2BFNSB.js → chunk-ZVTKWWLV.js} +2 -2
- package/dist/{chunk-RCOIKTHM.js → chunk-ZZXMB5F2.js} +1 -1
- package/dist/{cleanup-graph-garbage-6F22Y5SD.js → cleanup-graph-garbage-CAA625RJ.js} +10 -9
- package/dist/cloud-sync-command-DBB7WRHL.js +96 -0
- package/dist/cloud-sync-db-init-V7IB23W5.js +46 -0
- package/dist/{cloud-sync-shutdown-FWERMZB5.js → cloud-sync-shutdown-2D3B73CJ.js} +10 -4
- package/dist/{cloud-sync-state-DJRZORFI.js → cloud-sync-state-5DFKLWNB.js} +1 -1
- package/dist/{co-activation-UEEDCM5U.js → co-activation-JVN7EBS6.js} +4 -4
- package/dist/{co-occurrence-W6OPFRSY.js → co-occurrence-526PTFGT.js} +8 -7
- package/dist/{code-context-index-DWR6HS35.js → code-context-index-XOP6TLPZ.js} +5 -4
- package/dist/{conversation-entity-extractor-LWUIH3UB.js → conversation-entity-extractor-JO56DB2E.js} +9 -4
- package/dist/{conversation-wiki-populator-5EGRW2UZ.js → conversation-wiki-populator-EBUZXYEU.js} +1 -1
- package/dist/{crdt-sync-NHJX3ZJD.js → crdt-sync-LIJLZKFE.js} +2 -2
- package/dist/{crm-webhook-OY467ATC.js → crm-webhook-55F7Y6D2.js} +2 -2
- package/dist/{cto-delegation-gate-XH4YSQVC.js → cto-delegation-gate-QIYV4KFO.js} +41 -24
- package/dist/daemon-auth-SSPY5ODS.js +46 -0
- package/dist/{daemon-orchestration-7425ZVNH.js → daemon-orchestration-Q3GJA2JJ.js} +46 -30
- package/dist/{daemon-ready-VGPSRI3Z.js → daemon-ready-MKBH4QWD.js} +1 -1
- package/dist/{daemon-restart-report-HZU5LWXN.js → daemon-restart-report-EIVD6WDJ.js} +1 -1
- package/dist/db-integrity-events-5DTASXJF.js +22 -0
- package/dist/{db-restore-events-TFCZ4CPM.js → db-restore-events-2FI4ZMKA.js} +1 -1
- package/dist/{doc-graph-extractor-RR2VSO4W.js → doc-graph-extractor-P46R4QME.js} +13 -8
- package/dist/{documents-TRZ4R2ZW.js → documents-7KFEREWO.js} +12 -11
- package/dist/{dreaming-MAMZAPYW.js → dreaming-JMUXBAPU.js} +29 -27
- package/dist/employee-boot-brief-HN63D2BY.js +71 -0
- package/dist/{exe-drift-VBWB5E6S.js → exe-drift-7J7GX7DP.js} +5 -5
- package/dist/{exe-export-XJJTVVT7.js → exe-export-KJ7B2OBU.js} +14 -13
- package/dist/{exe-import-G6O7JFNZ.js → exe-import-HPZDWKGE.js} +14 -13
- package/dist/{exe-key-A2WJLLTM.js → exe-key-2PREP464.js} +117 -105
- package/dist/{exe-org-HXF4XBB3.js → exe-org-VEIISATF.js} +88 -26
- package/dist/{exe-snapshot-TL3TLKLR.js → exe-snapshot-JXQFLUKA.js} +33 -40
- package/dist/{fast-db-init-SO2XUQ7T.js → fast-db-init-SCXJXOYX.js} +1 -1
- package/dist/{founder-context-IOCADC66.js → founder-context-U2SZPLYV.js} +4 -3
- package/dist/{founder-monitor-envelope-SMILO4BT.js → founder-monitor-envelope-5KTKNL5G.js} +4 -4
- package/dist/fts-integrity-LKAZEZJE.js +96 -0
- package/dist/gateway/index.js +19 -19
- package/dist/{git-staleness-I6WT7EXV.js → git-staleness-S4NDR7NX.js} +4 -4
- package/dist/{global-procedures-3RMO6C3C.js → global-procedures-ZOFTOXIR.js} +6 -6
- package/dist/gotrue-session-ODZ2ERJX.js +25 -0
- package/dist/{graph-auto-extract-NKTYPD2I.js → graph-auto-extract-CLVTSUSB.js} +8 -7
- package/dist/{graph-rag-EOGPZOYI.js → graph-rag-LSJLWGXV.js} +4 -3
- package/dist/{hook-integrity-RTBF2BL2.js → hook-integrity-SGTKBL6W.js} +1 -1
- package/dist/{hook-prefetch-V5KCGW2N.js → hook-prefetch-BDSLB6F4.js} +26 -24
- package/dist/hooks/bug-report-worker.js +30 -28
- package/dist/hooks/codex-stop-task-finalizer.js +32 -30
- package/dist/hooks/commit-complete.js +29 -27
- package/dist/hooks/error-recall.js +11 -10
- package/dist/hooks/exe-heartbeat-hook.js +7 -6
- package/dist/hooks/ingest-worker.js +10 -9
- package/dist/hooks/ingest.js +18 -16
- package/dist/hooks/instructions-loaded.js +12 -8
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +8 -7
- package/dist/hooks/post-compact.js +7 -6
- package/dist/hooks/post-tool-combined.js +33 -14
- package/dist/hooks/pre-compact.js +31 -28
- package/dist/hooks/pre-tool-use.js +61 -34
- package/dist/hooks/prompt-submit.js +45 -42
- package/dist/hooks/session-end.js +40 -35
- package/dist/hooks/session-start.js +29 -71
- package/dist/hooks/stop.js +42 -36
- package/dist/hooks/subagent-stop.js +49 -33
- package/dist/hooks/summary-worker.js +35 -33
- package/dist/index.js +40 -38
- package/dist/{installer-G67M3DME.js → installer-EA7T3PBD.js} +7 -7
- package/dist/{installer-L3ZKMOPU.js → installer-KCEM4RCG.js} +7 -7
- package/dist/{installer-QBWZSYDG.js → installer-RC2JCKSE.js} +9 -7
- package/dist/{intercom-queue-R5LSXD3V.js → intercom-queue-6DZPHHQ2.js} +25 -23
- package/dist/{key-backup-status-3RC6XTUX.js → key-backup-status-6L2ARCXW.js} +1 -1
- package/dist/lib/agent-config.js +2 -2
- package/dist/lib/cloud-sync.js +25 -19
- package/dist/lib/config.js +1 -1
- package/dist/lib/consolidation.js +9 -9
- package/dist/lib/crypto.js +3 -1
- package/dist/lib/database.js +18 -4
- package/dist/lib/db-backup.js +4 -2
- package/dist/lib/db-daemon-client.js +5 -4
- package/dist/lib/db-write-worker.js +3 -3
- package/dist/lib/db.js +18 -4
- package/dist/lib/device-registry.js +2 -2
- package/dist/lib/embed-worker.js +1 -1
- package/dist/lib/embedder.js +5 -4
- package/dist/lib/employee-templates.js +7 -7
- package/dist/lib/employees.js +4 -4
- package/dist/lib/exe-daemon-client.js +4 -3
- package/dist/lib/exe-daemon.js +473 -206
- package/dist/lib/hybrid-search.js +8 -8
- package/dist/lib/identity-templates.js +1 -1
- package/dist/lib/identity.js +4 -4
- package/dist/lib/license.js +6 -4
- package/dist/lib/messaging.js +26 -24
- package/dist/lib/post-tool-memory.js +2 -2
- package/dist/lib/registry-proxy.js +3 -1
- package/dist/lib/reminders.js +5 -5
- package/dist/lib/schedules.js +8 -8
- package/dist/lib/session-registry.js +6 -6
- package/dist/lib/skill-learning.js +14 -12
- package/dist/lib/stack-invariants.js +21 -0
- package/dist/lib/status-brief.js +3 -3
- package/dist/lib/store.js +7 -7
- package/dist/lib/task-router.js +5 -5
- package/dist/lib/tasks.js +27 -25
- package/dist/lib/tmux-routing.js +25 -23
- package/dist/lib/token-spend.js +5 -5
- package/dist/{license-gate-6R3F3NQR.js → license-gate-HMSMUIAU.js} +5 -4
- package/dist/{license-sync-VBJCXBAP.js → license-sync-FBCMPC4J.js} +4 -3
- package/dist/{mailbox-inbox-CP2VRBXZ.js → mailbox-inbox-4MEUOL3J.js} +2 -2
- package/dist/{mailbox-outbox-HXI7DYNC.js → mailbox-outbox-J6WIF3UY.js} +1 -1
- package/dist/mcp/register-tools.js +114 -102
- package/dist/mcp/server.js +120 -108
- 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 +30 -27
- package/dist/mcp/tools/deactivate-behavior.js +15 -13
- package/dist/mcp/tools/list-reminders.js +6 -6
- package/dist/mcp/tools/list-tasks.js +30 -27
- package/dist/mcp/tools/send-message.js +29 -26
- package/dist/mcp/tools/update-task.js +28 -26
- package/dist/{mcp-http-config-BWX7AMAZ.js → mcp-http-config-YKJN52HG.js} +5 -5
- package/dist/{mcp-session-identity-GOBGICLI.js → mcp-session-identity-QLUVYWPR.js} +25 -23
- package/dist/{memory-cards-4EXX3BQS.js → memory-cards-K2OSX4AW.js} +7 -7
- package/dist/{memory-graph-extractor-OYVZIJ3R.js → memory-graph-extractor-YLTSKLSY.js} +9 -8
- package/dist/{memory-poisoning-defense-AHOD2EBX.js → memory-poisoning-defense-IPO4ADRL.js} +4 -4
- package/dist/{memory-pressure-watchdog-COJC3OYS.js → memory-pressure-watchdog-ZI3TH2OF.js} +26 -24
- package/dist/{memory-queue-4VN3DTOE.js → memory-queue-QJNWKWKG.js} +2 -2
- package/dist/{memory-queue-client-OI4LDT4W.js → memory-queue-client-HIHCA3W4.js} +6 -5
- package/dist/{memory-reflection-V2SNAUIB.js → memory-reflection-ZKVRU3NT.js} +4 -4
- package/dist/{monitor-grants-W3ISOLMC.js → monitor-grants-BW2WL4IU.js} +3 -3
- package/dist/{notification-ledger-J6Q2GAYU.js → notification-ledger-4REL6M3T.js} +27 -25
- package/dist/{notifications-56TP36IK.js → notifications-UXJUAP3C.js} +25 -23
- package/dist/{orchestration-events-CKQ756NA.js → orchestration-events-GMRGGBMN.js} +5 -5
- package/dist/{orchestration-phase-ZJ4XVNFO.js → orchestration-phase-UDS24CVQ.js} +2 -2
- package/dist/{orchestrator-ERSQ3KNT.js → orchestrator-5TV75HDJ.js} +27 -25
- package/dist/{org-brief-session-FSZ3QJDN.js → org-brief-session-7AZZEO3F.js} +13 -13
- package/dist/{org-consent-policy-BN7MKCZ2.js → org-consent-policy-XT6UZENB.js} +2 -2
- package/dist/{org-join-HTQ57JYH.js → org-join-BMBQDMVF.js} +10 -7
- package/dist/org-key-admin-SCCVVE2H.js +38 -0
- package/dist/{org-key-pin-OTOKAELD.js → org-key-pin-5WUSPGVN.js} +3 -3
- package/dist/{org-membership-SML6GCHP.js → org-membership-ESALTLLN.js} +4 -4
- package/dist/{org-partner-config-XQGOB7EJ.js → org-partner-config-YKHPDPZR.js} +6 -6
- package/dist/{org-partner-runtime-RNNUL5IN.js → org-partner-runtime-WLZAZJIY.js} +14 -14
- package/dist/{org-row-visibility-JZFJ3YRJ.js → org-row-visibility-A5XM4MVO.js} +1 -1
- package/dist/{pipeline-router-IUENNTAY.js → pipeline-router-UEVXDUHR.js} +5 -5
- package/dist/{plan-limits-ZUII366B.js → plan-limits-QEP32X4W.js} +8 -7
- package/dist/{platform-procedures-2VQGBJU7.js → platform-procedures-44NDFTB6.js} +1 -1
- package/dist/{postinstall-failure-A7WTAXD6.js → postinstall-failure-B2JHNFPM.js} +2 -2
- package/dist/{project-boot-3DFY5F35.js → project-boot-LEZSK3W7.js} +9 -1
- package/dist/project-name-ILJTETUE.js +14 -0
- package/dist/{projection-worker-MBWUPB5O.js → projection-worker-GMRC6SBH.js} +4 -4
- package/dist/{prospective-memory-GHE5ORN4.js → prospective-memory-QLHSAPSG.js} +4 -4
- package/dist/{push-notifications-PTQ5DHCD.js → push-notifications-GKRPXOGI.js} +26 -24
- package/dist/reproject-worktree-memories-IXYGHTGA.js +224 -0
- package/dist/{reranker-NUIGAPA3.js → reranker-GB4VEMUV.js} +2 -2
- package/dist/{retrieval-health-XHCERQPG.js → retrieval-health-QIBPBGN6.js} +5 -1
- package/dist/{review-polling-CYBCBHZA.js → review-polling-MU47NQ2N.js} +26 -24
- package/dist/runtime/index.js +37 -35
- package/dist/seat-benefit-VDQJYJOB.js +17 -0
- package/dist/{session-events-X33W4JNA.js → session-events-YMQ3VGBJ.js} +26 -24
- package/dist/{session-kill-telemetry-I2F5PUIW.js → session-kill-telemetry-VGPKE57M.js} +26 -24
- package/dist/{session-mcp-config-YKNXG5DW.js → session-mcp-config-F7KATWOF.js} +10 -1
- package/dist/{session-scope-WXP4F7OF.js → session-scope-P46KAHXQ.js} +26 -24
- package/dist/{setup-wizard-2CTVITIX.js → setup-wizard-BRNHSJ4U.js} +4 -3
- package/dist/{shard-manager-YEOHEOHL.js → shard-manager-UROHZE46.js} +2 -2
- package/dist/{skill-refinement-VDR5OT4V.js → skill-refinement-NLYDSFEH.js} +5 -5
- package/dist/{stack-promote-XVC7FRJW.js → stack-promote-NHFTNIM2.js} +7 -5
- package/dist/{stack-release-6PWAACRM.js → stack-release-AQVKZUS7.js} +7 -5
- package/dist/{stack-update-24VRBQ3U.js → stack-update-LLX5KT7G.js} +38 -6
- package/dist/{steward-gate-2ZNYDVFO.js → steward-gate-JKHYFAHA.js} +5 -5
- package/dist/subagent-brief-injection-VDVOHDOU.js +97 -0
- package/dist/subagent-spawn-ledger-USYZXU3M.js +22 -0
- package/dist/{support-inbox-ZHKLDETT.js → support-inbox-S6YO5YZU.js} +5 -4
- package/dist/{support-outbox-DSWU3IXH.js → support-outbox-HFJWG52M.js} +1 -1
- package/dist/{task-enforcement-GQDUTIFY.js → task-enforcement-LXW45H5Z.js} +26 -24
- package/dist/{task-request-inbox-BFXNUU44.js → task-request-inbox-UCSKDC3R.js} +2 -2
- package/dist/{task-scope-ERHPHLUM.js → task-scope-GDLFE26E.js} +25 -23
- package/dist/{tasks-crud-NVNF3NRA.js → tasks-crud-W7VGWRUV.js} +25 -23
- package/dist/{tasks-notify-DXLU5VCT.js → tasks-notify-CT7NWCS4.js} +26 -24
- package/dist/{tasks-review-BST6N34P.js → tasks-review-WCSKOUFW.js} +25 -23
- package/dist/{telemetry-upload-NY3EKOGY.js → telemetry-upload-FK5WKXVB.js} +10 -9
- package/dist/{token-budget-CLB3GUIX.js → token-budget-GBNGSIU3.js} +5 -5
- package/dist/{tool-capability-index-WZWVBI2R.js → tool-capability-index-BT2GGLLI.js} +1 -1
- package/dist/{tool-telemetry-PALAZUXT.js → tool-telemetry-VKMRS6MP.js} +1 -1
- package/dist/tui/App.js +39 -37
- package/dist/{tui-data-CNFSRZP7.js → tui-data-FTPV2XBQ.js} +25 -23
- package/dist/{update-support-ZVB3CNGY.js → update-support-J6UWPUOC.js} +18 -15
- package/dist/{work-state-heartbeat-O7UMB6SE.js → work-state-heartbeat-4LDF6DSM.js} +1 -1
- package/dist/{worker-gate-6DQQWDNB.js → worker-gate-35VZINZG.js} +2 -2
- package/dist/{workflow-engine-5ZULFH7O.js → workflow-engine-4DA6RSHI.js} +2 -2
- package/dist/working-memory-DPFRSKH3.js +18 -0
- package/dist/{worktree-ZWA35PKW.js → worktree-H3YFJ3NU.js} +6 -6
- package/dist/{worktree-sweep-5LCVT46V.js → worktree-sweep-4EDLLQ2E.js} +9 -7
- package/package.json +11 -5
- package/release-notes.json +86 -34
- package/src/commands/exe/call.md +6 -4
- package/src/commands/exe-reference.md +11 -7
- package/src/commands/exe.md +16 -20
- package/dist/chunk-HISFWAAK.js +0 -90
- package/dist/daemon-auth-OCHW2U6B.js +0 -20
- package/dist/project-name-EWG5KAZP.js +0 -10
- package/dist/session-summary-5EYI4XW4.js +0 -128
- /package/dist/{chunk-YAZ5ECEG.js → chunk-3NBWARKC.js} +0 -0
- /package/dist/{chunk-6C4UAKMS.js → chunk-6CAX7YH4.js} +0 -0
- /package/dist/{chunk-FIPUVCKC.js → chunk-7DMCAGSC.js} +0 -0
- /package/dist/{chunk-X7LY3IOB.js → chunk-JRPYLUXH.js} +0 -0
- /package/dist/{chunk-L4LPJMPV.js → chunk-QYECRPGD.js} +0 -0
- /package/dist/{chunk-UELGUVNL.js → chunk-UY6HRDB2.js} +0 -0
- /package/dist/{chunk-YWN3XMPU.js → chunk-YSDIJ3VI.js} +0 -0
- /package/dist/{core-memory-BZFPVS43.js → core-memory-CMPPHJN5.js} +0 -0
- /package/dist/{entity-boost-VXXED26D.js → entity-boost-CDFAXVYL.js} +0 -0
- /package/dist/{memory-isolation-3PIOWLYP.js → memory-isolation-ZB5S5HCO.js} +0 -0
- /package/dist/{message-queue-client-5XW7ZOK2.js → message-queue-client-PL2POQOV.js} +0 -0
- /package/dist/{oauth-server-KW5M437C.js → oauth-server-NP7KGF7N.js} +0 -0
- /package/dist/{webhook-pipe-QJRFZVKA.js → webhook-pipe-UQSEHFPO.js} +0 -0
- /package/dist/{wiki-acl-RXFV5OEU.js → wiki-acl-5DKOWOIH.js} +0 -0
- /package/dist/{wiki-client-57QWZIHQ.js → wiki-client-AXNM5FWY.js} +0 -0
|
@@ -51,7 +51,7 @@ SMTP_PASS=
|
|
|
51
51
|
# --- Auth gateway (exe-auth — shared SSO sign-in UI at auth.<domain>) ---
|
|
52
52
|
# Bug 58840873: pin the auth image so compose never falls back to its stale
|
|
53
53
|
# hardcoded default tag. Keep in sync with the manifest AUTH_IMAGE_TAG.
|
|
54
|
-
AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.
|
|
54
|
+
AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.5.0
|
|
55
55
|
# Bug 379e5c13: server_name / CORS from the CONFIGURED apex domain, not by naive
|
|
56
56
|
# last-2-label slicing (which breaks company.co.uk → co.uk).
|
|
57
57
|
AUTH_SERVER_NAME=auth.CHANGEME_DOMAIN
|
|
@@ -61,15 +61,59 @@ AUTH_DEFAULT_PRODUCT=AUTH
|
|
|
61
61
|
# the sign-up UI/route instead of showing a form that always fails.
|
|
62
62
|
AUTH_DISABLE_SIGNUP=true
|
|
63
63
|
|
|
64
|
+
# --- Centralized role administration (permissions) ---
|
|
65
|
+
# The apps refuse to let an unmanaged first login mint its own admin
|
|
66
|
+
# (exe-crm#102 / exe-wiki#45). Both flags below are therefore left at their
|
|
67
|
+
# SECURE default of true, stated explicitly rather than inherited silently.
|
|
68
|
+
#
|
|
69
|
+
# Because of that, a fresh CRM gets its first admin from EXE_CRM_ADMIN_EMAIL
|
|
70
|
+
# in the CRM section below — NOT from whoever signs in first. That user is
|
|
71
|
+
# seeded at boot, so their sign-in is an existing-user login and is allowed;
|
|
72
|
+
# every OTHER unmanaged first login is still refused. If you leave
|
|
73
|
+
# EXE_CRM_ADMIN_EMAIL empty, the seed silently does not happen and the CRM
|
|
74
|
+
# cannot be bootstrapped at all. The wiki does not need this: its first admin
|
|
75
|
+
# comes from POST /system/enable-multi-user, authorised by WIKI_AUTH_TOKEN.
|
|
76
|
+
CRM_REQUIRE_MANAGED_PERMS=true
|
|
77
|
+
WIKI_REQUIRE_MANAGED_PERMS=true
|
|
78
|
+
#
|
|
79
|
+
# MANAGED MODE — roles set ONLY in the Exe dashboard. Empty means unmanaged:
|
|
80
|
+
# no token can carry permissions for an org that was never named. To adopt it:
|
|
81
|
+
# EXE_ORG_ID=<org id from the Exe dashboard>
|
|
82
|
+
# EXE_ORG_WORKSPACE_ID=<the org's canonical ACTIVE CRM workspace>
|
|
83
|
+
# EXE_ORG_WORKSPACE_ID must ALREADY EXIST and have a legitimate admin, because
|
|
84
|
+
# managed users join THAT workspace instead of creating their own. That is why
|
|
85
|
+
# managed mode cannot be the shipped default: on a fresh stack the workspace
|
|
86
|
+
# does not exist yet, so its id is unknowable at install time. Bootstrap the
|
|
87
|
+
# stack first, then set these and redeploy. The wiki needs only EXE_ORG_ID.
|
|
88
|
+
EXE_ORG_ID=
|
|
89
|
+
EXE_ORG_WORKSPACE_ID=
|
|
90
|
+
|
|
64
91
|
# --- CRM ---
|
|
65
92
|
CRM_IMAGE_TAG=update.askexe.com/askexe/exe-crm:v0.9.51
|
|
66
93
|
CRM_SERVER_URL=https://crm.CHANGEME_DOMAIN
|
|
67
94
|
CRM_APP_SECRET=CHANGEME_CRM_APP_SECRET
|
|
95
|
+
# The CRM's first admin — seeded at boot by WorkspaceBootstrapService, which is
|
|
96
|
+
# what makes that person an EXISTING user whose sign-in is allowed while every
|
|
97
|
+
# other unmanaged first login is refused (e51ca54c §10.6b). Must be a real
|
|
98
|
+
# mailbox that also exists in GoTrue (CUSTOMER-GUIDE Step 6), so it cannot be
|
|
99
|
+
# generated. Leave it empty and the seed silently throws: the CRM comes up
|
|
100
|
+
# healthy with no workspace and no user, and nobody can ever sign in.
|
|
101
|
+
# SET_MANUALLY
|
|
102
|
+
EXE_CRM_ADMIN_EMAIL=CHANGEME_ADMIN_EMAIL
|
|
68
103
|
CRM_HOST_PORT=3000
|
|
69
104
|
|
|
70
105
|
# --- Wiki ---
|
|
71
106
|
WIKI_IMAGE_TAG=update.askexe.com/askexe/exe-wiki:v0.9.26
|
|
72
|
-
|
|
107
|
+
# Bug 2a8d3003 — DO NOT change this without migrating the data first.
|
|
108
|
+
# The wiki's users / workspaces / workspace_documents live in `public`. Point it at a
|
|
109
|
+
# different schema and Prisma will NOT error: it finds no tables, assumes a fresh
|
|
110
|
+
# database, creates empty ones, and the wiki comes up with zero documents and the
|
|
111
|
+
# admin locked out. It looks exactly like catastrophic data loss while every row is
|
|
112
|
+
# still sitting safely in `public`. That misread has a very expensive next step —
|
|
113
|
+
# restoring a backup over good data. This value used to default to `wiki`, and the
|
|
114
|
+
# only thing holding production together was a host-local compose override.
|
|
115
|
+
# exe-wiki-schema-guard blocks the boot if you get this wrong.
|
|
116
|
+
WIKI_DB_SCHEMA=public
|
|
73
117
|
WIKI_VECTOR_DB=exeOsMcp
|
|
74
118
|
WIKI_AUTH_TOKEN=CHANGEME_WIKI_AUTH_TOKEN
|
|
75
119
|
WIKI_JWT_SECRET=CHANGEME_WIKI_JWT_SECRET
|
|
@@ -80,26 +80,73 @@ SMTP_PASS=
|
|
|
80
80
|
# Bug 58840873: pin the auth image so compose never falls back to its stale
|
|
81
81
|
# hardcoded default tag. Keep in sync with the manifest AUTH_IMAGE_TAG. exe-auth
|
|
82
82
|
# ships only from the private update.askexe.com registry (no GHCR mirror).
|
|
83
|
-
AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.
|
|
83
|
+
AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.5.0
|
|
84
84
|
# Bug 379e5c13: server_name / CORS derived from the CONFIGURED apex domain,
|
|
85
85
|
# not by naive last-2-label slicing (which breaks company.co.uk → co.uk).
|
|
86
86
|
AUTH_SERVER_NAME=auth.CHANGEME_DOMAIN
|
|
87
87
|
AUTH_CORS_ORIGIN=https://CHANGEME_DOMAIN
|
|
88
88
|
AUTH_DEFAULT_PRODUCT=AUTH
|
|
89
|
+
# Brand word after the gold "EXE" in the login logo (exe-auth v0.5.0+). One
|
|
90
|
+
# identity for the whole front door — ?product= never rebrands the page. Leave
|
|
91
|
+
# unset for the stack default "EXE INTELLIGENCE"; white-label deploys set their
|
|
92
|
+
# own word here.
|
|
93
|
+
#AUTH_BRAND_NAME=INTELLIGENCE
|
|
89
94
|
# Bug 5960ebb1: invite-only — mirror GOTRUE_DISABLE_SIGNUP so the auth SPA hides
|
|
90
95
|
# the sign-up UI/route instead of showing a form that always fails.
|
|
91
96
|
AUTH_DISABLE_SIGNUP=true
|
|
92
97
|
|
|
98
|
+
# --- Centralized role administration (permissions) ---
|
|
99
|
+
# The apps refuse to let an unmanaged first login mint its own admin
|
|
100
|
+
# (exe-crm#102 / exe-wiki#45). Both flags below are therefore left at their
|
|
101
|
+
# SECURE default of true, stated explicitly rather than inherited silently.
|
|
102
|
+
#
|
|
103
|
+
# Because of that, a fresh CRM gets its first admin from EXE_CRM_ADMIN_EMAIL
|
|
104
|
+
# in the CRM section below — NOT from whoever signs in first. That user is
|
|
105
|
+
# seeded at boot, so their sign-in is an existing-user login and is allowed;
|
|
106
|
+
# every OTHER unmanaged first login is still refused. If you leave
|
|
107
|
+
# EXE_CRM_ADMIN_EMAIL empty, the seed silently does not happen and the CRM
|
|
108
|
+
# cannot be bootstrapped at all. The wiki does not need this: its first admin
|
|
109
|
+
# comes from POST /system/enable-multi-user, authorised by WIKI_AUTH_TOKEN.
|
|
110
|
+
CRM_REQUIRE_MANAGED_PERMS=true
|
|
111
|
+
WIKI_REQUIRE_MANAGED_PERMS=true
|
|
112
|
+
#
|
|
113
|
+
# MANAGED MODE — roles set ONLY in the Exe dashboard. Empty means unmanaged:
|
|
114
|
+
# no token can carry permissions for an org that was never named. To adopt it:
|
|
115
|
+
# EXE_ORG_ID=<org id from the Exe dashboard>
|
|
116
|
+
# EXE_ORG_WORKSPACE_ID=<the org's canonical ACTIVE CRM workspace>
|
|
117
|
+
# EXE_ORG_WORKSPACE_ID must ALREADY EXIST and have a legitimate admin, because
|
|
118
|
+
# managed users join THAT workspace instead of creating their own. That is why
|
|
119
|
+
# managed mode cannot be the shipped default: on a fresh stack the workspace
|
|
120
|
+
# does not exist yet, so its id is unknowable at install time. Bootstrap the
|
|
121
|
+
# stack first, then set these and redeploy. The wiki needs only EXE_ORG_ID.
|
|
122
|
+
EXE_ORG_ID=
|
|
123
|
+
EXE_ORG_WORKSPACE_ID=
|
|
124
|
+
|
|
93
125
|
# --- CRM ---
|
|
94
126
|
CRM_IMAGE_TAG=ghcr.io/askexe/exe-crm:v0.9.51
|
|
95
127
|
CRM_SERVER_URL=https://crm.CHANGEME_DOMAIN
|
|
96
128
|
CRM_APP_SECRET=CHANGEME_CRM_APP_SECRET
|
|
97
129
|
EXE_CRM_ADMIN_TOKEN=CHANGEME_EXE_CRM_ADMIN_TOKEN
|
|
130
|
+
# The CRM's first admin — seeded at boot by WorkspaceBootstrapService, which
|
|
131
|
+
# is what makes that person an EXISTING user whose sign-in is allowed while
|
|
132
|
+
# every other unmanaged first login is refused (e51ca54c §10.6b). Must be a
|
|
133
|
+
# real mailbox that also exists in GoTrue, so it cannot be generated.
|
|
134
|
+
# SET_MANUALLY
|
|
135
|
+
EXE_CRM_ADMIN_EMAIL=CHANGEME_ADMIN_EMAIL
|
|
98
136
|
CRM_HOST_PORT=3000
|
|
99
137
|
|
|
100
138
|
# --- Wiki ---
|
|
101
139
|
WIKI_IMAGE_TAG=ghcr.io/askexe/exe-wiki:v0.9.26
|
|
102
|
-
|
|
140
|
+
# Bug 2a8d3003 — DO NOT change this without migrating the data first.
|
|
141
|
+
# The wiki's users / workspaces / workspace_documents live in `public`. Point it at a
|
|
142
|
+
# different schema and Prisma will NOT error: it finds no tables, assumes a fresh
|
|
143
|
+
# database, creates empty ones, and the wiki comes up with zero documents and the
|
|
144
|
+
# admin locked out. It looks exactly like catastrophic data loss while every row is
|
|
145
|
+
# still sitting safely in `public`. That misread has a very expensive next step —
|
|
146
|
+
# restoring a backup over good data. This value used to default to `wiki`, and the
|
|
147
|
+
# only thing holding production together was a host-local compose override.
|
|
148
|
+
# exe-wiki-schema-guard blocks the boot if you get this wrong.
|
|
149
|
+
WIKI_DB_SCHEMA=public
|
|
103
150
|
WIKI_VECTOR_DB=exeOsMcp
|
|
104
151
|
WIKI_AUTH_TOKEN=CHANGEME_WIKI_AUTH_TOKEN
|
|
105
152
|
EXE_WIKI_ADMIN_TOKEN=CHANGEME_EXE_WIKI_ADMIN_TOKEN
|
|
@@ -8,16 +8,18 @@
|
|
|
8
8
|
# wiki.<domain> → http://exe-sso-edge:80 (unified SSO redirect)
|
|
9
9
|
# erp.<domain> → http://exe-sso-edge:80 (unified SSO redirect)
|
|
10
10
|
# gateway.<domain> → http://exe-gateway:3100
|
|
11
|
-
# dashboard
|
|
11
|
+
# dashboard.<domain> → http://exe-sso-edge:80 (unified SSO redirect — NOT
|
|
12
|
+
# exe-dashboard:80, which would skip the login gate)
|
|
12
13
|
# monitor.<domain> → http://exe-monitor-hub:8090
|
|
13
14
|
# auth.<domain> → http://exe-sso-edge:80 (auth gateway + real health aliases)
|
|
14
15
|
# api.<domain> → http://exe-os:8765
|
|
15
16
|
# No config.yml or credentials file needed — the token embeds everything.
|
|
16
17
|
#
|
|
17
|
-
# IMPORTANT: crm/wiki/erp MUST route through exe-sso-edge (NOT
|
|
18
|
-
# app container). The edge is what 302s unauthenticated
|
|
19
|
-
# auth.<domain>; routing direct to the app skips the redirect
|
|
20
|
-
# bug). exe-sso-edge picks the app by Host header, so all
|
|
18
|
+
# IMPORTANT: crm/wiki/erp/dashboard MUST route through exe-sso-edge (NOT
|
|
19
|
+
# straight to the app container). The edge is what 302s unauthenticated
|
|
20
|
+
# visitors to auth.<domain>; routing direct to the app skips the redirect
|
|
21
|
+
# (this was the bug). exe-sso-edge picks the app by Host header, so all four
|
|
22
|
+
# share one route.
|
|
21
23
|
#
|
|
22
24
|
# ADVANCED (config file mode): only needed if you want to manage routes locally
|
|
23
25
|
# instead of via the Cloudflare dashboard. Leave CLOUDFLARE_TUNNEL_TOKEN empty
|
|
@@ -44,9 +46,14 @@ ingress:
|
|
|
44
46
|
# Gateway (WhatsApp, webhooks, pairing)
|
|
45
47
|
- hostname: gateway.CHANGEME_DOMAIN
|
|
46
48
|
service: http://exe-gateway:3100
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
# Dashboard — through the unified SSO edge, same as crm/wiki/erp. The edge
|
|
50
|
+
# gates on the canonical exe_access_token cookie and 302s unauthenticated
|
|
51
|
+
# visitors to auth.<domain>/?product=Dashboard&redirect=<dashboard-url><uri>.
|
|
52
|
+
# Routing straight to exe-dashboard:80 skips that gate (same class of bug as
|
|
53
|
+
# 96f8b2b2 for crm/wiki/erp) and leaves an ungated hostname serving 200 to
|
|
54
|
+
# anonymous requests.
|
|
55
|
+
- hostname: dashboard.CHANGEME_DOMAIN
|
|
56
|
+
service: http://exe-sso-edge:80
|
|
50
57
|
# Monitor — /_/ admin panel blocked; only the API and UI are exposed publicly.
|
|
51
58
|
# The PocketBase superadmin UI must be accessed via SSH tunnel:
|
|
52
59
|
# ssh -L 8090:127.0.0.1:8090 <vps> then open http://localhost:8090/_/
|
|
@@ -254,7 +254,7 @@ services:
|
|
|
254
254
|
options: { max-size: "10m", max-file: "3" }
|
|
255
255
|
|
|
256
256
|
exe-monitor-hub:
|
|
257
|
-
image: ${MONITOR_HUB_IMAGE_TAG:-ghcr.io/askexe/exe-monitor-hub:v0.9.5}
|
|
257
|
+
image: ${MONITOR_HUB_IMAGE_TAG:-ghcr.io/askexe/exe-monitor-hub:v0.9.5@sha256:1af31893cc8b1e51892be7d7705fa6c6b3108af8366b1fa8da2879d8ae21ec88}
|
|
258
258
|
container_name: exe-monitor-hub
|
|
259
259
|
restart: unless-stopped
|
|
260
260
|
# bug d3d49101 / 1fdb8be9: PocketBase's data dir for this hub is a RELATIVE
|
|
@@ -332,7 +332,7 @@ services:
|
|
|
332
332
|
# ------------------------------------------------------------------
|
|
333
333
|
|
|
334
334
|
exe-crm:
|
|
335
|
-
image: ${CRM_IMAGE_TAG:-ghcr.io/askexe/exe-crm:v0.9.51}
|
|
335
|
+
image: ${CRM_IMAGE_TAG:-ghcr.io/askexe/exe-crm:v0.9.51@sha256:73864ce14aaac06b73d67100bbf88e669fd13c7da39edd9644107037211559b7}
|
|
336
336
|
container_name: exe-crm
|
|
337
337
|
restart: unless-stopped
|
|
338
338
|
# bug ad4471ad: NO compose `command` override. The image entrypoint
|
|
@@ -368,7 +368,52 @@ services:
|
|
|
368
368
|
MONITOR_API_KEY: ${MONITOR_API_KEY:-${EXE_MONITOR_KEY:-}}
|
|
369
369
|
APP_SECRET: ${CRM_APP_SECRET:?CRM_APP_SECRET is required}
|
|
370
370
|
EXE_CRM_ADMIN_TOKEN: ${EXE_CRM_ADMIN_TOKEN:-}
|
|
371
|
+
# ── Centralized role administration (e51ca54c §10.6b) ──────────────────
|
|
372
|
+
# READ BEFORE CHANGING. These four values decide whether a fresh install
|
|
373
|
+
# can seat an administrator at all, and whether a stranger can seat
|
|
374
|
+
# himself. Both failure modes are one empty variable away.
|
|
375
|
+
#
|
|
376
|
+
# HOW A FIRST ADMIN IS MEANT TO APPEAR. On an empty database
|
|
377
|
+
# WorkspaceBootstrapService (workspace-bootstrap.service.ts, OnModuleInit)
|
|
378
|
+
# seeds one workspace (activationStatus=PENDING_CREATION) plus the user
|
|
379
|
+
# named by EXE_CRM_ADMIN_EMAIL. When that person later signs in through
|
|
380
|
+
# GoTrue they are an EXISTING user, so the first-login path is never
|
|
381
|
+
# entered; the pending workspace is activated and setupDefaultRoles grants
|
|
382
|
+
# them Admin. The first admin is therefore chosen by the OPERATOR, in this
|
|
383
|
+
# file, before anyone logs in.
|
|
384
|
+
#
|
|
385
|
+
# WHY EXE_CRM_ADMIN_EMAIL IS NOT OPTIONAL IN PRACTICE. bootstrapIfEmpty()
|
|
386
|
+
# THROWS when it is empty, and onModuleInit swallows that error as
|
|
387
|
+
# "non-fatal" — the CRM boots healthy with no workspace and no user. Leave
|
|
388
|
+
# it unset and the seed silently does not happen; the next sign-in is then
|
|
389
|
+
# a FIRST login, which exe-crm#102 refuses (403), and the
|
|
390
|
+
# POST /api/auth/admin-token break-glass also fails ("No workspace found"),
|
|
391
|
+
# because it activates an existing workspace and never creates one. That is
|
|
392
|
+
# a fresh install nobody can ever get into. It is left `:-` rather than
|
|
393
|
+
# `:?` ONLY so that already-provisioned customer stacks keep parsing this
|
|
394
|
+
# file; a NEW install that omits it is broken, which is why generate-env.ts
|
|
395
|
+
# now emits it and .env.customer.example marks it SET_MANUALLY.
|
|
371
396
|
EXE_CRM_ADMIN_EMAIL: ${EXE_CRM_ADMIN_EMAIL:-}
|
|
397
|
+
# The guard itself stays at its SECURE default, stated rather than
|
|
398
|
+
# inherited. exe-crm#102 makes managed-permissions required by default so
|
|
399
|
+
# an unmanaged FIRST login can no longer create a workspace and take its
|
|
400
|
+
# Admin role. Because the bootstrap above seats the intended owner as an
|
|
401
|
+
# existing user, keeping this ON costs a correct install nothing — and it
|
|
402
|
+
# still refuses every OTHER unmanaged first login. Set it to false only for
|
|
403
|
+
# a deliberate no-control-plane bootstrap where you accept that the first
|
|
404
|
+
# unmanaged sign-in becomes a workspace Admin; the app logs that choice as
|
|
405
|
+
# a SECURITY DOWNGRADE on every boot.
|
|
406
|
+
CRM_REQUIRE_MANAGED_PERMS: ${CRM_REQUIRE_MANAGED_PERMS:-true}
|
|
407
|
+
# Managed mode (roles set ONLY in the Exe dashboard). Empty here means
|
|
408
|
+
# unmanaged: no token can carry permissions for an org that was never
|
|
409
|
+
# named, so every login resolves { managed: false }. To adopt it, set both
|
|
410
|
+
# — EXE_ORG_WORKSPACE_ID must name an ALREADY-EXISTING active workspace
|
|
411
|
+
# with a legitimate admin, because managed users join THAT workspace
|
|
412
|
+
# instead of minting their own. That ordering is why managed mode cannot be
|
|
413
|
+
# the shipped default: on a fresh stack the workspace does not exist yet,
|
|
414
|
+
# so its id is unknowable at install time. Bootstrap first, then adopt.
|
|
415
|
+
EXE_ORG_ID: ${EXE_ORG_ID:-}
|
|
416
|
+
EXE_ORG_WORKSPACE_ID: ${EXE_ORG_WORKSPACE_ID:-}
|
|
372
417
|
GOTRUE_URL: http://gotrue:9999
|
|
373
418
|
# Bug 51086951: the EXPECTED JWT issuer. GOTRUE_URL above is the INTERNAL
|
|
374
419
|
# address used to call GoTrue, but browser tokens are signed with the PUBLIC
|
|
@@ -376,6 +421,18 @@ services:
|
|
|
376
421
|
# SAME public value here so issuer validation accepts real browser sessions
|
|
377
422
|
# instead of rejecting them as iss-mismatch. Same default as the gotrue pin.
|
|
378
423
|
GOTRUE_JWT_ISSUER: ${GOTRUE_JWT_ISSUER:-${GOTRUE_EXTERNAL_URL:?GOTRUE_EXTERNAL_URL is required — set to https://auth.<your-domain> in .env}}
|
|
424
|
+
# Bug 550d6ab7: CRM verifies GoTrue tokens JWKS-first with an HS256
|
|
425
|
+
# shared-secret fallback (exe-crm access-token.service.ts verifyGoTrueToken
|
|
426
|
+
# -> getGoTrueSymmetricVerificationKey, landed in exe-crm 80c5cd95). Our
|
|
427
|
+
# GoTrue is configured with a SYMMETRIC GOTRUE_JWT_SECRET and no
|
|
428
|
+
# GOTRUE_JWT_KEYS, so it publishes an empty JWKS ({"keys":[]}) — and it
|
|
429
|
+
# MUST stay empty, because publishing an `oct` key would publish the
|
|
430
|
+
# signing secret itself. The HS256 fallback is therefore the ONLY viable
|
|
431
|
+
# verification path, and it returns null when this variable is unset. That
|
|
432
|
+
# is the same defect class as bug 0c0d5187 on exe-wiki (see the wiki
|
|
433
|
+
# service block below): the fix landed in the app, the secret was never
|
|
434
|
+
# handed to the container, so SSO stayed dead. Fail loud.
|
|
435
|
+
GOTRUE_JWT_SECRET: ${GOTRUE_JWT_SECRET:?GOTRUE_JWT_SECRET is required}
|
|
379
436
|
PG_DATABASE_URL: postgres://${POSTGRES_USER:-exe}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@exe-db:5432/${POSTGRES_DB:-exedb}?sslmode=disable
|
|
380
437
|
REDIS_URL: redis://:${REDIS_PASSWORD:?REDIS_PASSWORD is required}@redis:6379
|
|
381
438
|
CLICKHOUSE_URL: http://${CLICKHOUSE_USER:-exe}:${CLICKHOUSE_PASSWORD:?CLICKHOUSE_PASSWORD is required}@clickhouse:8123/${CLICKHOUSE_DB:-default}
|
|
@@ -401,7 +458,7 @@ services:
|
|
|
401
458
|
options: { max-size: "10m", max-file: "3" }
|
|
402
459
|
|
|
403
460
|
exe-crm-worker:
|
|
404
|
-
image: ${CRM_IMAGE_TAG:-ghcr.io/askexe/exe-crm:v0.9.51}
|
|
461
|
+
image: ${CRM_IMAGE_TAG:-ghcr.io/askexe/exe-crm:v0.9.51@sha256:73864ce14aaac06b73d67100bbf88e669fd13c7da39edd9644107037211559b7}
|
|
405
462
|
container_name: exe-crm-worker
|
|
406
463
|
restart: unless-stopped
|
|
407
464
|
command: ["yarn", "worker:prod"]
|
|
@@ -460,17 +517,63 @@ services:
|
|
|
460
517
|
driver: json-file
|
|
461
518
|
options: { max-size: "10m", max-file: "3" }
|
|
462
519
|
|
|
520
|
+
# Bug 2a8d3003: one-shot pre-flight that refuses to let exe-wiki start against a
|
|
521
|
+
# schema where its data isn't. Reuses the already-present Postgres image purely for
|
|
522
|
+
# its psql client — no extra pull. See wiki-schema-guard.sh for the full rationale;
|
|
523
|
+
# the short version is that Prisma silently bootstraps an empty schema rather than
|
|
524
|
+
# erroring, so "wiki looks wiped" and "wiki is misconfigured" are indistinguishable
|
|
525
|
+
# at a glance, and the wrong diagnosis (restore from backup) destroys real data.
|
|
526
|
+
exe-wiki-schema-guard:
|
|
527
|
+
image: ${EXE_DB_IMAGE:-pgvector/pgvector:0.8.0-pg16@sha256:a132765ec351c65111b5b675928a3a0515a466a40f97277329db8b8209ad8bc9}
|
|
528
|
+
container_name: exe-wiki-schema-guard
|
|
529
|
+
restart: "no"
|
|
530
|
+
depends_on:
|
|
531
|
+
exe-db:
|
|
532
|
+
condition: service_healthy
|
|
533
|
+
environment:
|
|
534
|
+
# MUST stay byte-identical to exe-wiki's DATABASE_URL below — the guard's whole
|
|
535
|
+
# job is to assert on the schema the wiki itself will resolve.
|
|
536
|
+
DATABASE_URL: postgres://${POSTGRES_USER:-exe}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@exe-db:5432/${POSTGRES_DB:-exedb}?schema=${WIKI_DB_SCHEMA:-public}&sslmode=disable
|
|
537
|
+
WIKI_SCHEMA_GUARD: ${WIKI_SCHEMA_GUARD:-enforce}
|
|
538
|
+
volumes:
|
|
539
|
+
- ./wiki-schema-guard.sh:/usr/local/bin/wiki-schema-guard.sh:ro
|
|
540
|
+
# Fail OPEN when the script itself is missing, fail CLOSED on what it detects.
|
|
541
|
+
# On a stack dir that predates this change Docker materialises the bind source as
|
|
542
|
+
# an empty directory, and a guard that can't be found must not be the reason the
|
|
543
|
+
# wiki stays down — an absent guard is no worse than the status quo, whereas a
|
|
544
|
+
# guard that wedges the wiki is a new outage. stack-update installs the real
|
|
545
|
+
# script next to docker-compose.yml on every run.
|
|
546
|
+
entrypoint:
|
|
547
|
+
- bash
|
|
548
|
+
- -c
|
|
549
|
+
- |
|
|
550
|
+
if [ -f /usr/local/bin/wiki-schema-guard.sh ]; then
|
|
551
|
+
exec bash /usr/local/bin/wiki-schema-guard.sh
|
|
552
|
+
fi
|
|
553
|
+
echo "[wiki-schema-guard] script not installed next to docker-compose.yml — skipping."
|
|
554
|
+
echo "[wiki-schema-guard] run 'exe-os stack update' to install it; until then the"
|
|
555
|
+
echo "[wiki-schema-guard] wiki can boot against an empty schema undetected (bug 2a8d3003)."
|
|
556
|
+
networks:
|
|
557
|
+
- backend
|
|
558
|
+
logging:
|
|
559
|
+
driver: json-file
|
|
560
|
+
options: { max-size: "10m", max-file: "3" }
|
|
561
|
+
|
|
463
562
|
exe-wiki:
|
|
464
|
-
image: ${WIKI_IMAGE_TAG:-ghcr.io/askexe/exe-wiki:v0.9.26}
|
|
563
|
+
image: ${WIKI_IMAGE_TAG:-ghcr.io/askexe/exe-wiki:v0.9.26@sha256:c0d61d183b274a67977fdfb1b40d5e4736559a9d90507843183e5642da2a959d}
|
|
465
564
|
container_name: exe-wiki
|
|
466
565
|
restart: unless-stopped
|
|
467
566
|
# Wiki uses Prisma — runs migrate on boot via built-in entrypoint.
|
|
468
|
-
# If tables don't exist, Prisma creates them automatically.
|
|
567
|
+
# If tables don't exist, Prisma creates them automatically. That convenience is
|
|
568
|
+
# exactly why exe-wiki-schema-guard has to clear the boot first (bug 2a8d3003):
|
|
569
|
+
# pointed at the wrong schema, Prisma builds empty tables instead of complaining.
|
|
469
570
|
depends_on:
|
|
470
571
|
exe-db:
|
|
471
572
|
condition: service_healthy
|
|
472
573
|
gotrue:
|
|
473
574
|
condition: service_healthy
|
|
575
|
+
exe-wiki-schema-guard:
|
|
576
|
+
condition: service_completed_successfully
|
|
474
577
|
# SECURITY (bug 67d62490): no blanket `env_file: .env`. Each service
|
|
475
578
|
# receives ONLY the secrets it owns via the explicit `environment:` block
|
|
476
579
|
# below (values interpolated from .env at compose-parse time, never the
|
|
@@ -486,10 +589,55 @@ services:
|
|
|
486
589
|
ERROR_REPORTING_ENABLED: "true"
|
|
487
590
|
MONITOR_ERROR_URL: http://exe-monitor-hub:8090/api/exe-monitor/errors
|
|
488
591
|
MONITOR_API_KEY: ${MONITOR_API_KEY:-${EXE_MONITOR_KEY:-}}
|
|
489
|
-
|
|
592
|
+
# Bug 2a8d3003: the wiki's live data lives in the `public` schema and ALWAYS has.
|
|
593
|
+
# This default used to be `wiki`, and the ONLY thing keeping production pointed at
|
|
594
|
+
# its real content was a hand-written docker-compose.override.yml on the host that
|
|
595
|
+
# dropped the schema param. Drop that override — or honour WIKI_DB_SCHEMA=wiki —
|
|
596
|
+
# and the wiki boots against an empty `wiki` schema that Prisma will happily
|
|
597
|
+
# bootstrap: zero users, zero documents, admin locked out, and the real rows
|
|
598
|
+
# sitting untouched in `public` looking exactly like data loss. `public` is now the
|
|
599
|
+
# explicit, authoritative default so base and override agree.
|
|
600
|
+
#
|
|
601
|
+
# Why keep `?schema=` rather than omitting it: an omitted param makes resolution
|
|
602
|
+
# implicit (it falls back to the role's search_path, which ALTER ROLE can silently
|
|
603
|
+
# change). Naming the schema pins it deterministically and keeps the knob available
|
|
604
|
+
# for operators who genuinely want isolation — see WIKI_DB_SCHEMA in .env.example
|
|
605
|
+
# for the migration that requires. exe-wiki-schema-guard below enforces the choice.
|
|
606
|
+
DATABASE_URL: postgres://${POSTGRES_USER:-exe}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@exe-db:5432/${POSTGRES_DB:-exedb}?schema=${WIKI_DB_SCHEMA:-public}&sslmode=disable
|
|
490
607
|
AUTH_TOKEN: ${WIKI_AUTH_TOKEN:?WIKI_AUTH_TOKEN is required}
|
|
491
608
|
EXE_WIKI_ADMIN_TOKEN: ${EXE_WIKI_ADMIN_TOKEN:-}
|
|
609
|
+
# ── Centralized role administration (e51ca54c §10.6b) ──────────────────
|
|
610
|
+
# The wiki keeps the SECURE default, stated rather than inherited.
|
|
611
|
+
#
|
|
612
|
+
# exe-wiki#45 makes WIKI_REQUIRE_MANAGED_PERMS default ON: an unmanaged
|
|
613
|
+
# identity (which is every identity while EXE_ORG_ID is empty) provisions
|
|
614
|
+
# as a non-privileged `default` — it can sign in, gets no admin and no
|
|
615
|
+
# workspace, and sees "contact your administrator to request access to a
|
|
616
|
+
# team". Unlike the CRM this does NOT strand a fresh install, because the
|
|
617
|
+
# wiki's first admin does not come from an SSO first login at all: a fresh
|
|
618
|
+
# wiki boots in single-user mode (prisma seed sets multi_user_mode=false)
|
|
619
|
+
# and POST /system/enable-multi-user — authorised by the admin-token bypass
|
|
620
|
+
# in validatedRequest.js, which accepts EXE_WIKI_ADMIN_TOKEN *or* the
|
|
621
|
+
# always-required AUTH_TOKEN above — creates the first `role: admin` user
|
|
622
|
+
# directly, never touching resolveGoTrueUser. So the guard costs a correct
|
|
623
|
+
# install nothing here and is left ON.
|
|
624
|
+
#
|
|
625
|
+
# Managed mode: set EXE_ORG_ID (shared with exe-crm) and roles follow the
|
|
626
|
+
# dashboard's caps. The wiki needs no workspace-id pin because it never
|
|
627
|
+
# creates a tenant, so it can be flipped as soon as an org id exists.
|
|
628
|
+
# Setting this to false restores first-user-admin and is logged as a
|
|
629
|
+
# SECURITY DOWNGRADE on every boot.
|
|
630
|
+
WIKI_REQUIRE_MANAGED_PERMS: ${WIKI_REQUIRE_MANAGED_PERMS:-true}
|
|
631
|
+
EXE_ORG_ID: ${EXE_ORG_ID:-}
|
|
492
632
|
GOTRUE_URL: http://gotrue:9999
|
|
633
|
+
# Bug 0c0d5187: the wiki verifies GoTrue HS256 tokens with GOTRUE_JWT_SECRET
|
|
634
|
+
# (server/utils/gotrue/index.js getGoTrueJwtSecret reads ONLY
|
|
635
|
+
# GOTRUE_JWT_SECRET || EXE_GOTRUE_JWT_SECRET) — NOT the wiki-local JWT_SECRET
|
|
636
|
+
# below. Without it, GoTrue's JWKS is empty so the asymmetric path is dead too,
|
|
637
|
+
# and every SSO exchange AND the wiki's own password form 401 with
|
|
638
|
+
# "Invalid or expired SSO token." Fail loud rather than ship a wiki nobody can
|
|
639
|
+
# log in to.
|
|
640
|
+
GOTRUE_JWT_SECRET: ${GOTRUE_JWT_SECRET:?GOTRUE_JWT_SECRET is required}
|
|
493
641
|
# Bug 98a528a7 (class): the PUBLIC auth domain the wiki login link must point at.
|
|
494
642
|
# Same lever as ERP — without it the wiki frontend can default to auth.askexe.com
|
|
495
643
|
# instead of the customer's auth.<domain>. The wiki image must build its SSO
|
|
@@ -552,7 +700,7 @@ services:
|
|
|
552
700
|
# to pin the split server image; falls back to the combined EXE_OS_IMAGE_TAG
|
|
553
701
|
# for backward compatibility with existing manifests.
|
|
554
702
|
exe-os:
|
|
555
|
-
image: ${EXE_OS_SERVER_IMAGE_TAG:-${EXE_OS_IMAGE_TAG:-${EXED_IMAGE_TAG:-ghcr.io/askexe/exe-os:v0.9.311}}}
|
|
703
|
+
image: ${EXE_OS_SERVER_IMAGE_TAG:-${EXE_OS_IMAGE_TAG:-${EXED_IMAGE_TAG:-ghcr.io/askexe/exe-os:v0.9.311@sha256:011730042f55277724dbe83fde1a6416db2f3e8bf62d3254738d68d8de33e1f9}}}
|
|
556
704
|
container_name: exe-os
|
|
557
705
|
restart: unless-stopped
|
|
558
706
|
# bug debf4a39 / 93ddfa27: the daemon connects to exe-db at boot
|
|
@@ -617,7 +765,22 @@ services:
|
|
|
617
765
|
# the GGUF model files at /home/exed/.exe-os/models/.
|
|
618
766
|
# ------------------------------------------------------------------
|
|
619
767
|
exe-os-worker:
|
|
620
|
-
|
|
768
|
+
# NO DEFAULT ON PURPOSE. This slot used to default to
|
|
769
|
+
# ghcr.io/askexe/exe-os-worker:v0.9.311 — an image that has NEVER been
|
|
770
|
+
# published (GHCR returns "manifest unknown" for every tag, and the package
|
|
771
|
+
# itself 404s). Nobody noticed because embeddings are off by default and this
|
|
772
|
+
# service is profile-gated, so the tag was only ever a promise.
|
|
773
|
+
#
|
|
774
|
+
# A default that cannot be pulled is worse than no default: it turns "enable
|
|
775
|
+
# embeddings" into an unpullable-image failure, and it cannot be digest-pinned,
|
|
776
|
+
# which is what the strict-digest gate requires. The slot is left EMPTY instead —
|
|
777
|
+
# `docker compose` refuses to start a service with no image, so activating the
|
|
778
|
+
# embeddings profile without setting this fails loudly and immediately. When a
|
|
779
|
+
# worker image is published, set EXE_OS_WORKER_IMAGE_TAG to a digest-pinned ref
|
|
780
|
+
# (ghcr.io/askexe/exe-os-worker:<tag>@sha256:<digest>) — strict-digest enforces
|
|
781
|
+
# the pin from there. Deliberately NOT `:?`: that would make the variable
|
|
782
|
+
# mandatory for every deploy, including the default embeddings-off one.
|
|
783
|
+
image: ${EXE_OS_WORKER_IMAGE_TAG:-}
|
|
621
784
|
container_name: exe-os-worker
|
|
622
785
|
profiles: ["embeddings"]
|
|
623
786
|
restart: unless-stopped
|
|
@@ -656,7 +819,7 @@ services:
|
|
|
656
819
|
options: { max-size: "10m", max-file: "3" }
|
|
657
820
|
|
|
658
821
|
exe-gateway:
|
|
659
|
-
image: ${GATEWAY_IMAGE_TAG:-ghcr.io/askexe/exe-gateway:v0.9.24}
|
|
822
|
+
image: ${GATEWAY_IMAGE_TAG:-ghcr.io/askexe/exe-gateway:v0.9.24@sha256:9cda7c00d886b4ab16a3b88aa953aa45c991f2977084ea8532f55fcaf75e8f37}
|
|
660
823
|
container_name: exe-gateway
|
|
661
824
|
restart: unless-stopped
|
|
662
825
|
# Gateway needs 45s to flush outbound queues + disconnect Baileys adapters.
|
|
@@ -804,7 +967,7 @@ services:
|
|
|
804
967
|
# include "monitor-agent". See deploy/monitor/HOST-ACCESS-CONSENT.md.
|
|
805
968
|
# ------------------------------------------------------------------
|
|
806
969
|
exe-monitor-agent:
|
|
807
|
-
image: ${MONITOR_AGENT_IMAGE_TAG:-ghcr.io/askexe/exe-monitor-agent:v0.9.5}
|
|
970
|
+
image: ${MONITOR_AGENT_IMAGE_TAG:-ghcr.io/askexe/exe-monitor-agent:v0.9.5@sha256:cada7dace00ccb629aa10976e80e20d7d25685042519bd2aec58ab4bf35ff0cd}
|
|
808
971
|
container_name: exe-monitor-agent
|
|
809
972
|
# Host-access consent gate: only starts when the operator has
|
|
810
973
|
# acknowledged the host-access scope (COMPOSE_PROFILES=monitor-agent).
|
|
@@ -853,11 +1016,32 @@ services:
|
|
|
853
1016
|
networks:
|
|
854
1017
|
- backend
|
|
855
1018
|
healthcheck:
|
|
856
|
-
#
|
|
857
|
-
#
|
|
858
|
-
#
|
|
859
|
-
#
|
|
860
|
-
|
|
1019
|
+
# COUPLED TO THE PINNED AGENT IMAGE GENERATION — change both together.
|
|
1020
|
+
#
|
|
1021
|
+
# Two agent image generations exist with DIFFERENT binary paths:
|
|
1022
|
+
# v0.9.4 and earlier -> /app/beszel-agent (has a shell)
|
|
1023
|
+
# v2026.08.09-*-stamped -> /agent (scratch, NO shell)
|
|
1024
|
+
#
|
|
1025
|
+
# bug 9ce2a68b moved this to `/agent health` for the stamped generation.
|
|
1026
|
+
# The stack manifest pins the v0.9.4 generation (the stamped monitor
|
|
1027
|
+
# rollout in stack 0.9.34 was attempted 3x on exe-db-jkt and rolled back
|
|
1028
|
+
# every time), so the check must address /app/beszel-agent again.
|
|
1029
|
+
#
|
|
1030
|
+
# A generation-agnostic check is NOT possible: the stamped image is
|
|
1031
|
+
# scratch, so there is no shell for a `a || b` fallback and no
|
|
1032
|
+
# wget/curl for a port probe. Docker healthchecks execute inside the
|
|
1033
|
+
# container, so the check can only use binaries the image ships.
|
|
1034
|
+
#
|
|
1035
|
+
# If this mismatches the pinned image the container is permanently
|
|
1036
|
+
# unhealthy from the first recreate. Observed live on exe-db-jkt
|
|
1037
|
+
# 2026-08-10 08:13-08:40, every 30s:
|
|
1038
|
+
# Health check ... error: OCI runtime exec failed: exec: "/agent":
|
|
1039
|
+
# stat /agent: no such file or directory
|
|
1040
|
+
#
|
|
1041
|
+
# The binary-native `health` subcommand checks the freshness of the
|
|
1042
|
+
# agent's health file, which only stays fresh while it is actively
|
|
1043
|
+
# reporting to the hub.
|
|
1044
|
+
test: ["CMD", "/app/beszel-agent", "health"]
|
|
861
1045
|
interval: 30s
|
|
862
1046
|
timeout: 5s
|
|
863
1047
|
start_period: 30s
|
|
@@ -884,7 +1068,7 @@ services:
|
|
|
884
1068
|
# Without a token the binary exits 0 (no crash-loop). (bug 3416cead)
|
|
885
1069
|
# ------------------------------------------------------------------
|
|
886
1070
|
exe-update:
|
|
887
|
-
image: ${EXE_OS_IMAGE_TAG:-${EXED_IMAGE_TAG:-ghcr.io/askexe/exe-os:v0.9.311}}
|
|
1071
|
+
image: ${EXE_OS_IMAGE_TAG:-${EXED_IMAGE_TAG:-ghcr.io/askexe/exe-os:v0.9.311@sha256:011730042f55277724dbe83fde1a6416db2f3e8bf62d3254738d68d8de33e1f9}}
|
|
888
1072
|
container_name: exe-update
|
|
889
1073
|
profiles: ["registry-proxy", "askexe-control-plane"]
|
|
890
1074
|
restart: unless-stopped
|
|
@@ -983,9 +1167,16 @@ services:
|
|
|
983
1167
|
# Probe an app subdomain so the gate's server block (not the default 404)
|
|
984
1168
|
# answers. Any 2xx/3xx from the edge proves it is serving.
|
|
985
1169
|
# bug f1e79d3b: nginx:alpine ships BusyBox wget, which does NOT support
|
|
986
|
-
# --max-redirect — that flag made the probe error out.
|
|
987
|
-
#
|
|
988
|
-
|
|
1170
|
+
# --max-redirect — that flag made the probe error out.
|
|
1171
|
+
# Follow-up: probing "/" on a gated vhost cannot work either. Anonymous "/"
|
|
1172
|
+
# is exactly what the gate 302s to auth.<domain>, and BusyBox wget FOLLOWS
|
|
1173
|
+
# redirects with no way to cap them, so the probe chases the login funnel
|
|
1174
|
+
# and dies with "wget: too many redirections" — the edge is serving
|
|
1175
|
+
# correctly but reports unhealthy (seen live on askexe.com once crm was
|
|
1176
|
+
# routed through the edge). Probe the crm vhost's EXEMPT /healthz instead:
|
|
1177
|
+
# it never redirects and it proves vhost selection + gate exemption + the
|
|
1178
|
+
# CRM upstream in one request.
|
|
1179
|
+
test: ["CMD", "wget", "-qO-", "--header=Host: crm.${DOMAIN}", "http://127.0.0.1:80/healthz"]
|
|
989
1180
|
interval: 30s
|
|
990
1181
|
timeout: 5s
|
|
991
1182
|
retries: 3
|
|
@@ -1086,7 +1277,7 @@ services:
|
|
|
1086
1277
|
# 4 services: gunicorn API, websocket, RQ worker, scheduler.
|
|
1087
1278
|
|
|
1088
1279
|
exe-erp:
|
|
1089
|
-
image: ${ERP_IMAGE_TAG:-ghcr.io/askexe/exe-erp:v0.2.2}
|
|
1280
|
+
image: ${ERP_IMAGE_TAG:-ghcr.io/askexe/exe-erp:v0.2.2@sha256:00fecc790ff848bfd4b7d87f42f859edfeb6090a7ca26bf2359dc6cb96767afb}
|
|
1090
1281
|
container_name: exe-erp
|
|
1091
1282
|
restart: unless-stopped
|
|
1092
1283
|
entrypoint: ["/usr/local/bin/entrypoint.sh"]
|
|
@@ -1227,7 +1418,7 @@ services:
|
|
|
1227
1418
|
options: { max-size: "10m", max-file: "3" }
|
|
1228
1419
|
|
|
1229
1420
|
exe-erp-websocket:
|
|
1230
|
-
image: ${ERP_IMAGE_TAG:-ghcr.io/askexe/exe-erp:v0.2.2}
|
|
1421
|
+
image: ${ERP_IMAGE_TAG:-ghcr.io/askexe/exe-erp:v0.2.2@sha256:00fecc790ff848bfd4b7d87f42f859edfeb6090a7ca26bf2359dc6cb96767afb}
|
|
1231
1422
|
container_name: exe-erp-websocket
|
|
1232
1423
|
restart: unless-stopped
|
|
1233
1424
|
entrypoint: []
|
|
@@ -1289,7 +1480,7 @@ services:
|
|
|
1289
1480
|
options: { max-size: "10m", max-file: "3" }
|
|
1290
1481
|
|
|
1291
1482
|
exe-erp-queue:
|
|
1292
|
-
image: ${ERP_IMAGE_TAG:-ghcr.io/askexe/exe-erp:v0.2.2}
|
|
1483
|
+
image: ${ERP_IMAGE_TAG:-ghcr.io/askexe/exe-erp:v0.2.2@sha256:00fecc790ff848bfd4b7d87f42f859edfeb6090a7ca26bf2359dc6cb96767afb}
|
|
1293
1484
|
container_name: exe-erp-queue
|
|
1294
1485
|
restart: unless-stopped
|
|
1295
1486
|
entrypoint: []
|
|
@@ -1320,11 +1511,16 @@ services:
|
|
|
1320
1511
|
networks:
|
|
1321
1512
|
- backend
|
|
1322
1513
|
healthcheck:
|
|
1323
|
-
#
|
|
1324
|
-
# bug
|
|
1325
|
-
#
|
|
1326
|
-
#
|
|
1327
|
-
|
|
1514
|
+
# Liveness = the RQ worker process (PID 1) is still running.
|
|
1515
|
+
# bug ed19883e: the slim Frappe base has NEITHER pgrep NOR ps/procps
|
|
1516
|
+
# (exit 127 "not found") → the process-table probes were permanently
|
|
1517
|
+
# false-unhealthy → 180s stack-update gate → rollback. Also `bench
|
|
1518
|
+
# worker` runs the RQ worker in-process (frappe.utils.background_jobs
|
|
1519
|
+
# .start_worker → Worker.work()); PID 1 argv stays "bench worker", so a
|
|
1520
|
+
# `rq worker` grep would miss it even if ps existed. Use python (the
|
|
1521
|
+
# image base is python:3.14-slim) to read PID 1's argv directly — this
|
|
1522
|
+
# matches the exe-erp repo's own docker-compose.yml probe.
|
|
1523
|
+
test: ["CMD-SHELL", "python -c \"import sys; cmd=open('/proc/1/cmdline','rb').read().replace(b'\\0', b' '); sys.exit(0 if b'bench worker' in cmd else 1)\""]
|
|
1328
1524
|
interval: 30s
|
|
1329
1525
|
timeout: 5s
|
|
1330
1526
|
start_period: 30s
|
|
@@ -1338,7 +1534,7 @@ services:
|
|
|
1338
1534
|
options: { max-size: "10m", max-file: "3" }
|
|
1339
1535
|
|
|
1340
1536
|
exe-erp-scheduler:
|
|
1341
|
-
image: ${ERP_IMAGE_TAG:-ghcr.io/askexe/exe-erp:v0.2.2}
|
|
1537
|
+
image: ${ERP_IMAGE_TAG:-ghcr.io/askexe/exe-erp:v0.2.2@sha256:00fecc790ff848bfd4b7d87f42f859edfeb6090a7ca26bf2359dc6cb96767afb}
|
|
1342
1538
|
container_name: exe-erp-scheduler
|
|
1343
1539
|
restart: unless-stopped
|
|
1344
1540
|
entrypoint: []
|
|
@@ -1369,11 +1565,13 @@ services:
|
|
|
1369
1565
|
networks:
|
|
1370
1566
|
- backend
|
|
1371
1567
|
healthcheck:
|
|
1372
|
-
#
|
|
1373
|
-
# bug
|
|
1374
|
-
#
|
|
1375
|
-
#
|
|
1376
|
-
|
|
1568
|
+
# Liveness = the scheduler process (PID 1) is still running.
|
|
1569
|
+
# bug ed19883e: the slim Frappe base has NEITHER pgrep NOR ps/procps
|
|
1570
|
+
# (exit 127 "not found") → the process-table probe was permanently
|
|
1571
|
+
# false-unhealthy → 180s stack-update gate → rollback. Use python (the
|
|
1572
|
+
# image base is python:3.14-slim) to read PID 1's argv directly — this
|
|
1573
|
+
# matches the exe-erp repo's own docker-compose.yml probe.
|
|
1574
|
+
test: ["CMD-SHELL", "python -c \"import sys; cmd=open('/proc/1/cmdline','rb').read().replace(b'\\0', b' '); sys.exit(0 if b'bench schedule' in cmd else 1)\""]
|
|
1377
1575
|
interval: 30s
|
|
1378
1576
|
timeout: 5s
|
|
1379
1577
|
start_period: 30s
|
|
@@ -1466,7 +1664,7 @@ services:
|
|
|
1466
1664
|
# a fresh/migrated install boots an old image while the manifest reads "latest".
|
|
1467
1665
|
# generate-env.ts now always writes AUTH_IMAGE_TAG, and this default mirrors the
|
|
1468
1666
|
# pin as defense-in-depth — keep BOTH in lockstep on every auth release.
|
|
1469
|
-
image: ${AUTH_IMAGE_TAG:-update.askexe.com/askexe/exe-auth:v0.
|
|
1667
|
+
image: ${AUTH_IMAGE_TAG:-update.askexe.com/askexe/exe-auth:v0.5.0@sha256:ecc57f92b1f2c2d9df4fafe648622fe1fdd87c27012048d950e3f6b82086ccf9}
|
|
1470
1668
|
container_name: exe-auth
|
|
1471
1669
|
restart: unless-stopped
|
|
1472
1670
|
environment:
|
|
@@ -1483,6 +1681,14 @@ services:
|
|
|
1483
1681
|
AUTH_CORS_ORIGIN: ${AUTH_CORS_ORIGIN:-https://${DOMAIN}}
|
|
1484
1682
|
AUTH_DEFAULT_REDIRECT: ${AUTH_DEFAULT_REDIRECT:-}
|
|
1485
1683
|
AUTH_DEFAULT_PRODUCT: ${AUTH_DEFAULT_PRODUCT:-AUTH}
|
|
1684
|
+
# Brand word rendered after the gold "EXE" in the login logo (exe-auth
|
|
1685
|
+
# v0.5.0+). The auth gateway is ONE front door for the whole stack, so it
|
|
1686
|
+
# carries one identity regardless of which product bounced the visitor
|
|
1687
|
+
# here — ?product= no longer rebrands the page. Unset => the image
|
|
1688
|
+
# defaults to INTELLIGENCE ("EXE INTELLIGENCE"); white-label deploys set
|
|
1689
|
+
# AUTH_BRAND_NAME in .env. Passthrough is required or the .env value can
|
|
1690
|
+
# never reach the container.
|
|
1691
|
+
AUTH_BRAND_NAME: ${AUTH_BRAND_NAME:-}
|
|
1486
1692
|
# Bug 5960ebb1: invite-only posture. Mirror GOTRUE_DISABLE_SIGNUP (which
|
|
1487
1693
|
# blocks signup server-side) so the auth SPA hides its sign-up UI/route
|
|
1488
1694
|
# instead of presenting a form that can only ever fail. Defaults true.
|