@askexenow/exe-os 0.9.382 → 0.9.384
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/delivery/catalog.json +1254 -0
- package/deploy/compose/.env.customer.example +5 -5
- package/deploy/compose/.env.example +3 -3
- package/deploy/compose/docker-compose.yml +1 -1
- package/deploy/compose/generate-env.ts +65 -9
- package/deploy/compose/setup.sh +205 -7
- package/deploy/compose/sso-edge/default.conf.template +45 -0
- package/deploy/compose/sso-edge/sso-redirect.conf +11 -2
- package/deploy/stack-manifests/v0.9.30-apps.json +1 -1
- package/deploy/stack-manifests/v0.9.json +254 -2
- package/dist/.dist-verified.json +3 -3
- package/dist/{active-agent-GFUUCFLD.js → active-agent-F5V4E4UL.js} +7 -7
- package/dist/{active-agent-LE6FE6SO.js → active-agent-YTBB4ZQM.js} +7 -7
- package/dist/{agent-defs-generator-EIUA3SH5.js → agent-defs-generator-7TFISIJQ.js} +6 -6
- package/dist/{agent-loop-7ZRH56EX.js → agent-loop-EZ7LDAGD.js} +1 -1
- package/dist/{agentic-ontology-67JGSP7G.js → agentic-ontology-XVTUVV7W.js} +1 -1
- package/dist/{artifact-backup-NYXAYASJ.js → artifact-backup-TF6YWQT2.js} +5 -5
- package/dist/{backfill-gate-KWJQ35YX.js → backfill-gate-FWYLCGNJ.js} +3 -3
- package/dist/{backfill-metadata-RQYG2WUJ.js → backfill-metadata-J6MXIDCW.js} +10 -10
- package/dist/{background-jobs-6VMD55PK.js → background-jobs-V3DZRFKU.js} +3 -3
- package/dist/{backup-verify-HC4YDSGN.js → backup-verify-6DVBQMDP.js} +67 -18
- package/dist/{behavior-injection-6HSXP43Q.js → behavior-injection-XDA7ZCYN.js} +21 -20
- package/dist/{behavior-promotion-SJDQ2Y3U.js → behavior-promotion-4VLQ7LXK.js} +20 -19
- package/dist/{behaviors-6ITLA2CK.js → behaviors-SCCZP7RZ.js} +19 -18
- package/dist/bin/age-ontology-load.js +3 -3
- package/dist/bin/agentic-ontology-backfill.js +12 -12
- package/dist/bin/agentic-reflection-backfill.js +13 -13
- package/dist/bin/agentic-semantic-label.js +12 -12
- package/dist/bin/backfill-conversations.js +17 -16
- package/dist/bin/backfill-responses.js +17 -16
- package/dist/bin/backfill-vectors.js +23 -22
- package/dist/bin/bulk-sync-postgres.js +28 -27
- package/dist/bin/cc-doctor.js +17 -16
- package/dist/bin/cleanup-stale-review-tasks.js +29 -28
- package/dist/bin/cli.js +35 -26
- package/dist/bin/deferred-daemon-restart.js +124 -123
- package/dist/bin/exe-actions.js +1 -1
- package/dist/bin/exe-agent-config.js +6 -6
- package/dist/bin/exe-agent.js +22 -22
- package/dist/bin/exe-assign.js +19 -18
- package/dist/bin/exe-boot.js +57 -56
- package/dist/bin/exe-call.js +7 -7
- package/dist/bin/exe-cicd.js +38 -8
- package/dist/bin/exe-cloud.js +30 -29
- package/dist/bin/exe-config-dump.js +6 -6
- package/dist/bin/exe-dispatch.js +30 -29
- package/dist/bin/exe-doctor.js +11 -11
- package/dist/bin/exe-export-behaviors.js +23 -22
- package/dist/bin/exe-forget.js +13 -13
- package/dist/bin/exe-gateway.js +47 -14
- package/dist/bin/exe-grant.js +6 -6
- package/dist/bin/exe-healthcheck.js +17 -16
- package/dist/bin/exe-heartbeat.js +41 -35
- package/dist/bin/exe-kill.js +35 -34
- package/dist/bin/exe-launch-agent.js +43 -42
- package/dist/bin/exe-mcp.js +9 -9
- package/dist/bin/exe-memory-reads.js +10 -10
- package/dist/bin/exe-new-employee.js +11 -11
- package/dist/bin/exe-os-mcp-proxy.js +9 -9
- package/dist/bin/exe-pending-messages.js +30 -29
- package/dist/bin/exe-pending-notifications.js +29 -28
- package/dist/bin/exe-pending-reviews.js +30 -29
- package/dist/bin/exe-preflight.js +1 -1
- package/dist/bin/exe-rename.js +9 -9
- package/dist/bin/exe-review.js +34 -33
- package/dist/bin/exe-search.js +12 -12
- package/dist/bin/exe-session-cleanup.js +35 -34
- package/dist/bin/exe-settings.js +29 -28
- package/dist/bin/exe-start-codex.js +30 -29
- package/dist/bin/exe-start-opencode.js +27 -26
- package/dist/bin/exe-status.js +31 -30
- package/dist/bin/exe-support.js +5 -5
- package/dist/bin/exe-team.js +7 -7
- package/dist/bin/exe-verify-running-images.js +1 -1
- package/dist/bin/exe-watchdog.js +8 -8
- package/dist/bin/generate-hook-manifest.js +7 -1
- package/dist/bin/git-sweep.js +30 -29
- package/dist/bin/graph-backfill.js +12 -12
- package/dist/bin/graph-export.js +11 -11
- package/dist/bin/hooks-cli.js +1 -1
- package/dist/bin/import-history.js +15 -15
- package/dist/bin/install.js +130 -129
- package/dist/bin/intercom-check.js +11 -7
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +7 -7
- package/dist/bin/postgres-agentic-reflection-backfill.js +5 -5
- package/dist/bin/postgres-agentic-semantic-backfill.js +4 -4
- package/dist/bin/reconcile-backlog.js +2 -2
- package/dist/bin/registry-proxy.js +1 -1
- package/dist/bin/repair-document-chunks.js +161 -0
- package/dist/bin/scan-tasks.js +30 -29
- package/dist/bin/setup.js +5 -5
- package/dist/bin/shard-migrate.js +11 -11
- package/dist/bin/stack-update.js +625 -33
- package/dist/bin/update.js +96 -22
- package/dist/bin/verify-stack.js +2 -2
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/{boot-generation-L55QANCX.js → boot-generation-Q7LGQ3AO.js} +6 -6
- package/dist/{boot-review-sections-AON5ZCR2.js → boot-review-sections-G5774FR5.js} +28 -27
- package/dist/{branch-hygiene-QLD77IMJ.js → branch-hygiene-44WLSOZR.js} +2 -2
- package/dist/{branding-I6KIMB7F.js → branding-KMWCY5HZ.js} +3 -3
- package/dist/build-manifest.json +1259 -1219
- package/dist/{capability-cards-WTOXY7O6.js → capability-cards-I3RHCF4F.js} +5 -5
- package/dist/{capacity-monitor-ZLG7FSWM.js → capacity-monitor-7I7GDONU.js} +30 -29
- package/dist/{catchup-brief-QHY7D7N2.js → catchup-brief-3T5PARIR.js} +39 -36
- package/dist/check-image-pullability-2AIVB4BX.js +338 -0
- package/dist/{chunk-CTCCYKOV.js → chunk-2FKU4ZEO.js} +55 -29
- package/dist/{chunk-M7O7TGGU.js → chunk-2NW4LRDU.js} +1 -1
- package/dist/{chunk-XTFM4KMW.js → chunk-2PZTMSMG.js} +6 -6
- package/dist/{chunk-UWX6MMCX.js → chunk-3B6FLNLV.js} +1 -1
- package/dist/{chunk-GPJIBLP4.js → chunk-3DAEZILW.js} +1 -1
- package/dist/{chunk-NY6SBR4O.js → chunk-3FGBBJYM.js} +15 -3
- package/dist/{chunk-C4OZVVSG.js → chunk-3OX34OC3.js} +50 -18
- package/dist/{chunk-TXTXC3QG.js → chunk-3RGTLZNO.js} +12 -12
- package/dist/{chunk-PYRO25A5.js → chunk-3SUPEE6H.js} +10 -11
- package/dist/{chunk-PPMGQFLJ.js → chunk-3XY57PKT.js} +2 -2
- package/dist/{chunk-CRHI5QTZ.js → chunk-46VSBDUW.js} +2 -2
- package/dist/{chunk-VZT66WWP.js → chunk-4AAMFWJT.js} +2 -2
- package/dist/{chunk-4GZTBLJG.js → chunk-4AR5XKCH.js} +1 -1
- package/dist/{chunk-IHXW4VUI.js → chunk-5IADGFGR.js} +1 -1
- package/dist/{chunk-GLQEJOXE.js → chunk-5MVKTNZP.js} +57 -0
- package/dist/{chunk-AVMLC2MR.js → chunk-5U2IJBFV.js} +290 -41
- package/dist/{chunk-JUKDL5MF.js → chunk-6BJCDWSM.js} +1 -1
- package/dist/{chunk-6WWNK7UX.js → chunk-6FIC57PH.js} +1 -1
- package/dist/{chunk-ASUICGPX.js → chunk-6YDY6ZTD.js} +4 -4
- package/dist/{chunk-FU5O2REK.js → chunk-72V3S44T.js} +108 -29
- package/dist/{chunk-LTIIZHNA.js → chunk-7J2ZQ4XN.js} +1 -1
- package/dist/{chunk-7RI2CNXJ.js → chunk-7OTR2OET.js} +1 -1
- package/dist/{chunk-ZVBVPX4W.js → chunk-7UHZBVP3.js} +82 -51
- package/dist/{chunk-PTY2N23C.js → chunk-AGC2V7JS.js} +26 -13
- package/dist/{chunk-44VR3PFW.js → chunk-AHESD3KW.js} +1 -1
- package/dist/{chunk-NPGV4MZ3.js → chunk-ALRHGEAJ.js} +1 -1
- package/dist/{chunk-WJC6AAJN.js → chunk-ANVHWV2X.js} +2 -2
- package/dist/{chunk-AGZSGAEN.js → chunk-APL7HUE3.js} +105 -32
- package/dist/{chunk-7UH2JWBF.js → chunk-AZSTIAVL.js} +176 -11
- package/dist/chunk-AZXMR25O.js +545 -0
- package/dist/{chunk-WPWEBZ37.js → chunk-B7AMNZTC.js} +2 -2
- package/dist/{chunk-4CF5KUWH.js → chunk-BPVFZ6Q4.js} +3 -3
- package/dist/{chunk-XTQ7R2PA.js → chunk-BV2IET6B.js} +73 -17
- package/dist/{chunk-4F5CNI65.js → chunk-C5ISP5FO.js} +2 -2
- package/dist/{chunk-NPWNXJ3U.js → chunk-CH7BUBP3.js} +7 -7
- package/dist/{chunk-X5Q66EOG.js → chunk-CHIUS5QB.js} +16 -16
- package/dist/{chunk-ZG62LIK3.js → chunk-CIPDQRFO.js} +1 -1
- package/dist/{chunk-4PYIRIU6.js → chunk-CM7N5MBY.js} +5 -5
- package/dist/{chunk-L5YDAFUH.js → chunk-CYCIX7AW.js} +5 -5
- package/dist/{chunk-76YRJKKF.js → chunk-D3LXVAIQ.js} +28 -16
- package/dist/{chunk-2GNAHBRD.js → chunk-DMUOTCDN.js} +1 -1
- package/dist/{chunk-QMUFSRQX.js → chunk-DN3ZR3UE.js} +1 -1
- package/dist/{chunk-V3WLC5TJ.js → chunk-DRTJCG6B.js} +1 -1
- package/dist/{chunk-275WHBEN.js → chunk-DYVLEMKS.js} +1 -1
- package/dist/{chunk-O34F5EP5.js → chunk-DZN7SDY2.js} +1 -1
- package/dist/{chunk-ZDIXMHY7.js → chunk-E3ZM32LF.js} +8 -8
- package/dist/{chunk-N2HXR5MB.js → chunk-E7C2WNR5.js} +4 -4
- package/dist/{chunk-VVGXWVZU.js → chunk-EGOEB42T.js} +3 -3
- package/dist/{chunk-QV5CQLQH.js → chunk-EIOGV75A.js} +2 -2
- package/dist/{chunk-ZY4IGUOS.js → chunk-ELCRJGCH.js} +3 -3
- package/dist/{chunk-5QCIWWFA.js → chunk-ELEGH4DX.js} +130 -14
- package/dist/{chunk-S7CTCPSW.js → chunk-EOTZSAQL.js} +1 -1
- package/dist/{chunk-PPLQ4ECD.js → chunk-EUGEFBGV.js} +3 -3
- package/dist/{chunk-UFNCL6MS.js → chunk-EYMFVITZ.js} +1 -1
- package/dist/{chunk-F6H7GP2O.js → chunk-F4BBMIPG.js} +3 -3
- package/dist/{chunk-FNEZ4BWT.js → chunk-FEU6QEEL.js} +1 -1
- package/dist/{chunk-JKOC2L6P.js → chunk-FHIFTSPL.js} +1 -1
- package/dist/{chunk-4RTKETV3.js → chunk-FMIYFHLE.js} +3 -3
- package/dist/{chunk-TK544DEW.js → chunk-FVLNNNH6.js} +3 -3
- package/dist/{chunk-AY2U4NZ5.js → chunk-GL47M7NY.js} +85 -17
- package/dist/{chunk-DN24VTS5.js → chunk-GSLFH4AI.js} +25 -13
- package/dist/{chunk-CHO5SNWR.js → chunk-HA63SH5W.js} +1 -1
- package/dist/{chunk-4IK2K3B3.js → chunk-HME6ITKV.js} +1 -1
- package/dist/{chunk-H2T6TFJZ.js → chunk-HU3VD4MQ.js} +2 -2
- package/dist/{chunk-ZW32RI66.js → chunk-I5XIW2BP.js} +49 -11
- package/dist/{chunk-3CL2I3RG.js → chunk-IGJMS7C5.js} +2 -2
- package/dist/{chunk-BRPO6GOH.js → chunk-JA3Y5TV6.js} +2 -2
- package/dist/{chunk-SFFXAPYK.js → chunk-JDDM6C57.js} +1 -1
- package/dist/{chunk-W4EGAQXW.js → chunk-JFJP6ATJ.js} +2 -2
- package/dist/{chunk-ENCUOZXX.js → chunk-JFTUAV4J.js} +1 -1
- package/dist/{chunk-3UOQH2DJ.js → chunk-JJTPPAZY.js} +2568 -345
- package/dist/{chunk-A6QBAUJH.js → chunk-KILR4FBR.js} +4 -4
- package/dist/{chunk-CGFGNHSP.js → chunk-KTKIFXIP.js} +1 -1
- package/dist/{chunk-NCJBPXGM.js → chunk-KXYKSLW4.js} +108 -24
- package/dist/{chunk-3MUARHPO.js → chunk-L3VUW5M4.js} +1 -1
- package/dist/{chunk-GZOG2MAX.js → chunk-L5EPGGDP.js} +1 -1
- package/dist/{chunk-T7VSKWES.js → chunk-L63V25HS.js} +6 -5
- package/dist/{chunk-R4VNGRKU.js → chunk-LFBLQE2P.js} +1 -1
- package/dist/{chunk-W5MCOZTW.js → chunk-LFUBEHFW.js} +12 -2
- package/dist/{chunk-AIBIEP4R.js → chunk-LKTN22L6.js} +61 -25
- package/dist/{chunk-3KFQCFQB.js → chunk-LR5O2XWZ.js} +5 -5
- package/dist/{chunk-VUOAPKPI.js → chunk-LSNBTGW4.js} +1 -1
- package/dist/{chunk-P5U3GAWU.js → chunk-MB47DRF5.js} +2 -2
- package/dist/{chunk-HZESME3B.js → chunk-MC4IM2CC.js} +16 -13
- package/dist/{chunk-ZKJ5S23O.js → chunk-MFAOAIUE.js} +12 -9
- package/dist/{chunk-62J64CHO.js → chunk-MKM6D7JM.js} +26 -7
- package/dist/{chunk-ZIG7VPJV.js → chunk-MMS2HBRT.js} +15 -3
- package/dist/{chunk-FHSV4BSW.js → chunk-MOANZQXF.js} +12 -4
- package/dist/{chunk-RTZZBWQC.js → chunk-MPZ2AVNS.js} +16 -5
- package/dist/{chunk-AZ6KLVDX.js → chunk-MROSARM5.js} +2 -2
- package/dist/{chunk-RV2FFCDS.js → chunk-MUAWCFW6.js} +6 -2
- package/dist/{chunk-K4ESASPL.js → chunk-MUCNYSJP.js} +1 -1
- package/dist/{chunk-5QGKMP6T.js → chunk-NF5FOSLD.js} +1 -1
- package/dist/{chunk-CKOJP7JI.js → chunk-NKEFYE4R.js} +2 -2
- package/dist/{chunk-3SXHEQ7X.js → chunk-NPXIS2RY.js} +1 -1
- package/dist/{chunk-A5USSF66.js → chunk-NVFNADTX.js} +12 -8
- package/dist/{chunk-VVUO3RJS.js → chunk-NYLJQ2M2.js} +4 -4
- package/dist/{chunk-HIVOLPLD.js → chunk-OAFENIHN.js} +1 -1
- package/dist/{chunk-PMZHZQ6K.js → chunk-OBBO6EJR.js} +1 -1
- package/dist/{chunk-SS6EMDLL.js → chunk-P2UY34XE.js} +6 -6
- package/dist/{chunk-Y4T5IUEP.js → chunk-P3QQ52QK.js} +2 -2
- package/dist/{chunk-GGEKMY6G.js → chunk-P3UX5EH4.js} +4 -4
- package/dist/{chunk-F7IRZU5G.js → chunk-P4PIZOL2.js} +3 -3
- package/dist/{chunk-GEPFKUUR.js → chunk-P4XLIPB7.js} +1 -1
- package/dist/{chunk-GPUOUUHA.js → chunk-PCV52RYM.js} +1 -1
- package/dist/{chunk-XR3773KZ.js → chunk-PL4CFSQ7.js} +1 -1
- package/dist/{chunk-LLZNPOGB.js → chunk-PLII76NJ.js} +58 -0
- package/dist/{chunk-FT5PPV2C.js → chunk-PRDDPQLC.js} +5 -5
- package/dist/{chunk-BZ546I4Q.js → chunk-PUBA5B4M.js} +24 -0
- package/dist/{chunk-2TGJ5XCV.js → chunk-PWC3C5ME.js} +4 -4
- package/dist/{chunk-A4YCLD3L.js → chunk-QFAFKEB5.js} +40 -4
- package/dist/{chunk-CL4J4757.js → chunk-QH5ZQ5SJ.js} +26 -0
- package/dist/{chunk-UJWZYK46.js → chunk-QNZ4562V.js} +1 -1
- package/dist/{chunk-IPHLUZ37.js → chunk-QPTSA4PP.js} +2 -2
- package/dist/{chunk-O3YJTHWI.js → chunk-R5E7WNAC.js} +3 -3
- package/dist/{chunk-V3M4LJRA.js → chunk-RB3J2WYQ.js} +1 -1
- package/dist/{chunk-IUCWOI4Y.js → chunk-RDWIKDMY.js} +237 -11
- package/dist/{chunk-ENN6DY4T.js → chunk-RVO5O5SR.js} +46 -21
- package/dist/{chunk-LY4AXCYJ.js → chunk-RZN2LEAK.js} +6 -6
- package/dist/{chunk-2YIB75UQ.js → chunk-S26CV7BE.js} +57 -13
- package/dist/{chunk-XC36HYP6.js → chunk-SDYWZRPN.js} +1 -1
- package/dist/{chunk-PHBU4LGO.js → chunk-SNHYZYGZ.js} +1 -1
- package/dist/{chunk-4KTTBKWQ.js → chunk-T5FEAQES.js} +1 -1
- package/dist/{chunk-XU57KFD6.js → chunk-T5SM4RXY.js} +5 -1
- package/dist/{chunk-KUV5VBAO.js → chunk-TKAU7IJ2.js} +1 -1
- package/dist/{chunk-KBR5LIWD.js → chunk-TKS5GMYA.js} +1 -1
- package/dist/{chunk-5DFE2NAF.js → chunk-TNS63ATU.js} +96 -22
- package/dist/{chunk-RFPMXR6B.js → chunk-U4GMOT4M.js} +1 -1
- package/dist/{chunk-CO5ZVE3D.js → chunk-UOPCVFVR.js} +17 -17
- package/dist/{chunk-22LNFCDF.js → chunk-UX2EO653.js} +1 -1
- package/dist/{chunk-LGC6TBA3.js → chunk-UXN4BICC.js} +2 -2
- package/dist/{chunk-7J5X4AK7.js → chunk-VF2KRROX.js} +1 -1
- package/dist/{chunk-7THUQU44.js → chunk-VF3BZOZK.js} +5 -2
- package/dist/{chunk-M2B35MUK.js → chunk-VHHX4UCP.js} +1 -1
- package/dist/{chunk-AZBJXATK.js → chunk-VJEJ7JNB.js} +1 -1
- package/dist/{chunk-4TRVALTR.js → chunk-VLBHZ6TF.js} +2 -2
- package/dist/{chunk-7BMSBACY.js → chunk-VOVFUKEB.js} +5 -5
- package/dist/{chunk-MDPGZS6C.js → chunk-VROK4X2L.js} +1 -1
- package/dist/{chunk-J6ABJDZ4.js → chunk-W3KPQE7H.js} +4 -4
- package/dist/{chunk-3Q7NEDHB.js → chunk-W6BZ4UGA.js} +48 -9
- package/dist/{chunk-IZ3IFLL2.js → chunk-XEBKIWI7.js} +14 -14
- package/dist/{chunk-UZDF6FLJ.js → chunk-XHU3KOKJ.js} +1 -1
- package/dist/{chunk-PA37MXV5.js → chunk-XSUALA32.js} +2 -2
- package/dist/{chunk-GR5WJPKF.js → chunk-XUZK23V7.js} +11 -6
- package/dist/{chunk-IDB3EZLW.js → chunk-YLB365YX.js} +148 -5
- package/dist/{chunk-JDQ7JU3A.js → chunk-YLFCH3VA.js} +24 -16
- package/dist/{chunk-ZJJL2Z23.js → chunk-YRQ26MNP.js} +4 -4
- package/dist/chunk-YRUZK2QA.js +35 -0
- package/dist/{chunk-7HLJ4BSF.js → chunk-ZAEUEDTN.js} +2 -2
- package/dist/{chunk-NY74W3S4.js → chunk-ZBPZDADW.js} +313 -43
- package/dist/{chunk-ZLPS3GR7.js → chunk-ZJQ56DZZ.js} +42 -1
- package/dist/{chunk-VMZZTFXT.js → chunk-ZOTTYCP5.js} +4 -4
- package/dist/{chunk-MP4ST7RO.js → chunk-ZPP63JSQ.js} +51 -11
- package/dist/{chunk-N4J5WHO2.js → chunk-ZT4LFTUJ.js} +1 -1
- package/dist/{cleanup-graph-garbage-GE2DYOTB.js → cleanup-graph-garbage-VQAJ2RBT.js} +11 -11
- package/dist/{cloud-sync-command-T6KF3ARK.js → cloud-sync-command-J7NEFUY7.js} +2 -2
- package/dist/{cloud-sync-db-init-RSHCCY74.js → cloud-sync-db-init-KWEMNMGA.js} +1 -1
- package/dist/{cloud-sync-shutdown-6IVCSLM5.js → cloud-sync-shutdown-P63AUTUI.js} +5 -5
- package/dist/{co-activation-AF7RCJPX.js → co-activation-7IHRPBZN.js} +5 -5
- package/dist/{co-occurrence-DMOOGBVV.js → co-occurrence-R5AG4OAU.js} +9 -9
- package/dist/{code-context-index-LIDOFKOR.js → code-context-index-WFLLZBVB.js} +10 -9
- package/dist/{code-context-watcher-4F7K2N3U.js → code-context-watcher-3QAPHO7N.js} +10 -9
- package/dist/{codex-consolidation-SH4UKFBQ.js → codex-consolidation-ONZ2AQFX.js} +2 -2
- package/dist/{consent-passphrase-WV7MZPMO.js → consent-passphrase-5ZBDJ5G7.js} +2 -2
- package/dist/{content-extractor-DJM5EUDA.js → content-extractor-ZLXC6GNR.js} +2 -2
- package/dist/{conversation-entity-extractor-4UG7BKWL.js → conversation-entity-extractor-7FRKLLBD.js} +4 -4
- package/dist/{conversation-wiki-populator-OS4C6W54.js → conversation-wiki-populator-YAOVCUGO.js} +1 -1
- package/dist/{crdt-sync-VL4KXZB7.js → crdt-sync-IFRZOEIS.js} +4 -4
- package/dist/{crm-webhook-IDBJ7X5Y.js → crm-webhook-L2S63ASV.js} +2 -2
- package/dist/{cto-delegation-gate-4FLSHSLO.js → cto-delegation-gate-3WU7OHX7.js} +29 -28
- package/dist/{daemon-auth-PNKHERLV.js → daemon-auth-OWLFYEFR.js} +3 -3
- package/dist/{daemon-orchestration-HFCB6OK4.js → daemon-orchestration-3VQYKLOR.js} +33 -32
- package/dist/{daemon-ready-BN6EZLTQ.js → daemon-ready-VZ6ZHA2C.js} +1 -1
- package/dist/{db-integrity-events-GYGANKZV.js → db-integrity-events-7NKWS5MT.js} +3 -3
- package/dist/{db-restore-events-G6NOQOVE.js → db-restore-events-XYL6CGPC.js} +2 -2
- package/dist/{destructive-data-guard-HHWUBIGS.js → destructive-data-guard-JDUJ2ULM.js} +58 -2
- package/dist/{dispatch-ack-X4DXUSKP.js → dispatch-ack-UYEAKON5.js} +2 -1
- package/dist/{doc-graph-extractor-E36PQUCS.js → doc-graph-extractor-YIR5E7OF.js} +9 -9
- package/dist/{documents-SCKKHDR7.js → documents-QEHPTYIY.js} +19 -18
- package/dist/{dreaming-Q26JBH56.js → dreaming-LNFE7DTN.js} +34 -33
- package/dist/{employee-boot-brief-XU6EI2EO.js → employee-boot-brief-ZTXDYNWM.js} +39 -38
- package/dist/{entity-boost-VNQLLR3Q.js → entity-boost-R5N6JWXD.js} +1 -1
- package/dist/{exe-drift-YZ6OIUAY.js → exe-drift-WYSJVZFO.js} +6 -6
- package/dist/{exe-export-HHRQMLSS.js → exe-export-GOLNAEAV.js} +20 -19
- package/dist/{exe-import-5XR4NQAB.js → exe-import-U4BSI6OH.js} +20 -19
- package/dist/{exe-key-5XOFVP3I.js → exe-key-V42G3NGO.js} +152 -130
- package/dist/{exe-org-TPAX4AAK.js → exe-org-U4GLQ6OP.js} +27 -27
- package/dist/{exe-snapshot-GIRP3XCJ.js → exe-snapshot-U7ONBYNY.js} +38 -37
- package/dist/{fast-db-init-MGY6VCLG.js → fast-db-init-W3NGKAEU.js} +1 -1
- package/dist/{founder-context-WD72OL2P.js → founder-context-ZSIBRVDM.js} +4 -4
- package/dist/{founder-monitor-envelope-XGYMHT4W.js → founder-monitor-envelope-L3IWZLFY.js} +7 -7
- package/dist/{fts-integrity-PLAL6NMG.js → fts-integrity-PHCKKOBC.js} +3 -3
- package/dist/gateway/index.js +23 -22
- package/dist/{gateway-client-VO3BRLV5.js → gateway-client-DJFCVIPT.js} +1 -1
- package/dist/{git-staleness-KGZABPP3.js → git-staleness-OF24QXFZ.js} +5 -5
- package/dist/{global-procedures-KOU6A5E5.js → global-procedures-WSIOWO43.js} +6 -6
- package/dist/{graph-auto-extract-OZNRDAHE.js → graph-auto-extract-IEVVN3L3.js} +9 -9
- package/dist/{graph-query-36K6VXFF.js → graph-query-JDZWAVCU.js} +1 -1
- package/dist/{graph-rag-TZLH3CTQ.js → graph-rag-BKAD2XQA.js} +4 -4
- package/dist/{hook-integrity-BWFFISJV.js → hook-integrity-TPWDGX2M.js} +3 -1
- package/dist/{hook-prefetch-MFUJRAIM.js → hook-prefetch-FD6VGJJA.js} +29 -28
- package/dist/hooks/bug-report-worker.js +34 -33
- package/dist/hooks/codex-stop-task-finalizer.js +36 -35
- package/dist/hooks/commit-complete.js +40 -36
- package/dist/hooks/error-recall.js +15 -15
- package/dist/hooks/exe-heartbeat-hook.js +8 -8
- package/dist/hooks/ingest-worker.js +21 -20
- package/dist/hooks/ingest.js +23 -23
- package/dist/hooks/instructions-loaded.js +10 -10
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +9 -9
- package/dist/hooks/post-compact.js +8 -8
- package/dist/hooks/post-tool-combined.js +15 -15
- package/dist/hooks/pre-compact.js +33 -32
- package/dist/hooks/pre-tool-use.js +2 -2
- package/dist/hooks/prompt-submit.js +52 -51
- package/dist/hooks/session-end.js +38 -37
- package/dist/hooks/session-start.js +25 -22
- package/dist/hooks/stop.js +40 -39
- package/dist/hooks/subagent-stop.js +36 -35
- package/dist/hooks/summary-worker.js +41 -40
- package/dist/index.js +43 -42
- package/dist/{inrun-inbox-DRKVDPLY.js → inrun-inbox-RGNFFGMU.js} +5 -0
- package/dist/{installer-RM4ASY7U.js → installer-NMOBSEZ2.js} +11 -11
- package/dist/{installer-IESPHXVH.js → installer-OTI5SA43.js} +11 -11
- package/dist/{installer-SQZRVD36.js → installer-SRJGE4GU.js} +11 -11
- package/dist/{intercom-queue-DGLAC224.js → intercom-queue-4FFXCBHO.js} +28 -27
- package/dist/{key-backup-status-LQPINQ3W.js → key-backup-status-6U7D5GOD.js} +2 -2
- package/dist/lib/agent-config.js +3 -3
- package/dist/lib/cloud-sync.js +28 -27
- package/dist/lib/config.js +4 -2
- package/dist/lib/consolidation.js +14 -12
- package/dist/lib/crypto.js +5 -3
- package/dist/lib/database.js +5 -5
- package/dist/lib/db-backup.js +11 -3
- package/dist/lib/db-daemon-client.js +11 -10
- package/dist/lib/db-write-worker.js +4 -4
- package/dist/lib/db.js +5 -5
- package/dist/lib/delivery-catalog.js +431 -0
- package/dist/lib/delivery-schemas.js +62 -0
- package/dist/lib/delivery-truth.js +1 -1
- package/dist/lib/device-registry.js +3 -3
- package/dist/lib/embed-worker.js +2 -2
- package/dist/lib/embedder.js +10 -9
- package/dist/lib/employee-templates.js +7 -7
- package/dist/lib/employees.js +5 -5
- package/dist/lib/exe-daemon-client.js +9 -8
- package/dist/lib/exe-daemon.js +186 -117
- package/dist/lib/hybrid-search.js +12 -12
- package/dist/lib/identity.js +5 -5
- package/dist/lib/keychain.js +13 -1
- package/dist/lib/license.js +8 -4
- package/dist/lib/messaging.js +39 -30
- package/dist/lib/post-tool-memory.js +9 -9
- package/dist/lib/registry-proxy.js +9 -1
- package/dist/lib/reminders.js +6 -6
- package/dist/lib/schedules.js +11 -11
- package/dist/lib/session-registry.js +7 -7
- package/dist/lib/skill-learning.js +20 -19
- package/dist/lib/status-brief.js +5 -4
- package/dist/lib/store.js +10 -10
- package/dist/lib/task-router.js +6 -6
- package/dist/lib/tasks.js +30 -29
- package/dist/lib/tmux-routing.js +28 -27
- package/dist/lib/tmux-status.js +3 -1
- package/dist/lib/token-spend.js +6 -6
- package/dist/lib/ws-client.js +1 -1
- package/dist/{license-gate-E6GTRYBA.js → license-gate-R4JWTWM4.js} +5 -5
- package/dist/{license-recheck-RBAO6Z2H.js → license-recheck-3MBJ4IJX.js} +1 -1
- package/dist/{license-sync-ZCZ2LIHK.js → license-sync-BVSG3WMW.js} +4 -4
- package/dist/local-secret-inventory-JWNBHZZ4.js +20 -0
- package/dist/mailbox-inbox-MTAT4MXX.js +13 -0
- package/dist/{mailbox-outbox-DNDDP2HW.js → mailbox-outbox-OY4IU6S4.js} +2 -1
- package/dist/mcp/register-tools.js +121 -120
- package/dist/mcp/server.js +123 -122
- package/dist/mcp/tools/complete-reminder.js +7 -7
- package/dist/mcp/tools/create-reminder.js +7 -7
- package/dist/mcp/tools/create-task.js +35 -32
- package/dist/mcp/tools/deactivate-behavior.js +22 -21
- package/dist/mcp/tools/list-reminders.js +7 -7
- package/dist/mcp/tools/list-tasks.js +33 -32
- package/dist/mcp/tools/send-message.js +32 -31
- package/dist/mcp/tools/update-task.js +31 -30
- package/dist/{mcp-child-registry-DVHYAHPW.js → mcp-child-registry-TIZERM7O.js} +5 -5
- package/dist/{mcp-health-B5EKRCZG.js → mcp-health-4ZHU67LM.js} +9 -3
- package/dist/{mcp-http-config-ME67QDOF.js → mcp-http-config-VUMSFWFH.js} +12 -12
- package/dist/{mcp-session-identity-DNG4ULAE.js → mcp-session-identity-DZHWEJRV.js} +28 -27
- package/dist/{memory-cards-WCISXY62.js → memory-cards-JVXTMSAT.js} +10 -10
- package/dist/{memory-graph-extractor-GXIK4QUF.js → memory-graph-extractor-PPBJMYFJ.js} +10 -10
- package/dist/{memory-poisoning-defense-25LZ5FJI.js → memory-poisoning-defense-K5Q74XQ4.js} +5 -5
- package/dist/{memory-pressure-watchdog-XGXI7WGE.js → memory-pressure-watchdog-YMJH5CSA.js} +29 -28
- package/dist/{memory-queue-YF7IDSFY.js → memory-queue-2MA67TAA.js} +3 -3
- package/dist/{memory-queue-client-QC2OTMJB.js → memory-queue-client-4G7HVRSX.js} +11 -10
- package/dist/{memory-reflection-GFGT44NT.js → memory-reflection-7BZWIHRE.js} +10 -10
- package/dist/{monitor-grants-Z2SEFE6E.js → monitor-grants-Q7X3MYQP.js} +6 -6
- package/dist/{monitor-identity-AEMHCVHV.js → monitor-identity-ZQB4IXEE.js} +2 -2
- package/dist/{notification-ledger-ETQBGRP7.js → notification-ledger-XRAXL5OI.js} +32 -29
- package/dist/{notifications-LPRCFJYY.js → notifications-JE3PX55X.js} +28 -27
- package/dist/{orchestration-events-T2GXV2NG.js → orchestration-events-JCQ5F5IJ.js} +6 -6
- package/dist/{orchestration-phase-T2WD45UA.js → orchestration-phase-QKTGQ2YT.js} +3 -3
- package/dist/{orchestrator-HY2IB3NA.js → orchestrator-X65INDTR.js} +30 -29
- package/dist/{org-brief-session-UWFCFEEB.js → org-brief-session-3PQ22UIX.js} +19 -18
- package/dist/{org-consent-policy-XXMST37J.js → org-consent-policy-VGELJ7K7.js} +7 -6
- package/dist/{org-join-72QKM7JR.js → org-join-6TO5ZYUZ.js} +12 -12
- package/dist/{org-key-admin-YCIAYP7V.js → org-key-admin-XHYVRRAZ.js} +12 -12
- package/dist/{org-key-pin-F7BQPI5P.js → org-key-pin-TTTYGTQL.js} +6 -6
- package/dist/{org-membership-JQSU4Z5P.js → org-membership-Y7T2BS57.js} +7 -7
- package/dist/{org-partner-config-PVJ45SLC.js → org-partner-config-OP4NEUNF.js} +10 -10
- package/dist/{org-partner-runtime-U4CTLWLC.js → org-partner-runtime-YNVUNT2R.js} +20 -19
- package/dist/{org-row-visibility-WUX4N3FX.js → org-row-visibility-JBBXNYXD.js} +1 -1
- package/dist/{pipeline-router-2RMBCBRM.js → pipeline-router-EIBB7QNG.js} +6 -6
- package/dist/{plan-limits-Z47XYEJR.js → plan-limits-MEWXYLEN.js} +8 -8
- package/dist/{postinstall-failure-O6TSSNJB.js → postinstall-failure-VETYYWEZ.js} +3 -3
- package/dist/{pre-tool-use-impl-JPE6XMRJ.js → pre-tool-use-impl-C6KJY22W.js} +60 -49
- package/dist/{project-boot-UFQDAFU5.js → project-boot-VEYFCCSL.js} +2 -2
- package/dist/{project-name-V4IREGHO.js → project-name-UYORSNGE.js} +6 -6
- package/dist/{projection-worker-HAD6H3VJ.js → projection-worker-WYFDWS57.js} +5 -5
- package/dist/{prospective-memory-KIF4JLFF.js → prospective-memory-E6XBQFJA.js} +5 -5
- package/dist/{push-notifications-GDKRTYXH.js → push-notifications-M7YU63FY.js} +29 -28
- package/dist/{reproject-worktree-memories-SG4BZJ3Z.js → reproject-worktree-memories-B5XMGJSD.js} +28 -27
- package/dist/{reranker-G2AZ67JP.js → reranker-SRA4BR7N.js} +3 -3
- package/dist/{retrieval-health-GBJRXTBZ.js → retrieval-health-P2JPZUPV.js} +4 -4
- package/dist/{review-polling-VUZPAAGT.js → review-polling-KQPN7IQE.js} +29 -28
- package/dist/runtime/index.js +37 -36
- package/dist/{session-events-BI6NIFIR.js → session-events-6LDDKKY3.js} +29 -28
- package/dist/{session-kill-telemetry-HPBDOPHT.js → session-kill-telemetry-5DSRGWCL.js} +29 -28
- package/dist/{session-mcp-config-WFZAH6R5.js → session-mcp-config-F7RCERUG.js} +3 -3
- package/dist/{session-scope-UB3HA5E7.js → session-scope-XG5R3P3D.js} +28 -27
- package/dist/{setup-wizard-6XULOT3L.js → setup-wizard-7QFLZIKT.js} +5 -5
- package/dist/{shard-manager-DYEJ6ETD.js → shard-manager-HHHHV2KZ.js} +3 -3
- package/dist/{skill-refinement-MKBQIWZ6.js → skill-refinement-I5RMAHSC.js} +6 -6
- package/dist/{stack-generate-manifest-7ODQ6W2O.js → stack-generate-manifest-AKMZ3AUX.js} +246 -13
- package/dist/stack-init-5VKL5PL5.js +136 -0
- package/dist/{stack-promote-3UKJBJSP.js → stack-promote-34CE2HHF.js} +7 -6
- package/dist/{stack-release-5CVXMJM5.js → stack-release-5PGWV5D4.js} +123 -12
- package/dist/{stack-update-Z53KG2P5.js → stack-update-ZQQ5YYPJ.js} +20 -5
- package/dist/{steward-gate-OKUYYIX6.js → steward-gate-AQJ6KT2C.js} +6 -6
- package/dist/{subagent-brief-injection-T2CVQLAS.js → subagent-brief-injection-3GU7YAWY.js} +50 -42
- package/dist/{subagent-spawn-ledger-E6U3OY6Z.js → subagent-spawn-ledger-52I66CLW.js} +3 -3
- package/dist/{supervisor-handoff-SGLEPOCY.js → supervisor-handoff-BWJW6CKZ.js} +4 -4
- package/dist/{support-inbox-WJIDCKJC.js → support-inbox-NY5TB3FN.js} +12 -12
- package/dist/{support-outbox-G2NG2U5K.js → support-outbox-KNI3FR3G.js} +3 -2
- package/dist/{task-enforcement-JL5ADPS6.js → task-enforcement-CAA6D2MH.js} +29 -28
- package/dist/{task-request-inbox-54BRRFHZ.js → task-request-inbox-QBZVU66E.js} +9 -6
- package/dist/{task-scope-OBPZBID5.js → task-scope-NHXB4ZRN.js} +32 -27
- package/dist/{tasks-crud-YBCPT7TY.js → tasks-crud-JHSWL5NM.js} +28 -27
- package/dist/{tasks-notify-CEEQSDJF.js → tasks-notify-7PBE4U7T.js} +29 -28
- package/dist/{tasks-review-JIEI656P.js → tasks-review-PPPVEE62.js} +28 -27
- package/dist/{telemetry-upload-ZZSEZR2U.js → telemetry-upload-YU2VRNHX.js} +10 -10
- package/dist/{token-budget-AUFMEMQ2.js → token-budget-QCMWKG3K.js} +6 -6
- package/dist/{tool-capability-index-6HLZU437.js → tool-capability-index-7AWQAJRP.js} +1 -1
- package/dist/{tool-gates-VXITVRFQ.js → tool-gates-5Q3RSQEG.js} +1 -1
- package/dist/{tool-gates-JWVSAYTW.js → tool-gates-QD26D2NE.js} +1 -1
- package/dist/{tool-telemetry-RHSEK2TO.js → tool-telemetry-LTOIC64I.js} +1 -1
- package/dist/tui/App.js +43 -42
- package/dist/{tui-data-PBZNN5YB.js → tui-data-NDBXD6U7.js} +32 -31
- package/dist/{update-support-V3ZCJR6L.js → update-support-BMJM4NG7.js} +27 -26
- package/dist/{whatsapp-NAM2CRVQ.js → whatsapp-QQLDAHUX.js} +2 -2
- package/dist/{wiki-acl-NUBAPLCD.js → wiki-acl-W6WDCVCP.js} +1 -1
- package/dist/{work-claims-Q2NU6JON.js → work-claims-6DM32MGO.js} +6 -6
- package/dist/{work-state-heartbeat-HAQRV3RK.js → work-state-heartbeat-HG7D4AWJ.js} +1 -1
- package/dist/{worker-gate-NUUSQMBT.js → worker-gate-FTMW7GBB.js} +3 -3
- package/dist/{workflow-engine-GEWPU5YR.js → workflow-engine-ZWC6CCXE.js} +2 -2
- package/dist/{worktree-C7LFMRKW.js → worktree-EMQCPGFE.js} +7 -7
- package/dist/{worktree-ownership-guard-4LKMW6PW.js → worktree-ownership-guard-O6JQF2CL.js} +2 -2
- package/dist/{worktree-sweep-SYF62ANH.js → worktree-sweep-XVUJZBXV.js} +8 -8
- package/package.json +23 -7
- package/release-notes.json +39 -12
- package/stack.release.json +4 -4
- package/dist/mailbox-inbox-XE72D3AX.js +0 -10
- /package/dist/{chunk-QIEYJ4KZ.js → chunk-2KY7WZZF.js} +0 -0
- /package/dist/{chunk-T3667X2B.js → chunk-2Q2CD6CD.js} +0 -0
- /package/dist/{chunk-JZJZYKMW.js → chunk-AJK2PVQW.js} +0 -0
- /package/dist/{chunk-ZEGEFBZV.js → chunk-AWWDKF22.js} +0 -0
- /package/dist/{chunk-QNTKRGJ6.js → chunk-GIRD7O5X.js} +0 -0
- /package/dist/{chunk-FWA4MYTA.js → chunk-JRIH6I7D.js} +0 -0
- /package/dist/{chunk-C7H2D7LX.js → chunk-M4XY4JRK.js} +0 -0
- /package/dist/{chunk-Q3DN5J6F.js → chunk-P2VVMGMI.js} +0 -0
- /package/dist/{chunk-BRAIWGMF.js → chunk-Q46NYJ77.js} +0 -0
- /package/dist/{chunk-3LQ2N4H7.js → chunk-U2D6PJ5T.js} +0 -0
- /package/dist/{chunk-3O6OGZL3.js → chunk-XDVOGDBC.js} +0 -0
- /package/dist/{core-memory-UNCAPGD4.js → core-memory-O6D5UC3T.js} +0 -0
- /package/dist/{hook-tamper-log-Z4PWC7N4.js → hook-tamper-log-ARGWCXKJ.js} +0 -0
- /package/dist/{memory-isolation-ALPJWLR5.js → memory-isolation-EBFFC6HF.js} +0 -0
- /package/dist/{oauth-server-AC2KB7NB.js → oauth-server-ZKBUHDFI.js} +0 -0
- /package/dist/{webhook-pipe-W2FVXY7M.js → webhook-pipe-PXH5MBRM.js} +0 -0
- /package/dist/{wiki-client-W65IOSWF.js → wiki-client-DD2NVWK2.js} +0 -0
|
@@ -69,7 +69,7 @@ SMTP_PASS=
|
|
|
69
69
|
# --- Auth gateway (exe-auth — shared SSO sign-in UI at auth.<domain>) ---
|
|
70
70
|
# Bug 58840873: pin the auth image so compose never falls back to its stale
|
|
71
71
|
# hardcoded default tag. Keep in sync with the manifest AUTH_IMAGE_TAG.
|
|
72
|
-
AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.6.
|
|
72
|
+
AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.6.5@sha256:dc8c1476ef1247079a6e115450bd35681712fa06367461589998ecf943f88089
|
|
73
73
|
# Bug 379e5c13: server_name / CORS from the CONFIGURED apex domain, not by naive
|
|
74
74
|
# last-2-label slicing (which breaks company.co.uk → co.uk).
|
|
75
75
|
AUTH_SERVER_NAME=auth.CHANGEME_DOMAIN
|
|
@@ -124,7 +124,7 @@ EXE_ORG_ID=
|
|
|
124
124
|
EXE_ORG_WORKSPACE_ID=
|
|
125
125
|
|
|
126
126
|
# --- CRM ---
|
|
127
|
-
CRM_IMAGE_TAG=update.askexe.com/askexe/exe-crm:v0.9.
|
|
127
|
+
CRM_IMAGE_TAG=update.askexe.com/askexe/exe-crm:v0.9.59@sha256:40619dce57540f86dc7c8b71f1da57f44600a288f75a28850a9a9b425d0b92a6
|
|
128
128
|
CRM_SERVER_URL=https://crm.CHANGEME_DOMAIN
|
|
129
129
|
CRM_APP_SECRET=CHANGEME_CRM_APP_SECRET
|
|
130
130
|
# The CRM's first admin — seeded at boot by WorkspaceBootstrapService, which is
|
|
@@ -138,7 +138,7 @@ EXE_CRM_ADMIN_EMAIL=CHANGEME_ADMIN_EMAIL
|
|
|
138
138
|
CRM_HOST_PORT=3000
|
|
139
139
|
|
|
140
140
|
# --- Wiki ---
|
|
141
|
-
WIKI_IMAGE_TAG=update.askexe.com/askexe/exe-wiki:v0.9.
|
|
141
|
+
WIKI_IMAGE_TAG=update.askexe.com/askexe/exe-wiki:v0.9.33@sha256:1f9e04a557c6034e0eac85ecdf76d465eab88394614184387ecf06cd2281e7d8
|
|
142
142
|
# Bug 2a8d3003 — DO NOT change this without migrating the data first.
|
|
143
143
|
# The wiki's users / workspaces / workspace_documents live in `public`. Point it at a
|
|
144
144
|
# different schema and Prisma will NOT error: it finds no tables, assumes a fresh
|
|
@@ -176,7 +176,7 @@ WIKI_HOST_PORT=3001
|
|
|
176
176
|
EXE_SSO_COOKIE_NAME=exe_access_token
|
|
177
177
|
|
|
178
178
|
# --- exe-os ---
|
|
179
|
-
EXE_OS_IMAGE_TAG=update.askexe.com/askexe/exe-os:v0.9.
|
|
179
|
+
EXE_OS_IMAGE_TAG=update.askexe.com/askexe/exe-os:v0.9.382@sha256:266a59a482865eab9f79497999acb33c1fe1868ec54ea5cd1ce971c492f11bd6
|
|
180
180
|
EXED_MCP_TOKEN=CHANGEME_EXED_MCP_TOKEN
|
|
181
181
|
EXED_DEVICE_ID=CHANGEME_DEVICE_ID
|
|
182
182
|
EXE_MCP_HOST_BIND=127.0.0.1
|
|
@@ -186,7 +186,7 @@ EXE_MCP_HOST_PORT=48739
|
|
|
186
186
|
EXE_CLOUD_SYNC_TO_POSTGRES=true
|
|
187
187
|
|
|
188
188
|
# --- ERP (Frappe/ERPNext fork) ---
|
|
189
|
-
ERP_IMAGE_TAG=update.askexe.com/askexe/exe-erp:
|
|
189
|
+
ERP_IMAGE_TAG=update.askexe.com/askexe/exe-erp:v0.3.11@sha256:5888b3e9d4ff309f37052dbdcac1fda66e235dbecb186a9ccf69380576e7b363
|
|
190
190
|
# Administrator password for the ERPNext site (created on first boot).
|
|
191
191
|
# bug 43854b31: this only applies at FIRST boot. To rotate it later you must also
|
|
192
192
|
# run `bench --site $ERP_SITE_NAME set-admin-password <new>` inside exe-erp —
|
|
@@ -158,7 +158,7 @@ EXE_ORG_ID=
|
|
|
158
158
|
EXE_ORG_WORKSPACE_ID=
|
|
159
159
|
|
|
160
160
|
# --- CRM ---
|
|
161
|
-
CRM_IMAGE_TAG=ghcr.io/askexe/exe-crm:v0.9.
|
|
161
|
+
CRM_IMAGE_TAG=ghcr.io/askexe/exe-crm:v0.9.59@sha256:40619dce57540f86dc7c8b71f1da57f44600a288f75a28850a9a9b425d0b92a6
|
|
162
162
|
CRM_SERVER_URL=https://crm.CHANGEME_DOMAIN
|
|
163
163
|
CRM_APP_SECRET=CHANGEME_CRM_APP_SECRET
|
|
164
164
|
EXE_CRM_ADMIN_TOKEN=CHANGEME_EXE_CRM_ADMIN_TOKEN
|
|
@@ -209,7 +209,7 @@ WIKI_HOST_PORT=3001
|
|
|
209
209
|
EXE_SSO_COOKIE_NAME=exe_access_token
|
|
210
210
|
|
|
211
211
|
# --- exe-os ---
|
|
212
|
-
EXE_OS_IMAGE_TAG=ghcr.io/askexe/exe-os:v0.9.
|
|
212
|
+
EXE_OS_IMAGE_TAG=ghcr.io/askexe/exe-os:v0.9.382@sha256:266a59a482865eab9f79497999acb33c1fe1868ec54ea5cd1ce971c492f11bd6
|
|
213
213
|
|
|
214
214
|
# Infra image pins — manifest-derived. Compose has no fallback default for
|
|
215
215
|
# these: a missing pin ABORTS the deploy instead of substituting an old image.
|
|
@@ -264,7 +264,7 @@ ERROR_REPORTING_ENABLED=true
|
|
|
264
264
|
MONITOR_ERROR_URL=http://exe-monitor-hub:8090/api/exe-monitor/errors
|
|
265
265
|
|
|
266
266
|
# --- ERP (optional — Exe ERP, Frappe/ERPNext fork) ---
|
|
267
|
-
ERP_IMAGE_TAG=ghcr.io/askexe/exe-erp:
|
|
267
|
+
ERP_IMAGE_TAG=ghcr.io/askexe/exe-erp:v0.3.11@sha256:5888b3e9d4ff309f37052dbdcac1fda66e235dbecb186a9ccf69380576e7b363
|
|
268
268
|
ERP_ADMIN_PASSWORD=CHANGEME_ERP_ADMIN_PASSWORD
|
|
269
269
|
EXE_ERP_ADMIN_TOKEN=CHANGEME_EXE_ERP_ADMIN_TOKEN
|
|
270
270
|
# Frappe site name — must match the erp.<domain> the customer serves (bug e61ad373).
|
|
@@ -764,7 +764,7 @@ services:
|
|
|
764
764
|
# overridden back to exeOsMcp — see bug c604df37 above before doing that;
|
|
765
765
|
# the spawn args below currently point at the wrong CLI entrypoint.
|
|
766
766
|
EXE_OS_MCP_COMMAND: ${WIKI_EXE_OS_MCP_COMMAND:-npx}
|
|
767
|
-
EXE_OS_MCP_ARGS: ${WIKI_EXE_OS_MCP_ARGS:--y @askexenow/exe-os@${WIKI_EXE_OS_NPM_VERSION:-0.9.
|
|
767
|
+
EXE_OS_MCP_ARGS: ${WIKI_EXE_OS_MCP_ARGS:--y @askexenow/exe-os@${WIKI_EXE_OS_NPM_VERSION:-0.9.382} mcp}
|
|
768
768
|
BRANDING_CONFIG_PATH: /app/branding.json
|
|
769
769
|
ports:
|
|
770
770
|
- "127.0.0.1:${WIKI_HOST_PORT:-3001}:3001"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
3
4
|
// ---------------------------------------------------------------------------
|
|
4
5
|
// IMAGE PINS — DERIVED FROM THE SIGNED MANIFEST. NEVER HAND-TYPED.
|
|
5
6
|
//
|
|
@@ -26,7 +27,52 @@ const REGISTRY = "ghcr.io/askexe";
|
|
|
26
27
|
// own registry constant rather than reusing REGISTRY (bug 58840873).
|
|
27
28
|
const AUTH_REGISTRY = "update.askexe.com/askexe";
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
// Bug cff0de47: the manifest used to be resolved as ONE path relative to this
|
|
31
|
+
// module's own file (`../stack-manifests/v0.9.json`). The documented VPS install
|
|
32
|
+
// copies `deploy/compose/*` into /opt/exe-stack WITHOUT its sibling
|
|
33
|
+
// `deploy/stack-manifests/`, so the relocated generator looked for
|
|
34
|
+
// /opt/stack-manifests/v0.9.json — a directory nobody ever creates — and died at
|
|
35
|
+
// MODULE INITIALIZATION before generating a single line of configuration.
|
|
36
|
+
//
|
|
37
|
+
// Resolution is now an ordered search over EXPLICIT, configurable locations, so
|
|
38
|
+
// relocating this file cannot break it:
|
|
39
|
+
// 1. $EXE_STACK_MANIFEST — explicit override (setup.sh exports it)
|
|
40
|
+
// 2. <this dir>/stack-manifests/… — manifest copied ALONGSIDE the compose files
|
|
41
|
+
// 3. <this dir>/../stack-manifests/…— in-repo / in-package layout
|
|
42
|
+
// A failure names every location searched instead of one phantom path.
|
|
43
|
+
const MANIFEST_FILENAME = "v0.9.json";
|
|
44
|
+
const MANIFEST_PATH_ENV_VAR = "EXE_STACK_MANIFEST";
|
|
45
|
+
|
|
46
|
+
export function manifestSearchPaths(
|
|
47
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
48
|
+
moduleUrl: string = import.meta.url,
|
|
49
|
+
): string[] {
|
|
50
|
+
const paths: string[] = [];
|
|
51
|
+
const override = (env[MANIFEST_PATH_ENV_VAR] ?? "").trim();
|
|
52
|
+
if (override) paths.push(override);
|
|
53
|
+
paths.push(fileURLToPath(new URL(`./stack-manifests/${MANIFEST_FILENAME}`, moduleUrl)));
|
|
54
|
+
paths.push(fileURLToPath(new URL(`../stack-manifests/${MANIFEST_FILENAME}`, moduleUrl)));
|
|
55
|
+
return paths;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function resolveManifestPath(
|
|
59
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
60
|
+
moduleUrl: string = import.meta.url,
|
|
61
|
+
exists: (p: string) => boolean = existsSync,
|
|
62
|
+
): string {
|
|
63
|
+
const candidates = manifestSearchPaths(env, moduleUrl);
|
|
64
|
+
for (const candidate of candidates) {
|
|
65
|
+
if (exists(candidate)) return candidate;
|
|
66
|
+
}
|
|
67
|
+
throw new Error(
|
|
68
|
+
`generate-env: the signed stack manifest (${MANIFEST_FILENAME}) was not found. Searched:\n` +
|
|
69
|
+
candidates.map((c) => ` - ${c}`).join("\n") +
|
|
70
|
+
`\nThe manifest is the single source of truth for every image pin, so generation cannot ` +
|
|
71
|
+
`continue without it. Copy deploy/stack-manifests/ next to these compose files, or set ` +
|
|
72
|
+
`${MANIFEST_PATH_ENV_VAR}=/path/to/${MANIFEST_FILENAME}. ` +
|
|
73
|
+
`This is NOT a node/tsx problem.`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
30
76
|
|
|
31
77
|
type ManifestFile = {
|
|
32
78
|
latest: string;
|
|
@@ -34,11 +80,12 @@ type ManifestFile = {
|
|
|
34
80
|
};
|
|
35
81
|
|
|
36
82
|
function loadManifestServices(): Record<string, { image?: string }> {
|
|
37
|
-
const
|
|
83
|
+
const manifestPath = resolveManifestPath();
|
|
84
|
+
const manifest = JSON.parse(readFileSync(manifestPath, "utf8")) as ManifestFile;
|
|
38
85
|
const services = manifest.stacks?.[manifest.latest]?.services;
|
|
39
86
|
if (!services) {
|
|
40
87
|
throw new Error(
|
|
41
|
-
`generate-env: stack manifest ${
|
|
88
|
+
`generate-env: stack manifest ${manifestPath} has no services for latest="${manifest.latest}". ` +
|
|
42
89
|
`Refusing to generate a .env with no pins — that is exactly the silent-substitution failure ` +
|
|
43
90
|
`the manifest-as-single-source-of-truth change exists to prevent.`,
|
|
44
91
|
);
|
|
@@ -192,9 +239,18 @@ export interface GenerateEnvOptions {
|
|
|
192
239
|
* a fresh deploy and the checked-in .env.example are unchanged.
|
|
193
240
|
*/
|
|
194
241
|
disableSignup?: boolean;
|
|
242
|
+
/**
|
|
243
|
+
* The CRM's first administrator (bug cff0de47). When supplied it is written
|
|
244
|
+
* straight into EXE_CRM_ADMIN_EMAIL instead of the CHANGEME_ADMIN_EMAIL placeholder, so the documented first-run path produces
|
|
245
|
+
* a .env that the deploy gate accepts. It is still never GUESSED — no
|
|
246
|
+
* admin@<domain> default — because it must be a real mailbox that also exists
|
|
247
|
+
* in GoTrue.
|
|
248
|
+
*/
|
|
249
|
+
adminEmail?: string;
|
|
195
250
|
}
|
|
196
251
|
|
|
197
252
|
export function generateEnv(options: GenerateEnvOptions): string {
|
|
253
|
+
const adminEmail = (options.adminEmail ?? "").trim();
|
|
198
254
|
const normalizedDomain = normalizeDomain(options.domain);
|
|
199
255
|
const normalizedClientName = normalizeClientName(options.clientName);
|
|
200
256
|
const gatewayWsAuthToken = randomSecret(RANDOM_SECRET_48);
|
|
@@ -318,8 +374,8 @@ export function generateEnv(options: GenerateEnvOptions): string {
|
|
|
318
374
|
// refused (e51ca54c §10.6b). It cannot be generated — it must be a real
|
|
319
375
|
// mailbox that also exists in GoTrue — so it ships as SET_MANUALLY rather
|
|
320
376
|
// than as a random secret or a guessed admin@<domain>.
|
|
321
|
-
MANUAL_VALUE_COMMENT,
|
|
322
|
-
"
|
|
377
|
+
...(adminEmail ? [] : [MANUAL_VALUE_COMMENT]),
|
|
378
|
+
`EXE_CRM_ADMIN_EMAIL=${adminEmail || "CHANGEME_ADMIN_EMAIL"}`,
|
|
323
379
|
`CRM_HOST_PORT=${CRM_HOST_PORT}`,
|
|
324
380
|
"",
|
|
325
381
|
"# --- Wiki ---",
|
|
@@ -935,7 +991,7 @@ export function joinEnvLines(lines: string[]): string {
|
|
|
935
991
|
function printUsage(): void {
|
|
936
992
|
process.stderr.write(
|
|
937
993
|
"Usage:\n" +
|
|
938
|
-
" npx tsx deploy/compose/generate-env.ts <client-name> <domain> [license-key]\n" +
|
|
994
|
+
" npx tsx deploy/compose/generate-env.ts <client-name> <domain> [license-key] [admin-email]\n" +
|
|
939
995
|
" npx tsx deploy/compose/generate-env.ts --example\n",
|
|
940
996
|
);
|
|
941
997
|
}
|
|
@@ -957,13 +1013,13 @@ function main(): void {
|
|
|
957
1013
|
return;
|
|
958
1014
|
}
|
|
959
1015
|
|
|
960
|
-
const [clientName, domain, licenseKey] = args;
|
|
1016
|
+
const [clientName, domain, licenseKey, adminEmail] = args;
|
|
961
1017
|
if (!clientName || !domain) {
|
|
962
1018
|
printUsage();
|
|
963
1019
|
process.exit(1);
|
|
964
1020
|
}
|
|
965
1021
|
|
|
966
|
-
process.stdout.write(generateEnv({ clientName, domain, licenseKey }));
|
|
1022
|
+
process.stdout.write(generateEnv({ clientName, domain, licenseKey, adminEmail }));
|
|
967
1023
|
}
|
|
968
1024
|
|
|
969
1025
|
if (isCliInvocation()) {
|
package/deploy/compose/setup.sh
CHANGED
|
@@ -14,17 +14,106 @@ info() { echo -e "${GREEN}[setup]${NC} $1"; }
|
|
|
14
14
|
warn() { echo -e "${YELLOW}[setup]${NC} $1"; }
|
|
15
15
|
err() { echo -e "${RED}[setup]${NC} $1" >&2; }
|
|
16
16
|
|
|
17
|
+
# Read one KEY from .env, empty if absent. Used to decide whether a RE-RUN
|
|
18
|
+
# already has the configuration this run did not pass on the command line.
|
|
19
|
+
get_env_var() {
|
|
20
|
+
[[ -f .env ]] || { echo ""; return 0; }
|
|
21
|
+
local raw
|
|
22
|
+
raw=$(grep -E "^$1=" .env 2>/dev/null | head -n1 | cut -d= -f2- || true)
|
|
23
|
+
# set_env_var writes dotenv DOUBLE-QUOTED values, so undo that quoting here —
|
|
24
|
+
# otherwise a re-run compares `"true"` against `true` and takes the wrong
|
|
25
|
+
# branch. Values written by generate-env.ts are unquoted and pass through.
|
|
26
|
+
if [[ ${#raw} -ge 2 && "$raw" == '"'*'"' ]]; then
|
|
27
|
+
local bs='\' dq='"' dollar='$'
|
|
28
|
+
raw="${raw:1:${#raw}-2}"
|
|
29
|
+
raw="${raw//$dollar$dollar/$dollar}"
|
|
30
|
+
raw="${raw//"$bs$dq"/$dq}"
|
|
31
|
+
raw="${raw//"$bs$bs"/$bs}"
|
|
32
|
+
fi
|
|
33
|
+
printf '%s\n' "$raw"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# Set (or append) one KEY=VALUE in .env WITHOUT echoing the value. sed cannot be
|
|
37
|
+
# used safely here: secrets contain /, & and = which are sed metacharacters.
|
|
38
|
+
#
|
|
39
|
+
# COMPOSE INTERPOLATES .env VALUES, so a `$` written raw is not a `$`. An SMTP
|
|
40
|
+
# password of `abc$TOKEN` is read by Compose as the variable TOKEN and becomes
|
|
41
|
+
# `abc` — the credential is silently changed, email verification and password
|
|
42
|
+
# reset stop working, and nothing in the stack reports a wrong password as
|
|
43
|
+
# anything but a failed login. Measured:
|
|
44
|
+
#
|
|
45
|
+
# .env: SMTP_PASS=abc$TOKEN -> docker compose config -> P: abc
|
|
46
|
+
# .env: SMTP_PASS=abc$$TOKEN -> docker compose config -> P: abc$$TOKEN
|
|
47
|
+
#
|
|
48
|
+
# (`docker compose config` re-escapes a literal `$` as `$$` on output, which is
|
|
49
|
+
# how the second line reads back as the intended `abc$TOKEN`.)
|
|
50
|
+
#
|
|
51
|
+
# ESCAPING `$` IS NOT ENOUGH: an UNQUOTED value also loses everything from the
|
|
52
|
+
# first `#`, and its surrounding whitespace. Measured the same way:
|
|
53
|
+
#
|
|
54
|
+
# .env: SMTP_PASS=abc #def -> docker compose config -> P: abc
|
|
55
|
+
# .env: SMTP_PASS="abc #def" -> docker compose config -> P: abc #def
|
|
56
|
+
#
|
|
57
|
+
# So values are written dotenv DOUBLE-QUOTED, with `\`, `"` and `$` escaped.
|
|
58
|
+
# These are literal secrets and hostnames, never expressions — nothing here is
|
|
59
|
+
# meant to interpolate. get_env_var() undoes exactly this quoting.
|
|
60
|
+
set_env_var() {
|
|
61
|
+
local key="$1" value="$2"
|
|
62
|
+
# The replacement side of ${var//x/y} IS expanded, so a literal `$$` written
|
|
63
|
+
# there becomes the shell's PID — `abc$TOKEN` came out as `abc87319TOKEN`.
|
|
64
|
+
# Going through a variable whose value is a single `$` keeps both characters
|
|
65
|
+
# literal, because an expansion's RESULT is not expanded again.
|
|
66
|
+
local dollar='$' bs='\' dq='"'
|
|
67
|
+
# The PATTERN side is quoted: an unquoted `$bs` is a lone backslash, which the
|
|
68
|
+
# pattern matcher reads as an escape character and matches nothing, so `a\b`
|
|
69
|
+
# went out unescaped and Compose read `\b` as a BACKSPACE byte.
|
|
70
|
+
value="${value//"$bs"/$bs$bs}" # backslash first: it escapes the rest
|
|
71
|
+
value="${value//$dq/$bs$dq}"
|
|
72
|
+
value="${value//$dollar/$dollar$dollar}"
|
|
73
|
+
value="$dq$value$dq"
|
|
74
|
+
SEV_KEY="$key" SEV_VALUE="$value" awk '
|
|
75
|
+
$0 ~ "^" ENVIRON["SEV_KEY"] "=" { print ENVIRON["SEV_KEY"] "=" ENVIRON["SEV_VALUE"]; found=1; next }
|
|
76
|
+
{ print }
|
|
77
|
+
END { if (!found) print ENVIRON["SEV_KEY"] "=" ENVIRON["SEV_VALUE"] }
|
|
78
|
+
' .env > .env.setenv.tmp && mv .env.setenv.tmp .env
|
|
79
|
+
chmod 600 .env 2>/dev/null || true
|
|
80
|
+
}
|
|
81
|
+
|
|
17
82
|
# Parse args
|
|
18
|
-
CLIENT="" DOMAIN="" LICENSE=""
|
|
83
|
+
CLIENT="" DOMAIN="" LICENSE="" ADMIN_EMAIL="" TUNNEL_TOKEN=""
|
|
84
|
+
SMTP_HOST="" SMTP_PORT="" SMTP_USER="" SMTP_PASS="" NO_EMAIL="no"
|
|
19
85
|
while [[ $# -gt 0 ]]; do
|
|
20
86
|
case $1 in
|
|
21
87
|
--client) CLIENT="$2"; shift 2;;
|
|
22
88
|
--domain) DOMAIN="$2"; shift 2;;
|
|
23
89
|
--license) LICENSE="$2"; shift 2;;
|
|
90
|
+
--admin-email) ADMIN_EMAIL="$2"; shift 2;;
|
|
91
|
+
--tunnel-token) TUNNEL_TOKEN="$2"; shift 2;;
|
|
92
|
+
--smtp-host) SMTP_HOST="$2"; shift 2;;
|
|
93
|
+
--smtp-port) SMTP_PORT="$2"; shift 2;;
|
|
94
|
+
--smtp-user) SMTP_USER="$2"; shift 2;;
|
|
95
|
+
--smtp-pass) SMTP_PASS="$2"; shift 2;;
|
|
96
|
+
--no-email) NO_EMAIL="yes"; shift 1;;
|
|
24
97
|
*) err "Unknown arg: $1"; exit 1;;
|
|
25
98
|
esac
|
|
26
99
|
done
|
|
27
|
-
[[ -z "$CLIENT" || -z "$DOMAIN" ]] && { err "Usage: ./setup.sh --client <name> --domain <domain>"; exit 1; }
|
|
100
|
+
[[ -z "$CLIENT" || -z "$DOMAIN" ]] && { err "Usage: ./setup.sh --client <name> --domain <domain> --admin-email <you@your-domain> [--tunnel-token <token>] [--smtp-host <host> --smtp-user <user> --smtp-pass <pass> | --no-email] [--license <key>]"; exit 1; }
|
|
101
|
+
# bug cff0de47: the CRM seeds its FIRST workspace owner from EXE_CRM_ADMIN_EMAIL.
|
|
102
|
+
# Without it the CRM boots healthy with no workspace and no user, and the first
|
|
103
|
+
# sign-in is refused with no way in. Ask for it here rather than deploying a
|
|
104
|
+
# stack nobody can log into (preflight refuses it either way).
|
|
105
|
+
if [[ -z "$ADMIN_EMAIL" ]]; then
|
|
106
|
+
if [[ -t 0 ]]; then
|
|
107
|
+
read -r -p " Admin email (owns the CRM/wiki; must be a real mailbox): " ADMIN_EMAIL
|
|
108
|
+
fi
|
|
109
|
+
fi
|
|
110
|
+
if [[ -z "$ADMIN_EMAIL" ]]; then
|
|
111
|
+
err "--admin-email is required. It becomes EXE_CRM_ADMIN_EMAIL: the mailbox that"
|
|
112
|
+
err "owns this stack. The CRM seeds its first workspace for exactly this address;"
|
|
113
|
+
err "without it the CRM comes up healthy but empty and NOBODY can sign in."
|
|
114
|
+
err " ./setup.sh --client $CLIENT --domain $DOMAIN --admin-email you@$DOMAIN${LICENSE:+ --license $LICENSE}"
|
|
115
|
+
exit 1
|
|
116
|
+
fi
|
|
28
117
|
|
|
29
118
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
30
119
|
cd "$SCRIPT_DIR"
|
|
@@ -59,13 +148,44 @@ else
|
|
|
59
148
|
# so any failure of the generator silently deployed ancient images that bypass
|
|
60
149
|
# the manifest's digest-pinning entirely. There is NO safe inline fallback for
|
|
61
150
|
# image tags — fail loudly instead and let the operator install node/npx.
|
|
151
|
+
# Bug cff0de47: generate-env.ts reads the SIGNED STACK MANIFEST at module
|
|
152
|
+
# initialization. The documented install copies deploy/compose/* into
|
|
153
|
+
# /opt/exe-stack without its sibling deploy/stack-manifests/, so the generator
|
|
154
|
+
# died on a manifest path that exists only inside the npm package — and the
|
|
155
|
+
# error below blamed node/tsx, sending the operator to debug the wrong thing.
|
|
156
|
+
# Locate the manifest explicitly and hand the generator its path.
|
|
157
|
+
if [[ -z "${EXE_STACK_MANIFEST:-}" ]]; then
|
|
158
|
+
for candidate in \
|
|
159
|
+
"$SCRIPT_DIR/stack-manifests/v0.9.json" \
|
|
160
|
+
"$SCRIPT_DIR/../stack-manifests/v0.9.json" \
|
|
161
|
+
"$(npm root -g 2>/dev/null)/@askexenow/exe-os/deploy/stack-manifests/v0.9.json"; do
|
|
162
|
+
if [[ -f "$candidate" ]]; then EXE_STACK_MANIFEST="$candidate"; break; fi
|
|
163
|
+
done
|
|
164
|
+
fi
|
|
165
|
+
if [[ -z "${EXE_STACK_MANIFEST:-}" || ! -f "${EXE_STACK_MANIFEST}" ]]; then
|
|
166
|
+
err "Stack manifest v0.9.json not found. Searched:"
|
|
167
|
+
err " - \$EXE_STACK_MANIFEST (${EXE_STACK_MANIFEST:-unset})"
|
|
168
|
+
err " - $SCRIPT_DIR/stack-manifests/v0.9.json"
|
|
169
|
+
err " - $SCRIPT_DIR/../stack-manifests/v0.9.json"
|
|
170
|
+
err " - \$(npm root -g)/@askexenow/exe-os/deploy/stack-manifests/v0.9.json"
|
|
171
|
+
err ""
|
|
172
|
+
err "The manifest is the single source of truth for every image pin, so .env"
|
|
173
|
+
err "cannot be generated without it. This is NOT a node/tsx problem."
|
|
174
|
+
err "Fix: run 'exe-os stack-init --dir $SCRIPT_DIR' (it copies the compose files"
|
|
175
|
+
err "AND the manifest), or set EXE_STACK_MANIFEST=/path/to/v0.9.json."
|
|
176
|
+
exit 1
|
|
177
|
+
fi
|
|
178
|
+
info "Using stack manifest: $EXE_STACK_MANIFEST"
|
|
179
|
+
export EXE_STACK_MANIFEST
|
|
62
180
|
if command -v node >/dev/null 2>&1 && command -v npx >/dev/null 2>&1; then
|
|
63
181
|
# Run via npx tsx (the project is pure ESM — require() is forbidden).
|
|
64
|
-
if ! npx --yes tsx "$SCRIPT_DIR/generate-env.ts" "$CLIENT" "$DOMAIN" "${LICENSE:-}" > .env 2>/tmp/exe-generate-env.err; then
|
|
182
|
+
if ! npx --yes tsx "$SCRIPT_DIR/generate-env.ts" "$CLIENT" "$DOMAIN" "${LICENSE:-}" "$ADMIN_EMAIL" > .env 2>/tmp/exe-generate-env.err; then
|
|
65
183
|
rm -f .env
|
|
66
184
|
err "generate-env.ts failed — refusing to write a .env with stale fallback image tags."
|
|
67
185
|
err "Generator error:"; cat /tmp/exe-generate-env.err >&2 || true
|
|
68
|
-
err "
|
|
186
|
+
err "If the error above is about a missing manifest, see EXE_STACK_MANIFEST"
|
|
187
|
+
err "(currently: $EXE_STACK_MANIFEST). Otherwise fix node/tsx and re-run"
|
|
188
|
+
err "setup.sh (the inline fallback was removed: bug 716c0f6e)."
|
|
69
189
|
exit 1
|
|
70
190
|
fi
|
|
71
191
|
else
|
|
@@ -80,6 +200,79 @@ else
|
|
|
80
200
|
info ".env generated with auto-generated secrets (chmod 600)"
|
|
81
201
|
fi
|
|
82
202
|
|
|
203
|
+
# Step 2a: Cloudflare tunnel token.
|
|
204
|
+
#
|
|
205
|
+
# bug cff0de47: the gated deploy at the end of this script REFUSES to run
|
|
206
|
+
# without a tunnel token (the cloudflared service has no compose profile gate,
|
|
207
|
+
# so a stack without a token has no public ingress). The customer guide used to
|
|
208
|
+
# hand the token over in a LATER step than the one that runs this script, so the
|
|
209
|
+
# documented order could never complete on a fresh machine. Take it here.
|
|
210
|
+
if [[ -n "$TUNNEL_TOKEN" ]]; then
|
|
211
|
+
set_env_var CLOUDFLARE_TUNNEL_TOKEN "$TUNNEL_TOKEN"
|
|
212
|
+
info "Cloudflare tunnel token written to .env"
|
|
213
|
+
else
|
|
214
|
+
warn "No --tunnel-token given. The deploy step below REQUIRES CLOUDFLARE_TUNNEL_TOKEN"
|
|
215
|
+
warn "in .env (Zero Trust > Networks > Tunnels > your tunnel > install token)."
|
|
216
|
+
warn "Set it and re-run this script, or re-run with --tunnel-token <token>."
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
# Step 2a-ii: Email delivery.
|
|
220
|
+
#
|
|
221
|
+
# bug cff0de47: a freshly generated .env ships SMTP_HOST empty and
|
|
222
|
+
# GOTRUE_MAILER_AUTOCONFIRM=false, and the deploy preflight REFUSES that
|
|
223
|
+
# combination — password-reset and email-verification would silently never
|
|
224
|
+
# send. Every fresh install hit it, and the customer guide never mentioned
|
|
225
|
+
# email at all. Ask for it here rather than deploying a stack whose recovery
|
|
226
|
+
# flow is dead, or record the operator's explicit decision to run without email.
|
|
227
|
+
if [[ "$NO_EMAIL" == "yes" ]]; then
|
|
228
|
+
set_env_var GOTRUE_MAILER_AUTOCONFIRM "true"
|
|
229
|
+
warn "Email flows DISABLED (--no-email): GOTRUE_MAILER_AUTOCONFIRM=true."
|
|
230
|
+
warn "Sign-ups are auto-confirmed and there is NO password-reset email."
|
|
231
|
+
warn "Signup stays disabled (invite-only), so this does not open registration."
|
|
232
|
+
elif [[ -n "$SMTP_HOST" ]]; then
|
|
233
|
+
set_env_var SMTP_HOST "$SMTP_HOST"
|
|
234
|
+
if [[ -n "$SMTP_PORT" ]]; then set_env_var SMTP_PORT "$SMTP_PORT"; fi
|
|
235
|
+
if [[ -n "$SMTP_USER" ]]; then set_env_var SMTP_USER "$SMTP_USER"; fi
|
|
236
|
+
if [[ -n "$SMTP_PASS" ]]; then set_env_var SMTP_PASS "$SMTP_PASS"; fi
|
|
237
|
+
# GOTRUE_MAILER_AUTOCONFIRM IS DERIVED FROM THE MAILER DECISION, not left at
|
|
238
|
+
# whatever a previous run wrote. Switching a `--no-email` install to SMTP used
|
|
239
|
+
# to leave AUTOCONFIRM=true behind: setup announced that verification would
|
|
240
|
+
# send while GoTrue kept auto-confirming every account without ever proving
|
|
241
|
+
# the mailbox belonged to the person signing up — and preflight's smtp_recovery
|
|
242
|
+
# check short-circuits on AUTOCONFIRM=true, so nothing downstream said
|
|
243
|
+
# otherwise. Each branch here writes the flag its own decision implies.
|
|
244
|
+
# (codex on PR #1152)
|
|
245
|
+
set_env_var GOTRUE_MAILER_AUTOCONFIRM "false"
|
|
246
|
+
info "SMTP configured ($SMTP_HOST) — email verification and password reset will send."
|
|
247
|
+
elif [[ -n "$(get_env_var SMTP_HOST)" ]]; then
|
|
248
|
+
# A RE-RUN IS NOT A FRESH INSTALL. This script is documented as re-runnable —
|
|
249
|
+
# the customer guide's own tunnel-token retry re-invokes it — and demanding
|
|
250
|
+
# the email flags again on every invocation made that retry fail on a stack
|
|
251
|
+
# that was already configured correctly. Judge the EFFECTIVE configuration in
|
|
252
|
+
# .env, not the flags of this particular run. (codex on PR #1152)
|
|
253
|
+
info "SMTP already configured in .env ($(get_env_var SMTP_HOST)) — keeping it."
|
|
254
|
+
if [[ "$(get_env_var GOTRUE_MAILER_AUTOCONFIRM)" == "true" ]]; then
|
|
255
|
+
# No decision was made THIS run, so this is reported, not silently flipped:
|
|
256
|
+
# SMTP + AUTOCONFIRM=true can be deliberate on an invite-only stack.
|
|
257
|
+
warn "...but GOTRUE_MAILER_AUTOCONFIRM=true, so accounts are auto-confirmed"
|
|
258
|
+
warn "WITHOUT verifying the mailbox. Re-run with --smtp-host to enforce"
|
|
259
|
+
warn "verification, or set GOTRUE_MAILER_AUTOCONFIRM=false in .env."
|
|
260
|
+
fi
|
|
261
|
+
elif [[ "$(get_env_var GOTRUE_MAILER_AUTOCONFIRM)" == "true" ]]; then
|
|
262
|
+
warn "Email flows already DISABLED in .env (GOTRUE_MAILER_AUTOCONFIRM=true) — keeping that choice."
|
|
263
|
+
warn "Sign-ups are auto-confirmed and there is NO password-reset email."
|
|
264
|
+
else
|
|
265
|
+
err "No email delivery configured. A stack with SMTP_HOST empty and"
|
|
266
|
+
err "GOTRUE_MAILER_AUTOCONFIRM=false cannot send password-reset or"
|
|
267
|
+
err "email-verification messages, and the deploy gate refuses it."
|
|
268
|
+
err ""
|
|
269
|
+
err "Either supply SMTP credentials:"
|
|
270
|
+
err " --smtp-host smtp.example.com --smtp-port 587 --smtp-user <user> --smtp-pass <pass>"
|
|
271
|
+
err "or run without email flows (sign-ups auto-confirmed, no password reset):"
|
|
272
|
+
err " --no-email"
|
|
273
|
+
exit 1
|
|
274
|
+
fi
|
|
275
|
+
|
|
83
276
|
# Step 2b: Host-access consent for the monitor agent.
|
|
84
277
|
#
|
|
85
278
|
# exe-monitor-agent reports fleet health to the monitoring hub, but to do so it
|
|
@@ -235,7 +428,7 @@ fi
|
|
|
235
428
|
|
|
236
429
|
if [[ -n "$EXE_CLI" ]]; then
|
|
237
430
|
info "Step 4+5: Deploying via '$EXE_CLI stack-update' (preflight + proxy auth + health-gated rollout + rollback)..."
|
|
238
|
-
if ! "$EXE_CLI" stack-update --yes; then
|
|
431
|
+
if ! "$EXE_CLI" stack-update --yes --domain "$DOMAIN" --admin-email "$ADMIN_EMAIL"; then
|
|
239
432
|
err "stack-update failed — the gated deploy refused or rolled back. Review the"
|
|
240
433
|
err "output above. Do NOT bypass with raw 'docker compose up' — fix the cause"
|
|
241
434
|
err "(preflight RED, image pull, or health failure) and re-run setup.sh."
|
|
@@ -249,7 +442,7 @@ else
|
|
|
249
442
|
err ""
|
|
250
443
|
err "Install the CLI and re-run setup.sh:"
|
|
251
444
|
err " npm install -g exe-os"
|
|
252
|
-
err " ./setup.sh --client $CLIENT --domain $DOMAIN${LICENSE:+ --license $LICENSE}"
|
|
445
|
+
err " ./setup.sh --client $CLIENT --domain $DOMAIN --admin-email $ADMIN_EMAIL${LICENSE:+ --license $LICENSE}"
|
|
253
446
|
exit 1
|
|
254
447
|
fi
|
|
255
448
|
|
|
@@ -259,7 +452,12 @@ docker ps --format 'table {{.Names}}\t{{.Status}}'
|
|
|
259
452
|
echo ""
|
|
260
453
|
info "Stack deployed! Next steps:"
|
|
261
454
|
echo " 1. Configure Cloudflare tunnel (if not done)"
|
|
262
|
-
|
|
455
|
+
# bug cff0de47: this used to say "to create admin account". GoTrue signup is OFF
|
|
456
|
+
# by default (invite-only), so there is no account to create in the CRM UI — the
|
|
457
|
+
# admin is SEEDED from EXE_CRM_ADMIN_EMAIL and must also be created in GoTrue.
|
|
458
|
+
echo " 2. Create the GoTrue user for ${ADMIN_EMAIL} (signup is DISABLED by default —"
|
|
459
|
+
echo " see CUSTOMER-GUIDE.md 'Create Your Admin Account'), then sign in at"
|
|
460
|
+
echo " https://crm.${DOMAIN}"
|
|
263
461
|
echo " 3. Open https://wiki.${DOMAIN} to set up wiki"
|
|
264
462
|
echo " 4. Configure WhatsApp: edit gateway.json, restart gateway, pair at https://gateway.${DOMAIN}/pair/<name>"
|
|
265
463
|
echo " 5. Verify: curl https://crm.${DOMAIN}/healthz && curl https://wiki.${DOMAIN}/api/ping"
|
|
@@ -153,6 +153,24 @@ server {
|
|
|
153
153
|
location = /health { auth_request off; proxy_pass http://$crm_upstream/healthz; }
|
|
154
154
|
location = /healthz { auth_request off; proxy_pass http://$crm_upstream/healthz; }
|
|
155
155
|
|
|
156
|
+
# G5 served-freshness (bug 529f45cf). See the doctrine note in
|
|
157
|
+
# sso-redirect.conf: an ungated path is granted EXPLICITLY, by exact match,
|
|
158
|
+
# never by a wildcard. Without this the watchdog's GET /__version was caught
|
|
159
|
+
# by the gate and 302'd to the auth login page, so the probe read auth's
|
|
160
|
+
# HTML and could not distinguish "wrong version" from "gated" from "down" —
|
|
161
|
+
# the served-freshness axis was unreadable for every SSO-gated surface.
|
|
162
|
+
#
|
|
163
|
+
# WHY UNAUTHENTICATED, DELIBERATELY: the response is a git sha/ref/repo and
|
|
164
|
+
# a build time, all of which the signed stack manifest already publishes
|
|
165
|
+
# unauthenticated at update.askexe.com/v1/stack-manifest.json. It leaks
|
|
166
|
+
# nothing the fleet does not already state publicly. The alternative —
|
|
167
|
+
# teaching the watchdog to hold an SSO session per surface — would put a
|
|
168
|
+
# live credential in a nightly job, widen its blast radius across five
|
|
169
|
+
# hosts, and make credential expiry look identical to real drift. A monitor
|
|
170
|
+
# whose failure mode is indistinguishable from the thing it monitors is the
|
|
171
|
+
# blind-monitor class this whole sweep is closing.
|
|
172
|
+
location = /__version { auth_request off; proxy_pass http://$crm_upstream/__version; }
|
|
173
|
+
|
|
156
174
|
# Logout endpoint must be exempt from SSO gate (bug 96f8b2b2). Without this,
|
|
157
175
|
# /auth/logout triggers 401 -> redirect to auth with logout URL as redirect param
|
|
158
176
|
# -> infinite loop. Let the app handle logout (clear its own cookies), then it
|
|
@@ -207,6 +225,9 @@ server {
|
|
|
207
225
|
location = /health { auth_request off; proxy_pass http://$wiki_upstream/api/ping; }
|
|
208
226
|
location = /healthz { auth_request off; proxy_pass http://$wiki_upstream/api/ping; }
|
|
209
227
|
|
|
228
|
+
# G5 served-freshness — see the CRM vhost's note (bug 529f45cf).
|
|
229
|
+
location = /__version { auth_request off; proxy_pass http://$wiki_upstream/__version; }
|
|
230
|
+
|
|
210
231
|
# Logout endpoint must be exempt from SSO gate (bug 96f8b2b2).
|
|
211
232
|
location = /auth/logout { auth_request off; proxy_pass http://$wiki_upstream/auth/logout; }
|
|
212
233
|
|
|
@@ -246,6 +267,27 @@ server {
|
|
|
246
267
|
set $gotrue_upstream gotrue:9999; # used by sso-redirect.conf's /_sso_gate
|
|
247
268
|
include /etc/nginx/snippets/sso-redirect.conf;
|
|
248
269
|
|
|
270
|
+
# G5 served-freshness — see the CRM vhost's note (bug 529f45cf).
|
|
271
|
+
#
|
|
272
|
+
# HONEST ABOUT WHAT THIS DOES AND DOES NOT FIX: exe-erp does not implement
|
|
273
|
+
# /__version yet (that is a change in AskExe/exe-erp, not here). Today this
|
|
274
|
+
# location turns a MISLEADING answer into an honest one — the probe stops
|
|
275
|
+
# reading auth.askexe.com's login HTML and starts reading ERP's own 404, so
|
|
276
|
+
# served-freshness reports ERP as unverifiable-because-unimplemented rather
|
|
277
|
+
# than silently comparing a login page against a git sha. It becomes a real
|
|
278
|
+
# verification the moment exe-erp ships the route; nothing here changes then.
|
|
279
|
+
#
|
|
280
|
+
# Host is preserved and the standard forwarded headers are set, matching the
|
|
281
|
+
# main location block below — a bare proxy_pass would send
|
|
282
|
+
# Host: exe-erp-nginx, which frappe's origin check rejects.
|
|
283
|
+
location = /__version {
|
|
284
|
+
auth_request off;
|
|
285
|
+
proxy_pass http://$erp_upstream/__version;
|
|
286
|
+
proxy_set_header Host $host;
|
|
287
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
288
|
+
proxy_set_header X-Forwarded-Proto https;
|
|
289
|
+
}
|
|
290
|
+
|
|
249
291
|
# ERP is the one upstream that runs a realtime socket.io service with
|
|
250
292
|
# origin authentication: frappe's realtime middleware compares the Host
|
|
251
293
|
# header against the Origin header and rejects mismatches ("Invalid
|
|
@@ -294,6 +336,9 @@ server {
|
|
|
294
336
|
location = /health { auth_request off; proxy_pass http://$dashboard_upstream/health; }
|
|
295
337
|
location = /healthz { auth_request off; proxy_pass http://$dashboard_upstream/health; }
|
|
296
338
|
|
|
339
|
+
# G5 served-freshness — see the CRM vhost's note (bug 529f45cf).
|
|
340
|
+
location = /__version { auth_request off; proxy_pass http://$dashboard_upstream/__version; }
|
|
341
|
+
|
|
297
342
|
# Logout endpoint must be exempt from SSO gate (bug 96f8b2b2).
|
|
298
343
|
location = /auth/logout { auth_request off; proxy_pass http://$dashboard_upstream/auth/logout; }
|
|
299
344
|
|
|
@@ -146,8 +146,17 @@
|
|
|
146
146
|
# make it fire). That is not a typo fix — it would newly open a real bypass for
|
|
147
147
|
# every path whose URI ends in an asset extension, including user-uploaded CRM
|
|
148
148
|
# attachments and wiki images. If a future app genuinely needs an ungated path,
|
|
149
|
-
# give it an explicit `location = /path { auth_request off; }` (as the /health
|
|
150
|
-
#
|
|
149
|
+
# give it an explicit `location = /path { auth_request off; }` (as the /health,
|
|
150
|
+
# /auth/logout and /__version routes already do), never an extension-shaped
|
|
151
|
+
# wildcard.
|
|
152
|
+
#
|
|
153
|
+
# /__version is the third such grant (bug 529f45cf). It is exact-match, it is
|
|
154
|
+
# read-only, and its body is a git sha/ref/repo already published without
|
|
155
|
+
# authentication in the signed stack manifest — so it widens no disclosure. It
|
|
156
|
+
# exists because the G5 served-freshness watchdog could not read ANY gated
|
|
157
|
+
# surface: every probe was 302'd to the login page, and the watchdog compared a
|
|
158
|
+
# git sha against auth's HTML. That is the shape this gate must never take —
|
|
159
|
+
# a control that cannot see reporting its blindness as ordinary traffic.
|
|
151
160
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
152
161
|
|
|
153
162
|
# Run the gate for every request on this vhost. The gate is a zero-cost local
|
|
@@ -76,6 +76,6 @@
|
|
|
76
76
|
"signature": {
|
|
77
77
|
"keyId": "exe-stack-1",
|
|
78
78
|
"alg": "ed25519",
|
|
79
|
-
"signature": "
|
|
79
|
+
"signature": "hZxmmxAMTi7l2yI0XDe3vnm35xl7z6A+BVcLFZopjULs9Q+v9CsqvoaLoDv6APiBfsagwr1wPmN0A7Uw0GrJBw=="
|
|
80
80
|
}
|
|
81
81
|
}
|