@askexenow/exe-os 0.9.373 → 0.9.374
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deploy/compose/.env.customer.example +28 -10
- package/deploy/compose/.env.example +28 -8
- package/deploy/compose/docker-compose.yml +101 -12
- package/deploy/compose/generate-env.ts +122 -31
- package/deploy/compose/sso-edge/default.conf.template +46 -7
- package/deploy/compose/sso-edge/sso-redirect.conf +50 -14
- package/dist/.dist-verified.json +3 -3
- package/dist/{active-agent-BVREYGFJ.js → active-agent-ONPPEWQV.js} +3 -3
- package/dist/{active-agent-HLV7IEU3.js → active-agent-UJKMG7LJ.js} +3 -3
- package/dist/{agent-defs-generator-TFBUJ67B.js → agent-defs-generator-ZWI6DXOE.js} +2 -2
- package/dist/{agent-loop-CYDFBCNA.js → agent-loop-OYHJKNYH.js} +1 -1
- package/dist/{agentic-ontology-WZKVHOUV.js → agentic-ontology-WHFJ3QFS.js} +1 -1
- package/dist/{backfill-metadata-FN3YMSKC.js → backfill-metadata-3OUSQD5V.js} +5 -5
- package/dist/{backup-verify-76235AHA.js → backup-verify-ZKTUYLTA.js} +1 -1
- package/dist/{behavior-injection-76FH424R.js → behavior-injection-M6UYZCMW.js} +13 -12
- package/dist/{behaviors-33WKK3BG.js → behaviors-ZJ45TFBJ.js} +11 -10
- package/dist/bin/agentic-ontology-backfill.js +6 -6
- package/dist/bin/agentic-reflection-backfill.js +7 -7
- package/dist/bin/agentic-semantic-label.js +6 -6
- package/dist/bin/backfill-conversations.js +9 -8
- package/dist/bin/backfill-responses.js +9 -8
- package/dist/bin/backfill-vectors.js +11 -10
- package/dist/bin/bulk-sync-postgres.js +15 -14
- package/dist/bin/cc-doctor.js +5 -5
- package/dist/bin/cleanup-stale-review-tasks.js +19 -18
- package/dist/bin/cli.js +24 -21
- package/dist/bin/deferred-daemon-restart.js +86 -85
- package/dist/bin/exe-agent-config.js +2 -2
- package/dist/bin/exe-agent.js +15 -14
- package/dist/bin/exe-assign.js +11 -10
- package/dist/bin/exe-boot.js +37 -36
- package/dist/bin/exe-call.js +4 -4
- package/dist/bin/exe-cloud.js +16 -15
- package/dist/bin/exe-config-dump.js +2 -2
- package/dist/bin/exe-dispatch.js +20 -19
- package/dist/bin/exe-doctor.js +7 -5
- package/dist/bin/exe-export-behaviors.js +15 -14
- package/dist/bin/exe-forget.js +7 -7
- package/dist/bin/exe-gateway.js +7 -7
- package/dist/bin/exe-healthcheck.js +5 -5
- package/dist/bin/exe-heartbeat.js +25 -24
- package/dist/bin/exe-kill.js +23 -22
- package/dist/bin/exe-launch-agent.js +30 -29
- package/dist/bin/exe-mcp.js +3 -3
- package/dist/bin/exe-memory-reads.js +5 -5
- package/dist/bin/exe-new-employee.js +8 -8
- package/dist/bin/exe-os-mcp-proxy.js +3 -3
- package/dist/bin/exe-pending-messages.js +20 -19
- package/dist/bin/exe-pending-notifications.js +19 -18
- package/dist/bin/exe-pending-reviews.js +20 -19
- package/dist/bin/exe-rename.js +4 -4
- package/dist/bin/exe-review.js +22 -21
- package/dist/bin/exe-search.js +6 -6
- package/dist/bin/exe-session-cleanup.js +23 -22
- package/dist/bin/exe-settings.js +15 -14
- package/dist/bin/exe-start-codex.js +21 -20
- package/dist/bin/exe-start-opencode.js +19 -18
- package/dist/bin/exe-status.js +21 -20
- package/dist/bin/exe-support.js +3 -3
- package/dist/bin/exe-team.js +4 -4
- package/dist/bin/exe-watchdog.js +13 -2
- package/dist/bin/git-sweep.js +20 -19
- package/dist/bin/graph-backfill.js +7 -7
- package/dist/bin/graph-export.js +6 -6
- package/dist/bin/import-history.js +10 -10
- package/dist/bin/install.js +88 -87
- package/dist/bin/intercom-check.js +5 -5
- package/dist/bin/mcp-sessions.js +2 -2
- package/dist/bin/orchestration-metrics.js +4 -4
- package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
- package/dist/bin/postgres-agentic-semantic-backfill.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 +19 -18
- package/dist/bin/setup.js +1 -1
- package/dist/bin/shard-migrate.js +5 -5
- package/dist/bin/stack-update.js +7 -6
- package/dist/bin/verify-stack.js +2 -2
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/{boot-generation-QY4H2VST.js → boot-generation-JKVZ4ZAT.js} +3 -3
- package/dist/{boot-review-sections-ITQVY2ZQ.js → boot-review-sections-2M6BTG73.js} +18 -17
- package/dist/build-manifest.json +950 -920
- package/dist/{capability-cards-JDJTJX4D.js → capability-cards-5IMJT6J7.js} +2 -2
- package/dist/{capacity-monitor-GK5IB6FJ.js → capacity-monitor-SAXCQK7O.js} +20 -19
- package/dist/{catchup-brief-ROSFMS46.js → catchup-brief-U2TXBLHD.js} +23 -22
- package/dist/{chunk-FGHPLZDF.js → chunk-23MVDXLY.js} +4 -4
- package/dist/{chunk-O5HTTJ2X.js → chunk-2ZOEC4KC.js} +2 -2
- package/dist/{chunk-72Y3I24H.js → chunk-32YV32VA.js} +2 -2
- package/dist/{chunk-JS5XMVXY.js → chunk-3KDCORDO.js} +1 -1
- package/dist/{chunk-NLGEFBND.js → chunk-3UUX5OY4.js} +1 -1
- package/dist/{chunk-SNW6E3Y4.js → chunk-44TLJZJ5.js} +1 -1
- package/dist/{chunk-MQAHDPU5.js → chunk-4EN3IZ3Q.js} +1 -1
- package/dist/{chunk-4IZ2ELU7.js → chunk-4HKTO2SV.js} +1 -1
- package/dist/{chunk-NMOEWLJY.js → chunk-4SJ4LK4V.js} +5 -5
- package/dist/{chunk-UUPAOKEO.js → chunk-55BEFF4V.js} +1 -1
- package/dist/{chunk-WZFVNICF.js → chunk-636LKCKE.js} +1 -1
- package/dist/{chunk-2W5J4T2F.js → chunk-6EZQUNE6.js} +2 -2
- package/dist/{chunk-NY75HDWW.js → chunk-6RKKVPYF.js} +1 -1
- package/dist/{chunk-HWKSG33T.js → chunk-6SCGLHJ7.js} +2 -2
- package/dist/{chunk-EM7NP2AC.js → chunk-6VHOQ3IM.js} +6 -6
- package/dist/{chunk-6KS57E66.js → chunk-6YVUR3OU.js} +2 -2
- package/dist/{chunk-DRXO46LA.js → chunk-7GE2EQ23.js} +1 -1
- package/dist/{chunk-U6RXHPK4.js → chunk-7TSBV3SD.js} +1 -1
- package/dist/{chunk-X65OJFQM.js → chunk-AETLDRZB.js} +1 -1
- package/dist/{chunk-7TIAQUBH.js → chunk-AKLJ4JH3.js} +1 -1
- package/dist/{chunk-IMX3VIIT.js → chunk-AKLQSC6W.js} +21 -21
- package/dist/{chunk-NMICTLJK.js → chunk-ANLFH23R.js} +1 -1
- package/dist/{chunk-JG4IOKQE.js → chunk-AWWKRZMB.js} +2 -2
- package/dist/{chunk-ICHQULGD.js → chunk-BBSIEYF5.js} +2 -2
- package/dist/{chunk-I422WQ3A.js → chunk-BJ7AVSY6.js} +2 -2
- package/dist/{chunk-L6WHOLGP.js → chunk-CBCGDEJA.js} +4 -4
- package/dist/{chunk-J4C442ZT.js → chunk-DB55JZHU.js} +1 -1
- package/dist/{chunk-XPPQ4PBN.js → chunk-DIXXEE3S.js} +158 -146
- package/dist/{chunk-YRC4NV2C.js → chunk-DJ7YXOTU.js} +2 -2
- package/dist/{chunk-SCHARPXE.js → chunk-DJOIMFKV.js} +2 -2
- package/dist/{chunk-ZFFRW73K.js → chunk-DSJI76XL.js} +2 -2
- package/dist/{chunk-3LQVIRGL.js → chunk-DZKPOSFD.js} +1 -1
- package/dist/{chunk-DMPIS4BY.js → chunk-EKE37MO4.js} +2 -2
- package/dist/{chunk-2HB5U5QT.js → chunk-EXTZSNWL.js} +1 -1
- package/dist/{chunk-6WUXRDTF.js → chunk-FTZET5YX.js} +138 -1
- package/dist/chunk-GHR4ZPJ7.js +70 -0
- package/dist/{chunk-FLNUXH6H.js → chunk-GJI77VDO.js} +3 -3
- package/dist/{chunk-45KCQK24.js → chunk-GNUAL43X.js} +2 -2
- package/dist/{chunk-I73AHVH5.js → chunk-GOMQ7PVQ.js} +1 -1
- package/dist/{chunk-KEC47ERR.js → chunk-GS7LIT34.js} +121 -5
- package/dist/{chunk-PFLDEJJJ.js → chunk-HNWS7YHN.js} +1 -1
- package/dist/{chunk-4XUPFJNB.js → chunk-I4DNJFDR.js} +4 -4
- package/dist/{chunk-6F4QFV4Q.js → chunk-IN6CAM4F.js} +3 -3
- package/dist/{chunk-ODOLBT7W.js → chunk-IRVOXUSK.js} +3 -3
- package/dist/{chunk-6D5KMMK4.js → chunk-JHI5WMK5.js} +4 -4
- package/dist/{chunk-LSY2JAFY.js → chunk-JSMDRKPJ.js} +1 -1
- package/dist/{chunk-TTELLO3M.js → chunk-JTVIANUB.js} +1 -1
- package/dist/{chunk-MJKWLOCW.js → chunk-KTCXJWJG.js} +1 -1
- package/dist/{chunk-MLYG3TI6.js → chunk-KTU3EAWK.js} +5 -5
- package/dist/{chunk-3W7U6ZKY.js → chunk-L6RXG36J.js} +1 -1
- package/dist/{chunk-TN2AXREB.js → chunk-LDNYSMPZ.js} +1 -1
- package/dist/{chunk-XEPLZKEB.js → chunk-LGS2V2XD.js} +3 -3
- package/dist/{chunk-RHRK3VDF.js → chunk-LP4GB656.js} +2 -2
- package/dist/{chunk-3FLDC2ZI.js → chunk-MOGA4Q7F.js} +1 -1
- package/dist/{chunk-HTUEAERH.js → chunk-MXPNVSXI.js} +14 -10
- package/dist/{chunk-KBRHGXE7.js → chunk-N7VEP5B3.js} +4 -4
- package/dist/{chunk-UEZQNJET.js → chunk-NBXDXKLC.js} +1 -1
- package/dist/{chunk-J7RIPMDI.js → chunk-NKETJCB5.js} +1 -1
- package/dist/{chunk-7HNQK2JA.js → chunk-NMH5ZQPU.js} +1 -1
- package/dist/{chunk-6WMJHNGN.js → chunk-NT7W4RXD.js} +1 -1
- package/dist/{chunk-P5YTFPCV.js → chunk-NUK7EEN5.js} +6 -4
- package/dist/{chunk-4Y523526.js → chunk-OVEQE6YS.js} +10 -10
- package/dist/{chunk-PLSY7Y5F.js → chunk-PB5S7YOF.js} +1 -1
- package/dist/{chunk-U45XMFOM.js → chunk-PDVXWXTL.js} +3 -3
- package/dist/{chunk-JKLA7AUZ.js → chunk-PLZSZOZN.js} +2 -2
- package/dist/{chunk-OTJVG7JM.js → chunk-QHJR7IMX.js} +1 -1
- package/dist/{chunk-P3DQL6JT.js → chunk-R4CBHKZ2.js} +1 -1
- package/dist/{chunk-BZYEOIT3.js → chunk-R522MWAR.js} +1 -1
- package/dist/{chunk-X63RNRZF.js → chunk-S2WBS6BG.js} +1 -1
- package/dist/{chunk-LFKRM3RK.js → chunk-SEQIPGLU.js} +1 -1
- package/dist/{chunk-S37PAH7F.js → chunk-SL6KQYDU.js} +24 -4
- package/dist/chunk-SLLLOOEI.js +103 -0
- package/dist/{chunk-T7AZ5K5K.js → chunk-T3QUKNLI.js} +1 -1
- package/dist/{chunk-USMESBOR.js → chunk-TAMDAOCU.js} +4 -4
- package/dist/{chunk-AMPNM6SB.js → chunk-TFKCERAK.js} +69 -21
- package/dist/{chunk-JVKIRKLC.js → chunk-TQAZTRQ3.js} +3 -3
- package/dist/{chunk-NFFCNZVD.js → chunk-U6SUKSZR.js} +2 -2
- package/dist/{chunk-TRMR77JJ.js → chunk-U73AC5AN.js} +11 -11
- package/dist/{chunk-RHNIWSOP.js → chunk-UBK7HK3J.js} +2 -2
- package/dist/{chunk-7P6YUA53.js → chunk-UCFC2AEI.js} +1 -1
- package/dist/{chunk-5SDE2HWI.js → chunk-UKLN57Q5.js} +2 -2
- package/dist/{chunk-QSAAN3H6.js → chunk-ULIBLJ6W.js} +5 -5
- package/dist/{chunk-X36BZYJ3.js → chunk-UM3N6VND.js} +4 -4
- package/dist/{chunk-KXBMR4ZD.js → chunk-V3WLC5TJ.js} +1 -98
- package/dist/{chunk-SMGSSWCW.js → chunk-VKJGHAZT.js} +8 -8
- package/dist/{chunk-V6KKNYF2.js → chunk-VMTZ4RUW.js} +13 -11
- package/dist/{chunk-GJD7D6HM.js → chunk-VYQ7B7DI.js} +3 -3
- package/dist/{chunk-PHA3OES7.js → chunk-W75GTHR3.js} +1 -1
- package/dist/{chunk-VYNY7K44.js → chunk-WJG344NC.js} +2 -2
- package/dist/{chunk-PBVBMZGO.js → chunk-WMEYJT4R.js} +3 -3
- package/dist/{chunk-L6MLYKY5.js → chunk-XH7YL7JM.js} +1 -1
- package/dist/{chunk-E7DFTCUW.js → chunk-XL5MFGMR.js} +2 -2
- package/dist/{chunk-3J37XIWU.js → chunk-XNNECNDL.js} +56 -11
- package/dist/{chunk-AWKZRRPX.js → chunk-XXFKSJYA.js} +5 -5
- package/dist/{chunk-G6P45SFB.js → chunk-XXOPG4BW.js} +3 -3
- package/dist/{chunk-UMNMC3DZ.js → chunk-XZ65ST2I.js} +1 -1
- package/dist/{chunk-SWK6MNAI.js → chunk-YMP2QSOP.js} +1 -1
- package/dist/{chunk-ZN3FAXDX.js → chunk-YSLGFPWX.js} +3 -3
- package/dist/{chunk-D2AR5PXE.js → chunk-YTSXPJUQ.js} +1 -1
- package/dist/{chunk-ZFXOA2CF.js → chunk-ZCERWHY2.js} +9 -9
- package/dist/{chunk-IVU3WN7S.js → chunk-ZG62LIK3.js} +74 -4
- package/dist/{chunk-52EK7KIA.js → chunk-ZGYNKA3O.js} +29 -87
- package/dist/{chunk-L67OHDSD.js → chunk-ZL4AGWAH.js} +2 -2
- package/dist/{chunk-WC6WL52H.js → chunk-ZSODLMFV.js} +1 -1
- package/dist/{cleanup-graph-garbage-6IJ6GJY2.js → cleanup-graph-garbage-DPJGO52H.js} +8 -8
- package/dist/{cloud-sync-command-TZVPTKZV.js → cloud-sync-command-JPNTT4OQ.js} +2 -2
- package/dist/{cloud-sync-db-init-2QLU6GCD.js → cloud-sync-db-init-V2LWIUQU.js} +1 -1
- package/dist/{cloud-sync-shutdown-OPCDMH4L.js → cloud-sync-shutdown-BNALPWGX.js} +2 -2
- package/dist/{co-activation-YMDKMDZ6.js → co-activation-CMNSWS6B.js} +2 -2
- package/dist/{co-occurrence-VYWPQSLC.js → co-occurrence-WRI2NAN6.js} +6 -6
- package/dist/{code-context-index-QLJDRL7B.js → code-context-index-NOJSHLPN.js} +9 -4
- package/dist/code-context-watcher-VZNZU3BO.js +118 -0
- package/dist/{conversation-entity-extractor-KGW4UEY4.js → conversation-entity-extractor-74252CAO.js} +4 -4
- package/dist/{crdt-sync-QS2DHTKW.js → crdt-sync-B3JN6AIV.js} +1 -1
- package/dist/{crm-webhook-5PNRCVO2.js → crm-webhook-GYWQRFET.js} +2 -2
- package/dist/{cto-delegation-gate-LD4XTG6U.js → cto-delegation-gate-LQHVLEMW.js} +18 -17
- package/dist/{daemon-orchestration-XC2VTPVI.js → daemon-orchestration-5HIQALZH.js} +23 -22
- package/dist/{daemon-ready-3WSKI3R5.js → daemon-ready-P2BR2XP5.js} +1 -1
- package/dist/{doc-graph-extractor-6TVQTBLO.js → doc-graph-extractor-PQHDHQPQ.js} +6 -6
- package/dist/{documents-4WQ5MQR2.js → documents-C4SSPJMC.js} +11 -10
- package/dist/{dreaming-SO4VH44W.js → dreaming-XAO3FCBV.js} +22 -21
- package/dist/{employee-boot-brief-Z4WTZVUC.js → employee-boot-brief-W4OHUMRQ.js} +26 -25
- package/dist/{exe-drift-BWSUUAEA.js → exe-drift-AG2KMKD5.js} +3 -3
- package/dist/{exe-export-4WPMVRNO.js → exe-export-IC5BT335.js} +12 -11
- package/dist/{exe-import-7C3SS62E.js → exe-import-A35ZLDPG.js} +12 -11
- package/dist/{exe-key-NFHZNJU6.js → exe-key-TCMJNYLA.js} +86 -85
- package/dist/{exe-org-5HYTAUH6.js → exe-org-JXCR3JYZ.js} +8 -8
- package/dist/{exe-snapshot-REKNH2WI.js → exe-snapshot-SV6SRIG6.js} +25 -24
- package/dist/{fast-db-init-OW6Z4YDB.js → fast-db-init-L2RGKJWH.js} +1 -1
- package/dist/{founder-context-6FAAM5LY.js → founder-context-D4HFIESJ.js} +2 -2
- package/dist/gateway/index.js +8 -8
- package/dist/{git-staleness-ELGGOVRV.js → git-staleness-TN7CYGFG.js} +2 -2
- package/dist/{global-procedures-JBMGJRR6.js → global-procedures-YFDEIOG7.js} +3 -3
- package/dist/{graph-auto-extract-O6IIL5O3.js → graph-auto-extract-3YR3TYRW.js} +6 -6
- package/dist/{graph-rag-WHZ6EPMW.js → graph-rag-Z2KCJTPK.js} +4 -4
- package/dist/{hook-integrity-UU5OXONF.js → hook-integrity-KGAV6ZC2.js} +1 -1
- package/dist/{hook-prefetch-VWHIZBTX.js → hook-prefetch-K5DN3TOQ.js} +19 -18
- package/dist/hooks/bug-report-worker.js +23 -22
- package/dist/hooks/codex-stop-task-finalizer.js +25 -24
- package/dist/hooks/commit-complete.js +22 -21
- package/dist/hooks/error-recall.js +8 -8
- package/dist/hooks/exe-heartbeat-hook.js +4 -4
- package/dist/hooks/ingest-worker.js +11 -10
- package/dist/hooks/ingest.js +13 -13
- package/dist/hooks/instructions-loaded.js +6 -6
- package/dist/hooks/manifest.json +20 -20
- package/dist/hooks/notification.js +5 -5
- package/dist/hooks/post-compact.js +4 -4
- package/dist/hooks/post-tool-combined.js +13 -13
- package/dist/hooks/pre-compact.js +22 -21
- package/dist/hooks/pre-tool-use.js +32 -31
- package/dist/hooks/prompt-submit.js +36 -35
- package/dist/hooks/session-end.js +27 -26
- package/dist/hooks/session-start.js +18 -18
- package/dist/hooks/stop.js +28 -27
- package/dist/hooks/subagent-stop.js +23 -22
- package/dist/hooks/summary-worker.js +27 -26
- package/dist/index.js +30 -29
- package/dist/{installer-OYBQQ7BY.js → installer-54HTN5RE.js} +5 -5
- package/dist/{installer-RYW65FRY.js → installer-LK35OX6R.js} +5 -5
- package/dist/{installer-A3V2W3NV.js → installer-LLWKZI2S.js} +5 -5
- package/dist/{intercom-queue-XBS5WVJM.js → intercom-queue-5NOT2RKI.js} +18 -17
- package/dist/lib/cloud-sync.js +15 -14
- package/dist/lib/consolidation.js +8 -8
- package/dist/lib/database.js +2 -2
- package/dist/lib/db-backup.js +1 -1
- package/dist/lib/db-daemon-client.js +5 -4
- package/dist/lib/db-write-worker.js +3 -3
- package/dist/lib/db.js +2 -2
- package/dist/lib/device-registry.js +1 -1
- package/dist/lib/embedder.js +5 -4
- package/dist/lib/employee-templates.js +4 -4
- package/dist/lib/employees.js +2 -2
- package/dist/lib/exe-daemon-client.js +4 -3
- package/dist/lib/exe-daemon.js +202 -88
- package/dist/lib/hybrid-search.js +8 -6
- package/dist/lib/identity.js +2 -2
- package/dist/lib/license.js +2 -2
- package/dist/lib/messaging.js +19 -18
- package/dist/lib/post-tool-memory.js +4 -4
- package/dist/lib/registry-proxy.js +1 -1
- package/dist/lib/reminders.js +3 -3
- package/dist/lib/schedules.js +6 -6
- package/dist/lib/session-registry.js +4 -4
- package/dist/lib/skill-learning.js +12 -11
- package/dist/lib/stack-invariants.js +11 -1
- package/dist/lib/store.js +5 -5
- package/dist/lib/task-router.js +3 -3
- package/dist/lib/tasks.js +20 -19
- package/dist/lib/tmux-routing.js +18 -17
- package/dist/lib/token-spend.js +3 -3
- package/dist/{license-gate-EOLMF7J5.js → license-gate-JVMB6OFD.js} +3 -3
- package/dist/{license-sync-ELY6PKEU.js → license-sync-5VYS2F2W.js} +2 -2
- package/dist/mcp/register-tools.js +85 -84
- package/dist/mcp/server.js +89 -88
- package/dist/mcp/tools/complete-reminder.js +4 -4
- package/dist/mcp/tools/create-reminder.js +4 -4
- package/dist/mcp/tools/create-task.js +22 -21
- package/dist/mcp/tools/deactivate-behavior.js +13 -12
- package/dist/mcp/tools/list-reminders.js +4 -4
- package/dist/mcp/tools/list-tasks.js +22 -21
- package/dist/mcp/tools/send-message.js +21 -20
- package/dist/mcp/tools/update-task.js +21 -20
- package/dist/{mcp-child-registry-FVGV5XSB.js → mcp-child-registry-OTG4MWO7.js} +3 -2
- package/dist/{mcp-http-config-4PHK6RHB.js → mcp-http-config-DQWL7U2Z.js} +3 -3
- package/dist/{mcp-session-identity-5DBVDLQR.js → mcp-session-identity-277GASTQ.js} +18 -17
- package/dist/{memory-cards-WJM4NG3Q.js → memory-cards-3S2ZQPR7.js} +9 -5
- package/dist/{memory-graph-extractor-TSTO7PYI.js → memory-graph-extractor-A6DFEFIN.js} +7 -7
- package/dist/{memory-poisoning-defense-BWVA5OBI.js → memory-poisoning-defense-ZVP4H6DY.js} +2 -2
- package/dist/{memory-pressure-watchdog-GES7RFL3.js → memory-pressure-watchdog-6W5F6R7H.js} +19 -18
- package/dist/{memory-queue-client-62NS3U56.js → memory-queue-client-ADSDP6OX.js} +5 -4
- package/dist/{memory-reflection-6UAL4IHM.js → memory-reflection-BKB2YOE6.js} +30 -10
- package/dist/{notification-ledger-E2WOQ3WQ.js → notification-ledger-CLGM7ODF.js} +19 -18
- package/dist/{notifications-IHLUYF3E.js → notifications-MACUZPYP.js} +18 -17
- package/dist/{orchestration-events-TKZV4PAI.js → orchestration-events-N7LYMUGA.js} +3 -3
- package/dist/{orchestrator-MQXUNOS2.js → orchestrator-4X24EWHV.js} +20 -19
- package/dist/{org-brief-session-7KKLV5OW.js → org-brief-session-FZOFMO5U.js} +5 -5
- package/dist/{org-consent-policy-7AHSKB6L.js → org-consent-policy-O5E6HXBL.js} +1 -1
- package/dist/{org-partner-runtime-EVZKR2SJ.js → org-partner-runtime-FODONVTM.js} +5 -5
- package/dist/{org-row-visibility-GUMNPRK7.js → org-row-visibility-VX4AVV5Q.js} +1 -1
- package/dist/{pipeline-router-E5XQUJGU.js → pipeline-router-6GGT2ZW3.js} +3 -3
- package/dist/{plan-limits-AJ6K2P6R.js → plan-limits-FUN76LYY.js} +5 -5
- package/dist/{project-name-FQKW5SFG.js → project-name-LJVFMYTQ.js} +3 -3
- package/dist/{projection-worker-UKSYJ4PG.js → projection-worker-4OANGP5K.js} +2 -2
- package/dist/{prospective-memory-S22KIIBP.js → prospective-memory-KR3P4T6N.js} +2 -2
- package/dist/{push-notifications-T5SJMFL4.js → push-notifications-NCZLH6DI.js} +19 -18
- package/dist/ref-provenance-gate-M4AQO4OT.js +269 -0
- package/dist/{reproject-worktree-memories-G6QO5J3X.js → reproject-worktree-memories-PWYKPB2U.js} +18 -17
- package/dist/{reranker-NYOFY5FK.js → reranker-6V3C2AO4.js} +1 -1
- package/dist/resolve-image-labels-ZI6UBW5W.js +15 -0
- package/dist/{retrieval-health-LWDBIBWJ.js → retrieval-health-5D7O6VH6.js} +1 -1
- package/dist/{review-polling-BSZXGHER.js → review-polling-QW3LJ4KN.js} +19 -18
- package/dist/runtime/index.js +27 -26
- package/dist/{session-events-EO7BFQ73.js → session-events-T45SSTMF.js} +19 -18
- package/dist/{session-kill-telemetry-FXUGITZK.js → session-kill-telemetry-QSPVJGBF.js} +19 -18
- package/dist/{session-scope-B3VWUG4G.js → session-scope-KRWE54C4.js} +18 -17
- package/dist/{setup-wizard-3JEJSXXN.js → setup-wizard-GP3TBTPF.js} +1 -1
- package/dist/{skill-refinement-5DDEQHGM.js → skill-refinement-C7JTMLJG.js} +3 -3
- package/dist/stack-generate-manifest-MFMDWRUP.js +810 -0
- package/dist/{stack-promote-KPEARCCS.js → stack-promote-EKSCYY63.js} +5 -4
- package/dist/{stack-release-FMGC57AD.js → stack-release-2GZAAFO4.js} +5 -4
- package/dist/{stack-update-TZ4P6EXU.js → stack-update-J6JXSTAZ.js} +4 -3
- package/dist/{steward-gate-PC6MD5VP.js → steward-gate-BFCCMCSW.js} +3 -3
- package/dist/{subagent-brief-injection-NBSQ5IBS.js → subagent-brief-injection-ED36PLYY.js} +28 -27
- package/dist/{supervisor-handoff-CSJQMI53.js → supervisor-handoff-SGLEPOCY.js} +12 -3
- package/dist/{support-inbox-M3HDZFVF.js → support-inbox-YW47SYJF.js} +6 -6
- package/dist/{task-enforcement-LXNIF3US.js → task-enforcement-CECTQX4U.js} +19 -18
- package/dist/{task-request-inbox-3EFDJT4E.js → task-request-inbox-Q5T4N5K7.js} +1 -1
- package/dist/{task-scope-ERJTOAS4.js → task-scope-ERVEUEYU.js} +18 -17
- package/dist/{tasks-crud-GUP437HH.js → tasks-crud-ZRQNJXQ2.js} +18 -17
- package/dist/{tasks-notify-AXFFZTI2.js → tasks-notify-MIZH4C2O.js} +19 -18
- package/dist/{tasks-review-AYNV37GQ.js → tasks-review-Z7J2P6DG.js} +18 -17
- package/dist/{telemetry-upload-4IP7KKIR.js → telemetry-upload-LVQUQYFP.js} +7 -7
- package/dist/{token-budget-UJD5CHUG.js → token-budget-BU4NOVZF.js} +3 -3
- package/dist/{tool-capability-index-TCTWUUBO.js → tool-capability-index-7F42MOJT.js} +1 -1
- package/dist/{tool-telemetry-YRVOD2RP.js → tool-telemetry-O27EVMBR.js} +1 -1
- package/dist/tui/App.js +27 -26
- package/dist/{tui-data-ZUFCSQ3G.js → tui-data-TPWWBIUQ.js} +18 -17
- package/dist/{update-support-V5LF2KMQ.js → update-support-F2F5537B.js} +14 -13
- package/dist/{work-claims-2BECZ5GA.js → work-claims-B73X5NE7.js} +3 -3
- package/dist/{work-state-heartbeat-7TMN2GSO.js → work-state-heartbeat-P4YX6E2R.js} +1 -1
- package/dist/{worker-gate-WUX2AYYZ.js → worker-gate-BEEIIVWA.js} +1 -1
- package/dist/{workflow-engine-HDEYIAWI.js → workflow-engine-5X46PFCW.js} +2 -2
- package/dist/{worktree-ZMNKH46X.js → worktree-W47CIMJ6.js} +4 -4
- package/dist/{worktree-sweep-ZNX6R25W.js → worktree-sweep-BNBD4RFX.js} +5 -5
- package/package.json +3 -2
- package/release-notes.json +4 -4
- package/stack.release.json +6 -0
- /package/dist/{chunk-KXIYWHBU.js → chunk-2AJGV5UL.js} +0 -0
- /package/dist/{chunk-IUXVUUIA.js → chunk-6WIFPD2P.js} +0 -0
- /package/dist/{chunk-B72KXFDR.js → chunk-AISULNGL.js} +0 -0
- /package/dist/{chunk-DHWJMFR6.js → chunk-DN4YVV4Z.js} +0 -0
- /package/dist/{chunk-4VB6NJOL.js → chunk-GM7TLYOK.js} +0 -0
- /package/dist/{chunk-X7HB4KLA.js → chunk-GQOEWNVM.js} +0 -0
- /package/dist/{chunk-NP62DK7V.js → chunk-KQ6RJWRW.js} +0 -0
- /package/dist/{chunk-NZH5VSBC.js → chunk-M4IRPXSZ.js} +0 -0
- /package/dist/{chunk-D2Q3AYMB.js → chunk-NRG7KZIP.js} +0 -0
- /package/dist/{chunk-SBMBWO2Y.js → chunk-VZAFWPAY.js} +0 -0
- /package/dist/{chunk-OJTF4SV7.js → chunk-WSQASFLP.js} +0 -0
- /package/dist/{chunk-XXNSHYPO.js → chunk-XFTEX77S.js} +0 -0
- /package/dist/{chunk-RWTYLRNY.js → chunk-YO4BO2CL.js} +0 -0
- /package/dist/{core-memory-33XVE547.js → core-memory-7I7RE2SJ.js} +0 -0
- /package/dist/{entity-boost-JY3KNTO2.js → entity-boost-3UWGXG5O.js} +0 -0
- /package/dist/{memory-isolation-Q3DSVL72.js → memory-isolation-2TUZ7Z4K.js} +0 -0
- /package/dist/{message-queue-client-VMVKIPV7.js → message-queue-client-XQN7QABL.js} +0 -0
- /package/dist/{oauth-server-ZP5ZXRL7.js → oauth-server-AYM37SQ4.js} +0 -0
- /package/dist/{project-boot-5ZXAIOBB.js → project-boot-3Q65LCIP.js} +0 -0
- /package/dist/{wiki-acl-EICCXRAK.js → wiki-acl-IBQLLBTS.js} +0 -0
|
@@ -10,7 +10,12 @@ DOMAIN=CHANGEME_DOMAIN
|
|
|
10
10
|
# bug 8dc31733: EXE_DB_IMAGE overrides the Postgres image tag in compose.
|
|
11
11
|
# The manifest declares env: "EXE_DB_IMAGE" — keep this in sync with the
|
|
12
12
|
# stack manifest pin. Defaults to pgvector/pgvector:0.8.0-pg16 in compose.
|
|
13
|
-
|
|
13
|
+
EXE_DB_IMAGE=update.askexe.com/askexe/pgvector:0.8.0-pg16@sha256:a132765ec351c65111b5b675928a3a0515a466a40f97277329db8b8209ad8bc9
|
|
14
|
+
|
|
15
|
+
# --- Observability ---
|
|
16
|
+
# OTLP collector image. Compose carries no fallback default: a missing pin
|
|
17
|
+
# ABORTS the deploy rather than substituting an old image.
|
|
18
|
+
OTEL_COLLECTOR_IMAGE=update.askexe.com/askexe/otel-collector-contrib:0.114.0@sha256:37fa87091cfaaec7234a27e4e395a40c31c2bfaea97a349a4afef6d9e9681197
|
|
14
19
|
POSTGRES_USER=exe
|
|
15
20
|
POSTGRES_PASSWORD=CHANGEME_POSTGRES_PASSWORD
|
|
16
21
|
POSTGRES_DB=exedb
|
|
@@ -33,7 +38,12 @@ GOTRUE_EXTERNAL_URL=https://auth.CHANGEME_DOMAIN
|
|
|
33
38
|
# tokens are rejected as iss-mismatch. Keep equal to GOTRUE_EXTERNAL_URL.
|
|
34
39
|
GOTRUE_JWT_ISSUER=https://auth.CHANGEME_DOMAIN
|
|
35
40
|
# SSO redirect allow-list (bug 66f8e10a) — app origins for unified SSO.
|
|
36
|
-
|
|
41
|
+
# Must list EVERY origin the SPA can redirect back to, including the opt-in
|
|
42
|
+
# dashboard: dashboard-page sends ?redirect=https://dashboard.<domain> through
|
|
43
|
+
# auth, and GoTrue rejects any redirect_to that is not on this list. Kept in
|
|
44
|
+
# lockstep with generate-env.ts and .env.example — a customer who enables the
|
|
45
|
+
# dashboard profile must not have to discover this entry themselves.
|
|
46
|
+
GOTRUE_URI_ALLOW_LIST=https://crm.CHANGEME_DOMAIN,https://wiki.CHANGEME_DOMAIN,https://erp.CHANGEME_DOMAIN,https://dashboard.CHANGEME_DOMAIN,https://gateway.CHANGEME_DOMAIN
|
|
37
47
|
# Bug 0327b017: parent-domain session cookie → shared across all subdomains.
|
|
38
48
|
GOTRUE_COOKIE_DOMAIN=.CHANGEME_DOMAIN
|
|
39
49
|
GOTRUE_COOKIE_KEY=exe-auth
|
|
@@ -48,10 +58,18 @@ SMTP_PORT=587
|
|
|
48
58
|
SMTP_USER=
|
|
49
59
|
SMTP_PASS=
|
|
50
60
|
|
|
61
|
+
# --- Dashboard (exe-dashboard — customer dashboard at dashboard.<domain>) ---
|
|
62
|
+
# OPT-IN: the exe-dashboard compose service sits behind `profiles: [dashboard]`.
|
|
63
|
+
# No default is written here on purpose — the pin comes from the signed stack
|
|
64
|
+
# manifest (services.dashboard.image), so .env stays derived rather than
|
|
65
|
+
# becoming a competing source of truth that outranks it once it goes stale.
|
|
66
|
+
#DASHBOARD_IMAGE_TAG=update.askexe.com/askexe/exe-dashboard:vX.Y.Z@sha256:...
|
|
67
|
+
#DASHBOARD_PORT=3301
|
|
68
|
+
|
|
51
69
|
# --- Auth gateway (exe-auth — shared SSO sign-in UI at auth.<domain>) ---
|
|
52
70
|
# Bug 58840873: pin the auth image so compose never falls back to its stale
|
|
53
71
|
# hardcoded default tag. Keep in sync with the manifest AUTH_IMAGE_TAG.
|
|
54
|
-
AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.
|
|
72
|
+
AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.6.1@sha256:89670a15bc59255299be695525863e66f949694eec1dd8886038dc3659a4a941
|
|
55
73
|
# Bug 379e5c13: server_name / CORS from the CONFIGURED apex domain, not by naive
|
|
56
74
|
# last-2-label slicing (which breaks company.co.uk → co.uk).
|
|
57
75
|
AUTH_SERVER_NAME=auth.CHANGEME_DOMAIN
|
|
@@ -106,7 +124,7 @@ EXE_ORG_ID=
|
|
|
106
124
|
EXE_ORG_WORKSPACE_ID=
|
|
107
125
|
|
|
108
126
|
# --- CRM ---
|
|
109
|
-
CRM_IMAGE_TAG=update.askexe.com/askexe/exe-crm:v0.9.
|
|
127
|
+
CRM_IMAGE_TAG=update.askexe.com/askexe/exe-crm:v0.9.53@sha256:a586dcc8bbd992538e3caa18c44e772d30f31155dfef0a2b7466ca3fc7c553d8
|
|
110
128
|
CRM_SERVER_URL=https://crm.CHANGEME_DOMAIN
|
|
111
129
|
CRM_APP_SECRET=CHANGEME_CRM_APP_SECRET
|
|
112
130
|
# The CRM's first admin — seeded at boot by WorkspaceBootstrapService, which is
|
|
@@ -120,7 +138,7 @@ EXE_CRM_ADMIN_EMAIL=CHANGEME_ADMIN_EMAIL
|
|
|
120
138
|
CRM_HOST_PORT=3000
|
|
121
139
|
|
|
122
140
|
# --- Wiki ---
|
|
123
|
-
WIKI_IMAGE_TAG=update.askexe.com/askexe/exe-wiki:v0.9.
|
|
141
|
+
WIKI_IMAGE_TAG=update.askexe.com/askexe/exe-wiki:v0.9.28@sha256:61856a4c6b97ce62c62ecdc3a377139287be5860eb807d9fbb737115758d7856
|
|
124
142
|
# Bug 2a8d3003 — DO NOT change this without migrating the data first.
|
|
125
143
|
# The wiki's users / workspaces / workspace_documents live in `public`. Point it at a
|
|
126
144
|
# different schema and Prisma will NOT error: it finds no tables, assumes a fresh
|
|
@@ -143,7 +161,7 @@ WIKI_HOST_PORT=3001
|
|
|
143
161
|
EXE_SSO_COOKIE_NAME=exe_access_token
|
|
144
162
|
|
|
145
163
|
# --- exe-os ---
|
|
146
|
-
EXE_OS_IMAGE_TAG=update.askexe.com/askexe/exe-os:v0.9.
|
|
164
|
+
EXE_OS_IMAGE_TAG=update.askexe.com/askexe/exe-os:v0.9.324@sha256:3ce6406e0f7f279ff2568bbbb7d55de51a46fdf35c49691f24fd959d6fd2d3fa
|
|
147
165
|
EXED_MCP_TOKEN=CHANGEME_EXED_MCP_TOKEN
|
|
148
166
|
EXED_DEVICE_ID=CHANGEME_DEVICE_ID
|
|
149
167
|
EXE_MCP_HOST_BIND=127.0.0.1
|
|
@@ -153,7 +171,7 @@ EXE_MCP_HOST_PORT=48739
|
|
|
153
171
|
EXE_CLOUD_SYNC_TO_POSTGRES=true
|
|
154
172
|
|
|
155
173
|
# --- ERP (Frappe/ERPNext fork) ---
|
|
156
|
-
ERP_IMAGE_TAG=update.askexe.com/askexe/exe-erp:
|
|
174
|
+
ERP_IMAGE_TAG=update.askexe.com/askexe/exe-erp:v2026.08.07-d185286-stamped@sha256:1c655f3f7819c797afd13c79561354f0276cf337403f32aee3e406a497e8827b
|
|
157
175
|
# Administrator password for the ERPNext site (created on first boot).
|
|
158
176
|
# bug 43854b31: this only applies at FIRST boot. To rotate it later you must also
|
|
159
177
|
# run `bench --site $ERP_SITE_NAME set-admin-password <new>` inside exe-erp —
|
|
@@ -169,7 +187,7 @@ ERP_WS_PORT=9069
|
|
|
169
187
|
ERP_SENTRY_DSN=
|
|
170
188
|
|
|
171
189
|
# --- Gateway ---
|
|
172
|
-
GATEWAY_IMAGE_TAG=update.askexe.com/askexe/exe-gateway:
|
|
190
|
+
GATEWAY_IMAGE_TAG=update.askexe.com/askexe/exe-gateway:v2026.08.07-c15f093-stamped@sha256:1bc11a2a0ad1f3929d59d2685696f22a72042b9fca9c75e15c02dc7d3c640105
|
|
173
191
|
EXE_GATEWAY_AUTH_TOKEN=CHANGEME_EXE_GATEWAY_AUTH_TOKEN
|
|
174
192
|
EXE_GATEWAY_WS_RELAY_AUTH_TOKEN=CHANGEME_EXE_GATEWAY_WS_RELAY_AUTH_TOKEN
|
|
175
193
|
EXE_GATEWAY_WHATSAPP_VERIFY_TOKEN=CHANGEME_EXE_GATEWAY_WHATSAPP_VERIFY_TOKEN
|
|
@@ -190,7 +208,7 @@ CRM_GRAPHQL_URL=http://exe-crm:3000/graphql
|
|
|
190
208
|
# bug 633995f1: v0.9.5 is a QUARANTINED build that crashloops on any existing
|
|
191
209
|
# deployment; v0.9.4 is the last known-good generation and matches the signed
|
|
192
210
|
# apps manifest. See deploy/known-bad-images.json.
|
|
193
|
-
MONITOR_HUB_IMAGE_TAG=update.askexe.com/askexe/exe-monitor-hub:
|
|
211
|
+
MONITOR_HUB_IMAGE_TAG=update.askexe.com/askexe/exe-monitor-hub:v2026.08.09-10660eb4-stamped@sha256:c9a9218c2713b8dffea7e1cf8c0702a614657d311a7a4e821c6a543bab29bb97
|
|
194
212
|
MONITOR_HUB_PORT=8090
|
|
195
213
|
# Bootstrap superuser created on first start. Use your admin email + a strong password.
|
|
196
214
|
# After first boot these values are no longer used (stored in pb_data volume).
|
|
@@ -224,7 +242,7 @@ GATEWAY_ALERT_URL=http://exe-gateway:3100/api/alerts/error-spike
|
|
|
224
242
|
# Full scope details: deploy/monitor/HOST-ACCESS-CONSENT.md
|
|
225
243
|
# COMPOSE_PROFILES=monitor-agent
|
|
226
244
|
# bug 633995f1 / 9ce2a68b: the agent healthcheck is coupled to this generation.
|
|
227
|
-
MONITOR_AGENT_IMAGE_TAG=update.askexe.com/askexe/exe-monitor-agent:
|
|
245
|
+
MONITOR_AGENT_IMAGE_TAG=update.askexe.com/askexe/exe-monitor-agent:v2026.08.09-10660eb4-stamped@sha256:29fbd445f79484df04f000603e4ff445e76f0380f86d687a0033e3a0ef7d1b7a
|
|
228
246
|
# Reports to the local hub. Auto-populated by `exe-os stack-update` during bootstrap.
|
|
229
247
|
MONITOR_HUB_URL=http://exe-monitor-hub:8090
|
|
230
248
|
# bug dacf0042: TOKEN and KEY MUST start EMPTY (the safe "unpaired" state) — NOT a
|
|
@@ -76,11 +76,26 @@ SMTP_PORT=587
|
|
|
76
76
|
SMTP_USER=
|
|
77
77
|
SMTP_PASS=
|
|
78
78
|
|
|
79
|
+
# --- Dashboard (exe-dashboard — customer dashboard at dashboard.<domain>) ---
|
|
80
|
+
# OPT-IN: the exe-dashboard compose service sits behind `profiles: [dashboard]`
|
|
81
|
+
# and is off unless you run `docker compose --profile dashboard ...`.
|
|
82
|
+
# DELIBERATELY UNSET AND COMMENTED OUT. Unlike the older *_IMAGE_TAG lines
|
|
83
|
+
# above/below, this one carries no hardcoded literal: a pinned default here is
|
|
84
|
+
# a second source of truth that silently outranks the manifest the moment it
|
|
85
|
+
# goes stale. Take the value from the signed stack manifest
|
|
86
|
+
# (deploy/stack-manifests/v0.9.json -> services.dashboard.image), digest and all.
|
|
87
|
+
# Leave it unset and compose refuses the dashboard loudly ("has neither an image
|
|
88
|
+
# nor a build context specified") instead of booting something arbitrary.
|
|
89
|
+
#DASHBOARD_IMAGE_TAG=update.askexe.com/askexe/exe-dashboard:vX.Y.Z@sha256:...
|
|
90
|
+
# Host port for the dashboard container (bound to 127.0.0.1; the tunnel and the
|
|
91
|
+
# SSO edge reach it over the docker network, not this port).
|
|
92
|
+
#DASHBOARD_PORT=3301
|
|
93
|
+
|
|
79
94
|
# --- Auth gateway (exe-auth — shared SSO sign-in UI at auth.<domain>) ---
|
|
80
95
|
# Bug 58840873: pin the auth image so compose never falls back to its stale
|
|
81
96
|
# hardcoded default tag. Keep in sync with the manifest AUTH_IMAGE_TAG. exe-auth
|
|
82
97
|
# ships only from the private update.askexe.com registry (no GHCR mirror).
|
|
83
|
-
AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.
|
|
98
|
+
AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.6.1@sha256:89670a15bc59255299be695525863e66f949694eec1dd8886038dc3659a4a941
|
|
84
99
|
# Bug 379e5c13: server_name / CORS derived from the CONFIGURED apex domain,
|
|
85
100
|
# not by naive last-2-label slicing (which breaks company.co.uk → co.uk).
|
|
86
101
|
AUTH_SERVER_NAME=auth.CHANGEME_DOMAIN
|
|
@@ -140,7 +155,7 @@ EXE_ORG_ID=
|
|
|
140
155
|
EXE_ORG_WORKSPACE_ID=
|
|
141
156
|
|
|
142
157
|
# --- CRM ---
|
|
143
|
-
CRM_IMAGE_TAG=ghcr.io/askexe/exe-crm:v0.9.
|
|
158
|
+
CRM_IMAGE_TAG=ghcr.io/askexe/exe-crm:v0.9.53@sha256:a586dcc8bbd992538e3caa18c44e772d30f31155dfef0a2b7466ca3fc7c553d8
|
|
144
159
|
CRM_SERVER_URL=https://crm.CHANGEME_DOMAIN
|
|
145
160
|
CRM_APP_SECRET=CHANGEME_CRM_APP_SECRET
|
|
146
161
|
EXE_CRM_ADMIN_TOKEN=CHANGEME_EXE_CRM_ADMIN_TOKEN
|
|
@@ -153,7 +168,7 @@ EXE_CRM_ADMIN_EMAIL=CHANGEME_ADMIN_EMAIL
|
|
|
153
168
|
CRM_HOST_PORT=3000
|
|
154
169
|
|
|
155
170
|
# --- Wiki ---
|
|
156
|
-
WIKI_IMAGE_TAG=ghcr.io/askexe/exe-wiki:v0.9.
|
|
171
|
+
WIKI_IMAGE_TAG=ghcr.io/askexe/exe-wiki:v0.9.28@sha256:61856a4c6b97ce62c62ecdc3a377139287be5860eb807d9fbb737115758d7856
|
|
157
172
|
# Bug 2a8d3003 — DO NOT change this without migrating the data first.
|
|
158
173
|
# The wiki's users / workspaces / workspace_documents live in `public`. Point it at a
|
|
159
174
|
# different schema and Prisma will NOT error: it finds no tables, assumes a fresh
|
|
@@ -176,7 +191,12 @@ WIKI_HOST_PORT=3001
|
|
|
176
191
|
EXE_SSO_COOKIE_NAME=exe_access_token
|
|
177
192
|
|
|
178
193
|
# --- exe-os ---
|
|
179
|
-
EXE_OS_IMAGE_TAG=ghcr.io/askexe/exe-os:v0.9.
|
|
194
|
+
EXE_OS_IMAGE_TAG=ghcr.io/askexe/exe-os:v0.9.324@sha256:3ce6406e0f7f279ff2568bbbb7d55de51a46fdf35c49691f24fd959d6fd2d3fa
|
|
195
|
+
|
|
196
|
+
# Infra image pins — manifest-derived. Compose has no fallback default for
|
|
197
|
+
# these: a missing pin ABORTS the deploy instead of substituting an old image.
|
|
198
|
+
EXE_DB_IMAGE=update.askexe.com/askexe/pgvector:0.8.0-pg16@sha256:a132765ec351c65111b5b675928a3a0515a466a40f97277329db8b8209ad8bc9
|
|
199
|
+
OTEL_COLLECTOR_IMAGE=update.askexe.com/askexe/otel-collector-contrib:0.114.0@sha256:37fa87091cfaaec7234a27e4e395a40c31c2bfaea97a349a4afef6d9e9681197
|
|
180
200
|
EXED_MCP_TOKEN=CHANGEME_EXED_MCP_TOKEN
|
|
181
201
|
EXED_DEVICE_ID=vps-default
|
|
182
202
|
EXE_MCP_HOST_BIND=127.0.0.1
|
|
@@ -186,7 +206,7 @@ EXE_MCP_HOST_PORT=48739
|
|
|
186
206
|
EXE_CLOUD_SYNC_TO_POSTGRES=true
|
|
187
207
|
|
|
188
208
|
# --- Gateway ---
|
|
189
|
-
GATEWAY_IMAGE_TAG=ghcr.io/askexe/exe-gateway:
|
|
209
|
+
GATEWAY_IMAGE_TAG=ghcr.io/askexe/exe-gateway:v2026.08.07-c15f093-stamped@sha256:1bc11a2a0ad1f3929d59d2685696f22a72042b9fca9c75e15c02dc7d3c640105
|
|
190
210
|
EXE_GATEWAY_AUTH_TOKEN=CHANGEME_EXE_GATEWAY_AUTH_TOKEN
|
|
191
211
|
EXE_GATEWAY_WS_RELAY_AUTH_TOKEN=CHANGEME_EXE_GATEWAY_WS_RELAY_AUTH_TOKEN
|
|
192
212
|
EXE_GATEWAY_WHATSAPP_VERIFY_TOKEN=CHANGEME_EXE_GATEWAY_WHATSAPP_VERIFY_TOKEN
|
|
@@ -226,7 +246,7 @@ ERROR_REPORTING_ENABLED=true
|
|
|
226
246
|
MONITOR_ERROR_URL=http://exe-monitor-hub:8090/api/exe-monitor/errors
|
|
227
247
|
|
|
228
248
|
# --- ERP (optional — Exe ERP, Frappe/ERPNext fork) ---
|
|
229
|
-
ERP_IMAGE_TAG=ghcr.io/askexe/exe-erp:
|
|
249
|
+
ERP_IMAGE_TAG=ghcr.io/askexe/exe-erp:v2026.08.07-d185286-stamped@sha256:1c655f3f7819c797afd13c79561354f0276cf337403f32aee3e406a497e8827b
|
|
230
250
|
ERP_ADMIN_PASSWORD=CHANGEME_ERP_ADMIN_PASSWORD
|
|
231
251
|
EXE_ERP_ADMIN_TOKEN=CHANGEME_EXE_ERP_ADMIN_TOKEN
|
|
232
252
|
# Frappe site name — must match the erp.<domain> the customer serves (bug e61ad373).
|
|
@@ -248,7 +268,7 @@ EXE_BUILD_HTTP_PORT=9222
|
|
|
248
268
|
# data dir and entrypoint all changed) and crashloops on any existing
|
|
249
269
|
# deployment. v0.9.4 is the last known-good generation and is what the signed
|
|
250
270
|
# apps manifest pins. See deploy/known-bad-images.json.
|
|
251
|
-
MONITOR_HUB_IMAGE_TAG=ghcr.io/askexe/exe-monitor-hub:
|
|
271
|
+
MONITOR_HUB_IMAGE_TAG=ghcr.io/askexe/exe-monitor-hub:v2026.08.09-10660eb4-stamped@sha256:c9a9218c2713b8dffea7e1cf8c0702a614657d311a7a4e821c6a543bab29bb97
|
|
252
272
|
MONITOR_HUB_PORT=8090
|
|
253
273
|
# Bootstrap superuser created on first start. Use your admin email + a strong password.
|
|
254
274
|
# After first boot these values are no longer used (stored in pb_data volume).
|
|
@@ -268,7 +288,7 @@ MONITOR_HUB_ADMIN_PASSWORD=CHANGEME_MONITOR_HUB_ADMIN_PASSWORD
|
|
|
268
288
|
# COMPOSE_PROFILES=monitor-agent
|
|
269
289
|
# bug 633995f1 / 9ce2a68b: keep the agent on the v0.9.4 generation — the
|
|
270
290
|
# compose healthcheck (`/app/beszel-agent health`) is coupled to it.
|
|
271
|
-
MONITOR_AGENT_IMAGE_TAG=ghcr.io/askexe/exe-monitor-agent:
|
|
291
|
+
MONITOR_AGENT_IMAGE_TAG=ghcr.io/askexe/exe-monitor-agent:v2026.08.09-10660eb4-stamped@sha256:29fbd445f79484df04f000603e4ff445e76f0380f86d687a0033e3a0ef7d1b7a
|
|
272
292
|
# Reports to the local hub. Auto-populated by `exe-os stack-update` during bootstrap.
|
|
273
293
|
MONITOR_HUB_URL=http://exe-monitor-hub:8090
|
|
274
294
|
# bug dacf0042: TOKEN and KEY MUST start EMPTY (the safe "unpaired" state) —
|
|
@@ -29,7 +29,7 @@ services:
|
|
|
29
29
|
# bug ee16e7ef: pin a versioned tag, not the mutable :pg16 rolling tag.
|
|
30
30
|
# pgvector/pgvector:pg16 can change upstream without notice; 0.8.0-pg16
|
|
31
31
|
# is the tested stable release. Override via EXE_DB_IMAGE in .env.
|
|
32
|
-
image: ${EXE_DB_IMAGE
|
|
32
|
+
image: ${EXE_DB_IMAGE:?EXE_DB_IMAGE must be set from the signed stack manifest (digest-pinned) — refusing to fall back to a stale hard-coded image}
|
|
33
33
|
container_name: exe-db
|
|
34
34
|
restart: unless-stopped
|
|
35
35
|
# SECURITY (bug 67d62490): no blanket `env_file: .env`. Each service
|
|
@@ -278,7 +278,7 @@ services:
|
|
|
278
278
|
# is what the signed apps manifest (deploy/stack-manifests/v0.9.30-apps.json)
|
|
279
279
|
# and exe-monitor's own stack.release.json pin. Do not reintroduce the bad
|
|
280
280
|
# digest.
|
|
281
|
-
image: ${MONITOR_HUB_IMAGE_TAG
|
|
281
|
+
image: ${MONITOR_HUB_IMAGE_TAG:?MONITOR_HUB_IMAGE_TAG must be set from the signed stack manifest (digest-pinned) — refusing to fall back to a stale hard-coded image}
|
|
282
282
|
container_name: exe-monitor-hub
|
|
283
283
|
restart: unless-stopped
|
|
284
284
|
# bug d3d49101 / 1fdb8be9: PocketBase's data dir for this hub is a RELATIVE
|
|
@@ -360,7 +360,7 @@ services:
|
|
|
360
360
|
# ------------------------------------------------------------------
|
|
361
361
|
|
|
362
362
|
exe-crm:
|
|
363
|
-
image: ${CRM_IMAGE_TAG
|
|
363
|
+
image: ${CRM_IMAGE_TAG:?CRM_IMAGE_TAG must be set from the signed stack manifest (digest-pinned) — refusing to fall back to a stale hard-coded image}
|
|
364
364
|
container_name: exe-crm
|
|
365
365
|
restart: unless-stopped
|
|
366
366
|
# bug ad4471ad: NO compose `command` override. The image entrypoint
|
|
@@ -486,7 +486,7 @@ services:
|
|
|
486
486
|
options: { max-size: "10m", max-file: "3" }
|
|
487
487
|
|
|
488
488
|
exe-crm-worker:
|
|
489
|
-
image: ${CRM_IMAGE_TAG
|
|
489
|
+
image: ${CRM_IMAGE_TAG:?CRM_IMAGE_TAG must be set from the signed stack manifest (digest-pinned) — refusing to fall back to a stale hard-coded image}
|
|
490
490
|
container_name: exe-crm-worker
|
|
491
491
|
restart: unless-stopped
|
|
492
492
|
command: ["yarn", "worker:prod"]
|
|
@@ -552,7 +552,7 @@ services:
|
|
|
552
552
|
# erroring, so "wiki looks wiped" and "wiki is misconfigured" are indistinguishable
|
|
553
553
|
# at a glance, and the wrong diagnosis (restore from backup) destroys real data.
|
|
554
554
|
exe-wiki-schema-guard:
|
|
555
|
-
image: ${EXE_DB_IMAGE
|
|
555
|
+
image: ${EXE_DB_IMAGE:?EXE_DB_IMAGE must be set from the signed stack manifest (digest-pinned) — refusing to fall back to a stale hard-coded image}
|
|
556
556
|
container_name: exe-wiki-schema-guard
|
|
557
557
|
restart: "no"
|
|
558
558
|
depends_on:
|
|
@@ -588,7 +588,7 @@ services:
|
|
|
588
588
|
options: { max-size: "10m", max-file: "3" }
|
|
589
589
|
|
|
590
590
|
exe-wiki:
|
|
591
|
-
image: ${WIKI_IMAGE_TAG
|
|
591
|
+
image: ${WIKI_IMAGE_TAG:?WIKI_IMAGE_TAG must be set from the signed stack manifest (digest-pinned) — refusing to fall back to a stale hard-coded image}
|
|
592
592
|
container_name: exe-wiki
|
|
593
593
|
restart: unless-stopped
|
|
594
594
|
# Wiki uses Prisma — runs migrate on boot via built-in entrypoint.
|
|
@@ -728,7 +728,15 @@ services:
|
|
|
728
728
|
# to pin the split server image; falls back to the combined EXE_OS_IMAGE_TAG
|
|
729
729
|
# for backward compatibility with existing manifests.
|
|
730
730
|
exe-os:
|
|
731
|
-
|
|
731
|
+
# FAIL-CLOSED PIN. The signed stack manifest is the single source of truth for
|
|
732
|
+
# this image; stack-update writes EXE_OS_IMAGE_TAG from it. The legacy aliases are
|
|
733
|
+
# kept so an older .env keeps working, and the chain terminates EMPTY on purpose:
|
|
734
|
+
# docker compose evaluates nested defaults eagerly, so `:?` inside a chain would
|
|
735
|
+
# fire even when an alias IS set. With no pin at all compose aborts with
|
|
736
|
+
# "has neither an image nor a build context specified" — loud, not a silent
|
|
737
|
+
# substitution of a stale hard-coded version (which is how auth nearly shipped a
|
|
738
|
+
# four-minor-version downgrade).
|
|
739
|
+
image: ${EXE_OS_SERVER_IMAGE_TAG:-${EXE_OS_IMAGE_TAG:-${EXED_IMAGE_TAG:-}}}
|
|
732
740
|
container_name: exe-os
|
|
733
741
|
restart: unless-stopped
|
|
734
742
|
# bug debf4a39 / 93ddfa27: the daemon connects to exe-db at boot
|
|
@@ -847,7 +855,7 @@ services:
|
|
|
847
855
|
options: { max-size: "10m", max-file: "3" }
|
|
848
856
|
|
|
849
857
|
exe-gateway:
|
|
850
|
-
image: ${GATEWAY_IMAGE_TAG
|
|
858
|
+
image: ${GATEWAY_IMAGE_TAG:?GATEWAY_IMAGE_TAG must be set from the signed stack manifest (digest-pinned) — refusing to fall back to a stale hard-coded image}
|
|
851
859
|
container_name: exe-gateway
|
|
852
860
|
restart: unless-stopped
|
|
853
861
|
# Gateway needs 45s to flush outbound queues + disconnect Baileys adapters.
|
|
@@ -1011,7 +1019,7 @@ services:
|
|
|
1011
1019
|
# v0.9.5 default contradicted that healthcheck, so the agent was
|
|
1012
1020
|
# permanently unhealthy from the first recreate. Matches the signed apps
|
|
1013
1021
|
# manifest and exe-monitor's stack.release.json.
|
|
1014
|
-
image: ${MONITOR_AGENT_IMAGE_TAG
|
|
1022
|
+
image: ${MONITOR_AGENT_IMAGE_TAG:?MONITOR_AGENT_IMAGE_TAG must be set from the signed stack manifest (digest-pinned) — refusing to fall back to a stale hard-coded image}
|
|
1015
1023
|
container_name: exe-monitor-agent
|
|
1016
1024
|
# Host-access consent gate: only starts when the operator has
|
|
1017
1025
|
# acknowledged the host-access scope (COMPOSE_PROFILES=monitor-agent).
|
|
@@ -1116,7 +1124,15 @@ services:
|
|
|
1116
1124
|
# Without a token the binary exits 0 (no crash-loop). (bug 3416cead)
|
|
1117
1125
|
# ------------------------------------------------------------------
|
|
1118
1126
|
exe-update:
|
|
1119
|
-
|
|
1127
|
+
# FAIL-CLOSED PIN. The signed stack manifest is the single source of truth for
|
|
1128
|
+
# this image; stack-update writes EXE_OS_IMAGE_TAG from it. The legacy aliases are
|
|
1129
|
+
# kept so an older .env keeps working, and the chain terminates EMPTY on purpose:
|
|
1130
|
+
# docker compose evaluates nested defaults eagerly, so `:?` inside a chain would
|
|
1131
|
+
# fire even when an alias IS set. With no pin at all compose aborts with
|
|
1132
|
+
# "has neither an image nor a build context specified" — loud, not a silent
|
|
1133
|
+
# substitution of a stale hard-coded version (which is how auth nearly shipped a
|
|
1134
|
+
# four-minor-version downgrade).
|
|
1135
|
+
image: ${EXE_OS_IMAGE_TAG:-${EXED_IMAGE_TAG:-}}
|
|
1120
1136
|
container_name: exe-update
|
|
1121
1137
|
profiles: ["registry-proxy", "askexe-control-plane"]
|
|
1122
1138
|
restart: unless-stopped
|
|
@@ -1675,7 +1691,7 @@ services:
|
|
|
1675
1691
|
exe-otel-collector:
|
|
1676
1692
|
# bug 32d6e02f: digest-pinned default (was tag-only) — matches the
|
|
1677
1693
|
# stack manifest pin for otel/opentelemetry-collector-contrib:0.114.0.
|
|
1678
|
-
image: ${OTEL_COLLECTOR_IMAGE
|
|
1694
|
+
image: ${OTEL_COLLECTOR_IMAGE:?OTEL_COLLECTOR_IMAGE must be set from the signed stack manifest (digest-pinned) — refusing to fall back to a stale hard-coded image}
|
|
1679
1695
|
container_name: exe-otel-collector
|
|
1680
1696
|
restart: unless-stopped
|
|
1681
1697
|
command: ["--config=/etc/otelcol-contrib/config.yaml"]
|
|
@@ -1743,7 +1759,7 @@ services:
|
|
|
1743
1759
|
# a fresh/migrated install boots an old image while the manifest reads "latest".
|
|
1744
1760
|
# generate-env.ts now always writes AUTH_IMAGE_TAG, and this default mirrors the
|
|
1745
1761
|
# pin as defense-in-depth — keep BOTH in lockstep on every auth release.
|
|
1746
|
-
image: ${AUTH_IMAGE_TAG
|
|
1762
|
+
image: ${AUTH_IMAGE_TAG:?AUTH_IMAGE_TAG must be set from the signed stack manifest (digest-pinned) — refusing to fall back to a stale hard-coded image}
|
|
1747
1763
|
container_name: exe-auth
|
|
1748
1764
|
restart: unless-stopped
|
|
1749
1765
|
environment:
|
|
@@ -1813,6 +1829,79 @@ services:
|
|
|
1813
1829
|
driver: json-file
|
|
1814
1830
|
options: { max-size: "10m", max-file: "3" }
|
|
1815
1831
|
|
|
1832
|
+
# ------------------------------------------------------------------
|
|
1833
|
+
# Dashboard — customer dashboard at dashboard.yourdomain.com
|
|
1834
|
+
# Static nginx image built from dashboard-page/ in the exe-os repo.
|
|
1835
|
+
# ------------------------------------------------------------------
|
|
1836
|
+
#
|
|
1837
|
+
# WHY THIS IS HERE AT ALL (2026-08-20). exe-dashboard has been running in
|
|
1838
|
+
# production for months WITHOUT a service in this file. Its only compose
|
|
1839
|
+
# definition was dashboard-page/docker-compose.yml — a standalone side-car
|
|
1840
|
+
# that carried `build: .` and a hardcoded `image: …:v0.1.0`, joined the
|
|
1841
|
+
# external `exe-net` network, and answered the `upstream sso_dashboard`
|
|
1842
|
+
# in sso-edge/default.conf.template. Nothing in the stack manifest could pin
|
|
1843
|
+
# a service the stack compose did not define, which is exactly why the
|
|
1844
|
+
# dashboard drifted three builds behind main with nobody able to see it.
|
|
1845
|
+
# This entry makes it a first-class, manifest-governed stack service.
|
|
1846
|
+
#
|
|
1847
|
+
# OPT-IN VIA PROFILE. `profiles: ["dashboard"]` keeps this off for every
|
|
1848
|
+
# existing deployment that has not opted in. That is deliberate and it is why
|
|
1849
|
+
# the image pin uses the empty-default form and NOT the required-variable
|
|
1850
|
+
# (colon-question-mark) form: compose interpolates the WHOLE file before it
|
|
1851
|
+
# filters by profile (verified on Docker 28.5.1 — a required-variable
|
|
1852
|
+
# reference inside an INACTIVE profile still aborts `docker compose config`),
|
|
1853
|
+
# so that form here would break every customer who never asked for the
|
|
1854
|
+
# dashboard. The empty terminator gets the same fail-loud
|
|
1855
|
+
# behaviour exactly where it belongs: with the profile ACTIVE and the variable
|
|
1856
|
+
# unset, compose refuses with `service "exe-dashboard" has neither an image nor
|
|
1857
|
+
# a build context specified` instead of silently substituting a stale literal.
|
|
1858
|
+
exe-dashboard:
|
|
1859
|
+
image: ${DASHBOARD_IMAGE_TAG:-}
|
|
1860
|
+
profiles: ["dashboard"]
|
|
1861
|
+
container_name: exe-dashboard
|
|
1862
|
+
restart: unless-stopped
|
|
1863
|
+
environment:
|
|
1864
|
+
# Customer apex domain — templates server_name, CSP and the SPA's API/auth
|
|
1865
|
+
# URLs at container start via dashboard-page/docker-entrypoint.sh. Never
|
|
1866
|
+
# falls back to askexe.com.
|
|
1867
|
+
DOMAIN: ${DOMAIN:?DOMAIN is required — set to your customer apex domain (e.g. hygo.co)}
|
|
1868
|
+
# Optional explicit overrides; each defaults to the matching *.${DOMAIN}.
|
|
1869
|
+
DASH_DOMAIN: ${DASH_DOMAIN:-}
|
|
1870
|
+
DASH_API_URL: ${DASH_API_URL:-}
|
|
1871
|
+
DASH_AUTH_URL: ${DASH_AUTH_URL:-}
|
|
1872
|
+
DASH_DASHBOARD_URL: ${DASH_DASHBOARD_URL:-}
|
|
1873
|
+
ports:
|
|
1874
|
+
- "127.0.0.1:${DASHBOARD_PORT:-3301}:80"
|
|
1875
|
+
networks:
|
|
1876
|
+
# `backend` so exe-sso-edge can resolve `exe-dashboard` for its
|
|
1877
|
+
# `upstream sso_dashboard { server exe-dashboard:80; }`; `frontend` so the
|
|
1878
|
+
# cloudflared tunnel can reach it. Same pair as exe-auth/exe-crm/exe-wiki.
|
|
1879
|
+
#
|
|
1880
|
+
# NOTE: exe-sso-edge deliberately does NOT list this service in its
|
|
1881
|
+
# depends_on. The edge must keep starting on deployments that never enable
|
|
1882
|
+
# the dashboard profile, and a depends_on would make the edge unstartable
|
|
1883
|
+
# for them.
|
|
1884
|
+
- backend
|
|
1885
|
+
- frontend
|
|
1886
|
+
healthcheck:
|
|
1887
|
+
# dashboard-page/nginx.conf serves `location = /health` as a literal 200.
|
|
1888
|
+
# This is the same URL the stack manifest's healthUrl names, so the deploy
|
|
1889
|
+
# gate and the container agree on what "up" means. Before this existed,
|
|
1890
|
+
# /health fell through to the SPA `location /` and returned the index page
|
|
1891
|
+
# with a 200 — a probe that could not fail while nginx was running at all.
|
|
1892
|
+
test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1/health"]
|
|
1893
|
+
interval: 30s
|
|
1894
|
+
timeout: 5s
|
|
1895
|
+
start_period: 5s
|
|
1896
|
+
retries: 3
|
|
1897
|
+
deploy:
|
|
1898
|
+
resources:
|
|
1899
|
+
limits:
|
|
1900
|
+
memory: 128M
|
|
1901
|
+
logging:
|
|
1902
|
+
driver: json-file
|
|
1903
|
+
options: { max-size: "10m", max-file: "3" }
|
|
1904
|
+
|
|
1816
1905
|
# ------------------------------------------------------------------
|
|
1817
1906
|
# Volumes
|
|
1818
1907
|
# ------------------------------------------------------------------
|
|
@@ -1,40 +1,89 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// IMAGE PINS — DERIVED FROM THE SIGNED MANIFEST. NEVER HAND-TYPED.
|
|
5
|
+
//
|
|
6
|
+
// .env used to be an INDEPENDENT source of pins: a block of hand-edited
|
|
7
|
+
// `*_RELEASE_TAG` constants that had to be "kept in sync" with
|
|
8
|
+
// deploy/stack-manifests/v0.9.json. It was not kept in sync. On 2026-08-20 the
|
|
9
|
+
// manifest, /opt/exe-stack/.env and the compose fallback defaults disagreed on
|
|
10
|
+
// 5 of 7 apps in production.
|
|
11
|
+
//
|
|
12
|
+
// One direction only: each repo cuts a release -> the manifest is generated
|
|
13
|
+
// from those releases -> .env is DERIVED from the manifest -> the VPS pulls what
|
|
14
|
+
// .env says. The version AND digest of every pin below now come from the
|
|
15
|
+
// manifest and nowhere else, so drift is unrepresentable rather than merely
|
|
16
|
+
// discouraged.
|
|
17
|
+
//
|
|
18
|
+
// The registry HOST is deployment topology, not a pin: .env.example targets
|
|
19
|
+
// GHCR so local simulation runs without private update.askexe.com credentials,
|
|
20
|
+
// while the same tag@digest is served by the pull-through proxy. Re-hosting
|
|
21
|
+
// preserves the digest, so the artifact is identical either way.
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
2
23
|
const REGISTRY = "ghcr.io/askexe";
|
|
3
24
|
// exe-auth (the shared SSO sign-in/sign-up SPA) ships only from the private
|
|
4
25
|
// update.askexe.com registry — it is not mirrored to GHCR — so it carries its
|
|
5
26
|
// own registry constant rather than reusing REGISTRY (bug 58840873).
|
|
6
27
|
const AUTH_REGISTRY = "update.askexe.com/askexe";
|
|
7
28
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
const MANIFEST_PATH = new URL("../stack-manifests/v0.9.json", import.meta.url);
|
|
30
|
+
|
|
31
|
+
type ManifestFile = {
|
|
32
|
+
latest: string;
|
|
33
|
+
stacks: Record<string, { services?: Record<string, { image?: string }> }>;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function loadManifestServices(): Record<string, { image?: string }> {
|
|
37
|
+
const manifest = JSON.parse(readFileSync(MANIFEST_PATH, "utf8")) as ManifestFile;
|
|
38
|
+
const services = manifest.stacks?.[manifest.latest]?.services;
|
|
39
|
+
if (!services) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`generate-env: stack manifest ${MANIFEST_PATH.pathname} has no services for latest="${manifest.latest}". ` +
|
|
42
|
+
`Refusing to generate a .env with no pins — that is exactly the silent-substitution failure ` +
|
|
43
|
+
`the manifest-as-single-source-of-truth change exists to prevent.`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return services;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const MANIFEST_SERVICES = loadManifestServices();
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The manifest's pin for a service, re-hosted onto `registry`. FAILS LOUDLY
|
|
53
|
+
* when the manifest does not govern the service, or governs it without a
|
|
54
|
+
* digest: a missing pin must abort generation, never fall back to a literal.
|
|
55
|
+
*/
|
|
56
|
+
function pin(serviceKey: string, registry: string, imageName: string): string {
|
|
57
|
+
const image = MANIFEST_SERVICES[serviceKey]?.image;
|
|
58
|
+
if (!image) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`generate-env: the stack manifest does not pin "${serviceKey}". Every service .env pins must be ` +
|
|
61
|
+
`manifest-governed — add it to the manifest (exe-os stack-generate-manifest) rather than ` +
|
|
62
|
+
`hard-coding a version here.`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
const at = image.indexOf("@");
|
|
66
|
+
if (at === -1) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
`generate-env: the manifest pin for "${serviceKey}" (${image}) carries no @sha256 digest. ` +
|
|
69
|
+
`Tags move, digests do not — refusing to emit an unpinned .env value.`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
const digest = image.slice(at + 1);
|
|
73
|
+
const beforeDigest = image.slice(0, at);
|
|
74
|
+
const colon = beforeDigest.lastIndexOf(":");
|
|
75
|
+
const slash = beforeDigest.lastIndexOf("/");
|
|
76
|
+
const tag = colon > slash ? beforeDigest.slice(colon + 1) : "";
|
|
77
|
+
return tag ? `${registry}/${imageName}:${tag}@${digest}` : `${registry}/${imageName}@${digest}`;
|
|
78
|
+
}
|
|
30
79
|
|
|
31
80
|
const POSTGRES_USER = "exe";
|
|
32
81
|
const POSTGRES_DB = "exedb";
|
|
33
82
|
const CLICKHOUSE_DB = "default";
|
|
34
83
|
const CLICKHOUSE_USER = "exe";
|
|
35
|
-
export const CRM_IMAGE_TAG =
|
|
84
|
+
export const CRM_IMAGE_TAG = pin("crm", REGISTRY, "exe-crm");
|
|
36
85
|
const CRM_HOST_PORT = "3000";
|
|
37
|
-
export const WIKI_IMAGE_TAG =
|
|
86
|
+
export const WIKI_IMAGE_TAG = pin("wiki", REGISTRY, "exe-wiki");
|
|
38
87
|
// Bug 2a8d3003: the wiki's data lives in `public` and generated .env files must say
|
|
39
88
|
// so. This constant used to be "wiki", which meant every freshly generated stack
|
|
40
89
|
// pinned the wiki to an empty schema — Prisma bootstraps it silently rather than
|
|
@@ -42,13 +91,22 @@ export const WIKI_IMAGE_TAG = `${REGISTRY}/exe-wiki:${WIKI_RELEASE_TAG}`;
|
|
|
42
91
|
const WIKI_DB_SCHEMA = "public";
|
|
43
92
|
const WIKI_VECTOR_DB = "exeOsMcp";
|
|
44
93
|
const WIKI_HOST_PORT = "3001";
|
|
45
|
-
export const EXE_OS_IMAGE_TAG =
|
|
46
|
-
export const GATEWAY_IMAGE_TAG =
|
|
47
|
-
export const MONITOR_AGENT_IMAGE_TAG =
|
|
48
|
-
export const MONITOR_HUB_IMAGE_TAG =
|
|
49
|
-
export const ERP_IMAGE_TAG =
|
|
50
|
-
|
|
51
|
-
|
|
94
|
+
export const EXE_OS_IMAGE_TAG = pin("exe-os", REGISTRY, "exe-os");
|
|
95
|
+
export const GATEWAY_IMAGE_TAG = pin("gateway", REGISTRY, "exe-gateway");
|
|
96
|
+
export const MONITOR_AGENT_IMAGE_TAG = pin("monitorAgent", REGISTRY, "exe-monitor-agent");
|
|
97
|
+
export const MONITOR_HUB_IMAGE_TAG = pin("monitorHub", REGISTRY, "exe-monitor-hub");
|
|
98
|
+
export const ERP_IMAGE_TAG = pin("erp", REGISTRY, "exe-erp");
|
|
99
|
+
// exe-build is control-plane only (not part of the customer stack), so the
|
|
100
|
+
// manifest does not govern it and there is nothing to derive. It is emitted
|
|
101
|
+
// as an opt-in for askexe-control-plane hosts.
|
|
102
|
+
export const EXE_BUILD_IMAGE_TAG = `${REGISTRY}/exe-build:v0.1.0`;
|
|
103
|
+
export const AUTH_IMAGE_TAG = pin("auth", AUTH_REGISTRY, "exe-auth");
|
|
104
|
+
// Infra pins. Compose no longer carries fallback defaults for these either, so
|
|
105
|
+
// the generated .env must state them — derived from the manifest like the rest.
|
|
106
|
+
// Third-party artifacts are served from the same pull-through proxy the manifest
|
|
107
|
+
// names, so they are NOT re-hosted onto GHCR.
|
|
108
|
+
export const EXE_DB_IMAGE = pin("exe-db", "update.askexe.com/askexe", "pgvector");
|
|
109
|
+
export const OTEL_COLLECTOR_IMAGE = pin("exe-otel-collector", "update.askexe.com/askexe", "otel-collector-contrib");
|
|
52
110
|
const GATEWAY_HTTP_HOST_PORT = "3100";
|
|
53
111
|
const GATEWAY_WS_HOST_PORT = "3101";
|
|
54
112
|
const RANDOM_SECRET_16 = 16;
|
|
@@ -201,6 +259,14 @@ export function generateEnv(options: GenerateEnvOptions): string {
|
|
|
201
259
|
"SMTP_USER=",
|
|
202
260
|
"SMTP_PASS=",
|
|
203
261
|
"",
|
|
262
|
+
"# --- Dashboard (exe-dashboard — customer dashboard at dashboard.<domain>) ---",
|
|
263
|
+
"# OPT-IN: the exe-dashboard compose service sits behind `profiles: [dashboard]`.",
|
|
264
|
+
"# No default is written here on purpose — the pin comes from the signed stack",
|
|
265
|
+
"# manifest (services.dashboard.image), so .env stays derived rather than",
|
|
266
|
+
"# becoming a competing source of truth that outranks it once it goes stale.",
|
|
267
|
+
"#DASHBOARD_IMAGE_TAG=update.askexe.com/askexe/exe-dashboard:vX.Y.Z@sha256:...",
|
|
268
|
+
"#DASHBOARD_PORT=3301",
|
|
269
|
+
"",
|
|
204
270
|
"# --- Auth gateway (exe-auth — shared SSO sign-in UI at auth.<domain>) ---",
|
|
205
271
|
"# Bug 58840873: pin the auth image in .env so compose never falls back to its",
|
|
206
272
|
"# stale hardcoded default tag. Keep in sync with the manifest AUTH_IMAGE_TAG.",
|
|
@@ -262,6 +328,11 @@ export function generateEnv(options: GenerateEnvOptions): string {
|
|
|
262
328
|
"",
|
|
263
329
|
"# --- exe-os ---",
|
|
264
330
|
`EXE_OS_IMAGE_TAG=${EXE_OS_IMAGE_TAG}`,
|
|
331
|
+
"",
|
|
332
|
+
"# Infra image pins — manifest-derived. Compose has no fallback default for",
|
|
333
|
+
"# these: a missing pin ABORTS the deploy instead of substituting an old image.",
|
|
334
|
+
`EXE_DB_IMAGE=${EXE_DB_IMAGE}`,
|
|
335
|
+
`OTEL_COLLECTOR_IMAGE=${OTEL_COLLECTOR_IMAGE}`,
|
|
265
336
|
`EXED_MCP_TOKEN=${randomSecret(RANDOM_SECRET_48)}`,
|
|
266
337
|
`EXED_DEVICE_ID=vps-${normalizedClientName}`,
|
|
267
338
|
`EXE_MCP_HOST_BIND=${DEFAULT_EXE_MCP_HOST_BIND}`,
|
|
@@ -483,6 +554,21 @@ export function generateExampleEnv(): string {
|
|
|
483
554
|
"SMTP_USER=",
|
|
484
555
|
"SMTP_PASS=",
|
|
485
556
|
"",
|
|
557
|
+
"# --- Dashboard (exe-dashboard — customer dashboard at dashboard.<domain>) ---",
|
|
558
|
+
"# OPT-IN: the exe-dashboard compose service sits behind `profiles: [dashboard]`",
|
|
559
|
+
"# and is off unless you run `docker compose --profile dashboard ...`.",
|
|
560
|
+
"# DELIBERATELY UNSET AND COMMENTED OUT. Unlike the older *_IMAGE_TAG lines",
|
|
561
|
+
"# above/below, this one carries no hardcoded literal: a pinned default here is",
|
|
562
|
+
"# a second source of truth that silently outranks the manifest the moment it",
|
|
563
|
+
"# goes stale. Take the value from the signed stack manifest",
|
|
564
|
+
"# (deploy/stack-manifests/v0.9.json -> services.dashboard.image), digest and all.",
|
|
565
|
+
"# Leave it unset and compose refuses the dashboard loudly (\"has neither an image",
|
|
566
|
+
"# nor a build context specified\") instead of booting something arbitrary.",
|
|
567
|
+
"#DASHBOARD_IMAGE_TAG=update.askexe.com/askexe/exe-dashboard:vX.Y.Z@sha256:...",
|
|
568
|
+
"# Host port for the dashboard container (bound to 127.0.0.1; the tunnel and the",
|
|
569
|
+
"# SSO edge reach it over the docker network, not this port).",
|
|
570
|
+
"#DASHBOARD_PORT=3301",
|
|
571
|
+
"",
|
|
486
572
|
"# --- Auth gateway (exe-auth — shared SSO sign-in UI at auth.<domain>) ---",
|
|
487
573
|
"# Bug 58840873: pin the auth image so compose never falls back to its stale",
|
|
488
574
|
"# hardcoded default tag. Keep in sync with the manifest AUTH_IMAGE_TAG. exe-auth",
|
|
@@ -559,6 +645,11 @@ export function generateExampleEnv(): string {
|
|
|
559
645
|
"",
|
|
560
646
|
"# --- exe-os ---",
|
|
561
647
|
`EXE_OS_IMAGE_TAG=${EXE_OS_IMAGE_TAG}`,
|
|
648
|
+
"",
|
|
649
|
+
"# Infra image pins — manifest-derived. Compose has no fallback default for",
|
|
650
|
+
"# these: a missing pin ABORTS the deploy instead of substituting an old image.",
|
|
651
|
+
`EXE_DB_IMAGE=${EXE_DB_IMAGE}`,
|
|
652
|
+
`OTEL_COLLECTOR_IMAGE=${OTEL_COLLECTOR_IMAGE}`,
|
|
562
653
|
"EXED_MCP_TOKEN=CHANGEME_EXED_MCP_TOKEN",
|
|
563
654
|
"EXED_DEVICE_ID=vps-default",
|
|
564
655
|
`EXE_MCP_HOST_BIND=${DEFAULT_EXE_MCP_HOST_BIND}`,
|