@askexenow/exe-os 0.9.294 → 0.9.296

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 (279) hide show
  1. package/deploy/compose/cloudflared/config.yml.example +14 -9
  2. package/deploy/compose/docker-compose.yml +86 -8
  3. package/deploy/compose/sso-edge/default.conf.template +87 -0
  4. package/deploy/compose/sso-edge/entrypoint.sh +23 -0
  5. package/deploy/compose/sso-edge/sso-redirect.conf +63 -0
  6. package/deploy/stack-manifests/v0.9.json +2 -2
  7. package/dist/active-agent-AFX2FODG.js +28 -0
  8. package/dist/active-agent-E2IJA7YX.js +27 -0
  9. package/dist/agentic-ontology-A2YUZK5O.js +25 -0
  10. package/dist/assets/com.askexe.exed.plist +4 -1
  11. package/dist/backfill-metadata-OC7EOD5U.js +600 -0
  12. package/dist/behaviors-H5ZOVHDH.js +46 -0
  13. package/dist/bin/agentic-ontology-backfill.js +5 -5
  14. package/dist/bin/agentic-reflection-backfill.js +6 -6
  15. package/dist/bin/agentic-semantic-label.js +5 -5
  16. package/dist/bin/backfill-conversations.js +6 -6
  17. package/dist/bin/backfill-responses.js +6 -6
  18. package/dist/bin/backfill-vectors.js +8 -8
  19. package/dist/bin/bulk-sync-postgres.js +7 -7
  20. package/dist/bin/cc-doctor.js +4 -4
  21. package/dist/bin/cleanup-stale-review-tasks.js +11 -11
  22. package/dist/bin/cli.js +16 -16
  23. package/dist/bin/deferred-daemon-restart.js +1 -1
  24. package/dist/bin/exe-agent-config.js +2 -2
  25. package/dist/bin/exe-agent.js +4 -4
  26. package/dist/bin/exe-assign.js +8 -8
  27. package/dist/bin/exe-boot.js +21 -18
  28. package/dist/bin/exe-call.js +4 -4
  29. package/dist/bin/exe-cloud.js +7 -7
  30. package/dist/bin/exe-dispatch.js +11 -11
  31. package/dist/bin/exe-doctor.js +3 -2
  32. package/dist/bin/exe-export-behaviors.js +7 -7
  33. package/dist/bin/exe-forget.js +6 -6
  34. package/dist/bin/exe-gateway.js +7 -7
  35. package/dist/bin/exe-healthcheck.js +6 -4
  36. package/dist/bin/exe-heartbeat.js +11 -11
  37. package/dist/bin/exe-kill.js +14 -14
  38. package/dist/bin/exe-launch-agent.js +18 -18
  39. package/dist/bin/exe-new-employee.js +6 -6
  40. package/dist/bin/exe-pending-messages.js +12 -12
  41. package/dist/bin/exe-pending-notifications.js +11 -11
  42. package/dist/bin/exe-pending-reviews.js +11 -11
  43. package/dist/bin/exe-rename.js +4 -4
  44. package/dist/bin/exe-review.js +13 -13
  45. package/dist/bin/exe-search.js +5 -5
  46. package/dist/bin/exe-session-cleanup.js +16 -16
  47. package/dist/bin/exe-settings.js +39 -9
  48. package/dist/bin/exe-start-codex.js +11 -11
  49. package/dist/bin/exe-start-opencode.js +8 -8
  50. package/dist/bin/exe-status.js +12 -12
  51. package/dist/bin/exe-team.js +3 -3
  52. package/dist/bin/git-sweep.js +12 -12
  53. package/dist/bin/graph-backfill.js +4 -4
  54. package/dist/bin/graph-export.js +5 -5
  55. package/dist/bin/import-history.js +7 -7
  56. package/dist/bin/install-launchd.js +13 -6
  57. package/dist/bin/install.js +26 -14
  58. package/dist/bin/intercom-check.js +4 -4
  59. package/dist/bin/mcp-sessions.js +2 -2
  60. package/dist/bin/orchestration-metrics.js +4 -4
  61. package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
  62. package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
  63. package/dist/bin/scan-tasks.js +11 -11
  64. package/dist/bin/setup.js +1 -1
  65. package/dist/bin/shard-migrate.js +4 -4
  66. package/dist/bin/stack-update.js +2 -2
  67. package/dist/bin/vps-health-gate.js +1 -1
  68. package/dist/capability-cards-4USI7CUW.js +89 -0
  69. package/dist/capacity-monitor-WLCBTEYR.js +51 -0
  70. package/dist/catchup-brief-ZR3NX6LZ.js +175 -0
  71. package/dist/chunk-22TVSRQQ.js +226 -0
  72. package/dist/chunk-2E43UXRH.js +395 -0
  73. package/dist/chunk-2PIGT6UJ.js +460 -0
  74. package/dist/chunk-3XTMW2MZ.js +535 -0
  75. package/dist/chunk-465PQFTH.js +262 -0
  76. package/dist/chunk-5CCXU2AW.js +129 -0
  77. package/dist/chunk-5D6MPWR7.js +1094 -0
  78. package/dist/chunk-5Q4MR6SL.js +123 -0
  79. package/dist/chunk-6327RBWR.js +345 -0
  80. package/dist/chunk-6MZZREZY.js +199 -0
  81. package/dist/chunk-7DI2Q4O5.js +1186 -0
  82. package/dist/chunk-7PW5VNIY.js +122 -0
  83. package/dist/chunk-7T7Y56HW.js +43 -0
  84. package/dist/chunk-7UHCWCLT.js +128 -0
  85. package/dist/chunk-A2ZUMF6L.js +1350 -0
  86. package/dist/chunk-AKV44JEH.js +185 -0
  87. package/dist/chunk-ANHWGX5N.js +735 -0
  88. package/dist/chunk-BQ3P4TKD.js +97 -0
  89. package/dist/chunk-BUZMT3KZ.js +604 -0
  90. package/dist/chunk-C2SBESBO.js +210 -0
  91. package/dist/chunk-CLSXZUZW.js +51 -0
  92. package/dist/chunk-CONHLVAR.js +1079 -0
  93. package/dist/chunk-D3WTZPFX.js +456 -0
  94. package/dist/chunk-DE6SOIYL.js +197 -0
  95. package/dist/chunk-EIVNMA3Q.js +284 -0
  96. package/dist/chunk-EJIF4FNT.js +12 -0
  97. package/dist/chunk-FDFOW564.js +171 -0
  98. package/dist/chunk-GZUBJ5EC.js +127 -0
  99. package/dist/chunk-HGZITN22.js +105 -0
  100. package/dist/chunk-HSRKDU6X.js +362 -0
  101. package/dist/chunk-IIEN2PHV.js +85 -0
  102. package/dist/chunk-JQ56VLMM.js +567 -0
  103. package/dist/chunk-JVHHXRFY.js +280 -0
  104. package/dist/chunk-JXCXGZ3S.js +55 -0
  105. package/dist/chunk-K5ZO532Q.js +4388 -0
  106. package/dist/chunk-K6CAAMXF.js +97 -0
  107. package/dist/chunk-KA26YTNU.js +81 -0
  108. package/dist/chunk-KMUW5C3R.js +381 -0
  109. package/dist/chunk-KOO3J5PV.js +20 -0
  110. package/dist/chunk-LSV7OFIH.js +290 -0
  111. package/dist/chunk-LSVFDVNY.js +1158 -0
  112. package/dist/chunk-LXDQTW32.js +230 -0
  113. package/dist/chunk-MEP7OUVZ.js +181 -0
  114. package/dist/chunk-MN2B2LKS.js +240 -0
  115. package/dist/chunk-N2EAYPYQ.js +1352 -0
  116. package/dist/chunk-N7I2A667.js +70 -0
  117. package/dist/chunk-NLZHVIOP.js +630 -0
  118. package/dist/chunk-NUH5TRZL.js +227 -0
  119. package/dist/chunk-OAHEIH3G.js +167 -0
  120. package/dist/chunk-OBHRQGCK.js +58 -0
  121. package/dist/chunk-ODFA7B2V.js +54 -0
  122. package/dist/chunk-OSNUP45F.js +731 -0
  123. package/dist/chunk-OTPRHBTO.js +33 -0
  124. package/dist/chunk-P6MUA4QU.js +157 -0
  125. package/dist/chunk-PGIOFKSK.js +2093 -0
  126. package/dist/chunk-PSE7VHWK.js +50 -0
  127. package/dist/chunk-QIFUVZFW.js +331 -0
  128. package/dist/chunk-RDPXKTVK.js +221 -0
  129. package/dist/chunk-RKYTYJGB.js +76 -0
  130. package/dist/chunk-RXLR6EFM.js +348 -0
  131. package/dist/chunk-SDB67PQJ.js +159 -0
  132. package/dist/chunk-SF2T7MP3.js +402 -0
  133. package/dist/chunk-SLU3FRFQ.js +2133 -0
  134. package/dist/chunk-SNDZJ5IV.js +214 -0
  135. package/dist/chunk-STEEAABW.js +448 -0
  136. package/dist/chunk-TUTWNHIQ.js +244 -0
  137. package/dist/chunk-UDP35QBR.js +30 -0
  138. package/dist/chunk-UKFHNJBI.js +85 -0
  139. package/dist/chunk-VC2DTK2X.js +382 -0
  140. package/dist/chunk-VRRAE5JX.js +836 -0
  141. package/dist/chunk-VVJTBQPR.js +38 -0
  142. package/dist/chunk-W3EQ362K.js +581 -0
  143. package/dist/chunk-WHIXIFHC.js +2242 -0
  144. package/dist/chunk-WRNGJJNR.js +377 -0
  145. package/dist/chunk-WUKHLCBE.js +3313 -0
  146. package/dist/chunk-WVPLHGDG.js +150 -0
  147. package/dist/chunk-XJZBSTL5.js +204 -0
  148. package/dist/chunk-Y3PMNUM5.js +304 -0
  149. package/dist/chunk-YHVS4QOV.js +14597 -0
  150. package/dist/chunk-YJ2OYAOC.js +668 -0
  151. package/dist/chunk-YYAD2GXX.js +128 -0
  152. package/dist/chunk-ZQML7EWE.js +333 -0
  153. package/dist/co-activation-XJLH46OX.js +74 -0
  154. package/dist/co-occurrence-GNN2X526.js +95 -0
  155. package/dist/code-context-index-OCPRLFG5.js +30 -0
  156. package/dist/core-memory-J4W2IYOF.js +110 -0
  157. package/dist/crdt-sync-QCBTSHIH.js +33 -0
  158. package/dist/crm-webhook-EM442VUW.js +10 -0
  159. package/dist/cto-delegation-gate-MLJMVHBK.js +280 -0
  160. package/dist/daemon-orchestration-2VNLZVTW.js +139 -0
  161. package/dist/db-backup-VUGFTPJ4.js +43 -0
  162. package/dist/doc-graph-extractor-PNRSFPSS.js +133 -0
  163. package/dist/dreaming-SK5VEQRF.js +34 -0
  164. package/dist/entity-boost-TQWWJUC2.js +375 -0
  165. package/dist/exe-drift-N34UPO7S.js +70 -0
  166. package/dist/exe-export-KACBKGVV.js +77 -0
  167. package/dist/exe-import-GXGDWACG.js +80 -0
  168. package/dist/exe-key-XPDOZBWW.js +673 -0
  169. package/dist/exe-snapshot-32GQKGQ5.js +338 -0
  170. package/dist/fast-db-init-F3TDD5VV.js +7 -0
  171. package/dist/gateway/index.js +8 -8
  172. package/dist/git-staleness-J45WNYRF.js +112 -0
  173. package/dist/git-task-sweep-BTGVQPFB.js +42 -0
  174. package/dist/global-procedures-6JCQWU4D.js +22 -0
  175. package/dist/graph-auto-extract-3ZQNXTPC.js +183 -0
  176. package/dist/hooks/bug-report-worker.js +13 -13
  177. package/dist/hooks/codex-stop-task-finalizer.js +13 -13
  178. package/dist/hooks/commit-complete.js +13 -13
  179. package/dist/hooks/error-recall.js +6 -6
  180. package/dist/hooks/exe-heartbeat-hook.js +3 -3
  181. package/dist/hooks/ingest-worker.js +3 -3
  182. package/dist/hooks/ingest.js +6 -6
  183. package/dist/hooks/instructions-loaded.js +4 -4
  184. package/dist/hooks/manifest.json +20 -20
  185. package/dist/hooks/notification.js +4 -4
  186. package/dist/hooks/post-compact.js +12 -12
  187. package/dist/hooks/post-tool-combined.js +6 -6
  188. package/dist/hooks/pre-compact.js +16 -16
  189. package/dist/hooks/pre-tool-use.js +16 -16
  190. package/dist/hooks/prompt-submit.js +24 -24
  191. package/dist/hooks/session-end.js +21 -21
  192. package/dist/hooks/session-start.js +12 -12
  193. package/dist/hooks/stop.js +19 -19
  194. package/dist/hooks/subagent-stop.js +12 -12
  195. package/dist/hooks/summary-worker.js +19 -19
  196. package/dist/index.js +19 -19
  197. package/dist/installer-5VPFY7SB.js +298 -0
  198. package/dist/installer-OENFPMA2.js +344 -0
  199. package/dist/installer-OIX4QOG5.js +40 -0
  200. package/dist/lib/cloud-sync.js +7 -7
  201. package/dist/lib/consolidation.js +6 -5
  202. package/dist/lib/database.js +2 -2
  203. package/dist/lib/db-daemon-client.js +2 -2
  204. package/dist/lib/db.js +2 -2
  205. package/dist/lib/embed-worker.js +1 -0
  206. package/dist/lib/embedder.js +7 -3
  207. package/dist/lib/employee-templates.js +4 -4
  208. package/dist/lib/employees.js +2 -2
  209. package/dist/lib/exe-daemon-client.js +2 -2
  210. package/dist/lib/exe-daemon.js +160 -79
  211. package/dist/lib/hybrid-search.js +5 -5
  212. package/dist/lib/identity.js +2 -2
  213. package/dist/lib/messaging.js +11 -11
  214. package/dist/lib/reminders.js +3 -3
  215. package/dist/lib/schedules.js +5 -5
  216. package/dist/lib/session-registry.js +4 -4
  217. package/dist/lib/skill-learning.js +6 -6
  218. package/dist/lib/store.js +4 -4
  219. package/dist/lib/task-router.js +3 -3
  220. package/dist/lib/tasks.js +12 -12
  221. package/dist/lib/tmux-routing.js +12 -10
  222. package/dist/lib/tmux-transport.js +1 -1
  223. package/dist/lib/token-spend.js +3 -3
  224. package/dist/lib/transport.js +2 -2
  225. package/dist/mcp/register-tools.js +62 -61
  226. package/dist/mcp/server.js +63 -62
  227. package/dist/mcp/tools/complete-reminder.js +4 -4
  228. package/dist/mcp/tools/create-reminder.js +4 -4
  229. package/dist/mcp/tools/create-task.js +14 -14
  230. package/dist/mcp/tools/deactivate-behavior.js +7 -7
  231. package/dist/mcp/tools/list-reminders.js +4 -4
  232. package/dist/mcp/tools/list-tasks.js +14 -14
  233. package/dist/mcp/tools/send-message.js +13 -13
  234. package/dist/mcp/tools/update-task.js +13 -13
  235. package/dist/mcp-http-config-PQTOLCTP.js +29 -0
  236. package/dist/memory-cards-4RVDZIY2.js +180 -0
  237. package/dist/memory-graph-extractor-L6YC7G4M.js +22 -0
  238. package/dist/memory-poisoning-defense-4YVJYH4G.js +224 -0
  239. package/dist/memory-queue-client-MVAUOZNJ.js +16 -0
  240. package/dist/memory-reflection-SHHDQNOH.js +244 -0
  241. package/dist/message-queue-client-DCKZT6X2.js +92 -0
  242. package/dist/notifications-JFR3G42W.js +47 -0
  243. package/dist/orchestration-events-MGCGPTDN.js +27 -0
  244. package/dist/orchestrator-DAFL2YZB.js +35 -0
  245. package/dist/pipeline-router-WWSZVPCH.js +15 -0
  246. package/dist/plan-limits-C7XCSDZC.js +28 -0
  247. package/dist/project-boot-N3NTBVLE.js +299 -0
  248. package/dist/projection-worker-MTPAPCWX.js +1084 -0
  249. package/dist/prospective-memory-BTIVUJSB.js +232 -0
  250. package/dist/reranker-UA6WVESJ.js +19 -0
  251. package/dist/retrieval-health-7XNZJEBF.js +12 -0
  252. package/dist/review-polling-4ALGMXC3.js +126 -0
  253. package/dist/runtime/index.js +13 -13
  254. package/dist/self-query-router-MROFQLQB.js +192 -0
  255. package/dist/session-events-CK44XOU4.js +38 -0
  256. package/dist/session-kill-telemetry-MT6ITDOG.js +31 -0
  257. package/dist/session-scope-3XDBWV65.js +88 -0
  258. package/dist/setup-wizard-X6DOD7MC.js +12 -0
  259. package/dist/skill-refinement-G2CCY3GM.js +159 -0
  260. package/dist/stack-update-JF7F56AS.js +84 -0
  261. package/dist/steward-gate-YF2CYXE7.js +15 -0
  262. package/dist/task-enforcement-YN6HK7NE.js +506 -0
  263. package/dist/task-scope-CVK6ISCZ.js +37 -0
  264. package/dist/tasks-crud-NTNET4JE.js +79 -0
  265. package/dist/tasks-notify-4LJVFPCV.js +40 -0
  266. package/dist/tasks-review-3V4WOIRG.js +49 -0
  267. package/dist/telemetry-upload-5PNUKGTM.js +741 -0
  268. package/dist/token-budget-E46G7ZAQ.js +86 -0
  269. package/dist/tool-capability-index-JDSMKJER.js +10 -0
  270. package/dist/tool-telemetry-J3NLS3LJ.js +17 -0
  271. package/dist/tui/App.js +18 -18
  272. package/dist/tui-data-6DOMUUCM.js +260 -0
  273. package/dist/wiki-acl-5UK37LKF.js +111 -0
  274. package/dist/worker-gate-FM7AEC7G.js +21 -0
  275. package/dist/workflow-engine-2EDUHUIY.js +28 -0
  276. package/dist/worktree-7YKKJIYR.js +28 -0
  277. package/dist/worktree-sweep-C3ELFGDN.js +21 -0
  278. package/package.json +1 -1
  279. package/release-notes.json +88 -88
@@ -4,15 +4,20 @@
4
4
  # 1. Create a tunnel at dash.cloudflare.com > Zero Trust > Networks > Tunnels
5
5
  # 2. Copy the tunnel token and set CLOUDFLARE_TUNNEL_TOKEN in .env
6
6
  # 3. Configure public hostnames in the Cloudflare dashboard:
7
- # crm.<domain> → http://exe-crm:3000
8
- # wiki.<domain> → http://exe-wiki:3001
7
+ # crm.<domain> → http://exe-sso-edge:80 (unified SSO redirect — bug 96f8b2b2)
8
+ # wiki.<domain> → http://exe-sso-edge:80 (unified SSO redirect)
9
+ # erp.<domain> → http://exe-sso-edge:80 (unified SSO redirect)
9
10
  # gateway.<domain> → http://exe-gateway:3100
10
- # erp.<domain> → http://exe-erp:8000
11
11
  # monitor.<domain> → http://exe-monitor-hub:8090
12
12
  # auth.<domain> → http://gotrue:9999
13
13
  # api.<domain> → http://exe-os:8765
14
14
  # No config.yml or credentials file needed — the token embeds everything.
15
15
  #
16
+ # IMPORTANT: crm/wiki/erp MUST route through exe-sso-edge (NOT straight to the
17
+ # app container). The edge is what 302s unauthenticated visitors to
18
+ # auth.<domain>; routing direct to the app skips the redirect (this was the
19
+ # bug). exe-sso-edge picks the app by Host header, so all three share one route.
20
+ #
16
21
  # ADVANCED (config file mode): only needed if you want to manage routes locally
17
22
  # instead of via the Cloudflare dashboard. Leave CLOUDFLARE_TUNNEL_TOKEN empty
18
23
  # and edit docker-compose.yml cloudflared command to use:
@@ -26,15 +31,15 @@ tunnel: CHANGEME_TUNNEL_ID
26
31
  credentials-file: /etc/cloudflared/CHANGEME_TUNNEL_ID.json
27
32
 
28
33
  ingress:
29
- # CRM
34
+ # CRM / Wiki / ERP — all routed through the unified SSO edge (bug 96f8b2b2).
35
+ # exe-sso-edge selects the app by Host header and 302s unauthenticated
36
+ # visitors to auth.<domain>/?product=<App>&redirect=<app-url>.
30
37
  - hostname: crm.CHANGEME_DOMAIN
31
- service: http://exe-crm:3000
32
- # Wiki
38
+ service: http://exe-sso-edge:80
33
39
  - hostname: wiki.CHANGEME_DOMAIN
34
- service: http://exe-wiki:3001
35
- # ERP
40
+ service: http://exe-sso-edge:80
36
41
  - hostname: erp.CHANGEME_DOMAIN
37
- service: http://exe-erp:8000
42
+ service: http://exe-sso-edge:80
38
43
  # Gateway (WhatsApp, webhooks, pairing)
39
44
  - hostname: gateway.CHANGEME_DOMAIN
40
45
  service: http://exe-gateway:3100
@@ -630,6 +630,66 @@ services:
630
630
  driver: json-file
631
631
  options: { max-size: "10m", max-file: "3" }
632
632
 
633
+ # ------------------------------------------------------------------
634
+ # Unified SSO edge — reverse proxy in front of crm / wiki / erp (bug 96f8b2b2)
635
+ #
636
+ # cloudflared routes the app subdomains to THIS edge instead of straight to
637
+ # each app container. The edge includes deploy/nginx/snippets/sso-redirect.conf
638
+ # per app server block, so an unauthenticated top-level request 302s to
639
+ # auth.<domain>/?product=<App>&redirect=<app-url>. The app then consumes the
640
+ # returned ?access_token (it already shares GoTrue) and sets its session cookie;
641
+ # subsequent requests carry the cookie and skip the redirect.
642
+ #
643
+ # Config is templated from ${DOMAIN} at container start (envsubst in the
644
+ # entrypoint) — no customer domain is baked into the image. Per-app session
645
+ # cookie names live in sso-edge/default.conf.template.
646
+ # ------------------------------------------------------------------
647
+
648
+ exe-sso-edge:
649
+ image: nginx:alpine
650
+ container_name: exe-sso-edge
651
+ restart: unless-stopped
652
+ depends_on:
653
+ exe-crm:
654
+ condition: service_healthy
655
+ exe-wiki:
656
+ condition: service_healthy
657
+ exe-erp-nginx:
658
+ condition: service_healthy
659
+ environment:
660
+ DOMAIN: ${DOMAIN:?DOMAIN is required — set to your customer apex domain (e.g. hygo.co)}
661
+ # Neutralize nginx:alpine's built-in 20-envsubst-on-templates.sh: it would
662
+ # envsubst EVERY $var in the template (mangling nginx runtime vars). Our
663
+ # 99-render script (escapes runtime vars, substitutes only ${DOMAIN}) is the
664
+ # single source of truth. Point the built-in at an empty dir so it no-ops.
665
+ NGINX_ENVSUBST_TEMPLATE_DIR: /etc/nginx/no-templates
666
+ volumes:
667
+ - ./sso-edge/default.conf.template:/etc/nginx/exe-templates/default.conf.template:ro
668
+ - ./sso-edge/sso-redirect.conf:/etc/nginx/snippets/sso-redirect.conf:ro
669
+ - ./sso-edge/entrypoint.sh:/docker-entrypoint.d/99-render-sso-edge.sh:ro
670
+ # nginx:alpine runs /docker-entrypoint.d/*.sh then `nginx -g 'daemon off;'`.
671
+ # Our script renders the template from ${DOMAIN}; it does not exec nginx
672
+ # itself (the base entrypoint does), so it ends after `nginx -t`.
673
+ networks:
674
+ - backend
675
+ - frontend
676
+ healthcheck:
677
+ # Probe an app subdomain so the gate's server block (not the default 404)
678
+ # answers. Unauthenticated → 302, which wget treats as success with
679
+ # --max-redirect=0; any 2xx/3xx from the edge proves it is serving.
680
+ test: ["CMD", "wget", "-qO-", "--max-redirect=0", "--header=Host: crm.${DOMAIN}", "http://127.0.0.1:80/"]
681
+ interval: 30s
682
+ timeout: 5s
683
+ retries: 3
684
+ start_period: 20s
685
+ deploy:
686
+ resources:
687
+ limits:
688
+ memory: 64M
689
+ logging:
690
+ driver: json-file
691
+ options: { max-size: "10m", max-file: "3" }
692
+
633
693
  # ------------------------------------------------------------------
634
694
  # Infrastructure — Cloudflare Tunnel (replaces nginx + SSL certs)
635
695
  #
@@ -656,22 +716,32 @@ services:
656
716
  run
657
717
  --token ${CLOUDFLARE_TUNNEL_TOKEN}
658
718
  depends_on:
659
- exe-crm:
719
+ # App subdomains (crm/wiki/erp) are fronted by exe-sso-edge for the unified
720
+ # SSO redirect (bug 96f8b2b2); gateway is routed directly.
721
+ exe-sso-edge:
660
722
  condition: service_healthy
661
723
  exe-gateway:
662
724
  condition: service_healthy
663
- exe-wiki:
664
- condition: service_healthy
665
725
  environment:
666
726
  TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN}
667
727
  networks:
668
728
  - backend
669
729
  - frontend
670
730
  healthcheck:
671
- # `tunnel info` requires API credentials unavailable in token mode.
672
- # The command above exposes cloudflared's local metrics endpoint; use it
673
- # for container liveness without hitting the Cloudflare control plane.
674
- test: ["CMD-SHELL", "pgrep -x cloudflared && wget -q --spider http://localhost:2000/ready || exit 1"]
731
+ # Bug 218b4d02 (HYGO): the original `tunnel info` probe needs exactly one
732
+ # positional arg (tunnel ID/name) + API creds unavailable in token mode, so
733
+ # it exited 255 and the container was ALWAYS 'unhealthy' (false alarm the
734
+ # tunnel works). The follow-up `pgrep + wget /ready` probe is ALSO broken:
735
+ # cloudflare/cloudflared is a distroless, SHELL-LESS image (no sh/wget/
736
+ # pgrep/curl), so CMD-SHELL (`/bin/sh -c …`) can't execute at all and the
737
+ # check still always fails.
738
+ #
739
+ # The cloudflared binary is the ONLY executable in the image. Use it as an
740
+ # exec-form (no shell) liveness probe — `--version` exits 0 iff the binary
741
+ # is runnable, needs no tunnel ID and never touches the Cloudflare control
742
+ # plane. (Token-mode tunnels expose /ready on :2000 but there is no
743
+ # in-image HTTP client to reach it, so this is the cleanest valid probe.)
744
+ test: ["CMD", "cloudflared", "--version"]
675
745
  interval: 30s
676
746
  timeout: 5s
677
747
  start_period: 30s
@@ -954,7 +1024,7 @@ services:
954
1024
  # ------------------------------------------------------------------
955
1025
 
956
1026
  exe-auth:
957
- image: ${AUTH_IMAGE_TAG:-update.askexe.com/askexe/exe-auth:v0.1.0}
1027
+ image: ${AUTH_IMAGE_TAG:-update.askexe.com/askexe/exe-auth:v0.1.1}
958
1028
  container_name: exe-auth
959
1029
  restart: unless-stopped
960
1030
  environment:
@@ -969,10 +1039,18 @@ services:
969
1039
  ports:
970
1040
  - "127.0.0.1:${AUTH_PORT:-3300}:80"
971
1041
  networks:
1042
+ # Bug d2b6b3d9 (HYGO): exe-auth's nginx proxies /api/ to upstream
1043
+ # `gotrue` (backend-only). With frontend-only networking nginx fails DNS
1044
+ # resolution at boot — '[emerg] host not found in upstream "gotrue"' — and
1045
+ # restart-loops. It needs `backend` to resolve+reach gotrue (and frontend
1046
+ # for the cloudflared tunnel), matching exe-crm/exe-wiki/gateway.
1047
+ - backend
972
1048
  - frontend
973
1049
  depends_on:
974
1050
  exe-db:
975
1051
  condition: service_healthy
1052
+ gotrue:
1053
+ condition: service_healthy
976
1054
  healthcheck:
977
1055
  test: ["CMD", "wget", "-qO-", "http://127.0.0.1:80/"]
978
1056
  interval: 30s
@@ -0,0 +1,87 @@
1
+ # ─────────────────────────────────────────────────────────────────────────────
2
+ # Unified SSO edge — reverse proxy in front of crm / wiki / erp (bug 96f8b2b2)
3
+ #
4
+ # WHY THIS EXISTS
5
+ # #198 shipped deploy/nginx/snippets/sso-redirect.conf but on a cloudflared-
6
+ # fronted stack (HYGO) cloudflared routes straight to each app container, so
7
+ # the snippet was never in the serving path and unauth requests returned 200
8
+ # with no 302. This edge puts a real nginx in the request path (cloudflared →
9
+ # exe-sso-edge → app) and INCLUDES the snippet per app server block, so an
10
+ # unauthenticated top-level request 302s to auth.<domain>.
11
+ #
12
+ # TEMPLATING
13
+ # ${DOMAIN} is substituted at container start by `envsubst` in the entrypoint
14
+ # (matching the exe-auth gateway convention). No customer domain is hardcoded.
15
+ # nginx runtime variables ($request_uri, $cookie_*, $arg_*, $sso_*) are escaped
16
+ # in the entrypoint so envsubst leaves them untouched.
17
+ # ─────────────────────────────────────────────────────────────────────────────
18
+
19
+ upstream sso_crm { server exe-crm:3000; }
20
+ upstream sso_wiki { server exe-wiki:3001; }
21
+ # ERP must be reached through its own nginx (gunicorn can't serve /assets/ — bug 6776edf0)
22
+ upstream sso_erp { server exe-erp-nginx:80; }
23
+
24
+ map $http_upgrade $sso_conn_upgrade {
25
+ default upgrade;
26
+ '' close;
27
+ }
28
+
29
+ # Shared proxy headers (avoids repetition; keeps WebSocket upgrade working).
30
+ proxy_http_version 1.1;
31
+ proxy_set_header Host $host;
32
+ proxy_set_header X-Real-IP $remote_addr;
33
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
34
+ proxy_set_header X-Forwarded-Proto https;
35
+ proxy_set_header Upgrade $http_upgrade;
36
+ proxy_set_header Connection $sso_conn_upgrade;
37
+ proxy_read_timeout 120;
38
+ client_max_body_size 50m;
39
+
40
+ # ── CRM ──────────────────────────────────────────────────────────────────────
41
+ server {
42
+ listen 80;
43
+ server_name crm.${DOMAIN};
44
+
45
+ set $sso_auth_base "https://auth.${DOMAIN}";
46
+ set $sso_app_url "https://crm.${DOMAIN}";
47
+ set $sso_product "CRM";
48
+ set $sso_session_cookie $cookie_tokenPair; # Twenty/CRM session cookie
49
+ include /etc/nginx/snippets/sso-redirect.conf;
50
+
51
+ location / { proxy_pass http://sso_crm; }
52
+ }
53
+
54
+ # ── Wiki ─────────────────────────────────────────────────────────────────────
55
+ server {
56
+ listen 80;
57
+ server_name wiki.${DOMAIN};
58
+
59
+ set $sso_auth_base "https://auth.${DOMAIN}";
60
+ set $sso_app_url "https://wiki.${DOMAIN}";
61
+ set $sso_product "Wiki";
62
+ set $sso_session_cookie $cookie_wiki_session; # exe-wiki session cookie
63
+ include /etc/nginx/snippets/sso-redirect.conf;
64
+
65
+ location / { proxy_pass http://sso_wiki; }
66
+ }
67
+
68
+ # ── ERP ──────────────────────────────────────────────────────────────────────
69
+ server {
70
+ listen 80;
71
+ server_name erp.${DOMAIN};
72
+
73
+ set $sso_auth_base "https://auth.${DOMAIN}";
74
+ set $sso_app_url "https://erp.${DOMAIN}";
75
+ set $sso_product "ERP";
76
+ set $sso_session_cookie $cookie_sid; # Frappe/ERPNext session cookie
77
+ include /etc/nginx/snippets/sso-redirect.conf;
78
+
79
+ location / { proxy_pass http://sso_erp; }
80
+ }
81
+
82
+ # Default — unknown host → 404 (no open proxy).
83
+ server {
84
+ listen 80 default_server;
85
+ server_name _;
86
+ return 404;
87
+ }
@@ -0,0 +1,23 @@
1
+ #!/bin/sh
2
+ # SSO edge render script (bug 96f8b2b2).
3
+ #
4
+ # Mounted as /docker-entrypoint.d/99-render-sso-edge.sh. The nginx:alpine base
5
+ # entrypoint runs every /docker-entrypoint.d/*.sh and THEN execs
6
+ # `nginx -g 'daemon off;'`, so this script only renders config — it must NOT
7
+ # exec nginx itself.
8
+ #
9
+ # Renders the templated server blocks from ${DOMAIN} only, mirroring the
10
+ # exe-auth gateway's start-time templating so no customer domain is baked in.
11
+ set -eu
12
+
13
+ : "${DOMAIN:?DOMAIN is required — set to your customer apex domain (e.g. hygo.co)}"
14
+
15
+ TEMPLATE=/etc/nginx/exe-templates/default.conf.template
16
+ TARGET=/etc/nginx/conf.d/default.conf
17
+
18
+ # Substitute ONLY ${DOMAIN}. All nginx runtime variables ($request_uri,
19
+ # $cookie_*, $arg_*, $sso_*, $host, $remote_addr, $proxy_add_x_forwarded_for,
20
+ # $http_upgrade, $sso_conn_upgrade) must survive envsubst untouched.
21
+ envsubst '${DOMAIN}' < "$TEMPLATE" > "$TARGET"
22
+
23
+ echo "[sso-edge] rendered default.conf for DOMAIN=${DOMAIN}"
@@ -0,0 +1,63 @@
1
+ # ─────────────────────────────────────────────────────────────────────────────
2
+ # Unified SSO redirect snippet (bug 66f8e10a)
3
+ #
4
+ # Funnels UNAUTHENTICATED visitors of an app subdomain (crm / wiki / erp) to the
5
+ # central auth gateway at auth.<domain>, then lets the gateway redirect them back
6
+ # with ?access_token=. Without this, each app serves its own login form and the
7
+ # advertised "single front door" does not exist.
8
+ #
9
+ # ── How it works ────────────────────────────────────────────────────────────
10
+ # 1. nginx checks for a session cookie that the app sets once authenticated.
11
+ # The cookie name differs per app (Twenty/CRM, Wiki, Frappe/ERP) — set it
12
+ # via $sso_session_cookie below.
13
+ # 2. If the cookie is ABSENT, nginx 302-redirects to:
14
+ # https://auth.<domain>/?product=<App>&redirect=https://<app>.<domain><uri>
15
+ # 3. The gateway authenticates against the shared GoTrue and bounces the user
16
+ # back to the app URL with ?access_token=<jwt>&refresh_token=<...>.
17
+ # 4. The app consumes the token (it already shares GoTrue) and sets its session
18
+ # cookie — subsequent requests carry the cookie and skip the redirect.
19
+ #
20
+ # ── Per-customer install ────────────────────────────────────────────────────
21
+ # These are templated values — replace before installing, or render with envsubst
22
+ # (DOMAIN, APP_NAME, APP_SUBDOMAIN, APP_SESSION_COOKIE):
23
+ #
24
+ # server {
25
+ # server_name crm.${DOMAIN};
26
+ # set $sso_auth_base "https://auth.${DOMAIN}";
27
+ # set $sso_app_url "https://crm.${DOMAIN}";
28
+ # set $sso_product "CRM";
29
+ # set $sso_session_cookie $cookie_tokenPair; # Twenty/CRM session cookie
30
+ # include /etc/nginx/snippets/sso-redirect.conf;
31
+ # location / { proxy_pass http://exe-crm:3000; }
32
+ # }
33
+ #
34
+ # For Wiki: set $sso_product "Wiki"; set $sso_session_cookie $cookie_wiki_session;
35
+ # proxy_pass http://exe-wiki:3001;
36
+ # For ERP: set $sso_product "ERP"; set $sso_session_cookie $cookie_sid;
37
+ # proxy_pass http://exe-erp:8000;
38
+ #
39
+ # NOTE: This is an EDGE-level gate (host nginx in front of the app). If you front
40
+ # the stack with Cloudflare Tunnel instead of host nginx, implement the same gate
41
+ # with Cloudflare Access (see sso-redirect.README.md) — cloudflared ingress alone
42
+ # cannot express a cookie-conditional redirect.
43
+ # ─────────────────────────────────────────────────────────────────────────────
44
+
45
+ # Decide whether the request is authenticated. If the app session cookie is
46
+ # present we treat the request as authenticated and do NOT redirect.
47
+ # $sso_session_cookie must be set by the including server block (default: empty).
48
+ set $sso_needs_login 1;
49
+ if ($sso_session_cookie) {
50
+ set $sso_needs_login 0;
51
+ }
52
+
53
+ # Never redirect the SSO callback itself (it carries ?access_token=) or static/
54
+ # health/API paths — only redirect top-level navigations.
55
+ if ($arg_access_token) {
56
+ set $sso_needs_login 0;
57
+ }
58
+
59
+ # Perform the redirect for unauthenticated top-level page loads.
60
+ # $request_uri preserves the path + query the user was trying to reach.
61
+ if ($sso_needs_login = 1) {
62
+ return 302 "$sso_auth_base/?product=$sso_product&redirect=$sso_app_url$request_uri";
63
+ }
@@ -1346,7 +1346,7 @@
1346
1346
  "breakingChanges": [],
1347
1347
  "services": {
1348
1348
  "exe-os": {
1349
- "image": "update.askexe.com/askexe/exe-os:v0.9.281@sha256:f5926c281b9f158063128daed39c1d296eec29e986e88ec33686440c177e5c4e",
1349
+ "image": "update.askexe.com/askexe/exe-os:v0.9.294@sha256:cb89b04278beafc1596dd7b7c0012cbb75ce58a8e4c0ea2c1ffa5efffd5a03d7",
1350
1350
  "env": "EXE_OS_IMAGE_TAG",
1351
1351
  "composeService": "exe-os",
1352
1352
  "healthUrl": "http://127.0.0.1:8765/health",
@@ -1408,7 +1408,7 @@
1408
1408
  "description": "Monitoring Dashboard"
1409
1409
  },
1410
1410
  "auth": {
1411
- "image": "update.askexe.com/askexe/exe-auth:v0.1.0@sha256:9203e855eb45635913cd6772eaaa49209a6c32468f56051f9fa0760817a30e7d",
1411
+ "image": "update.askexe.com/askexe/exe-auth:v0.1.1",
1412
1412
  "env": "AUTH_IMAGE_TAG",
1413
1413
  "composeService": "exe-auth",
1414
1414
  "healthUrl": "http://127.0.0.1:3300/",
@@ -0,0 +1,28 @@
1
+ import "./chunk-SH45SJQW.js";
2
+ import {
3
+ cleanupSessionMarkers,
4
+ clearActiveAgent,
5
+ getActiveAgent,
6
+ getAllActiveAgents,
7
+ resolveActiveAgentFromTmuxSession,
8
+ writeActiveAgent
9
+ } from "./chunk-AKV44JEH.js";
10
+ import "./chunk-CVYC6DUW.js";
11
+ import "./chunk-GJV3WDWM.js";
12
+ import "./chunk-WUKHLCBE.js";
13
+ import "./chunk-2I23RPSI.js";
14
+ import "./chunk-2E43UXRH.js";
15
+ import "./chunk-PNQDP3OA.js";
16
+ import "./chunk-7HLWBYH7.js";
17
+ import "./chunk-FXU7JOXK.js";
18
+ import "./chunk-R36FAN53.js";
19
+ import "./chunk-LYH5HE24.js";
20
+ import "./chunk-MLKGABMK.js";
21
+ export {
22
+ cleanupSessionMarkers,
23
+ clearActiveAgent,
24
+ getActiveAgent,
25
+ getAllActiveAgents,
26
+ resolveActiveAgentFromTmuxSession,
27
+ writeActiveAgent
28
+ };
@@ -0,0 +1,27 @@
1
+ import {
2
+ cleanupSessionMarkers,
3
+ clearActiveAgent,
4
+ getActiveAgent,
5
+ getAllActiveAgents,
6
+ resolveActiveAgentFromTmuxSession,
7
+ writeActiveAgent
8
+ } from "./chunk-AKV44JEH.js";
9
+ import "./chunk-CVYC6DUW.js";
10
+ import "./chunk-GJV3WDWM.js";
11
+ import "./chunk-WUKHLCBE.js";
12
+ import "./chunk-2I23RPSI.js";
13
+ import "./chunk-2E43UXRH.js";
14
+ import "./chunk-PNQDP3OA.js";
15
+ import "./chunk-7HLWBYH7.js";
16
+ import "./chunk-FXU7JOXK.js";
17
+ import "./chunk-R36FAN53.js";
18
+ import "./chunk-LYH5HE24.js";
19
+ import "./chunk-MLKGABMK.js";
20
+ export {
21
+ cleanupSessionMarkers,
22
+ clearActiveAgent,
23
+ getActiveAgent,
24
+ getAllActiveAgents,
25
+ resolveActiveAgentFromTmuxSession,
26
+ writeActiveAgent
27
+ };
@@ -0,0 +1,25 @@
1
+ import {
2
+ clean,
3
+ extractGoalCandidates,
4
+ inferIntention,
5
+ inferOntologyEventType,
6
+ inferOutcome,
7
+ inferSemanticLabel,
8
+ insertOntologyForBatch,
9
+ insertOntologyForMemory,
10
+ ontologyPayload,
11
+ stableId
12
+ } from "./chunk-465PQFTH.js";
13
+ import "./chunk-MLKGABMK.js";
14
+ export {
15
+ clean,
16
+ extractGoalCandidates,
17
+ inferIntention,
18
+ inferOntologyEventType,
19
+ inferOutcome,
20
+ inferSemanticLabel,
21
+ insertOntologyForBatch,
22
+ insertOntologyForMemory,
23
+ ontologyPayload,
24
+ stableId
25
+ };
@@ -40,8 +40,11 @@
40
40
  <!-- Environment -->
41
41
  <key>EnvironmentVariables</key>
42
42
  <dict>
43
+ <!-- Resolved at install time: the running node's bin dir is front-loaded so
44
+ the daemon and its children find node even when it lives in an
45
+ nvm/volta/fnm dir outside the system defaults (bug 19d3bfdb / 71adcb68). -->
43
46
  <key>PATH</key>
44
- <string>/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin</string>
47
+ <string>__PATH__</string>
45
48
  <key>HOME</key>
46
49
  <string>__HOME__</string>__EXE_EMBEDDINGS_ENV__
47
50
  </dict>