@askexenow/exe-os 0.9.361 → 0.9.364

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 (443) hide show
  1. package/deploy/compose/.env.customer.example +10 -1
  2. package/deploy/compose/.env.example +10 -1
  3. package/deploy/compose/cloudflared/config.yml.example +15 -8
  4. package/deploy/compose/docker-compose.yml +109 -15
  5. package/deploy/compose/generate-env.ts +23 -1
  6. package/deploy/compose/status.sh +30 -0
  7. package/deploy/compose/uptime-check.sh +39 -2
  8. package/deploy/compose/wiki-schema-guard.sh +302 -0
  9. package/deploy/stack-manifests/v0.9.json +232 -2
  10. package/dist/.dist-verified.json +3 -3
  11. package/dist/{active-agent-UZAQUW7E.js → active-agent-MVEEEKUD.js} +9 -4
  12. package/dist/{active-agent-5RXOXM47.js → active-agent-WL3VEPS3.js} +9 -4
  13. package/dist/agent-defs-generator-MLQ4ULA2.js +240 -0
  14. package/dist/{agentic-ontology-EHUWSJCG.js → agentic-ontology-X3JMWNAM.js} +1 -1
  15. package/dist/artifact-backup-6VQ2332X.js +209 -0
  16. package/dist/artifact-provenance-C7HQ267L.js +13 -0
  17. package/dist/{backfill-gate-LRX77SUD.js → backfill-gate-BWFX6B55.js} +2 -2
  18. package/dist/{backfill-metadata-CTSVPOC6.js → backfill-metadata-FFDTWSGA.js} +6 -6
  19. package/dist/{background-jobs-Z6KHCWES.js → background-jobs-EB4BPQMT.js} +2 -2
  20. package/dist/{backup-verify-YJMSP24E.js → backup-verify-BZQ5RI5I.js} +27 -14
  21. package/dist/{behavior-injection-DTFGF6DT.js → behavior-injection-U7FGR6VM.js} +11 -11
  22. package/dist/{behaviors-XW7ZZKHF.js → behaviors-NLOMQW34.js} +10 -10
  23. package/dist/bin/age-ontology-load.js +2 -2
  24. package/dist/bin/agentic-ontology-backfill.js +8 -8
  25. package/dist/bin/agentic-reflection-backfill.js +9 -9
  26. package/dist/bin/agentic-semantic-label.js +8 -8
  27. package/dist/bin/backfill-conversations.js +8 -8
  28. package/dist/bin/backfill-responses.js +8 -8
  29. package/dist/bin/backfill-vectors.js +12 -12
  30. package/dist/bin/bulk-sync-postgres.js +21 -18
  31. package/dist/bin/cc-doctor.js +8 -7
  32. package/dist/bin/cleanup-stale-review-tasks.js +23 -22
  33. package/dist/bin/cli.js +53 -102
  34. package/dist/bin/customer-readiness.js +3 -1
  35. package/dist/bin/deferred-daemon-restart.js +111 -100
  36. package/dist/bin/exe-agent-config.js +4 -4
  37. package/dist/bin/exe-agent.js +13 -13
  38. package/dist/bin/exe-assign.js +10 -10
  39. package/dist/bin/exe-boot.js +52 -44
  40. package/dist/bin/exe-call.js +6 -6
  41. package/dist/bin/exe-cloud.js +24 -21
  42. package/dist/bin/exe-config-dump.js +4 -4
  43. package/dist/bin/exe-dispatch.js +27 -22
  44. package/dist/bin/exe-doctor.js +10 -7
  45. package/dist/bin/exe-export-behaviors.js +12 -12
  46. package/dist/bin/exe-forget.js +8 -8
  47. package/dist/bin/exe-gateway.js +8 -8
  48. package/dist/bin/exe-grant.js +5 -5
  49. package/dist/bin/exe-healthcheck.js +10 -7
  50. package/dist/bin/exe-heartbeat.js +30 -24
  51. package/dist/bin/exe-kill.js +27 -26
  52. package/dist/bin/exe-launch-agent.js +38 -35
  53. package/dist/bin/exe-mcp.js +4 -4
  54. package/dist/bin/exe-memory-reads.js +6 -6
  55. package/dist/bin/exe-new-employee.js +11 -10
  56. package/dist/bin/exe-os-mcp-proxy.js +4 -4
  57. package/dist/bin/exe-pending-messages.js +24 -23
  58. package/dist/bin/exe-pending-notifications.js +23 -22
  59. package/dist/bin/exe-pending-reviews.js +23 -22
  60. package/dist/bin/exe-rename.js +6 -6
  61. package/dist/bin/exe-review.js +26 -25
  62. package/dist/bin/exe-search.js +7 -7
  63. package/dist/bin/exe-session-cleanup.js +27 -26
  64. package/dist/bin/exe-settings.js +22 -19
  65. package/dist/bin/exe-start-codex.js +33 -19
  66. package/dist/bin/exe-start-opencode.js +13 -13
  67. package/dist/bin/exe-status.js +25 -23
  68. package/dist/bin/exe-support.js +5 -4
  69. package/dist/bin/exe-team.js +11 -5
  70. package/dist/bin/exe-verify-running-images.js +145 -0
  71. package/dist/bin/exe-watchdog.js +1 -1
  72. package/dist/bin/git-sweep.js +24 -23
  73. package/dist/bin/graph-backfill.js +9 -8
  74. package/dist/bin/graph-export.js +7 -7
  75. package/dist/bin/import-history.js +12 -10
  76. package/dist/bin/install.js +192 -121
  77. package/dist/bin/intercom-check.js +4 -4
  78. package/dist/bin/mcp-sessions.js +2 -2
  79. package/dist/bin/orchestration-metrics.js +5 -5
  80. package/dist/bin/postgres-agentic-reflection-backfill.js +4 -4
  81. package/dist/bin/postgres-agentic-semantic-backfill.js +3 -3
  82. package/dist/bin/pre-publish.js +1 -1
  83. package/dist/bin/reconcile-backlog.js +2 -2
  84. package/dist/bin/registry-proxy.js +1 -1
  85. package/dist/bin/scan-tasks.js +23 -22
  86. package/dist/bin/setup.js +4 -3
  87. package/dist/bin/shard-migrate.js +7 -7
  88. package/dist/bin/stack-update.js +7 -5
  89. package/dist/bin/vps-health-gate.js +1 -1
  90. package/dist/{boot-generation-ALCHPQOK.js → boot-generation-LGWKWMCF.js} +4 -4
  91. package/dist/{boot-review-sections-E4QOMWZM.js → boot-review-sections-IXBD7UGL.js} +22 -21
  92. package/dist/{branch-hygiene-Z4IBWAOX.js → branch-hygiene-UYHJ5SC5.js} +17 -10
  93. package/dist/{branding-7MZDHTKN.js → branding-J2MTHQUP.js} +2 -2
  94. package/dist/build-manifest.json +1158 -1018
  95. package/dist/{capability-cards-IE2DEJKT.js → capability-cards-3OGBIJRM.js} +3 -3
  96. package/dist/{capacity-monitor-3HVLTPQA.js → capacity-monitor-6VDEATYE.js} +24 -23
  97. package/dist/{catchup-brief-E2QZPNMH.js → catchup-brief-XYX5SOC6.js} +27 -26
  98. package/dist/{chunk-J5KRIGHE.js → chunk-2HRAVECR.js} +1 -1
  99. package/dist/{chunk-KDMVVHZH.js → chunk-2ROXEOGE.js} +95 -23
  100. package/dist/{chunk-YZLDE3XJ.js → chunk-34XAUB2R.js} +9 -5
  101. package/dist/{chunk-IXRNZ2Y2.js → chunk-3NETEIM6.js} +534 -221
  102. package/dist/{chunk-II5TSD4F.js → chunk-43PHKRHR.js} +2 -2
  103. package/dist/{chunk-PLLBBNMC.js → chunk-4DJCHH5R.js} +1 -1
  104. package/dist/{chunk-2PIEDT3G.js → chunk-4FNUBXYO.js} +1 -1
  105. package/dist/{chunk-R6AJ6VIJ.js → chunk-4KFTA7U7.js} +5 -1
  106. package/dist/{chunk-YZUHSV24.js → chunk-4LWBC7CM.js} +1 -1
  107. package/dist/{chunk-LEZAPRMW.js → chunk-4LYIZD3H.js} +71 -1
  108. package/dist/{chunk-PE4DEYIW.js → chunk-5G46JZTE.js} +3 -3
  109. package/dist/{org-key-admin-4W6LZ5KZ.js → chunk-5M6LXPR4.js} +62 -17
  110. package/dist/{chunk-P3ACGGW6.js → chunk-5WADTD5Y.js} +1 -1
  111. package/dist/{chunk-Q556G3P2.js → chunk-6BDSDDKT.js} +13 -4
  112. package/dist/{chunk-V6T42AQN.js → chunk-6G6JGJD3.js} +2 -2
  113. package/dist/{chunk-ASQPFNLC.js → chunk-6LNT6NCB.js} +2 -2
  114. package/dist/{chunk-NVRUZOEW.js → chunk-6ML32VHG.js} +5 -5
  115. package/dist/{chunk-ZGYRQHQ3.js → chunk-6MQWZZS5.js} +2 -2
  116. package/dist/{chunk-LYEQZ7TW.js → chunk-6NGFGT23.js} +272 -54
  117. package/dist/{chunk-RO326K57.js → chunk-6TF4ZOXP.js} +14 -5
  118. package/dist/{chunk-B3JV3F35.js → chunk-6WBEFNO4.js} +1 -1
  119. package/dist/{chunk-6LQGPGOS.js → chunk-74H5NWLY.js} +2 -2
  120. package/dist/{chunk-I4ILH2R6.js → chunk-7JR2IRBY.js} +5 -5
  121. package/dist/{chunk-CY5RX7QR.js → chunk-7WVR5UQF.js} +144 -99
  122. package/dist/{chunk-NO5KHKKB.js → chunk-7ZBIZFC3.js} +1 -1
  123. package/dist/{chunk-NGDXBN3M.js → chunk-A6PDF4BO.js} +2 -2
  124. package/dist/chunk-A7XLR3K7.js +45 -0
  125. package/dist/{chunk-FK3HX7VO.js → chunk-AA6AD7OM.js} +13 -13
  126. package/dist/{chunk-QNETW6LZ.js → chunk-AIVK4A5Y.js} +4 -4
  127. package/dist/{chunk-A4EPO6F3.js → chunk-ASBMFQAY.js} +9 -9
  128. package/dist/{chunk-V3ORKXAU.js → chunk-AU7AVWTM.js} +4 -4
  129. package/dist/{chunk-PRJBAIHV.js → chunk-AUIXAFYX.js} +221 -55
  130. package/dist/{chunk-EXAUIWUG.js → chunk-AYMOVFBG.js} +1 -1
  131. package/dist/{chunk-VEGTALBX.js → chunk-B5T43JSQ.js} +53 -21
  132. package/dist/{chunk-WYETVNK4.js → chunk-BIMCKCGZ.js} +1 -1
  133. package/dist/{chunk-4L33OFU4.js → chunk-BU36IRW2.js} +5 -2
  134. package/dist/{chunk-NKP4S2G5.js → chunk-CA7JP44I.js} +3 -3
  135. package/dist/{chunk-J7S2SOM2.js → chunk-CAV64C4J.js} +2 -2
  136. package/dist/chunk-CE323JHD.js +234 -0
  137. package/dist/{chunk-J34U3NT2.js → chunk-CLCNYC3F.js} +13 -2
  138. package/dist/chunk-CTXNEZFW.js +78 -0
  139. package/dist/{chunk-XQDF2I4D.js → chunk-DNRLIHUO.js} +1 -1
  140. package/dist/{chunk-NXTQAY7Z.js → chunk-DSQCXCPS.js} +7 -7
  141. package/dist/{chunk-YJJ7FRX5.js → chunk-DVPBCGC2.js} +11 -11
  142. package/dist/{chunk-F4GLFLQK.js → chunk-E5TFF3M7.js} +1 -1
  143. package/dist/{chunk-4P2BFNSB.js → chunk-ECVWCFY4.js} +2 -2
  144. package/dist/{chunk-BRIZ6OZ3.js → chunk-EKOWJXHN.js} +4 -0
  145. package/dist/{chunk-NVWBZXDK.js → chunk-EUEESRS6.js} +4 -4
  146. package/dist/{chunk-R7F6HKTH.js → chunk-EXDW3E2R.js} +3 -1
  147. package/dist/{chunk-QFQWHCOJ.js → chunk-FLK5IS6R.js} +3 -3
  148. package/dist/{chunk-6EM6USV7.js → chunk-FXPWMPU2.js} +2 -2
  149. package/dist/{chunk-CC4I7337.js → chunk-G4XMAGTW.js} +3 -3
  150. package/dist/{chunk-M67ARGXY.js → chunk-G6EUAI67.js} +1 -1
  151. package/dist/{chunk-AUSKITKI.js → chunk-GETICKB4.js} +53 -2
  152. package/dist/{chunk-WDA2KAV7.js → chunk-GSJLB6JI.js} +1 -1
  153. package/dist/{chunk-OLIXPGWN.js → chunk-GSWAKK5Q.js} +1 -1
  154. package/dist/{chunk-RBWLUYTO.js → chunk-GVZI4MK2.js} +1 -1
  155. package/dist/{chunk-J73I53JO.js → chunk-H5G2VUIX.js} +21 -10
  156. package/dist/{chunk-VQWRRXBD.js → chunk-HEFM2DBN.js} +62 -2
  157. package/dist/{chunk-W6J25BU7.js → chunk-HJQILEBL.js} +1 -1
  158. package/dist/{chunk-J5QNK5VL.js → chunk-HJVXKDEK.js} +1 -1
  159. package/dist/{chunk-PK5ATL23.js → chunk-HKQH4R5X.js} +6 -6
  160. package/dist/{working-memory-BACVOAIV.js → chunk-HSFBNCNC.js} +3 -3
  161. package/dist/{chunk-3YBJ36UX.js → chunk-IANRPLHA.js} +2 -2
  162. package/dist/{chunk-ZR4CQBAP.js → chunk-IR2MLURD.js} +1 -1
  163. package/dist/{chunk-IM7PRQ27.js → chunk-J2OTTJWG.js} +5 -10
  164. package/dist/{chunk-4UTSVUMY.js → chunk-J2W3XZHV.js} +4 -4
  165. package/dist/{chunk-5TKIVK3L.js → chunk-J4VETNHT.js} +1 -1
  166. package/dist/{chunk-RFKRCVGW.js → chunk-J7EXACGN.js} +1 -1
  167. package/dist/{chunk-DZLOUB4G.js → chunk-JCVDT3DG.js} +4 -4
  168. package/dist/{chunk-PU7UYQRC.js → chunk-JLG3GAQS.js} +1 -1
  169. package/dist/{chunk-RCOIKTHM.js → chunk-JN7IFPIQ.js} +1 -1
  170. package/dist/{chunk-E3YI6FVJ.js → chunk-JQTM2UFN.js} +1 -1
  171. package/dist/{chunk-A5544WYJ.js → chunk-JVLQJWUG.js} +111 -22
  172. package/dist/{chunk-GIFXL4AC.js → chunk-JWLZQSHW.js} +2 -2
  173. package/dist/{chunk-3Q2YK6UT.js → chunk-K2HYCBAG.js} +1 -1
  174. package/dist/{chunk-SSZIGWIG.js → chunk-K5RPFS6A.js} +1 -1
  175. package/dist/{chunk-ESGLOI6Q.js → chunk-KAF66DIP.js} +263 -35
  176. package/dist/chunk-L25OAFOU.js +93 -0
  177. package/dist/{chunk-FUQ2OSDV.js → chunk-L2VZBPJJ.js} +25 -8
  178. package/dist/chunk-LYXICKAH.js +57 -0
  179. package/dist/{chunk-EIBTRKUF.js → chunk-M2IZ3TQT.js} +1 -1
  180. package/dist/chunk-M4REI3JS.js +328 -0
  181. package/dist/{chunk-6DTALXOA.js → chunk-MM45YT2B.js} +1 -1
  182. package/dist/{chunk-NE5ZMNHN.js → chunk-MR56CIB5.js} +3 -3
  183. package/dist/chunk-NEHOQ3P2.js +19 -0
  184. package/dist/{chunk-INATSOZV.js → chunk-NQKZKOYF.js} +1 -1
  185. package/dist/{gotrue-session-2IT7MDGW.js → chunk-NUTZJZKW.js} +7 -8
  186. package/dist/{chunk-6KVG6RTP.js → chunk-O3OGCHUZ.js} +1 -1
  187. package/dist/{chunk-2PRAXZWM.js → chunk-OFQBR26Y.js} +10 -5
  188. package/dist/{chunk-UWEFIIEG.js → chunk-OJ56HXDB.js} +1 -1
  189. package/dist/{chunk-B6PFGUYJ.js → chunk-OZIDGXKH.js} +46 -5
  190. package/dist/{chunk-OUUWGAH4.js → chunk-P5OPYQZE.js} +4 -4
  191. package/dist/{chunk-PWNPP727.js → chunk-P7JLMFKX.js} +1 -1
  192. package/dist/{chunk-65WUZISK.js → chunk-PGJG5TCQ.js} +3 -3
  193. package/dist/{chunk-BGMLECK5.js → chunk-PX2OHZKN.js} +4 -4
  194. package/dist/{chunk-3TWIRKUD.js → chunk-QY6B23U2.js} +3 -3
  195. package/dist/{chunk-6H44454F.js → chunk-RKUGAHPO.js} +1 -1
  196. package/dist/{chunk-32FEF5BW.js → chunk-RSDCOZVM.js} +2 -2
  197. package/dist/{chunk-6EGNSEEX.js → chunk-SCGQOY5F.js} +1 -1
  198. package/dist/chunk-SO7KTH3Q.js +27 -0
  199. package/dist/{chunk-CIXA5TXF.js → chunk-T26JNDO3.js} +2 -2
  200. package/dist/chunk-TCTED52S.js +120 -0
  201. package/dist/{chunk-63Z76YCI.js → chunk-TF5T2ASS.js} +8 -8
  202. package/dist/{chunk-JCICPQJV.js → chunk-TLBAZU3V.js} +1 -1
  203. package/dist/{chunk-VEJKY5I6.js → chunk-TOLJH6XP.js} +2 -2
  204. package/dist/{chunk-IFJ4SVIP.js → chunk-TPXBX2LD.js} +2 -2
  205. package/dist/{chunk-AQF6XMZ7.js → chunk-U4KDN5B7.js} +1 -1
  206. package/dist/{chunk-7N63G4JS.js → chunk-U6E3CLKI.js} +3 -3
  207. package/dist/{chunk-GWBD5P7E.js → chunk-UCSD67VW.js} +14 -14
  208. package/dist/{chunk-VYFZVIWX.js → chunk-UHPMK6QZ.js} +16 -2
  209. package/dist/{chunk-CKOMH7TL.js → chunk-UIUO3N5Y.js} +2 -2
  210. package/dist/{chunk-ZZEKOI2M.js → chunk-UPCXDJ2S.js} +1 -1
  211. package/dist/chunk-UXX2JSZO.js +170 -0
  212. package/dist/{chunk-NBVSBSMZ.js → chunk-V3K6FLAS.js} +19 -7
  213. package/dist/{chunk-XTGR3LMF.js → chunk-VFYF7EMB.js} +2 -2
  214. package/dist/{chunk-WBG7XYVR.js → chunk-VHJVD3MZ.js} +8 -0
  215. package/dist/{chunk-HNB5IAVK.js → chunk-VVXXMY6I.js} +1 -1
  216. package/dist/{chunk-U32RDCUB.js → chunk-W33NLSKN.js} +52 -6
  217. package/dist/chunk-W352QOGG.js +45 -0
  218. package/dist/{chunk-RJJZH7Z7.js → chunk-W3Q53NBI.js} +71 -2
  219. package/dist/{chunk-HU4ZAYGH.js → chunk-X24VCGZA.js} +3 -3
  220. package/dist/chunk-X2X3IGZU.js +215 -0
  221. package/dist/{chunk-VAOUB2TK.js → chunk-X73CND7J.js} +1 -1
  222. package/dist/{chunk-4BI4YKHE.js → chunk-XE23TMKN.js} +10 -10
  223. package/dist/{chunk-FU3CUTIA.js → chunk-XI2BLVH6.js} +3 -3
  224. package/dist/chunk-XMVSLLED.js +38 -0
  225. package/dist/{chunk-7GPK2ANS.js → chunk-XOFIXD5U.js} +5 -5
  226. package/dist/{chunk-PGXESCSL.js → chunk-Y2DUIE6X.js} +8 -3
  227. package/dist/{chunk-BSPBWLUP.js → chunk-Y4JCCHHJ.js} +10 -4
  228. package/dist/{chunk-6W5MDNLX.js → chunk-YNR3DSAF.js} +2 -2
  229. package/dist/{chunk-5XEKQJE5.js → chunk-YWFFAM2S.js} +1 -1
  230. package/dist/{chunk-OZNCAMS3.js → chunk-Z6VZ62MY.js} +95 -10
  231. package/dist/{chunk-MZYNW5OY.js → chunk-Z75FBAP2.js} +1 -1
  232. package/dist/{chunk-3BAGFZFN.js → chunk-ZACPAM2C.js} +5 -5
  233. package/dist/{chunk-ZPW6FAEQ.js → chunk-ZSQNPN2W.js} +1 -1
  234. package/dist/{chunk-34ABBEHN.js → chunk-ZT5PSVWW.js} +43 -34
  235. package/dist/{chunk-VGWGXAHT.js → chunk-ZVZEYHWY.js} +104 -32
  236. package/dist/{cleanup-graph-garbage-SJHT3RXT.js → cleanup-graph-garbage-MLRFYWDJ.js} +9 -8
  237. package/dist/cloud-sync-command-LU5KLLQY.js +96 -0
  238. package/dist/cloud-sync-db-init-G7LBCE7T.js +46 -0
  239. package/dist/{cloud-sync-shutdown-43RY4ZBS.js → cloud-sync-shutdown-4IZXMEKK.js} +9 -3
  240. package/dist/{cloud-sync-state-DJRZORFI.js → cloud-sync-state-5DFKLWNB.js} +1 -1
  241. package/dist/{co-activation-5GP2E54J.js → co-activation-FCEZYVGI.js} +3 -3
  242. package/dist/{co-occurrence-OXF6MLM6.js → co-occurrence-5WBK7HPH.js} +7 -6
  243. package/dist/{code-context-index-DWR6HS35.js → code-context-index-4EQJW44K.js} +4 -4
  244. package/dist/{conversation-entity-extractor-YSXUBOXC.js → conversation-entity-extractor-JXAKVKF2.js} +9 -4
  245. package/dist/{conversation-wiki-populator-5EGRW2UZ.js → conversation-wiki-populator-6BCICVAB.js} +1 -1
  246. package/dist/{crdt-sync-FKEQAOQL.js → crdt-sync-RTAWVLV4.js} +2 -2
  247. package/dist/{crm-webhook-K4ZOGKOO.js → crm-webhook-EWALI4C5.js} +2 -2
  248. package/dist/{cto-delegation-gate-TQIOXGNV.js → cto-delegation-gate-HU4YUH7C.js} +22 -21
  249. package/dist/daemon-auth-LXP5I6BA.js +46 -0
  250. package/dist/{daemon-orchestration-HSW7IOH4.js → daemon-orchestration-35RSNUNI.js} +43 -28
  251. package/dist/{daemon-ready-VGPSRI3Z.js → daemon-ready-ZC2ANOR3.js} +1 -1
  252. package/dist/{daemon-restart-report-HZU5LWXN.js → daemon-restart-report-EIVD6WDJ.js} +1 -1
  253. package/dist/db-integrity-events-RBX7FN5E.js +16 -0
  254. package/dist/{db-restore-events-TFCZ4CPM.js → db-restore-events-NBARRGAC.js} +1 -1
  255. package/dist/{doc-graph-extractor-W5KHZUL4.js → doc-graph-extractor-PTNIPSDV.js} +12 -7
  256. package/dist/{documents-SLQWZNOW.js → documents-BUFAJHVZ.js} +10 -10
  257. package/dist/{dreaming-E2M2O32J.js → dreaming-ZPUWXFEJ.js} +26 -25
  258. package/dist/employee-boot-brief-QD2SP4FM.js +70 -0
  259. package/dist/{exe-drift-NUYEPGFR.js → exe-drift-KCZFM2RP.js} +4 -4
  260. package/dist/{exe-export-CFX2JAOJ.js → exe-export-W2SXNMYL.js} +12 -12
  261. package/dist/{exe-import-ZD5QMFN2.js → exe-import-YCYNUMER.js} +12 -12
  262. package/dist/{exe-key-O4KHCKZZ.js → exe-key-7IIKQRR2.js} +113 -102
  263. package/dist/{exe-org-TV7KW4D6.js → exe-org-223EX7VP.js} +88 -26
  264. package/dist/{exe-snapshot-P4YW62MR.js → exe-snapshot-QX3RERAL.js} +28 -27
  265. package/dist/{fast-db-init-YZNPKBNX.js → fast-db-init-PAC3C5O5.js} +1 -1
  266. package/dist/{founder-context-TU5G4AKR.js → founder-context-XM47756J.js} +4 -3
  267. package/dist/{founder-monitor-envelope-SMILO4BT.js → founder-monitor-envelope-4WFWI26F.js} +4 -4
  268. package/dist/fts-integrity-4M2MF2LQ.js +96 -0
  269. package/dist/gateway/index.js +18 -18
  270. package/dist/{git-staleness-CKSL73QX.js → git-staleness-XT6GXOYG.js} +3 -3
  271. package/dist/{global-procedures-X36SK7LZ.js → global-procedures-QICIAC33.js} +5 -5
  272. package/dist/gotrue-session-ODZ2ERJX.js +25 -0
  273. package/dist/{graph-auto-extract-OW7YWKRT.js → graph-auto-extract-RYX57CW5.js} +7 -6
  274. package/dist/{graph-rag-6GFTXM5O.js → graph-rag-MOBZTWOD.js} +4 -3
  275. package/dist/{hook-integrity-AIDFKMTA.js → hook-integrity-LGUYWWQX.js} +1 -1
  276. package/dist/{hook-prefetch-THLIXCLE.js → hook-prefetch-VE2NXAFN.js} +23 -22
  277. package/dist/hooks/bug-report-worker.js +27 -26
  278. package/dist/hooks/codex-stop-task-finalizer.js +28 -27
  279. package/dist/hooks/commit-complete.js +26 -25
  280. package/dist/hooks/error-recall.js +10 -9
  281. package/dist/hooks/exe-heartbeat-hook.js +6 -5
  282. package/dist/hooks/ingest-worker.js +8 -8
  283. package/dist/hooks/ingest.js +14 -13
  284. package/dist/hooks/instructions-loaded.js +7 -6
  285. package/dist/hooks/manifest.json +20 -20
  286. package/dist/hooks/notification.js +7 -6
  287. package/dist/hooks/post-compact.js +6 -5
  288. package/dist/hooks/post-tool-combined.js +31 -13
  289. package/dist/hooks/pre-compact.js +27 -25
  290. package/dist/hooks/pre-tool-use.js +58 -32
  291. package/dist/hooks/prompt-submit.js +41 -39
  292. package/dist/hooks/session-end.js +32 -30
  293. package/dist/hooks/session-start.js +28 -70
  294. package/dist/hooks/stop.js +33 -31
  295. package/dist/hooks/subagent-stop.js +46 -31
  296. package/dist/hooks/summary-worker.js +32 -31
  297. package/dist/index.js +37 -36
  298. package/dist/{installer-LORTXEPZ.js → installer-4VXHJEVU.js} +8 -6
  299. package/dist/{installer-CBHPY3RI.js → installer-CH7GIFHI.js} +6 -6
  300. package/dist/{installer-R4EKAE7F.js → installer-IK4HFXD4.js} +6 -6
  301. package/dist/{intercom-queue-QGXWXDYJ.js → intercom-queue-PI5APF65.js} +22 -21
  302. package/dist/{key-backup-status-3RC6XTUX.js → key-backup-status-G7CHESRL.js} +1 -1
  303. package/dist/lib/agent-config.js +2 -2
  304. package/dist/lib/cloud-sync.js +23 -18
  305. package/dist/lib/config.js +1 -1
  306. package/dist/lib/consolidation.js +8 -8
  307. package/dist/lib/crypto.js +3 -1
  308. package/dist/lib/database.js +17 -3
  309. package/dist/lib/db-backup.js +4 -2
  310. package/dist/lib/db-daemon-client.js +4 -4
  311. package/dist/lib/db-write-worker-client.js +3 -1
  312. package/dist/lib/db-write-worker.js +20 -2
  313. package/dist/lib/db.js +17 -3
  314. package/dist/lib/device-registry.js +2 -2
  315. package/dist/lib/embed-worker.js +1 -1
  316. package/dist/lib/embedder.js +4 -4
  317. package/dist/lib/employee-templates.js +6 -6
  318. package/dist/lib/employees.js +3 -3
  319. package/dist/lib/exe-daemon-client.js +3 -3
  320. package/dist/lib/exe-daemon.js +425 -227
  321. package/dist/lib/hybrid-search.js +7 -7
  322. package/dist/lib/identity.js +3 -3
  323. package/dist/lib/license.js +6 -4
  324. package/dist/lib/messaging.js +23 -22
  325. package/dist/lib/post-tool-memory.js +1 -1
  326. package/dist/lib/registry-proxy.js +3 -1
  327. package/dist/lib/reminders.js +4 -4
  328. package/dist/lib/schedules.js +7 -7
  329. package/dist/lib/session-registry.js +5 -5
  330. package/dist/lib/skill-learning.js +12 -11
  331. package/dist/lib/stack-invariants.js +21 -0
  332. package/dist/lib/status-brief.js +3 -3
  333. package/dist/lib/store.js +6 -6
  334. package/dist/lib/task-router.js +4 -4
  335. package/dist/lib/tasks.js +24 -23
  336. package/dist/lib/tmux-routing.js +22 -21
  337. package/dist/lib/token-spend.js +4 -4
  338. package/dist/{license-gate-NO2WGZPU.js → license-gate-Z5YXTWMH.js} +5 -4
  339. package/dist/{license-sync-CVEMSX3H.js → license-sync-LLX3FTHY.js} +4 -3
  340. package/dist/{mailbox-inbox-CP2VRBXZ.js → mailbox-inbox-4MEUOL3J.js} +2 -2
  341. package/dist/{mailbox-outbox-HXI7DYNC.js → mailbox-outbox-J6WIF3UY.js} +1 -1
  342. package/dist/mcp/register-tools.js +110 -99
  343. package/dist/mcp/server.js +116 -105
  344. package/dist/mcp/tools/complete-reminder.js +5 -5
  345. package/dist/mcp/tools/create-reminder.js +5 -5
  346. package/dist/mcp/tools/create-task.js +27 -25
  347. package/dist/mcp/tools/deactivate-behavior.js +13 -12
  348. package/dist/mcp/tools/list-reminders.js +5 -5
  349. package/dist/mcp/tools/list-tasks.js +27 -25
  350. package/dist/mcp/tools/send-message.js +26 -24
  351. package/dist/mcp/tools/update-task.js +25 -24
  352. package/dist/{mcp-http-config-H4B5LHCL.js → mcp-http-config-PTGZH6RV.js} +4 -4
  353. package/dist/{mcp-session-identity-MCIJPH7T.js → mcp-session-identity-JRR4ZW2F.js} +22 -21
  354. package/dist/{memory-cards-PX3ZU7WC.js → memory-cards-ENOF74LR.js} +6 -6
  355. package/dist/{memory-graph-extractor-M5LHDSFC.js → memory-graph-extractor-V4ZUDCUN.js} +8 -7
  356. package/dist/{memory-poisoning-defense-LORMP5QJ.js → memory-poisoning-defense-VNCV5BFL.js} +3 -3
  357. package/dist/{memory-pressure-watchdog-AXJKFOCO.js → memory-pressure-watchdog-5WKDX7KP.js} +23 -22
  358. package/dist/{memory-queue-4VN3DTOE.js → memory-queue-RD5CSMSC.js} +2 -2
  359. package/dist/{memory-queue-client-OI4LDT4W.js → memory-queue-client-2NHZQRSD.js} +5 -5
  360. package/dist/{memory-reflection-XB6CE5MY.js → memory-reflection-H7AGGSO5.js} +3 -3
  361. package/dist/{monitor-grants-W3ISOLMC.js → monitor-grants-5KVETEJB.js} +3 -3
  362. package/dist/{notification-ledger-4JVPBNDO.js → notification-ledger-4DRPS7GP.js} +109 -47
  363. package/dist/{notifications-7EJE7FEP.js → notifications-ZNIPKB3G.js} +22 -21
  364. package/dist/{orchestration-events-GCMG4TBV.js → orchestration-events-FWR64GIC.js} +4 -4
  365. package/dist/{orchestration-phase-ZJ4XVNFO.js → orchestration-phase-ZED4QYF3.js} +2 -2
  366. package/dist/{orchestrator-W4PANW2L.js → orchestrator-AVQRCIMG.js} +24 -23
  367. package/dist/{org-brief-session-65THKUUQ.js → org-brief-session-XK2BTYHE.js} +12 -12
  368. package/dist/{org-consent-policy-QE3TE273.js → org-consent-policy-ULCYJC4W.js} +2 -2
  369. package/dist/{org-join-HTQ57JYH.js → org-join-P6PHLFFK.js} +10 -7
  370. package/dist/org-key-admin-BXGBQ3XY.js +38 -0
  371. package/dist/{org-key-pin-OTOKAELD.js → org-key-pin-CVVHZIMZ.js} +3 -3
  372. package/dist/{org-membership-SML6GCHP.js → org-membership-VC54DLZ7.js} +4 -4
  373. package/dist/{org-partner-config-XQGOB7EJ.js → org-partner-config-VQVT62IZ.js} +6 -6
  374. package/dist/{org-partner-runtime-VEQ2OQQM.js → org-partner-runtime-CCXM2LEA.js} +13 -13
  375. package/dist/{org-row-visibility-V2YHQMU7.js → org-row-visibility-OSDGUOYT.js} +1 -1
  376. package/dist/{pipeline-router-HJSXQN2M.js → pipeline-router-YA6JZ7SA.js} +4 -4
  377. package/dist/{plan-limits-GVLMARLS.js → plan-limits-YC6TLA4S.js} +7 -6
  378. package/dist/{platform-procedures-2VQGBJU7.js → platform-procedures-QNOMEXJF.js} +1 -1
  379. package/dist/postinstall-failure-M6PCKX4P.js +20 -0
  380. package/dist/{project-boot-YMHABZNL.js → project-boot-INRUUEND.js} +1 -1
  381. package/dist/{projection-worker-JUNR4VAH.js → projection-worker-G3AO6ASG.js} +4 -4
  382. package/dist/{prospective-memory-NOGTSZC4.js → prospective-memory-GXCBC5WL.js} +3 -3
  383. package/dist/{push-notifications-FIVZB27Y.js → push-notifications-BZZJTMN6.js} +23 -22
  384. package/dist/{reranker-ZZYVYCQW.js → reranker-O3NLXWT3.js} +2 -2
  385. package/dist/{retrieval-health-B7USNBNW.js → retrieval-health-5OSAJIQF.js} +1 -1
  386. package/dist/{review-polling-G7ZCVGXI.js → review-polling-3D2KID2T.js} +23 -22
  387. package/dist/runtime/index.js +34 -33
  388. package/dist/seat-benefit-VDQJYJOB.js +17 -0
  389. package/dist/{session-events-HIULW2JW.js → session-events-KJKEKAXC.js} +23 -22
  390. package/dist/{session-kill-telemetry-5FLZAMWE.js → session-kill-telemetry-RRAZEXLS.js} +23 -22
  391. package/dist/{session-mcp-config-YKNXG5DW.js → session-mcp-config-JTPM2XBN.js} +10 -1
  392. package/dist/{session-scope-64QIDBJS.js → session-scope-IPEVYKRA.js} +22 -21
  393. package/dist/{setup-wizard-JHR2HYWC.js → setup-wizard-7XF4NFQK.js} +4 -3
  394. package/dist/{shard-manager-YEOHEOHL.js → shard-manager-FW4KRSE4.js} +2 -2
  395. package/dist/{skill-refinement-BYZNTHQJ.js → skill-refinement-5444QK44.js} +4 -4
  396. package/dist/{stack-promote-4WRGX5YI.js → stack-promote-FZAXOG5N.js} +7 -5
  397. package/dist/{stack-release-HRUOH243.js → stack-release-AF4KZWQA.js} +15 -5
  398. package/dist/{stack-update-X5LCAIMH.js → stack-update-RIL3XYZG.js} +10 -4
  399. package/dist/{steward-gate-LWTZRKBJ.js → steward-gate-V3CDSK35.js} +4 -4
  400. package/dist/subagent-brief-injection-WZJRP6VC.js +96 -0
  401. package/dist/subagent-spawn-ledger-P6Q6JX3E.js +20 -0
  402. package/dist/{support-inbox-HA7N3XFN.js → support-inbox-45CEKHAK.js} +5 -4
  403. package/dist/{support-outbox-DSWU3IXH.js → support-outbox-HFJWG52M.js} +1 -1
  404. package/dist/{task-enforcement-4MFBYFXY.js → task-enforcement-HG6LBTYU.js} +23 -22
  405. package/dist/{task-request-inbox-VSXZKKPQ.js → task-request-inbox-ZIQW2TPL.js} +2 -2
  406. package/dist/{task-scope-MWBLCI4L.js → task-scope-ZWRHD2PQ.js} +22 -21
  407. package/dist/{tasks-crud-FXGSJNQG.js → tasks-crud-QN33WNXT.js} +22 -21
  408. package/dist/{tasks-notify-NHACVTKE.js → tasks-notify-DQKP253B.js} +23 -22
  409. package/dist/{tasks-review-L3FTWM6K.js → tasks-review-P7JTBLWK.js} +22 -21
  410. package/dist/{telemetry-upload-OFC56N3C.js → telemetry-upload-55GD4D27.js} +9 -8
  411. package/dist/{token-budget-JHZJH2OU.js → token-budget-PPDT7CLD.js} +4 -4
  412. package/dist/{tool-capability-index-WZWVBI2R.js → tool-capability-index-MOZ5EOIO.js} +1 -1
  413. package/dist/{tool-telemetry-MX4CODRA.js → tool-telemetry-R27EMAEB.js} +1 -1
  414. package/dist/tui/App.js +36 -35
  415. package/dist/{tui-data-OLCJT3X3.js → tui-data-KJNJBAAT.js} +22 -21
  416. package/dist/{update-support-Q5QYK6TG.js → update-support-VDS4ME3L.js} +18 -16
  417. package/dist/{work-state-heartbeat-FOF6RQSC.js → work-state-heartbeat-RUE6ETPX.js} +1 -1
  418. package/dist/{worker-gate-UEBG2QLF.js → worker-gate-LAXZSHSZ.js} +2 -2
  419. package/dist/{workflow-engine-E7PG3R34.js → workflow-engine-RPKV7XM3.js} +2 -2
  420. package/dist/working-memory-DPFRSKH3.js +18 -0
  421. package/dist/{worktree-VOLK2GOS.js → worktree-6LRKLO2U.js} +5 -5
  422. package/dist/{worktree-sweep-AATRCA33.js → worktree-sweep-NAPVXZHQ.js} +8 -6
  423. package/package.json +9 -5
  424. package/postinstall.mjs +7 -7
  425. package/release-notes.json +89 -32
  426. package/dist/chunk-HISFWAAK.js +0 -90
  427. package/dist/daemon-auth-OCHW2U6B.js +0 -20
  428. package/dist/session-summary-5EYI4XW4.js +0 -128
  429. /package/dist/{chunk-3NPMPEAC.js → chunk-3DWNESVC.js} +0 -0
  430. /package/dist/{chunk-YWN3XMPU.js → chunk-7VBIK4HP.js} +0 -0
  431. /package/dist/{chunk-STDYMMOX.js → chunk-ESOETGYC.js} +0 -0
  432. /package/dist/{chunk-6C4UAKMS.js → chunk-HVMZBCP4.js} +0 -0
  433. /package/dist/{chunk-Q2DLJR3C.js → chunk-IY7LTYEP.js} +0 -0
  434. /package/dist/{chunk-LRSBJCDL.js → chunk-QKOLA6FI.js} +0 -0
  435. /package/dist/{chunk-7AY76CBP.js → chunk-VNVDUM5X.js} +0 -0
  436. /package/dist/{core-memory-BA7UCIR6.js → core-memory-RZHRZPKR.js} +0 -0
  437. /package/dist/{entity-boost-VXXED26D.js → entity-boost-ZLQIQ4JU.js} +0 -0
  438. /package/dist/{memory-isolation-3HQ6NNX3.js → memory-isolation-OSZBBUHB.js} +0 -0
  439. /package/dist/{message-queue-client-5XW7ZOK2.js → message-queue-client-UKGJ6QKQ.js} +0 -0
  440. /package/dist/{oauth-server-H6EJUPEP.js → oauth-server-MHOTAUOI.js} +0 -0
  441. /package/dist/{webhook-pipe-QJRFZVKA.js → webhook-pipe-BVLWBMIC.js} +0 -0
  442. /package/dist/{wiki-acl-X67M7QT3.js → wiki-acl-E24PM3YR.js} +0 -0
  443. /package/dist/{wiki-client-57QWZIHQ.js → wiki-client-ZDPDQDX2.js} +0 -0
@@ -69,7 +69,16 @@ CRM_HOST_PORT=3000
69
69
 
70
70
  # --- Wiki ---
71
71
  WIKI_IMAGE_TAG=update.askexe.com/askexe/exe-wiki:v0.9.26
72
- WIKI_DB_SCHEMA=wiki
72
+ # Bug 2a8d3003 — DO NOT change this without migrating the data first.
73
+ # The wiki's users / workspaces / workspace_documents live in `public`. Point it at a
74
+ # different schema and Prisma will NOT error: it finds no tables, assumes a fresh
75
+ # database, creates empty ones, and the wiki comes up with zero documents and the
76
+ # admin locked out. It looks exactly like catastrophic data loss while every row is
77
+ # still sitting safely in `public`. That misread has a very expensive next step —
78
+ # restoring a backup over good data. This value used to default to `wiki`, and the
79
+ # only thing holding production together was a host-local compose override.
80
+ # exe-wiki-schema-guard blocks the boot if you get this wrong.
81
+ WIKI_DB_SCHEMA=public
73
82
  WIKI_VECTOR_DB=exeOsMcp
74
83
  WIKI_AUTH_TOKEN=CHANGEME_WIKI_AUTH_TOKEN
75
84
  WIKI_JWT_SECRET=CHANGEME_WIKI_JWT_SECRET
@@ -99,7 +99,16 @@ CRM_HOST_PORT=3000
99
99
 
100
100
  # --- Wiki ---
101
101
  WIKI_IMAGE_TAG=ghcr.io/askexe/exe-wiki:v0.9.26
102
- WIKI_DB_SCHEMA=wiki
102
+ # Bug 2a8d3003 — DO NOT change this without migrating the data first.
103
+ # The wiki's users / workspaces / workspace_documents live in `public`. Point it at a
104
+ # different schema and Prisma will NOT error: it finds no tables, assumes a fresh
105
+ # database, creates empty ones, and the wiki comes up with zero documents and the
106
+ # admin locked out. It looks exactly like catastrophic data loss while every row is
107
+ # still sitting safely in `public`. That misread has a very expensive next step —
108
+ # restoring a backup over good data. This value used to default to `wiki`, and the
109
+ # only thing holding production together was a host-local compose override.
110
+ # exe-wiki-schema-guard blocks the boot if you get this wrong.
111
+ WIKI_DB_SCHEMA=public
103
112
  WIKI_VECTOR_DB=exeOsMcp
104
113
  WIKI_AUTH_TOKEN=CHANGEME_WIKI_AUTH_TOKEN
105
114
  EXE_WIKI_ADMIN_TOKEN=CHANGEME_EXE_WIKI_ADMIN_TOKEN
@@ -8,16 +8,18 @@
8
8
  # wiki.<domain> → http://exe-sso-edge:80 (unified SSO redirect)
9
9
  # erp.<domain> → http://exe-sso-edge:80 (unified SSO redirect)
10
10
  # gateway.<domain> → http://exe-gateway:3100
11
- # dashboard.askexe.com → http://exe-dashboard:80
11
+ # dashboard.<domain> → http://exe-sso-edge:80 (unified SSO redirect — NOT
12
+ # exe-dashboard:80, which would skip the login gate)
12
13
  # monitor.<domain> → http://exe-monitor-hub:8090
13
14
  # auth.<domain> → http://exe-sso-edge:80 (auth gateway + real health aliases)
14
15
  # api.<domain> → http://exe-os:8765
15
16
  # No config.yml or credentials file needed — the token embeds everything.
16
17
  #
17
- # IMPORTANT: crm/wiki/erp MUST route through exe-sso-edge (NOT straight to the
18
- # app container). The edge is what 302s unauthenticated visitors to
19
- # auth.<domain>; routing direct to the app skips the redirect (this was the
20
- # bug). exe-sso-edge picks the app by Host header, so all three share one route.
18
+ # IMPORTANT: crm/wiki/erp/dashboard MUST route through exe-sso-edge (NOT
19
+ # straight to the app container). The edge is what 302s unauthenticated
20
+ # visitors to auth.<domain>; routing direct to the app skips the redirect
21
+ # (this was the bug). exe-sso-edge picks the app by Host header, so all four
22
+ # share one route.
21
23
  #
22
24
  # ADVANCED (config file mode): only needed if you want to manage routes locally
23
25
  # instead of via the Cloudflare dashboard. Leave CLOUDFLARE_TUNNEL_TOKEN empty
@@ -44,9 +46,14 @@ ingress:
44
46
  # Gateway (WhatsApp, webhooks, pairing)
45
47
  - hostname: gateway.CHANGEME_DOMAIN
46
48
  service: http://exe-gateway:3100
47
- # AskExe customer dashboard (nginx in exe-dashboard listens on container port 80).
48
- - hostname: dashboard.askexe.com
49
- service: http://exe-dashboard:80
49
+ # Dashboard through the unified SSO edge, same as crm/wiki/erp. The edge
50
+ # gates on the canonical exe_access_token cookie and 302s unauthenticated
51
+ # visitors to auth.<domain>/?product=Dashboard&redirect=<dashboard-url><uri>.
52
+ # Routing straight to exe-dashboard:80 skips that gate (same class of bug as
53
+ # 96f8b2b2 for crm/wiki/erp) and leaves an ungated hostname serving 200 to
54
+ # anonymous requests.
55
+ - hostname: dashboard.CHANGEME_DOMAIN
56
+ service: http://exe-sso-edge:80
50
57
  # Monitor — /_/ admin panel blocked; only the API and UI are exposed publicly.
51
58
  # The PocketBase superadmin UI must be accessed via SSH tunnel:
52
59
  # ssh -L 8090:127.0.0.1:8090 <vps> then open http://localhost:8090/_/
@@ -376,6 +376,18 @@ services:
376
376
  # SAME public value here so issuer validation accepts real browser sessions
377
377
  # instead of rejecting them as iss-mismatch. Same default as the gotrue pin.
378
378
  GOTRUE_JWT_ISSUER: ${GOTRUE_JWT_ISSUER:-${GOTRUE_EXTERNAL_URL:?GOTRUE_EXTERNAL_URL is required — set to https://auth.<your-domain> in .env}}
379
+ # Bug 550d6ab7: CRM verifies GoTrue tokens JWKS-first with an HS256
380
+ # shared-secret fallback (exe-crm access-token.service.ts verifyGoTrueToken
381
+ # -> getGoTrueSymmetricVerificationKey, landed in exe-crm 80c5cd95). Our
382
+ # GoTrue is configured with a SYMMETRIC GOTRUE_JWT_SECRET and no
383
+ # GOTRUE_JWT_KEYS, so it publishes an empty JWKS ({"keys":[]}) — and it
384
+ # MUST stay empty, because publishing an `oct` key would publish the
385
+ # signing secret itself. The HS256 fallback is therefore the ONLY viable
386
+ # verification path, and it returns null when this variable is unset. That
387
+ # is the same defect class as bug 0c0d5187 on exe-wiki (see the wiki
388
+ # service block below): the fix landed in the app, the secret was never
389
+ # handed to the container, so SSO stayed dead. Fail loud.
390
+ GOTRUE_JWT_SECRET: ${GOTRUE_JWT_SECRET:?GOTRUE_JWT_SECRET is required}
379
391
  PG_DATABASE_URL: postgres://${POSTGRES_USER:-exe}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@exe-db:5432/${POSTGRES_DB:-exedb}?sslmode=disable
380
392
  REDIS_URL: redis://:${REDIS_PASSWORD:?REDIS_PASSWORD is required}@redis:6379
381
393
  CLICKHOUSE_URL: http://${CLICKHOUSE_USER:-exe}:${CLICKHOUSE_PASSWORD:?CLICKHOUSE_PASSWORD is required}@clickhouse:8123/${CLICKHOUSE_DB:-default}
@@ -460,17 +472,63 @@ services:
460
472
  driver: json-file
461
473
  options: { max-size: "10m", max-file: "3" }
462
474
 
475
+ # Bug 2a8d3003: one-shot pre-flight that refuses to let exe-wiki start against a
476
+ # schema where its data isn't. Reuses the already-present Postgres image purely for
477
+ # its psql client — no extra pull. See wiki-schema-guard.sh for the full rationale;
478
+ # the short version is that Prisma silently bootstraps an empty schema rather than
479
+ # erroring, so "wiki looks wiped" and "wiki is misconfigured" are indistinguishable
480
+ # at a glance, and the wrong diagnosis (restore from backup) destroys real data.
481
+ exe-wiki-schema-guard:
482
+ image: ${EXE_DB_IMAGE:-pgvector/pgvector:0.8.0-pg16@sha256:a132765ec351c65111b5b675928a3a0515a466a40f97277329db8b8209ad8bc9}
483
+ container_name: exe-wiki-schema-guard
484
+ restart: "no"
485
+ depends_on:
486
+ exe-db:
487
+ condition: service_healthy
488
+ environment:
489
+ # MUST stay byte-identical to exe-wiki's DATABASE_URL below — the guard's whole
490
+ # job is to assert on the schema the wiki itself will resolve.
491
+ DATABASE_URL: postgres://${POSTGRES_USER:-exe}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@exe-db:5432/${POSTGRES_DB:-exedb}?schema=${WIKI_DB_SCHEMA:-public}&sslmode=disable
492
+ WIKI_SCHEMA_GUARD: ${WIKI_SCHEMA_GUARD:-enforce}
493
+ volumes:
494
+ - ./wiki-schema-guard.sh:/usr/local/bin/wiki-schema-guard.sh:ro
495
+ # Fail OPEN when the script itself is missing, fail CLOSED on what it detects.
496
+ # On a stack dir that predates this change Docker materialises the bind source as
497
+ # an empty directory, and a guard that can't be found must not be the reason the
498
+ # wiki stays down — an absent guard is no worse than the status quo, whereas a
499
+ # guard that wedges the wiki is a new outage. stack-update installs the real
500
+ # script next to docker-compose.yml on every run.
501
+ entrypoint:
502
+ - bash
503
+ - -c
504
+ - |
505
+ if [ -f /usr/local/bin/wiki-schema-guard.sh ]; then
506
+ exec bash /usr/local/bin/wiki-schema-guard.sh
507
+ fi
508
+ echo "[wiki-schema-guard] script not installed next to docker-compose.yml — skipping."
509
+ echo "[wiki-schema-guard] run 'exe-os stack update' to install it; until then the"
510
+ echo "[wiki-schema-guard] wiki can boot against an empty schema undetected (bug 2a8d3003)."
511
+ networks:
512
+ - backend
513
+ logging:
514
+ driver: json-file
515
+ options: { max-size: "10m", max-file: "3" }
516
+
463
517
  exe-wiki:
464
518
  image: ${WIKI_IMAGE_TAG:-ghcr.io/askexe/exe-wiki:v0.9.26}
465
519
  container_name: exe-wiki
466
520
  restart: unless-stopped
467
521
  # Wiki uses Prisma — runs migrate on boot via built-in entrypoint.
468
- # If tables don't exist, Prisma creates them automatically.
522
+ # If tables don't exist, Prisma creates them automatically. That convenience is
523
+ # exactly why exe-wiki-schema-guard has to clear the boot first (bug 2a8d3003):
524
+ # pointed at the wrong schema, Prisma builds empty tables instead of complaining.
469
525
  depends_on:
470
526
  exe-db:
471
527
  condition: service_healthy
472
528
  gotrue:
473
529
  condition: service_healthy
530
+ exe-wiki-schema-guard:
531
+ condition: service_completed_successfully
474
532
  # SECURITY (bug 67d62490): no blanket `env_file: .env`. Each service
475
533
  # receives ONLY the secrets it owns via the explicit `environment:` block
476
534
  # below (values interpolated from .env at compose-parse time, never the
@@ -486,10 +544,32 @@ services:
486
544
  ERROR_REPORTING_ENABLED: "true"
487
545
  MONITOR_ERROR_URL: http://exe-monitor-hub:8090/api/exe-monitor/errors
488
546
  MONITOR_API_KEY: ${MONITOR_API_KEY:-${EXE_MONITOR_KEY:-}}
489
- DATABASE_URL: postgres://${POSTGRES_USER:-exe}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@exe-db:5432/${POSTGRES_DB:-exedb}?schema=${WIKI_DB_SCHEMA:-wiki}&sslmode=disable
547
+ # Bug 2a8d3003: the wiki's live data lives in the `public` schema and ALWAYS has.
548
+ # This default used to be `wiki`, and the ONLY thing keeping production pointed at
549
+ # its real content was a hand-written docker-compose.override.yml on the host that
550
+ # dropped the schema param. Drop that override — or honour WIKI_DB_SCHEMA=wiki —
551
+ # and the wiki boots against an empty `wiki` schema that Prisma will happily
552
+ # bootstrap: zero users, zero documents, admin locked out, and the real rows
553
+ # sitting untouched in `public` looking exactly like data loss. `public` is now the
554
+ # explicit, authoritative default so base and override agree.
555
+ #
556
+ # Why keep `?schema=` rather than omitting it: an omitted param makes resolution
557
+ # implicit (it falls back to the role's search_path, which ALTER ROLE can silently
558
+ # change). Naming the schema pins it deterministically and keeps the knob available
559
+ # for operators who genuinely want isolation — see WIKI_DB_SCHEMA in .env.example
560
+ # for the migration that requires. exe-wiki-schema-guard below enforces the choice.
561
+ DATABASE_URL: postgres://${POSTGRES_USER:-exe}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}@exe-db:5432/${POSTGRES_DB:-exedb}?schema=${WIKI_DB_SCHEMA:-public}&sslmode=disable
490
562
  AUTH_TOKEN: ${WIKI_AUTH_TOKEN:?WIKI_AUTH_TOKEN is required}
491
563
  EXE_WIKI_ADMIN_TOKEN: ${EXE_WIKI_ADMIN_TOKEN:-}
492
564
  GOTRUE_URL: http://gotrue:9999
565
+ # Bug 0c0d5187: the wiki verifies GoTrue HS256 tokens with GOTRUE_JWT_SECRET
566
+ # (server/utils/gotrue/index.js getGoTrueJwtSecret reads ONLY
567
+ # GOTRUE_JWT_SECRET || EXE_GOTRUE_JWT_SECRET) — NOT the wiki-local JWT_SECRET
568
+ # below. Without it, GoTrue's JWKS is empty so the asymmetric path is dead too,
569
+ # and every SSO exchange AND the wiki's own password form 401 with
570
+ # "Invalid or expired SSO token." Fail loud rather than ship a wiki nobody can
571
+ # log in to.
572
+ GOTRUE_JWT_SECRET: ${GOTRUE_JWT_SECRET:?GOTRUE_JWT_SECRET is required}
493
573
  # Bug 98a528a7 (class): the PUBLIC auth domain the wiki login link must point at.
494
574
  # Same lever as ERP — without it the wiki frontend can default to auth.askexe.com
495
575
  # instead of the customer's auth.<domain>. The wiki image must build its SSO
@@ -983,9 +1063,16 @@ services:
983
1063
  # Probe an app subdomain so the gate's server block (not the default 404)
984
1064
  # answers. Any 2xx/3xx from the edge proves it is serving.
985
1065
  # bug f1e79d3b: nginx:alpine ships BusyBox wget, which does NOT support
986
- # --max-redirect — that flag made the probe error out. Drop it and follow
987
- # the unauthenticated 302 to a 2xx; either way wget exits 0 when served.
988
- test: ["CMD", "wget", "-qO-", "--header=Host: crm.${DOMAIN}", "http://127.0.0.1:80/"]
1066
+ # --max-redirect — that flag made the probe error out.
1067
+ # Follow-up: probing "/" on a gated vhost cannot work either. Anonymous "/"
1068
+ # is exactly what the gate 302s to auth.<domain>, and BusyBox wget FOLLOWS
1069
+ # redirects with no way to cap them, so the probe chases the login funnel
1070
+ # and dies with "wget: too many redirections" — the edge is serving
1071
+ # correctly but reports unhealthy (seen live on askexe.com once crm was
1072
+ # routed through the edge). Probe the crm vhost's EXEMPT /healthz instead:
1073
+ # it never redirects and it proves vhost selection + gate exemption + the
1074
+ # CRM upstream in one request.
1075
+ test: ["CMD", "wget", "-qO-", "--header=Host: crm.${DOMAIN}", "http://127.0.0.1:80/healthz"]
989
1076
  interval: 30s
990
1077
  timeout: 5s
991
1078
  retries: 3
@@ -1320,11 +1407,16 @@ services:
1320
1407
  networks:
1321
1408
  - backend
1322
1409
  healthcheck:
1323
- # Verify the bench worker process is alive and Redis queue is reachable.
1324
- # bug c8fb434f: pgrep is NOT in the Frappe image (exit 127) → permanent
1325
- # false-unhealthy. ps + grep are present; the [r] bracket avoids matching
1326
- # the grep process itself.
1327
- test: ["CMD-SHELL", "ps -ef | grep -q '[r]q worker'"]
1410
+ # Liveness = the RQ worker process (PID 1) is still running.
1411
+ # bug ed19883e: the slim Frappe base has NEITHER pgrep NOR ps/procps
1412
+ # (exit 127 "not found") the process-table probes were permanently
1413
+ # false-unhealthy 180s stack-update gate → rollback. Also `bench
1414
+ # worker` runs the RQ worker in-process (frappe.utils.background_jobs
1415
+ # .start_worker → Worker.work()); PID 1 argv stays "bench worker", so a
1416
+ # `rq worker` grep would miss it even if ps existed. Use python (the
1417
+ # image base is python:3.14-slim) to read PID 1's argv directly — this
1418
+ # matches the exe-erp repo's own docker-compose.yml probe.
1419
+ test: ["CMD-SHELL", "python -c \"import sys; cmd=open('/proc/1/cmdline','rb').read().replace(b'\\0', b' '); sys.exit(0 if b'bench worker' in cmd else 1)\""]
1328
1420
  interval: 30s
1329
1421
  timeout: 5s
1330
1422
  start_period: 30s
@@ -1369,11 +1461,13 @@ services:
1369
1461
  networks:
1370
1462
  - backend
1371
1463
  healthcheck:
1372
- # Verify the bench schedule process is alive.
1373
- # bug c8fb434f: pgrep is NOT in the Frappe image (exit 127) → permanent
1374
- # false-unhealthy. ps + grep are present; the [b] bracket avoids matching
1375
- # the grep process itself.
1376
- test: ["CMD-SHELL", "ps -ef | grep -q '[b]ench schedule'"]
1464
+ # Liveness = the scheduler process (PID 1) is still running.
1465
+ # bug ed19883e: the slim Frappe base has NEITHER pgrep NOR ps/procps
1466
+ # (exit 127 "not found") the process-table probe was permanently
1467
+ # false-unhealthy 180s stack-update gate → rollback. Use python (the
1468
+ # image base is python:3.14-slim) to read PID 1's argv directly — this
1469
+ # matches the exe-erp repo's own docker-compose.yml probe.
1470
+ test: ["CMD-SHELL", "python -c \"import sys; cmd=open('/proc/1/cmdline','rb').read().replace(b'\\0', b' '); sys.exit(0 if b'bench schedule' in cmd else 1)\""]
1377
1471
  interval: 30s
1378
1472
  timeout: 5s
1379
1473
  start_period: 30s
@@ -27,7 +27,11 @@ const CLICKHOUSE_USER = "exe";
27
27
  export const CRM_IMAGE_TAG = `${REGISTRY}/exe-crm:${CRM_RELEASE_TAG}`;
28
28
  const CRM_HOST_PORT = "3000";
29
29
  export const WIKI_IMAGE_TAG = `${REGISTRY}/exe-wiki:${WIKI_RELEASE_TAG}`;
30
- const WIKI_DB_SCHEMA = "wiki";
30
+ // Bug 2a8d3003: the wiki's data lives in `public` and generated .env files must say
31
+ // so. This constant used to be "wiki", which meant every freshly generated stack
32
+ // pinned the wiki to an empty schema — Prisma bootstraps it silently rather than
33
+ // erroring, so the wiki simply comes up with no users and no documents.
34
+ const WIKI_DB_SCHEMA = "public";
31
35
  const WIKI_VECTOR_DB = "exeOsMcp";
32
36
  const WIKI_HOST_PORT = "3001";
33
37
  export const EXE_OS_IMAGE_TAG = `${REGISTRY}/exe-os:${EXED_RELEASE_TAG}`;
@@ -174,6 +178,15 @@ export function generateEnv(options: GenerateEnvOptions): string {
174
178
  "",
175
179
  "# --- Wiki ---",
176
180
  `WIKI_IMAGE_TAG=${WIKI_IMAGE_TAG}`,
181
+ "# Bug 2a8d3003 — DO NOT change this without migrating the data first.",
182
+ "# The wiki's users / workspaces / workspace_documents live in `public`. Point it at a",
183
+ "# different schema and Prisma will NOT error: it finds no tables, assumes a fresh",
184
+ "# database, creates empty ones, and the wiki comes up with zero documents and the",
185
+ "# admin locked out. It looks exactly like catastrophic data loss while every row is",
186
+ "# still sitting safely in `public`. That misread has a very expensive next step —",
187
+ "# restoring a backup over good data. This value used to default to `wiki`, and the",
188
+ "# only thing holding production together was a host-local compose override.",
189
+ "# exe-wiki-schema-guard blocks the boot if you get this wrong.",
177
190
  `WIKI_DB_SCHEMA=${WIKI_DB_SCHEMA}`,
178
191
  `WIKI_VECTOR_DB=${WIKI_VECTOR_DB}`,
179
192
  `WIKI_AUTH_TOKEN=${randomSecret(RANDOM_SECRET_48)}`,
@@ -428,6 +441,15 @@ export function generateExampleEnv(): string {
428
441
  "",
429
442
  "# --- Wiki ---",
430
443
  `WIKI_IMAGE_TAG=${WIKI_IMAGE_TAG}`,
444
+ "# Bug 2a8d3003 — DO NOT change this without migrating the data first.",
445
+ "# The wiki's users / workspaces / workspace_documents live in `public`. Point it at a",
446
+ "# different schema and Prisma will NOT error: it finds no tables, assumes a fresh",
447
+ "# database, creates empty ones, and the wiki comes up with zero documents and the",
448
+ "# admin locked out. It looks exactly like catastrophic data loss while every row is",
449
+ "# still sitting safely in `public`. That misread has a very expensive next step —",
450
+ "# restoring a backup over good data. This value used to default to `wiki`, and the",
451
+ "# only thing holding production together was a host-local compose override.",
452
+ "# exe-wiki-schema-guard blocks the boot if you get this wrong.",
431
453
  `WIKI_DB_SCHEMA=${WIKI_DB_SCHEMA}`,
432
454
  `WIKI_VECTOR_DB=${WIKI_VECTOR_DB}`,
433
455
  "WIKI_AUTH_TOKEN=CHANGEME_WIKI_AUTH_TOKEN",
@@ -47,6 +47,36 @@ docker exec exe-db psql -U exe -d exedb -c "SELECT schemaname, COUNT(*) as table
47
47
 
48
48
  echo ""
49
49
 
50
+ # Bug 2a8d3003: which schema is the wiki ACTUALLY running against?
51
+ # exe-wiki-schema-guard gates `docker compose up`, but compose dependencies are not
52
+ # evaluated by `docker start exe-wiki` or by restart:unless-stopped after a reboot —
53
+ # so a wiki can still come back on the wrong schema without the guard ever running.
54
+ # This makes that visible on demand. Read from the LIVE container, never from .env:
55
+ # a docker-compose.override.yml can rewrite DATABASE_URL and .env would not show it.
56
+ echo "Wiki schema (bug 2a8d3003):"
57
+ WIKI_URL=$(docker inspect exe-wiki --format '{{range .Config.Env}}{{println .}}{{end}}' 2>/dev/null | sed -n 's/^DATABASE_URL=//p')
58
+ if [[ -z "$WIKI_URL" ]]; then
59
+ echo " ⚠️ exe-wiki not running — cannot determine schema"
60
+ else
61
+ WIKI_SCHEMA=$(printf '%s' "$WIKI_URL" | sed -n 's/.*[?&]schema=\([^&]*\).*/\1/p')
62
+ [[ -z "$WIKI_SCHEMA" ]] && WIKI_SCHEMA="public"
63
+ COUNTS=$(docker exec exe-db psql -U exe -d exedb -tA -F' ' -c \
64
+ "SELECT COALESCE((SELECT count(*) FROM ${WIKI_SCHEMA}.users), -1),
65
+ COALESCE((SELECT count(*) FROM ${WIKI_SCHEMA}.workspace_documents), -1)" 2>/dev/null)
66
+ W_USERS=$(echo "$COUNTS" | awk '{print $1}')
67
+ W_DOCS=$(echo "$COUNTS" | awk '{print $2}')
68
+ if [[ "${W_USERS:-0}" -gt 0 || "${W_DOCS:-0}" -gt 0 ]]; then
69
+ echo -e " ${GREEN}✅${NC} schema '$WIKI_SCHEMA' — users=$W_USERS documents=$W_DOCS"
70
+ else
71
+ echo -e " ${RED}❌${NC} schema '$WIKI_SCHEMA' has NO users and NO documents — the wiki is"
72
+ echo -e " serving an EMPTY schema. This is a config fault, not data loss."
73
+ echo -e " ${YELLOW}DO NOT RESTORE FROM BACKUP.${NC} Check WIKI_DB_SCHEMA in .env and any"
74
+ echo -e " docker-compose.override.yml, then: docker compose up -d exe-wiki"
75
+ fi
76
+ fi
77
+
78
+ echo ""
79
+
50
80
  # Disk/Memory
51
81
  echo "Resources:"
52
82
  echo " RAM: $(free -h 2>/dev/null | awk '/^Mem:/ {print $3 "/" $2}' || echo 'N/A')"
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
  # exe-os uptime check — runs every 5 min via cron.
3
- # Checks: CRM, Gateway, WhatsApp state, Postgres.
3
+ # Checks: CRM, Gateway, WhatsApp state, Postgres, wiki schema (bug 2a8d3003).
4
4
  # Writes JSONL to /opt/exe-stack/uptime.jsonl.
5
5
  # Logs ALERT to stderr (captured by cron/syslog) on any failure.
6
6
  #
@@ -92,10 +92,40 @@ check_whatsapp() {
92
92
  # --- Run checks ---
93
93
  NOW=$(ts)
94
94
 
95
+ # Bug 2a8d3003: is the wiki serving the schema its data is actually in?
96
+ # exe-wiki-schema-guard gates `docker compose up`, but nothing evaluates compose
97
+ # dependencies on `docker start exe-wiki` or on restart:unless-stopped after a
98
+ # reboot. Those paths can bring the wiki back on an empty schema with no guard run
99
+ # and no error anywhere — silent-empty, which is the whole failure mode. Checking it
100
+ # here bounds how long that can go unnoticed to one cron interval.
101
+ # Reads the LIVE container env, not .env: a compose override can rewrite DATABASE_URL.
102
+ check_wiki_schema() {
103
+ local url schema counts users docs
104
+ url=$(docker inspect exe-wiki --format '{{range .Config.Env}}{{println .}}{{end}}' 2>/dev/null \
105
+ | sed -n 's/^DATABASE_URL=//p')
106
+ [[ -z "$url" ]] && { echo "skip"; return; }
107
+ schema=$(printf '%s' "$url" | sed -n 's/.*[?&]schema=\([^&]*\).*/\1/p')
108
+ [[ -z "$schema" ]] && schema="public"
109
+ # Only ever interpolate a bare identifier into SQL.
110
+ [[ ! "$schema" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] && { echo "fail:bad-schema-name"; return; }
111
+ counts=$(docker exec exe-db psql -U "${POSTGRES_USER:-exe}" -d "${POSTGRES_DB:-exedb}" -tA -F' ' -c \
112
+ "SELECT COALESCE((SELECT count(*) FROM ${schema}.users), 0),
113
+ COALESCE((SELECT count(*) FROM ${schema}.workspace_documents), 0)" 2>/dev/null)
114
+ [[ -z "$counts" ]] && { echo "skip"; return; }
115
+ users=$(echo "$counts" | awk '{print $1}')
116
+ docs=$(echo "$counts" | awk '{print $2}')
117
+ if [[ "${users:-0}" -gt 0 || "${docs:-0}" -gt 0 ]]; then
118
+ echo "ok:$schema"
119
+ else
120
+ echo "fail:empty-schema-$schema"
121
+ fi
122
+ }
123
+
95
124
  crm_status=$(check_http "CRM" "http://127.0.0.1:3000/healthz")
96
125
  gateway_status=$(check_http "Gateway" "http://127.0.0.1:3100/health")
97
126
  whatsapp_status=$(check_whatsapp)
98
127
  postgres_status=$(check_postgres)
128
+ wiki_schema_status=$(check_wiki_schema)
99
129
 
100
130
  # --- Determine overall health ---
101
131
  overall="ok"
@@ -117,11 +147,18 @@ if [[ "$postgres_status" != "ok" ]]; then
117
147
  overall="critical"
118
148
  alerts="${alerts}Postgres($postgres_status) "
119
149
  fi
150
+ # A wiki serving an empty schema is critical: it looks like total data loss to
151
+ # whoever opens it, and the wrong reflex (restore from backup) destroys the real
152
+ # rows still sitting in the other schema. Say so in the alert itself.
153
+ if [[ "$wiki_schema_status" == fail:* ]]; then
154
+ overall="critical"
155
+ alerts="${alerts}WikiSchema($wiki_schema_status — CONFIG FAULT, DO NOT RESTORE FROM BACKUP, see bug 2a8d3003) "
156
+ fi
120
157
 
121
158
  # --- Write JSONL ---
122
159
  # Single-line JSON — no jq dependency required
123
160
  ENTRY=$(cat <<JSONEOF
124
- {"ts":"${NOW}","overall":"${overall}","crm":"${crm_status}","gateway":"${gateway_status}","whatsapp":"${whatsapp_status}","postgres":"${postgres_status}"}
161
+ {"ts":"${NOW}","overall":"${overall}","crm":"${crm_status}","gateway":"${gateway_status}","whatsapp":"${whatsapp_status}","postgres":"${postgres_status}","wiki_schema":"${wiki_schema_status}"}
125
162
  JSONEOF
126
163
  )
127
164