@askexenow/exe-os 0.9.380 → 0.9.381

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.
Files changed (350) hide show
  1. package/deploy/compose/.env.example +2 -2
  2. package/deploy/compose/generate-env.ts +57 -2
  3. package/deploy/compose/sso-edge/default.conf.template +88 -24
  4. package/deploy/compose/sso-edge/sso-redirect.conf +48 -8
  5. package/deploy/stack-manifests/v0.9.json +8 -6
  6. package/dist/.dist-verified.json +3 -3
  7. package/dist/{active-agent-2JP4PR6N.js → active-agent-GE6HDADY.js} +3 -3
  8. package/dist/{active-agent-PM6IXYLO.js → active-agent-GZ6O7KKS.js} +3 -3
  9. package/dist/{agent-defs-generator-HH4Q5KY4.js → agent-defs-generator-3VHBN56U.js} +2 -2
  10. package/dist/{agentic-ontology-OB6ZJQOJ.js → agentic-ontology-6X5Z5QPD.js} +1 -1
  11. package/dist/{backfill-metadata-Y5JOMDH5.js → backfill-metadata-4NI4MZEE.js} +5 -5
  12. package/dist/{backup-verify-TS5AHG4F.js → backup-verify-7UQ5PXRZ.js} +1 -1
  13. package/dist/{behavior-injection-QU5ZDYCP.js → behavior-injection-LZSLBWIF.js} +8 -8
  14. package/dist/{behavior-promotion-XZ3EGXZX.js → behavior-promotion-7IZKCZFC.js} +7 -7
  15. package/dist/{behaviors-6KKG4VGE.js → behaviors-S6MOP2C3.js} +6 -6
  16. package/dist/bin/agentic-ontology-backfill.js +6 -6
  17. package/dist/bin/agentic-reflection-backfill.js +7 -7
  18. package/dist/bin/agentic-semantic-label.js +6 -6
  19. package/dist/bin/backfill-conversations.js +5 -5
  20. package/dist/bin/backfill-responses.js +5 -5
  21. package/dist/bin/backfill-vectors.js +5 -5
  22. package/dist/bin/bulk-sync-postgres.js +10 -10
  23. package/dist/bin/cc-doctor.js +6 -6
  24. package/dist/bin/cleanup-stale-review-tasks.js +15 -15
  25. package/dist/bin/cli.js +21 -21
  26. package/dist/bin/deferred-daemon-restart.js +77 -77
  27. package/dist/bin/exe-agent-config.js +2 -2
  28. package/dist/bin/exe-agent.js +4 -4
  29. package/dist/bin/exe-assign.js +6 -6
  30. package/dist/bin/exe-boot.js +36 -39
  31. package/dist/bin/exe-call.js +4 -4
  32. package/dist/bin/exe-cicd.js +29 -5
  33. package/dist/bin/exe-cloud.js +11 -11
  34. package/dist/bin/exe-config-dump.js +2 -2
  35. package/dist/bin/exe-dispatch.js +16 -16
  36. package/dist/bin/exe-doctor.js +4 -4
  37. package/dist/bin/exe-export-behaviors.js +10 -10
  38. package/dist/bin/exe-forget.js +7 -7
  39. package/dist/bin/exe-gateway.js +7 -7
  40. package/dist/bin/exe-healthcheck.js +6 -6
  41. package/dist/bin/exe-heartbeat.js +21 -21
  42. package/dist/bin/exe-kill.js +19 -19
  43. package/dist/bin/exe-launch-agent.js +25 -25
  44. package/dist/bin/exe-mcp.js +4 -4
  45. package/dist/bin/exe-memory-reads.js +5 -5
  46. package/dist/bin/exe-new-employee.js +8 -8
  47. package/dist/bin/exe-os-mcp-proxy.js +4 -4
  48. package/dist/bin/exe-pending-messages.js +16 -16
  49. package/dist/bin/exe-pending-notifications.js +15 -15
  50. package/dist/bin/exe-pending-reviews.js +16 -16
  51. package/dist/bin/exe-rename.js +4 -4
  52. package/dist/bin/exe-review.js +18 -18
  53. package/dist/bin/exe-search.js +6 -6
  54. package/dist/bin/exe-session-cleanup.js +19 -19
  55. package/dist/bin/exe-settings.js +10 -10
  56. package/dist/bin/exe-start-codex.js +17 -17
  57. package/dist/bin/exe-start-opencode.js +14 -14
  58. package/dist/bin/exe-status.js +17 -17
  59. package/dist/bin/exe-support.js +3 -3
  60. package/dist/bin/exe-team.js +4 -4
  61. package/dist/bin/git-sweep.js +16 -16
  62. package/dist/bin/graph-backfill.js +6 -6
  63. package/dist/bin/graph-export.js +6 -6
  64. package/dist/bin/hooks-cli.js +1 -1
  65. package/dist/bin/import-history.js +9 -9
  66. package/dist/bin/install.js +79 -79
  67. package/dist/bin/intercom-check.js +5 -5
  68. package/dist/bin/mcp-sessions.js +2 -2
  69. package/dist/bin/orchestration-metrics.js +4 -4
  70. package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
  71. package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
  72. package/dist/bin/reconcile-backlog.js +2 -2
  73. package/dist/bin/registry-proxy.js +1 -1
  74. package/dist/bin/scan-tasks.js +16 -16
  75. package/dist/bin/setup.js +1 -1
  76. package/dist/bin/shard-migrate.js +5 -5
  77. package/dist/bin/stack-update.js +4 -4
  78. package/dist/bin/vps-health-gate.js +1 -1
  79. package/dist/{boot-generation-VZ74DFIV.js → boot-generation-K5EI6KLP.js} +3 -3
  80. package/dist/{boot-review-sections-NB7OINYD.js → boot-review-sections-RNJY5D7E.js} +14 -14
  81. package/dist/build-manifest.json +795 -790
  82. package/dist/{capability-cards-FRQJDQI6.js → capability-cards-G3ZT3KJ5.js} +2 -2
  83. package/dist/{capacity-monitor-YZAGDWQ4.js → capacity-monitor-6P26RG7K.js} +16 -16
  84. package/dist/{catchup-brief-IV57FTLV.js → catchup-brief-5TUY3RPB.js} +19 -19
  85. package/dist/{chunk-JVODYXRG.js → chunk-23BI4FIU.js} +1 -1
  86. package/dist/{chunk-LDQHWLSQ.js → chunk-2P5B4PMY.js} +2 -2
  87. package/dist/{chunk-PR4577H6.js → chunk-3PFQKTW3.js} +1 -1
  88. package/dist/{chunk-YUQYW7JR.js → chunk-3UFGISID.js} +1 -1
  89. package/dist/{chunk-LFGOGN5Z.js → chunk-4CWPMTPV.js} +1 -1
  90. package/dist/{chunk-IXND3QVT.js → chunk-5DE75FKS.js} +2 -2
  91. package/dist/{chunk-UPLQFBQY.js → chunk-5WCRSUOT.js} +1 -1
  92. package/dist/{chunk-FIQUYB7M.js → chunk-66J2QLDB.js} +1 -1
  93. package/dist/{chunk-BHX2OLMA.js → chunk-6EDL7IV2.js} +4 -4
  94. package/dist/{chunk-ZDQT56LJ.js → chunk-6V33K5VX.js} +1 -1
  95. package/dist/{chunk-MTITMT27.js → chunk-7KXJ2Y5G.js} +2 -2
  96. package/dist/{chunk-PHEAF5DS.js → chunk-A2HKHDVO.js} +1 -1
  97. package/dist/{chunk-SSM5BO3H.js → chunk-ATKH4YHE.js} +1 -1
  98. package/dist/{chunk-ZMOPX77A.js → chunk-B2324KTU.js} +3 -3
  99. package/dist/{chunk-VW2UK5YS.js → chunk-BL6FTJ4R.js} +4 -4
  100. package/dist/{chunk-43HPY3WK.js → chunk-BVJWGIBA.js} +5 -5
  101. package/dist/{chunk-HPJ5BYH2.js → chunk-CAFAVLFW.js} +1 -1
  102. package/dist/{chunk-6SMLVDEB.js → chunk-CLXDTM6D.js} +5 -5
  103. package/dist/{chunk-CYBYSEN4.js → chunk-CMU73A3R.js} +1 -1
  104. package/dist/{chunk-PB6I2JCZ.js → chunk-CSAK5WHK.js} +2 -2
  105. package/dist/{chunk-LIU53YDQ.js → chunk-CURJYC3V.js} +2 -2
  106. package/dist/{chunk-HNTP4NCB.js → chunk-DF4V7ME3.js} +1 -1
  107. package/dist/{chunk-VSGPSJQV.js → chunk-DLG6YKHQ.js} +2 -2
  108. package/dist/{chunk-SVMUF2G7.js → chunk-DNP6Z7FD.js} +3 -3
  109. package/dist/{chunk-V3PXTPQG.js → chunk-DVMOZPMN.js} +2 -2
  110. package/dist/{chunk-JWUR7WFM.js → chunk-DWA7QET3.js} +2 -2
  111. package/dist/{chunk-OYGHAPJ5.js → chunk-DYGBOWGB.js} +4 -4
  112. package/dist/{chunk-BQZE2CVE.js → chunk-EQWKSGBY.js} +3 -3
  113. package/dist/{chunk-3AZALDSA.js → chunk-EXIMHXHN.js} +5 -5
  114. package/dist/{chunk-PXOZ6YUG.js → chunk-FX7VMFWS.js} +1 -1
  115. package/dist/{chunk-FAFV2W5J.js → chunk-G3RANZRO.js} +2 -2
  116. package/dist/{chunk-RE5GF2NF.js → chunk-GODDBYPL.js} +2 -2
  117. package/dist/{chunk-PWQIWRW3.js → chunk-GQAEAIBH.js} +4 -4
  118. package/dist/{chunk-M4UIKNMV.js → chunk-GTSWUQFT.js} +1 -1
  119. package/dist/{chunk-RFZP26YI.js → chunk-HELW3SV2.js} +3 -3
  120. package/dist/{chunk-VV6J34WF.js → chunk-HESUCM6A.js} +1 -1
  121. package/dist/{chunk-WR7AKUCP.js → chunk-HWPKB52A.js} +4 -4
  122. package/dist/{chunk-OSWJHZYN.js → chunk-HYXHA4EJ.js} +3 -3
  123. package/dist/{chunk-DUIMTNQO.js → chunk-I44IJ3TV.js} +1 -1
  124. package/dist/{chunk-GWB4IZKA.js → chunk-IXPDII4H.js} +11 -11
  125. package/dist/{chunk-G2MD57CO.js → chunk-JEJ6C64A.js} +2 -2
  126. package/dist/{chunk-2NEOTYIU.js → chunk-JMNPPQEM.js} +1 -1
  127. package/dist/{chunk-ACFMTIVI.js → chunk-JRHLVN6K.js} +1 -1
  128. package/dist/{chunk-JJLXC2VA.js → chunk-JZGMDMN7.js} +22 -22
  129. package/dist/{chunk-2TYOM7BL.js → chunk-KL3GZVFJ.js} +9 -9
  130. package/dist/{chunk-ASFF22XP.js → chunk-KQLTJWK3.js} +3 -3
  131. package/dist/{chunk-YNCUKR54.js → chunk-M64Y62AR.js} +4 -4
  132. package/dist/{chunk-UYOIKBBL.js → chunk-MAOKR5AL.js} +4 -4
  133. package/dist/{chunk-6G7B7ZWR.js → chunk-ME3SE5HB.js} +6 -6
  134. package/dist/{chunk-URHBKNDM.js → chunk-MGLY2HRK.js} +2 -2
  135. package/dist/{chunk-SVW2QPTC.js → chunk-NBYX3Y4Y.js} +1 -1
  136. package/dist/{chunk-D46UBZIY.js → chunk-NNSBI4H4.js} +3 -3
  137. package/dist/{chunk-JFPU4HIL.js → chunk-O6NASQJQ.js} +1 -1
  138. package/dist/{chunk-YR2LI7FX.js → chunk-OKHCISVQ.js} +2 -2
  139. package/dist/{chunk-EFCSQEGP.js → chunk-OKLZXKO6.js} +10 -10
  140. package/dist/{chunk-AFN4FEBV.js → chunk-OX4ELHFB.js} +4 -4
  141. package/dist/{chunk-5UMI64ZZ.js → chunk-OZLVWDZ3.js} +1 -1
  142. package/dist/{chunk-REZTVJKL.js → chunk-PAETAECN.js} +1 -1
  143. package/dist/{chunk-PJ2IDCBE.js → chunk-PHXRUJXH.js} +2 -2
  144. package/dist/{chunk-4PBBZHWC.js → chunk-PL6FWDSB.js} +2 -2
  145. package/dist/{chunk-EBBVIOSY.js → chunk-PNFUHLNT.js} +1 -1
  146. package/dist/{chunk-NR3ZKNPA.js → chunk-PSWGRTUP.js} +1 -1
  147. package/dist/{chunk-Q37J67CY.js → chunk-PUQI4R46.js} +1 -1
  148. package/dist/{chunk-BZTVMDRV.js → chunk-QRYZRLIF.js} +141 -141
  149. package/dist/{chunk-7UBUNGHK.js → chunk-QV4YQQAH.js} +4 -4
  150. package/dist/{chunk-3NGHSAZS.js → chunk-RLIHHSIY.js} +1 -1
  151. package/dist/{chunk-KGYZXEYT.js → chunk-RUWXKXUQ.js} +3 -3
  152. package/dist/{chunk-TSMVBIUX.js → chunk-S25C5FPP.js} +2 -2
  153. package/dist/{chunk-O6M75PDY.js → chunk-S7W5WHKI.js} +10 -10
  154. package/dist/{chunk-PSLF4D5N.js → chunk-SFFYGYET.js} +1 -1
  155. package/dist/{chunk-YIIQQMT2.js → chunk-SJNKMUXK.js} +6 -6
  156. package/dist/{chunk-M4KKQS4X.js → chunk-TG6UC6OC.js} +1 -1
  157. package/dist/{chunk-PMS7CQJD.js → chunk-TKTEFYPH.js} +1 -1
  158. package/dist/{chunk-CTUJ2ZV2.js → chunk-TX2WJE27.js} +1 -1
  159. package/dist/{chunk-SR5OOOVN.js → chunk-U272MACB.js} +5 -5
  160. package/dist/{chunk-XYW4EGL4.js → chunk-UB7CHH4B.js} +3 -3
  161. package/dist/{chunk-GY5JI7IO.js → chunk-UVM3HYIC.js} +19 -1
  162. package/dist/{chunk-AQ54NIM5.js → chunk-VJ76SXBN.js} +1 -1
  163. package/dist/{chunk-RMVW47EM.js → chunk-VLOVI6EW.js} +1 -1
  164. package/dist/{chunk-NZPNGCRU.js → chunk-VMEZNP7H.js} +2 -2
  165. package/dist/{chunk-VCVEX4DS.js → chunk-VOBQG46I.js} +3 -3
  166. package/dist/{chunk-ATZOT6TG.js → chunk-VYSHZB7N.js} +2 -2
  167. package/dist/{chunk-4Z5MYJAN.js → chunk-W4EZ5RSQ.js} +2 -2
  168. package/dist/{chunk-Y7GWHMAB.js → chunk-W7ZGTTHN.js} +2 -2
  169. package/dist/{chunk-UPLHE5JH.js → chunk-WATC3K3F.js} +1 -1
  170. package/dist/{chunk-E3B2OTRL.js → chunk-WH25C4IE.js} +1 -1
  171. package/dist/{chunk-UDGDNM4H.js → chunk-WLB5M4VC.js} +12 -12
  172. package/dist/{chunk-4NUNWMKV.js → chunk-XBLUWKRG.js} +1 -1
  173. package/dist/{chunk-6COYVPMU.js → chunk-XN5AN3JP.js} +2 -2
  174. package/dist/{chunk-AJIXH5JF.js → chunk-XU57KFD6.js} +1 -1
  175. package/dist/{chunk-XTVQNOYF.js → chunk-YG5JKDTX.js} +2 -2
  176. package/dist/{chunk-QQGLX22R.js → chunk-YZCVZT67.js} +5 -5
  177. package/dist/{chunk-VRDYNQSS.js → chunk-ZONICSKY.js} +1 -1
  178. package/dist/{cleanup-graph-garbage-UNEH6HX7.js → cleanup-graph-garbage-KY6WU5G4.js} +7 -7
  179. package/dist/{cloud-sync-command-D6F3UN2D.js → cloud-sync-command-XCQDIMQF.js} +2 -2
  180. package/dist/{cloud-sync-db-init-5ZBBM5XA.js → cloud-sync-db-init-244Q5GSC.js} +1 -1
  181. package/dist/{cloud-sync-shutdown-COAAU45S.js → cloud-sync-shutdown-2GQEUM25.js} +2 -2
  182. package/dist/{co-activation-KQFMPRY6.js → co-activation-T4E5BQME.js} +2 -2
  183. package/dist/{co-occurrence-RCWL5T7R.js → co-occurrence-H3T4EJDD.js} +5 -5
  184. package/dist/{conversation-entity-extractor-MGSYACMQ.js → conversation-entity-extractor-FMZDYA5F.js} +3 -3
  185. package/dist/{crdt-sync-CLPQRL2R.js → crdt-sync-ZFRTVKPP.js} +1 -1
  186. package/dist/{crm-webhook-TRUGTIMD.js → crm-webhook-FBHC6ZSX.js} +2 -2
  187. package/dist/{cto-delegation-gate-JPPD36HI.js → cto-delegation-gate-NLE4XAAW.js} +14 -14
  188. package/dist/{daemon-orchestration-GX3YTKTA.js → daemon-orchestration-Y2NUGJAG.js} +19 -19
  189. package/dist/{dispatch-ack-AZL3WKCK.js → dispatch-ack-X4DXUSKP.js} +1 -1
  190. package/dist/{doc-graph-extractor-N6GRFQIX.js → doc-graph-extractor-XI6GYDAF.js} +5 -5
  191. package/dist/{documents-5KCCM4DV.js → documents-M73UVEWK.js} +6 -6
  192. package/dist/{dreaming-VQ4IN6XM.js → dreaming-T73YLCHX.js} +18 -18
  193. package/dist/{employee-boot-brief-R7GWE4AO.js → employee-boot-brief-TA4ECIMC.js} +21 -21
  194. package/dist/{entity-boost-GV2OMWIO.js → entity-boost-A6NVXNBE.js} +1 -1
  195. package/dist/{exe-drift-NRSRACTY.js → exe-drift-GLCRFOSM.js} +3 -3
  196. package/dist/{exe-export-XAHNLU2V.js → exe-export-MTAACTQO.js} +7 -7
  197. package/dist/{exe-import-ZYCXOV77.js → exe-import-ZK7RVQAX.js} +7 -7
  198. package/dist/{exe-key-CXUR6HBY.js → exe-key-HFAEVMPQ.js} +77 -77
  199. package/dist/{exe-org-FINGK7Y5.js → exe-org-3PBCLPUK.js} +8 -8
  200. package/dist/{exe-snapshot-FJ5SC2NW.js → exe-snapshot-N6DHTLHQ.js} +20 -20
  201. package/dist/{fast-db-init-2ISRU3CD.js → fast-db-init-XXCFUBVI.js} +1 -1
  202. package/dist/{founder-context-RKL46M2V.js → founder-context-ZGGEQ3Q4.js} +2 -2
  203. package/dist/gateway/index.js +8 -8
  204. package/dist/{git-staleness-RSR3X7DR.js → git-staleness-W3EI5FYL.js} +2 -2
  205. package/dist/{global-procedures-T454IFNL.js → global-procedures-DKZV2JUY.js} +3 -3
  206. package/dist/{graph-auto-extract-UHVZ3G6K.js → graph-auto-extract-RSV72JPO.js} +5 -5
  207. package/dist/{graph-query-IPSKKTDK.js → graph-query-W4XVTJQ2.js} +1 -1
  208. package/dist/{graph-rag-2CYWFR3X.js → graph-rag-HKHUQLVO.js} +3 -3
  209. package/dist/{hook-integrity-IDNGLL6Z.js → hook-integrity-7FKR3HRX.js} +1 -1
  210. package/dist/{hook-prefetch-YMDMZDDD.js → hook-prefetch-UWTAY5IR.js} +15 -15
  211. package/dist/hooks/bug-report-worker.js +19 -19
  212. package/dist/hooks/codex-stop-task-finalizer.js +21 -21
  213. package/dist/hooks/commit-complete.js +18 -18
  214. package/dist/hooks/error-recall.js +8 -8
  215. package/dist/hooks/exe-heartbeat-hook.js +4 -4
  216. package/dist/hooks/ingest-worker.js +6 -6
  217. package/dist/hooks/ingest.js +12 -12
  218. package/dist/hooks/instructions-loaded.js +6 -6
  219. package/dist/hooks/manifest.json +20 -20
  220. package/dist/hooks/notification.js +5 -5
  221. package/dist/hooks/post-compact.js +4 -4
  222. package/dist/hooks/post-tool-combined.js +12 -12
  223. package/dist/hooks/pre-compact.js +18 -18
  224. package/dist/hooks/pre-tool-use.js +2 -2
  225. package/dist/hooks/prompt-submit.js +33 -33
  226. package/dist/hooks/session-end.js +22 -22
  227. package/dist/hooks/session-start.js +17 -17
  228. package/dist/hooks/stop.js +21 -21
  229. package/dist/hooks/subagent-stop.js +20 -20
  230. package/dist/hooks/summary-worker.js +21 -21
  231. package/dist/index.js +24 -24
  232. package/dist/{installer-PAU44RVP.js → installer-JVDKOZSC.js} +6 -6
  233. package/dist/{installer-C5J2FMPK.js → installer-OMXHKOUV.js} +6 -6
  234. package/dist/{installer-LCTWLVIG.js → installer-RWV4GBVV.js} +6 -6
  235. package/dist/{intercom-queue-35S66A6T.js → intercom-queue-73AFFNQU.js} +14 -14
  236. package/dist/lib/cloud-sync.js +10 -10
  237. package/dist/lib/consolidation.js +7 -7
  238. package/dist/lib/database.js +2 -2
  239. package/dist/lib/db-backup.js +1 -1
  240. package/dist/lib/db-write-worker.js +3 -3
  241. package/dist/lib/db.js +2 -2
  242. package/dist/lib/device-registry.js +1 -1
  243. package/dist/lib/employee-templates.js +4 -4
  244. package/dist/lib/employees.js +2 -2
  245. package/dist/lib/exe-daemon.js +85 -79
  246. package/dist/lib/hybrid-search.js +6 -6
  247. package/dist/lib/identity.js +2 -2
  248. package/dist/lib/license.js +8 -2
  249. package/dist/lib/messaging.js +15 -15
  250. package/dist/lib/post-tool-memory.js +4 -4
  251. package/dist/lib/registry-proxy.js +1 -1
  252. package/dist/lib/reminders.js +3 -3
  253. package/dist/lib/schedules.js +6 -6
  254. package/dist/lib/session-registry.js +4 -4
  255. package/dist/lib/skill-learning.js +7 -7
  256. package/dist/lib/store.js +5 -5
  257. package/dist/lib/task-router.js +3 -3
  258. package/dist/lib/tasks.js +16 -16
  259. package/dist/lib/tmux-routing.js +14 -14
  260. package/dist/lib/token-spend.js +3 -3
  261. package/dist/{license-gate-JJ6CMOJN.js → license-gate-D6JW5OTJ.js} +3 -3
  262. package/dist/license-recheck-AGRXJ5WR.js +48 -0
  263. package/dist/{license-sync-W5HINRAJ.js → license-sync-K7LZ74FG.js} +2 -2
  264. package/dist/mcp/register-tools.js +76 -76
  265. package/dist/mcp/server.js +76 -76
  266. package/dist/mcp/tools/complete-reminder.js +4 -4
  267. package/dist/mcp/tools/create-reminder.js +4 -4
  268. package/dist/mcp/tools/create-task.js +18 -18
  269. package/dist/mcp/tools/deactivate-behavior.js +8 -8
  270. package/dist/mcp/tools/list-reminders.js +4 -4
  271. package/dist/mcp/tools/list-tasks.js +18 -18
  272. package/dist/mcp/tools/send-message.js +17 -17
  273. package/dist/mcp/tools/update-task.js +17 -17
  274. package/dist/{mcp-http-config-XWQVJGIX.js → mcp-http-config-UNDKWKQU.js} +4 -4
  275. package/dist/{mcp-session-identity-U7ZYXBGT.js → mcp-session-identity-CVAS3E3G.js} +14 -14
  276. package/dist/{memory-cards-S6EFJ3RY.js → memory-cards-UMXD44FU.js} +5 -5
  277. package/dist/{memory-graph-extractor-76TUTLQJ.js → memory-graph-extractor-AFPSMFEZ.js} +6 -6
  278. package/dist/{memory-poisoning-defense-AKEJD7C4.js → memory-poisoning-defense-QGR7HUYM.js} +2 -2
  279. package/dist/{memory-pressure-watchdog-ILKHIP3K.js → memory-pressure-watchdog-ZXWKCBWJ.js} +15 -15
  280. package/dist/{memory-reflection-2CYBCV4O.js → memory-reflection-2VWEWVHH.js} +5 -5
  281. package/dist/{notification-ledger-5KC6FT6A.js → notification-ledger-Z2K5VWCZ.js} +15 -15
  282. package/dist/{notifications-JQ4OLPXN.js → notifications-7OHREN67.js} +14 -14
  283. package/dist/{orchestration-events-EH6C7Z3Z.js → orchestration-events-ODSQAZU4.js} +3 -3
  284. package/dist/{orchestrator-N7BUDNOF.js → orchestrator-CAUOELC6.js} +16 -16
  285. package/dist/{org-brief-session-OMT77MBE.js → org-brief-session-EDZUREPX.js} +5 -5
  286. package/dist/{org-consent-policy-JWFAHOLM.js → org-consent-policy-FPYT63CA.js} +1 -1
  287. package/dist/{org-partner-runtime-AP5UH3EM.js → org-partner-runtime-4P2APMAS.js} +5 -5
  288. package/dist/{org-row-visibility-LASDP5M2.js → org-row-visibility-FMZ7GCW6.js} +1 -1
  289. package/dist/{pipeline-router-667THJNY.js → pipeline-router-WEVGOK2Q.js} +3 -3
  290. package/dist/{plan-limits-XTQAMSWP.js → plan-limits-HQL4YPCO.js} +5 -5
  291. package/dist/{pre-tool-use-impl-C6JRUCJV.js → pre-tool-use-impl-2LZ3IWVG.js} +28 -28
  292. package/dist/{project-name-FSEAUAYH.js → project-name-HSNEM2B6.js} +3 -3
  293. package/dist/{projection-worker-TAF7G2NQ.js → projection-worker-YNWVG66K.js} +2 -2
  294. package/dist/{prospective-memory-3YMVHDSN.js → prospective-memory-JIAU7G7X.js} +2 -2
  295. package/dist/{push-notifications-R77DDYWR.js → push-notifications-4BVJBPFG.js} +15 -15
  296. package/dist/{reproject-worktree-memories-D6GZ5RSH.js → reproject-worktree-memories-VVXJYJPX.js} +14 -14
  297. package/dist/{reranker-BMWUVEHM.js → reranker-ROOUTM6H.js} +1 -1
  298. package/dist/{retrieval-health-BSBLI6PN.js → retrieval-health-RJLW7V34.js} +1 -1
  299. package/dist/{review-polling-YGUEC4P6.js → review-polling-OFT7YVVR.js} +15 -15
  300. package/dist/runtime/index.js +18 -18
  301. package/dist/{session-events-KLQ2XNPY.js → session-events-5DMOCC55.js} +15 -15
  302. package/dist/{session-kill-telemetry-K2JG5EQ6.js → session-kill-telemetry-GQIMT6Q6.js} +15 -15
  303. package/dist/{session-scope-NW75IDIM.js → session-scope-2ZCD23FN.js} +14 -14
  304. package/dist/{setup-wizard-HLWNR27G.js → setup-wizard-K6TQ4DUY.js} +1 -1
  305. package/dist/{skill-refinement-S3FIE2IZ.js → skill-refinement-GJ7GPZI7.js} +3 -3
  306. package/dist/{stack-generate-manifest-MBNDSYKZ.js → stack-generate-manifest-CYL3WO73.js} +4 -4
  307. package/dist/{stack-promote-I5RLMJ4W.js → stack-promote-IFBEA572.js} +4 -4
  308. package/dist/{stack-release-WOYATRP5.js → stack-release-WOWE5OEX.js} +4 -4
  309. package/dist/{stack-update-M33KTNFO.js → stack-update-WCBBURSE.js} +3 -3
  310. package/dist/{steward-gate-HYZSPJO5.js → steward-gate-OBUY7NHD.js} +3 -3
  311. package/dist/{subagent-brief-injection-V6WF2V67.js → subagent-brief-injection-7EZOA6IB.js} +23 -23
  312. package/dist/{support-inbox-AAZQBCPF.js → support-inbox-FOP23OI5.js} +6 -6
  313. package/dist/{task-enforcement-N3NGPY6K.js → task-enforcement-44SYOIF2.js} +15 -15
  314. package/dist/{task-request-inbox-JD5VZWTB.js → task-request-inbox-GRTPLCVU.js} +1 -1
  315. package/dist/{task-scope-74HJOPZZ.js → task-scope-VD7QNIVO.js} +14 -14
  316. package/dist/{tasks-crud-XWAZ2PNV.js → tasks-crud-XJIRYQZ7.js} +14 -14
  317. package/dist/{tasks-notify-DL3FWK3Q.js → tasks-notify-EBKXIYFO.js} +15 -15
  318. package/dist/{tasks-review-2PXZQAP7.js → tasks-review-3RVFDTHF.js} +14 -14
  319. package/dist/{telemetry-upload-QGFNAKR6.js → telemetry-upload-IEWVUEZD.js} +7 -7
  320. package/dist/{token-budget-Y3U4ZDFI.js → token-budget-6R5E23BK.js} +3 -3
  321. package/dist/{tool-telemetry-YUUZHDKG.js → tool-telemetry-4Z5UN7OR.js} +1 -1
  322. package/dist/tui/App.js +22 -22
  323. package/dist/{tui-data-GCYORCUT.js → tui-data-VJXHRQUO.js} +18 -18
  324. package/dist/{update-support-OTYOPBLG.js → update-support-NWGGDGBT.js} +9 -9
  325. package/dist/{work-claims-QT7A67NN.js → work-claims-OFNMCIKF.js} +3 -3
  326. package/dist/{work-state-heartbeat-Z4RP3XVD.js → work-state-heartbeat-PZFJI7LF.js} +1 -1
  327. package/dist/{workflow-engine-XTR7J2DN.js → workflow-engine-WE6GMJGU.js} +2 -2
  328. package/dist/{worktree-LVJPANY2.js → worktree-WV722AND.js} +4 -4
  329. package/dist/{worktree-sweep-6SGKNS2S.js → worktree-sweep-ZYQWLIHA.js} +5 -5
  330. package/package.json +1 -1
  331. package/release-notes.json +14 -17
  332. package/stack.release.json +2 -2
  333. /package/dist/{chunk-CE3K4XM5.js → chunk-25DUFD2C.js} +0 -0
  334. /package/dist/{chunk-CHEMMA25.js → chunk-2XIMJNWB.js} +0 -0
  335. /package/dist/{chunk-W5X5P3DI.js → chunk-3LITZ2RB.js} +0 -0
  336. /package/dist/{chunk-2PL5IC7K.js → chunk-4G5MWV7O.js} +0 -0
  337. /package/dist/{chunk-CH5F5DQQ.js → chunk-7PXV7NUN.js} +0 -0
  338. /package/dist/{chunk-FTQGMSKA.js → chunk-GKK7SSUW.js} +0 -0
  339. /package/dist/{chunk-52ZZOIJ2.js → chunk-HB5JD7UK.js} +0 -0
  340. /package/dist/{chunk-NY3DAQVI.js → chunk-JTOS2R26.js} +0 -0
  341. /package/dist/{chunk-FH2GKODZ.js → chunk-NQYXSLEM.js} +0 -0
  342. /package/dist/{chunk-W4DRJIGC.js → chunk-PAVF2CXV.js} +0 -0
  343. /package/dist/{chunk-PJ4SNSDY.js → chunk-SFUNP5Q6.js} +0 -0
  344. /package/dist/{chunk-XJ27ET4J.js → chunk-TGMCTZVW.js} +0 -0
  345. /package/dist/{chunk-OYDB7EPN.js → chunk-TYAM2ROO.js} +0 -0
  346. /package/dist/{core-memory-BVERJ2G5.js → core-memory-3EFPOWVG.js} +0 -0
  347. /package/dist/{memory-isolation-UDDRASDJ.js → memory-isolation-BWOZSIF3.js} +0 -0
  348. /package/dist/{oauth-server-MLDEJSOC.js → oauth-server-ISCDJMWO.js} +0 -0
  349. /package/dist/{project-boot-C3XUMAMB.js → project-boot-2JBCNWZH.js} +0 -0
  350. /package/dist/{wiki-acl-EHXSLYNU.js → wiki-acl-OLXP4N4T.js} +0 -0
@@ -98,7 +98,7 @@ SMTP_PASS=
98
98
  # Bug 58840873: pin the auth image so compose never falls back to its stale
99
99
  # hardcoded default tag. Keep in sync with the manifest AUTH_IMAGE_TAG. exe-auth
100
100
  # ships only from the private update.askexe.com registry (no GHCR mirror).
101
- AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.6.1@sha256:89670a15bc59255299be695525863e66f949694eec1dd8886038dc3659a4a941
101
+ AUTH_IMAGE_TAG=update.askexe.com/askexe/exe-auth:v0.6.5@sha256:dc8c1476ef1247079a6e115450bd35681712fa06367461589998ecf943f88089
102
102
  # Bug 379e5c13: server_name / CORS derived from the CONFIGURED apex domain,
103
103
  # not by naive last-2-label slicing (which breaks company.co.uk → co.uk).
104
104
  AUTH_SERVER_NAME=auth.CHANGEME_DOMAIN
@@ -171,7 +171,7 @@ EXE_CRM_ADMIN_EMAIL=CHANGEME_ADMIN_EMAIL
171
171
  CRM_HOST_PORT=3000
172
172
 
173
173
  # --- Wiki ---
174
- WIKI_IMAGE_TAG=ghcr.io/askexe/exe-wiki:v0.9.28@sha256:61856a4c6b97ce62c62ecdc3a377139287be5860eb807d9fbb737115758d7856
174
+ WIKI_IMAGE_TAG=ghcr.io/askexe/exe-wiki:v0.9.33@sha256:1f9e04a557c6034e0eac85ecdf76d465eab88394614184387ecf06cd2281e7d8
175
175
  # Bug 2a8d3003 — DO NOT change this without migrating the data first.
176
176
  # The wiki's users / workspaces / workspace_documents live in `public`. Point it at a
177
177
  # different schema and Prisma will NOT error: it finds no tables, assumes a fresh
@@ -873,8 +873,63 @@ function normalizeClientName(clientName: string): string {
873
873
  .replace(/^-|-$/g, "") || "client";
874
874
  }
875
875
 
876
- function joinEnvLines(lines: string[]): string {
877
- return `${lines.join("\n")}\n`;
876
+ // Bug 5dc66955: a multi-word value (e.g. an SSH public key —
877
+ // "ssh-ed25519 AAAA... comment") written to .env WITHOUT quoting breaks every
878
+ // shell consumer that does `set -a; . /opt/exe-stack/.env`. The shell parses
879
+ // the first whitespace-delimited token as VAR=first-word, then tries to RUN
880
+ // the second token as a command:
881
+ // /opt/exe-stack/.env: line N: AAAAC3NzaC1lZDI1NTE5...: command not found
882
+ // Under `set -e` that aborts the whole source mid-file, leaving every var
883
+ // after the bad line unset while the script believes the environment loaded.
884
+ // Docker Compose's own env_file parser tolerates bare multi-word values (it
885
+ // reads to end-of-line, not to the first space), which is exactly why this
886
+ // class of bug goes unnoticed — only shell consumers break, and nothing here
887
+ // exercises that path.
888
+ //
889
+ // INVESTIGATED: this generator does NOT currently emit that SSH-key line —
890
+ // grepped every value it writes (deploy/compose/generate-env.ts,
891
+ // .env.example, .env.customer.example) and none holds an SSH key or any
892
+ // other value containing a space; ssh_public_key lives only in the Ansible
893
+ // role (deploy/ansible/group_vars/all.yml), which is a wholly separate write
894
+ // path that never touches this file. So /opt/exe-stack/.env line 38 was
895
+ // hand-edited on the host — that repair is NOT made here, on purpose (an
896
+ // operator-maintained host file is not something to guess at from the repo).
897
+ //
898
+ // Quoting is applied ONLY to values that actually need it (contain
899
+ // whitespace), not blanket-applied to every line. Several deploy scripts
900
+ // read specific .env values with `grep '^VAR=' .env | cut -d= -f2-`
901
+ // (deploy/upgrade.sh, deploy/compose/{setup,backup}.sh,
902
+ // deploy/host/exe-db-jkt/*) — those return the literal text after `=`,
903
+ // quote characters included, so blanket-quoting every existing token/URL/key
904
+ // value would silently inject stray `'` characters into every one of those
905
+ // currently-unquoted, single-word values. Every value this generator emits
906
+ // today is single-word (verified: no `=` line here contains a space), so
907
+ // conditional quoting changes NOTHING for any value produced today — it only
908
+ // activates for the next multi-word value someone adds, which is exactly the
909
+ // pattern this bug is about (and which would already be broken for
910
+ // `set -a; .` sourcing, quoted or not, if left bare).
911
+ function quoteEnvValue(value: string): string {
912
+ // Single-quote: no escape-sequence interpretation to worry about (unlike
913
+ // double quotes), just the standard shell trick for an embedded quote —
914
+ // close the quote, emit an escaped one, reopen it.
915
+ return `'${value.replace(/'/g, `'\\''`)}'`;
916
+ }
917
+
918
+ const ENV_ASSIGNMENT = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/;
919
+ const NEEDS_QUOTING = /[ \t]/;
920
+
921
+ function quoteEnvLine(line: string): string {
922
+ const match = ENV_ASSIGNMENT.exec(line);
923
+ if (!match) return line; // comments, blank lines, section headers — untouched
924
+ const [, key, value] = match;
925
+ if (!NEEDS_QUOTING.test(value)) return line; // no whitespace — nothing to break, leave bare
926
+ const alreadyQuoted = /^'.*'$|^".*"$/.test(value);
927
+ if (alreadyQuoted) return line;
928
+ return `${key}=${quoteEnvValue(value)}`;
929
+ }
930
+
931
+ export function joinEnvLines(lines: string[]): string {
932
+ return `${lines.map(quoteEnvLine).join("\n")}\n`;
878
933
  }
879
934
 
880
935
  function printUsage(): void {
@@ -16,18 +16,38 @@
16
16
  # in the entrypoint so envsubst leaves them untouched.
17
17
  # ─────────────────────────────────────────────────────────────────────────────
18
18
 
19
- upstream sso_crm { server exe-crm:3000; }
20
- upstream sso_wiki { server exe-wiki:3001; }
21
- upstream sso_auth { server exe-auth:80; }
19
+ # Backend hostnames (bug 94a6a19a — see the resolver note below for why these
20
+ # are no longer `upstream {}` blocks).
21
+ #
22
22
  # ERP must be reached through its own nginx (gunicorn can't serve /assets/ — bug 6776edf0)
23
- upstream sso_erp { server exe-erp-nginx:80; }
23
+ #
24
24
  # Dashboard — must be on the same docker network as exe-sso-edge.
25
25
  # If the dashboard uses a separate compose (dashboard-page/docker-compose.yml),
26
26
  # ensure it joins exe-os_backend or exe-os_frontend (not the legacy exe-net).
27
- upstream sso_dashboard { server exe-dashboard:80; }
27
+ #
28
28
  # Shared GoTrue — the sso-redirect snippet's /_sso_gate validates ?access_token=
29
- # against GET /user here instead of trusting its presence (P0 bug 462d3273).
30
- upstream sso_gotrue { server gotrue:9999; }
29
+ # / the Bearer header against GET /user here instead of trusting presence
30
+ # alone (P0 bug 462d3273, bug cc40e9ea).
31
+ #
32
+ # STALE-IP FIX (bug 94a6a19a): these used to be static `upstream sso_X {
33
+ # server host:port; }` blocks. An nginx `upstream` block resolves its
34
+ # `server` hostnames ONCE, at config load (container start or `nginx -s
35
+ # reload`), and then proxies to that cached IP forever — Docker's embedded
36
+ # DNS (127.0.0.11) is never consulted again. When a backend container is
37
+ # recreated (redeploy, `docker compose up -d <service>`, OOM restart, ...) it
38
+ # gets a new IP; the edge keeps sending traffic to the dead old one and every
39
+ # request 502s until someone reloads/restarts THIS container too, which is
40
+ # not otherwise required for a backend-only change.
41
+ #
42
+ # Fix: no `upstream` block, plus an explicit `resolver` pointed at Docker's
43
+ # embedded DNS with a short TTL, plus a `set $x_upstream host:port;` in each
44
+ # server block. Putting the hostname in a variable is what makes nginx defer
45
+ # resolution to REQUEST time instead of config-load time — a static
46
+ # `proxy_pass http://exe-crm:3000;` with no variable is just as stale as the
47
+ # upstream block was. `valid=10s` bounds how long a dead IP can keep being
48
+ # used after a recreate to one DNS TTL, without hammering the embedded
49
+ # resolver on every request.
50
+ resolver 127.0.0.11 valid=10s ipv6=off;
31
51
 
32
52
  # Extract the SSO callback token from the request line (P0 bug 462d3273).
33
53
  # The gate's auth_request subrequest does not inherit the query string, but it
@@ -37,6 +57,22 @@ map $request_uri $sso_uri_access_token {
37
57
  "~[?&]access_token=(?<tok>[^&]+)" $tok;
38
58
  }
39
59
 
60
+ # Extract a Developer API bearer token from `Authorization: Bearer <token>`
61
+ # (bug cc40e9ea). auth_request DOES inherit request headers (unlike the query
62
+ # string above), so the subrequest reads this directly off $http_authorization.
63
+ # Anchored to require the `Bearer` scheme (case-insensitive) and at least one
64
+ # non-whitespace token character; a missing header, an empty/whitespace-only
65
+ # token, or any other scheme (Basic, Digest, a bare garbage string) all miss
66
+ # every arm and resolve to the map's `default ""` below — presence of the
67
+ # header alone can never satisfy this map. The extracted value is still only a
68
+ # CANDIDATE credential: sso-redirect.conf's /_sso_gate validates it against
69
+ # GoTrue /user in step 3 exactly like every other bearer source, so a
70
+ # well-formed-but-invalid token is rejected there, not trusted here.
71
+ map $http_authorization $sso_header_bearer {
72
+ default "";
73
+ "~*^Bearer\s+(?<tok>\S.*)$" $tok;
74
+ }
75
+
40
76
  # Extract the shared apex SSO cookie from the Cookie header.
41
77
  #
42
78
  # THE COOKIE IS `exe_access_token` (bug 21ae2388). This map previously matched
@@ -105,21 +141,33 @@ server {
105
141
  set $sso_app_url "https://crm.${DOMAIN}";
106
142
  set $sso_product "CRM";
107
143
  set $sso_session_cookie $cookie_tokenPair; # Twenty/CRM session cookie
144
+ # Re-resolved per request via the file-level `resolver` (bug 94a6a19a) —
145
+ # see the note above the old upstream blocks.
146
+ set $crm_upstream exe-crm:3000;
147
+ set $gotrue_upstream gotrue:9999; # used by sso-redirect.conf's /_sso_gate
108
148
  include /etc/nginx/snippets/sso-redirect.conf;
109
149
 
110
150
  # Bug d3ba1136: public monitors hit /health as well as /healthz. Keep both
111
151
  # exact paths outside the SSO gate and proxy them to CRM's real health
112
152
  # endpoint so they never fall through to the app shell HTML.
113
- location = /health { auth_request off; proxy_pass http://sso_crm/healthz; }
114
- location = /healthz { auth_request off; proxy_pass http://sso_crm/healthz; }
153
+ location = /health { auth_request off; proxy_pass http://$crm_upstream/healthz; }
154
+ location = /healthz { auth_request off; proxy_pass http://$crm_upstream/healthz; }
115
155
 
116
156
  # Logout endpoint must be exempt from SSO gate (bug 96f8b2b2). Without this,
117
157
  # /auth/logout triggers 401 -> redirect to auth with logout URL as redirect param
118
158
  # -> infinite loop. Let the app handle logout (clear its own cookies), then it
119
159
  # redirects to auth.askexe.com/logout for the central SSO cookie clear.
120
- location = /auth/logout { auth_request off; proxy_pass http://sso_crm/auth/logout; }
121
-
122
- location / { proxy_pass http://sso_crm; }
160
+ location = /auth/logout { auth_request off; proxy_pass http://$crm_upstream/auth/logout; }
161
+
162
+ # No URI after $crm_upstream (bug 94a6a19a): nginx's location-prefix
163
+ # substitution (the thing a *static* `proxy_pass http://host/path;` relies
164
+ # on) is only computed for a literal, config-time-known target. The moment
165
+ # the host is a variable, that substitution is undefined, so the directive
166
+ # must be written exactly as it was before (bare host, no trailing path) —
167
+ # nginx then falls back to its other documented behavior for "proxy_pass
168
+ # without URI": forward $request_uri unchanged. That is the exact routing
169
+ # this location already had; only the DNS timing changed.
170
+ location / { proxy_pass http://$crm_upstream; }
123
171
  }
124
172
 
125
173
  # ── Wiki ─────────────────────────────────────────────────────────────────────
@@ -149,18 +197,21 @@ server {
149
197
  # If exe-wiki ever mints a real server-side session cookie, set that name
150
198
  # here — never the sentinel.
151
199
  set $sso_session_cookie "";
200
+ set $wiki_upstream exe-wiki:3001; # re-resolved per request (bug 94a6a19a)
201
+ set $gotrue_upstream gotrue:9999; # used by sso-redirect.conf's /_sso_gate
152
202
  include /etc/nginx/snippets/sso-redirect.conf;
153
203
 
154
204
  # Bug d3ba1136: wiki's actual health probe is /api/ping. Expose the standard
155
205
  # monitor aliases as exact, ungated health routes so /health cannot return
156
206
  # a false-healthy SPA HTML page.
157
- location = /health { auth_request off; proxy_pass http://sso_wiki/api/ping; }
158
- location = /healthz { auth_request off; proxy_pass http://sso_wiki/api/ping; }
207
+ location = /health { auth_request off; proxy_pass http://$wiki_upstream/api/ping; }
208
+ location = /healthz { auth_request off; proxy_pass http://$wiki_upstream/api/ping; }
159
209
 
160
210
  # Logout endpoint must be exempt from SSO gate (bug 96f8b2b2).
161
- location = /auth/logout { auth_request off; proxy_pass http://sso_wiki/auth/logout; }
211
+ location = /auth/logout { auth_request off; proxy_pass http://$wiki_upstream/auth/logout; }
162
212
 
163
- location / { proxy_pass http://sso_wiki; }
213
+ # No URI after $wiki_upstream — see the CRM vhost's comment above (bug 94a6a19a).
214
+ location / { proxy_pass http://$wiki_upstream; }
164
215
  }
165
216
 
166
217
  # ── Auth ─────────────────────────────────────────────────────────────────────
@@ -168,12 +219,17 @@ server {
168
219
  listen 80;
169
220
  server_name auth.${DOMAIN};
170
221
 
222
+ # Re-resolved per request via the file-level `resolver` (bug 94a6a19a).
223
+ set $gotrue_upstream gotrue:9999;
224
+ set $auth_upstream exe-auth:80;
225
+
171
226
  # Route auth.<domain> through this edge too, so exact health aliases can
172
227
  # probe GoTrue instead of the auth SPA's nginx fallback.
173
- location = /health { proxy_pass http://sso_gotrue/health; }
174
- location = /healthz { proxy_pass http://sso_gotrue/health; }
228
+ location = /health { proxy_pass http://$gotrue_upstream/health; }
229
+ location = /healthz { proxy_pass http://$gotrue_upstream/health; }
175
230
 
176
- location / { proxy_pass http://sso_auth; }
231
+ # No URI after $auth_upstream — see the CRM vhost's comment (bug 94a6a19a).
232
+ location / { proxy_pass http://$auth_upstream; }
177
233
  }
178
234
 
179
235
  # ── ERP ──────────────────────────────────────────────────────────────────────
@@ -185,6 +241,9 @@ server {
185
241
  set $sso_app_url "https://erp.${DOMAIN}";
186
242
  set $sso_product "ERP";
187
243
  set $sso_session_cookie $cookie_sid; # Frappe/ERPNext session cookie
244
+ # Re-resolved per request via the file-level `resolver` (bug 94a6a19a).
245
+ set $erp_upstream exe-erp-nginx:80;
246
+ set $gotrue_upstream gotrue:9999; # used by sso-redirect.conf's /_sso_gate
188
247
  include /etc/nginx/snippets/sso-redirect.conf;
189
248
 
190
249
  # ERP is the one upstream that runs a realtime socket.io service with
@@ -195,8 +254,10 @@ server {
195
254
  # headers, so every desk socket.io connection is rejected and the desk
196
255
  # shows "Error connecting to socket.io: Invalid origin" (found in the
197
256
  # 2026-09-02 four-domain demo verification).
257
+ #
258
+ # No URI after $erp_upstream — see the CRM vhost's comment (bug 94a6a19a).
198
259
  location / {
199
- proxy_pass http://sso_erp;
260
+ proxy_pass http://$erp_upstream;
200
261
  proxy_set_header Host $host;
201
262
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
202
263
  # Literal https, matching the template-level convention at the top of
@@ -226,15 +287,18 @@ server {
226
287
  # app-native session cookie to name instead, so leave this empty and let
227
288
  # steps 2-3 validate the apex `exe_sess` cookie against GoTrue.
228
289
  set $sso_session_cookie "";
290
+ set $dashboard_upstream exe-dashboard:80; # re-resolved per request (bug 94a6a19a)
291
+ set $gotrue_upstream gotrue:9999; # used by sso-redirect.conf's /_sso_gate
229
292
  include /etc/nginx/snippets/sso-redirect.conf;
230
293
 
231
- location = /health { auth_request off; proxy_pass http://sso_dashboard/health; }
232
- location = /healthz { auth_request off; proxy_pass http://sso_dashboard/health; }
294
+ location = /health { auth_request off; proxy_pass http://$dashboard_upstream/health; }
295
+ location = /healthz { auth_request off; proxy_pass http://$dashboard_upstream/health; }
233
296
 
234
297
  # Logout endpoint must be exempt from SSO gate (bug 96f8b2b2).
235
- location = /auth/logout { auth_request off; proxy_pass http://sso_dashboard/auth/logout; }
298
+ location = /auth/logout { auth_request off; proxy_pass http://$dashboard_upstream/auth/logout; }
236
299
 
237
- location / { proxy_pass http://sso_dashboard; }
300
+ # No URI after $dashboard_upstream — see the CRM vhost's comment (bug 94a6a19a).
301
+ location / { proxy_pass http://$dashboard_upstream; }
238
302
  }
239
303
 
240
304
  # Default — unknown host or edge-generated error → branded shared error pages
@@ -38,13 +38,18 @@
38
38
  # These are templated values — replace before installing, or render with envsubst
39
39
  # (DOMAIN, APP_NAME, APP_SUBDOMAIN, APP_SESSION_COOKIE):
40
40
  #
41
- # # THREE http-context declarations MUST exist once per nginx config (the
42
- # # compose edge ships them in sso-edge/default.conf.template; host-nginx
43
- # # installs add them next to their `include`s — see sso-redirect.README.md):
41
+ # FOUR http-context declarations MUST exist once per nginx config (the
42
+ # compose edge ships them in sso-edge/default.conf.template; host-nginx
43
+ # installs add them next to their `include`s — see sso-redirect.README.md):
44
44
  # #
45
- # # 1. The shared GoTrue upstream the gate validates tokens against
46
- # # (compose: `server gotrue:9999`; host nginx: the published port):
47
- # upstream sso_gotrue { server 127.0.0.1:9999; }
45
+ # # 1. A resolver + a per-server $gotrue_upstream variable the gate
46
+ # # validates tokens against (bug 94a6a19a: a static `upstream sso_gotrue
47
+ # # { server ...; }` block resolves its hostname ONCE at config load and
48
+ # # never re-resolves it, so it goes stale — and 502s — the moment the
49
+ # # GoTrue container is recreated with a new IP):
50
+ # resolver 127.0.0.11 valid=10s ipv6=off; # Docker embedded DNS (host nginx: your resolver)
51
+ # # ... then inside EACH server block that includes this snippet:
52
+ # # set $gotrue_upstream gotrue:9999; # compose: container name; host nginx: 127.0.0.1:9999
48
53
  # # 2. The callback-token extractor. The auth_request subrequest does not
49
54
  # # inherit the query string, but it DOES inherit $request_uri, so the
50
55
  # # token is mapped from it:
@@ -52,7 +57,16 @@
52
57
  # default "";
53
58
  # "~[?&]access_token=(?<tok>[^&]+)" $tok;
54
59
  # }
55
- # # 3. The shared apex SSO cookie — the cross-app-logout signal. The name is
60
+ # # 3. The Developer API bearer-header extractor (bug cc40e9ea) — a
61
+ # # well-formed `Authorization: Bearer <token>` request must be read at
62
+ # # the edge or a programmatic client always falls through to a 401 ->
63
+ # # HTML login redirect. Extraction only; step 3 below still validates
64
+ # # whatever this pulls out against GoTrue before trusting it:
65
+ # map $http_authorization $sso_header_bearer {
66
+ # default "";
67
+ # "~*^Bearer\s+(?<tok>\S.*)$" $tok;
68
+ # }
69
+ # # 4. The shared apex SSO cookie — the cross-app-logout signal. The name is
56
70
  # # `exe_access_token` (bug 21ae2388: this used to read a nonexistent
57
71
  # # `exe-auth`, which 401'd every authenticated request). Presence only —
58
72
  # # the value is the literal "1", never a bearer token:
@@ -227,7 +241,30 @@ location = /_sso_gate {
227
241
  # Precedence keeps the callback param first purely for backward
228
242
  # compatibility with any older auth build still mid-rollout; it is still
229
243
  # validated, never trusted on presence (bug 462d3273 stays fixed).
244
+ #
245
+ # Bug cc40e9ea: an `Authorization: Bearer <token>` request — the
246
+ # Developer API pattern — was never inspected at all (nothing here read
247
+ # $http_authorization), so a programmatic client always fell through to
248
+ # "no credential" and got a 401 -> HTML login redirect for what should
249
+ # have been an API response. $sso_header_bearer (map on $http_authorization,
250
+ # defined alongside the other gate maps) extracts the token ONLY when the
251
+ # header is a well-formed `Bearer <token>`; a missing header, a header
252
+ # with no scheme, an empty/whitespace-only token, or a non-Bearer scheme
253
+ # (e.g. Basic) all fail the map and leave this "" — they fall through to
254
+ # the cookie arm exactly like today, never satisfying the gate on
255
+ # presence alone. Whatever token IS extracted is still just a candidate:
256
+ # it flows into the same step 3 GoTrue /user validation as every other
257
+ # source below, so a well-formed-but-bogus Bearer value is rejected
258
+ # there, not trusted here. This is chosen over exempting an /api/v1/*
259
+ # path prefix (rejected: a path exemption widens the unauthenticated
260
+ # surface to anything ever served under that prefix, present or future;
261
+ # a header check narrows to a single well-formed credential shape and
262
+ # still funnels through the existing validation, so it cannot become a
263
+ # bypass on its own).
230
264
  set $sso_bearer $sso_uri_access_token;
265
+ if ($sso_bearer = "") {
266
+ set $sso_bearer $sso_header_bearer;
267
+ }
231
268
  if ($sso_bearer = "") {
232
269
  set $sso_bearer $cookie_exe_sess;
233
270
  }
@@ -246,7 +283,10 @@ location = /_sso_gate {
246
283
  # server-side exchange of the apex `exe_sess` cookie for its own session
247
284
  # (exe-wiki / exe-erp / exe-crm, bug d0652644 and related) — the edge is
248
285
  # the login funnel, not the authorization boundary, exactly as before.
249
- proxy_pass http://sso_gotrue/user;
286
+ # $gotrue_upstream is set by every including server block (bug 94a6a19a —
287
+ # re-resolved per request via the file-level `resolver`, not a static
288
+ # upstream{} cached at config load).
289
+ proxy_pass http://$gotrue_upstream/user;
250
290
  proxy_pass_request_body off;
251
291
  proxy_set_header Content-Length "";
252
292
  proxy_set_header Authorization "Bearer $sso_bearer";
@@ -2721,11 +2721,13 @@
2721
2721
  "category": "app"
2722
2722
  },
2723
2723
  "wiki": {
2724
- "image": "update.askexe.com/askexe/exe-wiki:v0.9.28@sha256:61856a4c6b97ce62c62ecdc3a377139287be5860eb807d9fbb737115758d7856",
2724
+ "image": "update.askexe.com/askexe/exe-wiki:v0.9.33@sha256:1f9e04a557c6034e0eac85ecdf76d465eab88394614184387ecf06cd2281e7d8",
2725
2725
  "env": "WIKI_IMAGE_TAG",
2726
2726
  "composeService": "exe-wiki",
2727
2727
  "healthUrl": "http://127.0.0.1:3001/api/ping",
2728
- "category": "app"
2728
+ "category": "app",
2729
+ "description": "exe-wiki v0.9.33 — typography unified onto the shared @askexenow/exe-theme tokens. plus-jakarta-sans removed repo-wide, and a latent bug fixed: font-headline was defined in Tailwind but no rule ever applied it, so h1-h6 had silently inherited the body font and wiki headings had never once rendered in Epilogue. Also dark first paint before stylesheets load, so switching between CRM, wiki and ERP no longer flashes white.",
2730
+ "gitSha": "3f35bd9c52543987e2ebaec9e5876cc6c6fd8f3a"
2729
2731
  },
2730
2732
  "gateway": {
2731
2733
  "image": "update.askexe.com/askexe/exe-gateway:v2026.08.07-c15f093-stamped@sha256:1bc11a2a0ad1f3929d59d2685696f22a72042b9fca9c75e15c02dc7d3c640105",
@@ -2752,13 +2754,13 @@
2752
2754
  "gitSha": "10660eb4abdeffbcba2aad13549aa58e208ac7a3"
2753
2755
  },
2754
2756
  "auth": {
2755
- "image": "update.askexe.com/askexe/exe-auth:v0.6.1@sha256:89670a15bc59255299be695525863e66f949694eec1dd8886038dc3659a4a941",
2757
+ "image": "update.askexe.com/askexe/exe-auth:v0.6.5@sha256:dc8c1476ef1247079a6e115450bd35681712fa06367461589998ecf943f88089",
2756
2758
  "env": "AUTH_IMAGE_TAG",
2757
2759
  "composeService": "exe-auth",
2758
2760
  "healthUrl": "http://127.0.0.1:3300/api/health",
2759
2761
  "category": "auth",
2760
- "description": "exe-auth v0.6.1 — the v0.6.0 hardening (GoTrue admin API no longer public; nginx 404s /api/admin|invite; query strings redacted from access + error logs) PLUS the four fixes that merged after v0.6.0 was tagged and had never been built into any image (bug 9e054a59): /api/recover CORS + method restriction (0f9fbebe); a recovery link can no longer mint a session and link hashes are sent as token_hash (056abf8d, c9b62c91); the Secure cookie flag fails closed and HSTS is set (bb99ceda); the session token is kept out of upstream request lines, shape-checked, and a service_role JWT is refused (bff591fe). Verified inside this exact digest, not from a green badge.",
2761
- "gitSha": "633e7a4d9930aad8b0ce6783a1b3bc2f96b454a8"
2762
+ "description": "exe-auth v0.6.5 — an already-authenticated user switching between ERP, wiki and CRM no longer sees the login page flash. The session is now validated SERVER-SIDE before any login markup is sent, so an authenticated request gets a bare 302 (bug 910ff2a5). A forged exe_access_token sentinel still receives the login page, so this is not an auth bypass. Also strips the leading dot from AUTH_COOKIE_DOMAIN (bug ee4b831d).",
2763
+ "gitSha": "e119d1fa1fd08f2faf951f9998fe33393cf8b258"
2762
2764
  },
2763
2765
  "erp": {
2764
2766
  "image": "update.askexe.com/askexe/exe-erp:v2026.08.07-d185286-stamped@sha256:1c655f3f7819c797afd13c79561354f0276cf337403f32aee3e406a497e8827b",
@@ -2809,6 +2811,6 @@
2809
2811
  "signature": {
2810
2812
  "keyId": "exe-stack-1",
2811
2813
  "alg": "ed25519",
2812
- "signature": "zJx3MxMUaco9bPRAPvmMs8qFXScuuAS9xWXSQBgtzKJB3ERe5aNvb+f6O39jWjxAvoPUQUObPjCuhwbu0aD8AQ=="
2814
+ "signature": "UAQm9FB5Ai8KaBSGe6LEkBfXZ3XtBFT/5/8DozCK1v7f8llD33AhrAF11HEttf33z3w/weWhxZEXG3yGIWw/Dg=="
2813
2815
  }
2814
2816
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "verified_at": "2026-09-07T16:50:49.001Z",
4
- "manifest_sha256": "27bcfdc27713439f36c09113cba1c029e503a2cdbfba354f02fcc898bcf54982",
5
- "package_version": "0.9.380"
3
+ "verified_at": "2026-09-08T02:19:11.078Z",
4
+ "manifest_sha256": "b55b6c21dd560116c3ce9ca67bbfc648b6a910b0bed064e64b9f36e13576ea74",
5
+ "package_version": "0.9.381"
6
6
  }
@@ -8,15 +8,15 @@ import {
8
8
  resolveAgentAttribution,
9
9
  resolveAgentForPayload,
10
10
  writeActiveAgent
11
- } from "./chunk-PMS7CQJD.js";
11
+ } from "./chunk-TKTEFYPH.js";
12
12
  import "./chunk-K4ESASPL.js";
13
13
  import "./chunk-CVYC6DUW.js";
14
14
  import "./chunk-GJV3WDWM.js";
15
- import "./chunk-UYOIKBBL.js";
15
+ import "./chunk-MAOKR5AL.js";
16
16
  import "./chunk-BBMTVAE3.js";
17
17
  import "./chunk-TKDITWDN.js";
18
18
  import "./chunk-5YEUPUV4.js";
19
- import "./chunk-RE5GF2NF.js";
19
+ import "./chunk-GODDBYPL.js";
20
20
  import "./chunk-YYB5PMTK.js";
21
21
  import "./chunk-L5CGXEZC.js";
22
22
  import "./chunk-CL4J4757.js";
@@ -7,15 +7,15 @@ import {
7
7
  resolveAgentAttribution,
8
8
  resolveAgentForPayload,
9
9
  writeActiveAgent
10
- } from "./chunk-PMS7CQJD.js";
10
+ } from "./chunk-TKTEFYPH.js";
11
11
  import "./chunk-K4ESASPL.js";
12
12
  import "./chunk-CVYC6DUW.js";
13
13
  import "./chunk-GJV3WDWM.js";
14
- import "./chunk-UYOIKBBL.js";
14
+ import "./chunk-MAOKR5AL.js";
15
15
  import "./chunk-BBMTVAE3.js";
16
16
  import "./chunk-TKDITWDN.js";
17
17
  import "./chunk-5YEUPUV4.js";
18
- import "./chunk-RE5GF2NF.js";
18
+ import "./chunk-GODDBYPL.js";
19
19
  import "./chunk-YYB5PMTK.js";
20
20
  import "./chunk-L5CGXEZC.js";
21
21
  import "./chunk-CL4J4757.js";
@@ -5,11 +5,11 @@ import "./chunk-AM7S2TY6.js";
5
5
  import {
6
6
  loadEmployeesSync,
7
7
  validateEmployeeName
8
- } from "./chunk-UYOIKBBL.js";
8
+ } from "./chunk-MAOKR5AL.js";
9
9
  import "./chunk-BBMTVAE3.js";
10
10
  import "./chunk-TKDITWDN.js";
11
11
  import "./chunk-5YEUPUV4.js";
12
- import "./chunk-RE5GF2NF.js";
12
+ import "./chunk-GODDBYPL.js";
13
13
  import "./chunk-YYB5PMTK.js";
14
14
  import "./chunk-L5CGXEZC.js";
15
15
  import "./chunk-CL4J4757.js";
@@ -10,7 +10,7 @@ import {
10
10
  insertOntologyForMemory,
11
11
  ontologyPayload,
12
12
  stableId
13
- } from "./chunk-2PL5IC7K.js";
13
+ } from "./chunk-4G5MWV7O.js";
14
14
  import "./chunk-MLKGABMK.js";
15
15
  export {
16
16
  ONTOLOGY_YIELD_EVERY,
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  disposeStore,
4
4
  initStore
5
- } from "./chunk-EFCSQEGP.js";
6
- import "./chunk-OYDB7EPN.js";
5
+ } from "./chunk-OKLZXKO6.js";
6
+ import "./chunk-TYAM2ROO.js";
7
7
  import "./chunk-CHCA3ZM2.js";
8
8
  import "./chunk-OTVEIJUQ.js";
9
- import "./chunk-PJ4SNSDY.js";
9
+ import "./chunk-SFUNP5Q6.js";
10
10
  import "./chunk-5MOYSU5A.js";
11
11
  import "./chunk-5QCIWWFA.js";
12
12
  import "./chunk-76CJBM36.js";
@@ -15,11 +15,11 @@ import {
15
15
  getClient,
16
16
  getEmployeeNamesByRole,
17
17
  loadEmployeesSync
18
- } from "./chunk-UYOIKBBL.js";
18
+ } from "./chunk-MAOKR5AL.js";
19
19
  import "./chunk-BBMTVAE3.js";
20
20
  import "./chunk-TKDITWDN.js";
21
21
  import "./chunk-5YEUPUV4.js";
22
- import "./chunk-RE5GF2NF.js";
22
+ import "./chunk-GODDBYPL.js";
23
23
  import "./chunk-YYB5PMTK.js";
24
24
  import "./chunk-L5CGXEZC.js";
25
25
  import "./chunk-CL4J4757.js";
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  getLatestBackup,
6
6
  reasonFromBackupName
7
- } from "./chunk-RE5GF2NF.js";
7
+ } from "./chunk-GODDBYPL.js";
8
8
  import "./chunk-YYB5PMTK.js";
9
9
  import "./chunk-ZIG7VPJV.js";
10
10
  import "./chunk-HSGBZSCA.js";
@@ -19,19 +19,19 @@ import {
19
19
  selectInjectedBehaviors,
20
20
  selectRelevantBehaviors,
21
21
  selectRelevantBehaviorsWithReasons
22
- } from "./chunk-PB6I2JCZ.js";
23
- import "./chunk-NZPNGCRU.js";
22
+ } from "./chunk-CSAK5WHK.js";
23
+ import "./chunk-VMEZNP7H.js";
24
24
  import "./chunk-QV5CQLQH.js";
25
25
  import "./chunk-QGGH7LOU.js";
26
- import "./chunk-EFCSQEGP.js";
27
- import "./chunk-OYDB7EPN.js";
26
+ import "./chunk-OKLZXKO6.js";
27
+ import "./chunk-TYAM2ROO.js";
28
28
  import "./chunk-CHCA3ZM2.js";
29
29
  import "./chunk-OTVEIJUQ.js";
30
- import "./chunk-PJ4SNSDY.js";
30
+ import "./chunk-SFUNP5Q6.js";
31
31
  import "./chunk-5MOYSU5A.js";
32
32
  import "./chunk-5QCIWWFA.js";
33
33
  import "./chunk-76CJBM36.js";
34
- import "./chunk-UPLHE5JH.js";
34
+ import "./chunk-WATC3K3F.js";
35
35
  import "./chunk-ZKJ5S23O.js";
36
36
  import "./chunk-GPUOUUHA.js";
37
37
  import "./chunk-BTSWFMEH.js";
@@ -41,11 +41,11 @@ import "./chunk-NLEW62VC.js";
41
41
  import "./chunk-GPJIBLP4.js";
42
42
  import "./chunk-V3WLC5TJ.js";
43
43
  import "./chunk-MP2AFCGL.js";
44
- import "./chunk-UYOIKBBL.js";
44
+ import "./chunk-MAOKR5AL.js";
45
45
  import "./chunk-BBMTVAE3.js";
46
46
  import "./chunk-TKDITWDN.js";
47
47
  import "./chunk-5YEUPUV4.js";
48
- import "./chunk-RE5GF2NF.js";
48
+ import "./chunk-GODDBYPL.js";
49
49
  import "./chunk-YYB5PMTK.js";
50
50
  import "./chunk-L5CGXEZC.js";
51
51
  import "./chunk-CL4J4757.js";
@@ -9,15 +9,15 @@ import {
9
9
  listPromotionCandidates,
10
10
  promoteBehaviorToIdentity,
11
11
  promotedRulesDropped
12
- } from "./chunk-LIU53YDQ.js";
13
- import "./chunk-NZPNGCRU.js";
12
+ } from "./chunk-CURJYC3V.js";
13
+ import "./chunk-VMEZNP7H.js";
14
14
  import "./chunk-QV5CQLQH.js";
15
15
  import "./chunk-QGGH7LOU.js";
16
- import "./chunk-EFCSQEGP.js";
17
- import "./chunk-OYDB7EPN.js";
16
+ import "./chunk-OKLZXKO6.js";
17
+ import "./chunk-TYAM2ROO.js";
18
18
  import "./chunk-CHCA3ZM2.js";
19
19
  import "./chunk-OTVEIJUQ.js";
20
- import "./chunk-PJ4SNSDY.js";
20
+ import "./chunk-SFUNP5Q6.js";
21
21
  import "./chunk-5MOYSU5A.js";
22
22
  import "./chunk-5QCIWWFA.js";
23
23
  import "./chunk-76CJBM36.js";
@@ -30,11 +30,11 @@ import "./chunk-NLEW62VC.js";
30
30
  import "./chunk-GPJIBLP4.js";
31
31
  import "./chunk-V3WLC5TJ.js";
32
32
  import "./chunk-MP2AFCGL.js";
33
- import "./chunk-UYOIKBBL.js";
33
+ import "./chunk-MAOKR5AL.js";
34
34
  import "./chunk-BBMTVAE3.js";
35
35
  import "./chunk-TKDITWDN.js";
36
36
  import "./chunk-5YEUPUV4.js";
37
- import "./chunk-RE5GF2NF.js";
37
+ import "./chunk-GODDBYPL.js";
38
38
  import "./chunk-YYB5PMTK.js";
39
39
  import "./chunk-L5CGXEZC.js";
40
40
  import "./chunk-CL4J4757.js";