@askexenow/exe-os 0.9.239 → 0.9.244

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 (319) hide show
  1. package/deploy/compose/.env.customer.example +12 -0
  2. package/deploy/compose/.env.example +13 -1
  3. package/deploy/compose/cloudflared/config.yml.example +29 -5
  4. package/deploy/compose/docker-compose.yml +27 -7
  5. package/deploy/compose/generate-env.ts +49 -1
  6. package/deploy/compose/init-db.sql +10 -2
  7. package/deploy/stack-manifests/v0.9.json +113 -9
  8. package/dist/{active-agent-7MIVNARP.js → active-agent-KO4ZWDXE.js} +4 -4
  9. package/dist/{active-agent-55C5Y3XL.js → active-agent-KP2O52HA.js} +4 -4
  10. package/dist/{agentic-ontology-NCAQIQQI.js → agentic-ontology-DXE5J6I5.js} +1 -1
  11. package/dist/{backfill-metadata-3JP7EZ2U.js → backfill-metadata-DFTIGPXP.js} +7 -7
  12. package/dist/{background-jobs-RWL46VRD.js → background-jobs-CRXY7T4Y.js} +2 -2
  13. package/dist/{behaviors-6BGALYGW.js → behaviors-BL3QCHBT.js} +4 -4
  14. package/dist/bin/age-ontology-load.js +2 -2
  15. package/dist/bin/agentic-ontology-backfill.js +9 -9
  16. package/dist/bin/agentic-reflection-backfill.js +10 -10
  17. package/dist/bin/agentic-semantic-label.js +9 -9
  18. package/dist/bin/backfill-conversations.js +9 -9
  19. package/dist/bin/backfill-responses.js +9 -9
  20. package/dist/bin/backfill-vectors.js +11 -11
  21. package/dist/bin/bulk-sync-postgres.js +10 -10
  22. package/dist/bin/cc-doctor.js +3 -3
  23. package/dist/bin/cleanup-stale-review-tasks.js +13 -13
  24. package/dist/bin/cli.js +27 -22
  25. package/dist/bin/exe-agent-config.js +4 -4
  26. package/dist/bin/exe-agent.js +8 -8
  27. package/dist/bin/exe-assign.js +11 -11
  28. package/dist/bin/exe-boot.js +22 -22
  29. package/dist/bin/exe-call.js +5 -5
  30. package/dist/bin/exe-cloud.js +8 -8
  31. package/dist/bin/exe-dispatch.js +13 -13
  32. package/dist/bin/exe-doctor.js +1 -1
  33. package/dist/bin/exe-export-behaviors.js +10 -10
  34. package/dist/bin/exe-forget.js +9 -9
  35. package/dist/bin/exe-gateway.js +8 -8
  36. package/dist/bin/exe-healthcheck.js +3 -3
  37. package/dist/bin/exe-heartbeat.js +13 -13
  38. package/dist/bin/exe-kill.js +18 -18
  39. package/dist/bin/exe-launch-agent.js +22 -22
  40. package/dist/bin/exe-new-employee.js +8 -8
  41. package/dist/bin/exe-pending-messages.js +14 -14
  42. package/dist/bin/exe-pending-notifications.js +13 -13
  43. package/dist/bin/exe-pending-reviews.js +13 -13
  44. package/dist/bin/exe-rename.js +5 -5
  45. package/dist/bin/exe-review.js +17 -17
  46. package/dist/bin/exe-search.js +8 -8
  47. package/dist/bin/exe-session-cleanup.js +20 -20
  48. package/dist/bin/exe-settings.js +7 -7
  49. package/dist/bin/exe-start-codex.js +14 -14
  50. package/dist/bin/exe-start-opencode.js +11 -11
  51. package/dist/bin/exe-status.js +14 -14
  52. package/dist/bin/exe-support.js +3 -3
  53. package/dist/bin/exe-team.js +4 -4
  54. package/dist/bin/git-sweep.js +13 -13
  55. package/dist/bin/graph-backfill.js +8 -8
  56. package/dist/bin/graph-export.js +8 -8
  57. package/dist/bin/import-history.js +10 -10
  58. package/dist/bin/install.js +7 -7
  59. package/dist/bin/intercom-check.js +4 -4
  60. package/dist/bin/mcp-sessions.js +2 -2
  61. package/dist/bin/orchestration-metrics.js +5 -5
  62. package/dist/bin/postgres-agentic-reflection-backfill.js +4 -4
  63. package/dist/bin/postgres-agentic-semantic-backfill.js +3 -3
  64. package/dist/bin/registry-proxy.js +1 -1
  65. package/dist/bin/scan-tasks.js +13 -13
  66. package/dist/bin/setup.js +3 -3
  67. package/dist/bin/shard-migrate.js +8 -8
  68. package/dist/bin/stack-update.js +348 -20
  69. package/dist/bin/verify-stack.js +3 -383
  70. package/dist/bin/vps-backup.js +8 -160
  71. package/dist/bin/vps-health-gate.js +10 -220
  72. package/dist/{branding-I7YYX4FM.js → branding-XWMO5EDR.js} +1 -1
  73. package/dist/{capacity-monitor-IFCZKRPG.js → capacity-monitor-4CSBC7AP.js} +14 -14
  74. package/dist/{catchup-brief-PIDRWXOW.js → catchup-brief-LF5Z6Q6E.js} +17 -17
  75. package/dist/{chunk-FGJUGDNM.js → chunk-222SI7QC.js} +14 -14
  76. package/dist/{chunk-JZMVLAZ2.js → chunk-2WBBVEIB.js} +1 -1
  77. package/dist/{chunk-JDOE33C2.js → chunk-3V53HH5T.js} +4 -4
  78. package/dist/{chunk-2KZSKURT.js → chunk-57SULZJ2.js} +3 -3
  79. package/dist/{chunk-QI4IXJN7.js → chunk-5CHYEKMH.js} +7 -4
  80. package/dist/chunk-5DMAMQNU.js +168 -0
  81. package/dist/{chunk-PLQAFB3Z.js → chunk-5JIG2FP2.js} +1 -1
  82. package/dist/{chunk-UWQ3XCDG.js → chunk-5WK7X5CF.js} +2 -2
  83. package/dist/{chunk-DDPAQ4LT.js → chunk-6JAGJN77.js} +2 -2
  84. package/dist/{chunk-7F37NMKB.js → chunk-73UE2PHT.js} +1 -1
  85. package/dist/{chunk-JL3K5OTS.js → chunk-7IZWLMTP.js} +1 -1
  86. package/dist/{chunk-ELRRL2NC.js → chunk-A4K2ZT6N.js} +4 -4
  87. package/dist/{chunk-GWYADLIW.js → chunk-AHXEU5XB.js} +1 -1
  88. package/dist/{chunk-WSHMBME6.js → chunk-AWRL5FGM.js} +19 -78
  89. package/dist/{chunk-OMPCFLWA.js → chunk-BSPOEYAO.js} +1 -1
  90. package/dist/{chunk-F4TCKCKK.js → chunk-BYCNUKII.js} +47 -12
  91. package/dist/{chunk-DHVC4RN7.js → chunk-CBDPEJOR.js} +5 -5
  92. package/dist/{chunk-2H55BIV2.js → chunk-CEJO7244.js} +2 -2
  93. package/dist/{chunk-FKWZVO2T.js → chunk-CPXGLSIL.js} +3 -3
  94. package/dist/{chunk-HX5G4AS4.js → chunk-CWITU7DW.js} +2 -2
  95. package/dist/{chunk-5GG7MTRJ.js → chunk-DGBGIXCC.js} +4 -4
  96. package/dist/{chunk-IQXPMK46.js → chunk-DLZYAYVM.js} +60 -14
  97. package/dist/{chunk-PPYWQV2M.js → chunk-DR5BGWFR.js} +2 -2
  98. package/dist/{chunk-BZWKTFEB.js → chunk-ENVRFBTB.js} +2 -2
  99. package/dist/{chunk-DUVO2PUJ.js → chunk-F3GM6OOP.js} +4 -4
  100. package/dist/{chunk-HNLPLLE6.js → chunk-F7JLZXHC.js} +60 -26
  101. package/dist/{chunk-AL4DRC5H.js → chunk-FFLILAG6.js} +1 -1
  102. package/dist/{chunk-BZNI4OK5.js → chunk-GHEWRYMY.js} +18 -2
  103. package/dist/{chunk-C7SFJO5F.js → chunk-GHT4REOS.js} +5 -5
  104. package/dist/{chunk-FBWUJEXS.js → chunk-HANG6NLF.js} +4 -6
  105. package/dist/{chunk-5NJ4A4ZA.js → chunk-HCBMPZDT.js} +1 -1
  106. package/dist/chunk-HOGTZLVU.js +244 -0
  107. package/dist/{chunk-IQSCZDBQ.js → chunk-I5PIBL56.js} +3 -3
  108. package/dist/chunk-IRHNV4GY.js +388 -0
  109. package/dist/{chunk-4HROS3GJ.js → chunk-IZVKWBIP.js} +1 -1
  110. package/dist/{chunk-DKI5BTBC.js → chunk-J7V7LPPX.js} +2 -2
  111. package/dist/{chunk-TOZ5NN5V.js → chunk-JLKUVK5J.js} +1 -1
  112. package/dist/{chunk-4SC65UBG.js → chunk-JLNXKG3K.js} +1 -1
  113. package/dist/{chunk-KVSQOG3W.js → chunk-K2BDE2B5.js} +4 -4
  114. package/dist/{chunk-KDJRFJDL.js → chunk-K333WOW4.js} +30 -2
  115. package/dist/{chunk-6LBCUA2A.js → chunk-KEZXW3RP.js} +1 -1
  116. package/dist/{chunk-W7G3GY4I.js → chunk-KLQI7QY4.js} +3 -3
  117. package/dist/{chunk-UODVZGBQ.js → chunk-KN7LPTIB.js} +1 -1
  118. package/dist/{chunk-ESKBZN4Q.js → chunk-L4WRH3DL.js} +1 -1
  119. package/dist/{chunk-VFQKKMKE.js → chunk-LAOB5BKV.js} +2 -2
  120. package/dist/{chunk-MAN5LZQ4.js → chunk-LQSFP2BV.js} +1 -1
  121. package/dist/{chunk-EJ7LOTV2.js → chunk-LSFHEMVI.js} +9 -9
  122. package/dist/{chunk-RA2RO27E.js → chunk-MCESA5UW.js} +2 -2
  123. package/dist/{chunk-UPMHG7ET.js → chunk-MEIHREPM.js} +1 -1
  124. package/dist/{chunk-D5C56WO3.js → chunk-MOZ2YQ54.js} +1 -1
  125. package/dist/{chunk-CLGB3FGL.js → chunk-MPX3TRMQ.js} +2 -2
  126. package/dist/{chunk-5R75ODPS.js → chunk-NBY6R37W.js} +61 -232
  127. package/dist/{chunk-RWFGXC35.js → chunk-NEYQAEYU.js} +7 -7
  128. package/dist/{chunk-MBHZDXGN.js → chunk-NL35XNLI.js} +1 -1
  129. package/dist/{chunk-TPQVLYSV.js → chunk-NLGMHPEN.js} +1 -1
  130. package/dist/{chunk-5LMH4YHG.js → chunk-NRVV4Y5V.js} +4 -4
  131. package/dist/{chunk-GN5VHPPR.js → chunk-NVZR7T4E.js} +1 -1
  132. package/dist/{chunk-Y2L7RMGH.js → chunk-NWBHL5PI.js} +1 -1
  133. package/dist/{chunk-YPYDLW75.js → chunk-OEMX65EA.js} +1 -1
  134. package/dist/{chunk-UAFUGPKO.js → chunk-ONAQAL3O.js} +1 -1
  135. package/dist/{chunk-AVM7XZE4.js → chunk-OWQ3CCYJ.js} +7 -6
  136. package/dist/{chunk-K525WLL7.js → chunk-PI6V23GF.js} +5 -4
  137. package/dist/{chunk-AURM7FOT.js → chunk-Q2OAQPWY.js} +1 -1
  138. package/dist/{chunk-FB5VRO5S.js → chunk-QLDWASTX.js} +28 -32
  139. package/dist/{chunk-EPWDTS2Q.js → chunk-QMTGMCWB.js} +1 -1
  140. package/dist/{chunk-VI2FJY2M.js → chunk-QP4FHME2.js} +2 -2
  141. package/dist/{chunk-NJWK6J4N.js → chunk-QUNKPR6Y.js} +5 -5
  142. package/dist/{chunk-O6DAF2TY.js → chunk-QUZVAHO7.js} +2 -2
  143. package/dist/{chunk-VHKL4S4T.js → chunk-RRHSONV5.js} +2 -2
  144. package/dist/{chunk-GPF6X6HE.js → chunk-RYDHEWYY.js} +2 -2
  145. package/dist/{chunk-SVXDCELZ.js → chunk-SHN5O73O.js} +32 -4
  146. package/dist/chunk-TD5CADZ5.js +230 -0
  147. package/dist/{chunk-C2YS2AA6.js → chunk-U7WOVXBB.js} +2 -2
  148. package/dist/{chunk-FE45RXGC.js → chunk-V2GZMY6O.js} +1 -1
  149. package/dist/{chunk-PATCHPNY.js → chunk-VHALWCUO.js} +1 -1
  150. package/dist/{chunk-HLZSC5WK.js → chunk-VQAP35DA.js} +20 -18
  151. package/dist/{chunk-452XB7OZ.js → chunk-VRIMTCX2.js} +1 -1
  152. package/dist/{chunk-SUNYJ6YE.js → chunk-VT2B5BHM.js} +1 -1
  153. package/dist/{chunk-UZIJDYDA.js → chunk-VWVJVQDH.js} +2 -2
  154. package/dist/{chunk-TRZ5KA2R.js → chunk-VXIMSRTO.js} +2 -2
  155. package/dist/{chunk-DAZIV4QZ.js → chunk-WCXZF42W.js} +1 -1
  156. package/dist/{chunk-6OJJF4WP.js → chunk-XJUUWHVN.js} +1 -1
  157. package/dist/{chunk-F7LU65PQ.js → chunk-Y25OJWOQ.js} +14 -2
  158. package/dist/{chunk-2ORPA23Y.js → chunk-YMXXD2GW.js} +36 -8
  159. package/dist/{chunk-5WLMF6PL.js → chunk-YMZHTTOQ.js} +1 -1
  160. package/dist/{chunk-7DIDOQCX.js → chunk-YRVW57UW.js} +139 -125
  161. package/dist/{chunk-BRFH5X7G.js → chunk-Z7VDUS6L.js} +1 -1
  162. package/dist/{chunk-YFE6W75D.js → chunk-ZKFPHJIJ.js} +1 -1
  163. package/dist/{chunk-5WUTKDH6.js → chunk-ZVXJSQOR.js} +1 -1
  164. package/dist/{co-activation-VB4CJQZB.js → co-activation-L6I2LSJO.js} +3 -3
  165. package/dist/{co-occurrence-XZQJJIBM.js → co-occurrence-QARWYUAY.js} +3 -3
  166. package/dist/{code-context-index-FCQOPUEA.js → code-context-index-UIYQRDHD.js} +4 -4
  167. package/dist/{content-extractor-SPSH5X33.js → content-extractor-EYRVGD6O.js} +2 -2
  168. package/dist/{conversation-wiki-populator-YU35LNRK.js → conversation-wiki-populator-L7O6F3BB.js} +1 -1
  169. package/dist/{crdt-sync-KXETGV45.js → crdt-sync-R6YROKDH.js} +1 -1
  170. package/dist/{crm-webhook-JMOAHTJ6.js → crm-webhook-WK3PYJJK.js} +2 -2
  171. package/dist/{cto-delegation-gate-IJ3KQIKF.js → cto-delegation-gate-5JZORQIT.js} +12 -12
  172. package/dist/{daemon-auth-2IZACWSG.js → daemon-auth-2HEOL6VG.js} +2 -2
  173. package/dist/{daemon-orchestration-ZCY4GEI3.js → daemon-orchestration-BJ3T5MMF.js} +16 -15
  174. package/dist/{db-backup-HLX5OLIV.js → db-backup-EWS52P2W.js} +2 -2
  175. package/dist/{dreaming-2CJML3TU.js → dreaming-BOSBDRI3.js} +13 -13
  176. package/dist/{entity-boost-T5IYWWDZ.js → entity-boost-6ZVX7DFB.js} +26 -2
  177. package/dist/{exe-drift-P5OIRNSH.js → exe-drift-WRE6RADZ.js} +4 -4
  178. package/dist/{exe-export-QQL2H322.js → exe-export-7N5PBCMK.js} +8 -8
  179. package/dist/{exe-import-V4RJCUEP.js → exe-import-YOOE7S3H.js} +8 -8
  180. package/dist/{exe-key-MENJGDD7.js → exe-key-GXJSTCX2.js} +4 -4
  181. package/dist/{exe-org-3FNET2J7.js → exe-org-42YMQL75.js} +2 -2
  182. package/dist/{exe-snapshot-YRARQE7F.js → exe-snapshot-ODUCFW7G.js} +18 -18
  183. package/dist/{fast-db-init-HIJWWKAO.js → fast-db-init-YSR7RMVZ.js} +1 -1
  184. package/dist/{founder-context-BQ5NBDUV.js → founder-context-Q2HUCZX4.js} +2 -2
  185. package/dist/gateway/index.js +9 -9
  186. package/dist/{gateway-client-YGSA5QMC.js → gateway-client-4QXHKN5C.js} +1 -1
  187. package/dist/{git-staleness-IHTKCUMN.js → git-staleness-BJDTCDPC.js} +3 -3
  188. package/dist/{git-task-sweep-5ZPNQS7Y.js → git-task-sweep-L3U3T5HM.js} +13 -13
  189. package/dist/{global-procedures-XHDIZRJU.js → global-procedures-HCHEHKY2.js} +4 -4
  190. package/dist/{graph-auto-extract-5TPT67GP.js → graph-auto-extract-FP5C76LS.js} +3 -3
  191. package/dist/{hook-integrity-SB53Y7UK.js → hook-integrity-2OU3T6UC.js} +1 -1
  192. package/dist/hooks/bug-report-worker.js +15 -14
  193. package/dist/hooks/codex-stop-task-finalizer.js +15 -14
  194. package/dist/hooks/commit-complete.js +16 -16
  195. package/dist/hooks/error-recall.js +10 -10
  196. package/dist/hooks/exe-heartbeat-hook.js +5 -5
  197. package/dist/hooks/ingest-worker.js +8 -8
  198. package/dist/hooks/ingest.js +13 -13
  199. package/dist/hooks/instructions-loaded.js +7 -7
  200. package/dist/hooks/manifest.json +20 -20
  201. package/dist/hooks/notification.js +6 -6
  202. package/dist/hooks/post-compact.js +15 -15
  203. package/dist/hooks/post-tool-combined.js +7 -7
  204. package/dist/hooks/pre-compact.js +20 -20
  205. package/dist/hooks/pre-tool-use.js +28 -25
  206. package/dist/hooks/prompt-submit.js +62 -31
  207. package/dist/hooks/session-end.js +26 -26
  208. package/dist/hooks/session-start.js +39 -15
  209. package/dist/hooks/stop.js +22 -22
  210. package/dist/hooks/subagent-stop.js +15 -15
  211. package/dist/hooks/summary-worker.js +32 -27
  212. package/dist/index.js +21 -21
  213. package/dist/{installer-AMZM4MLS.js → installer-AWMUCRN4.js} +7 -7
  214. package/dist/{installer-KT5FW4CN.js → installer-HB3NH6FG.js} +9 -9
  215. package/dist/{installer-HW74W3IT.js → installer-RU6EVOBL.js} +6 -6
  216. package/dist/{intercom-queue-RNM6EPGA.js → intercom-queue-A6UJEFIF.js} +1 -1
  217. package/dist/{key-backup-status-OZ2CXUDW.js → key-backup-status-4YKCV4ZV.js} +1 -1
  218. package/dist/lib/agent-config.js +2 -2
  219. package/dist/lib/cloud-sync.js +10 -8
  220. package/dist/lib/config.js +1 -1
  221. package/dist/lib/consolidation.js +8 -8
  222. package/dist/lib/database.js +3 -3
  223. package/dist/lib/db-daemon-client.js +3 -3
  224. package/dist/lib/db.js +3 -3
  225. package/dist/lib/device-registry.js +1 -1
  226. package/dist/lib/embedder.js +4 -4
  227. package/dist/lib/employee-templates.js +5 -5
  228. package/dist/lib/employees.js +3 -3
  229. package/dist/lib/exe-daemon-client.js +3 -3
  230. package/dist/lib/exe-daemon.js +105 -74
  231. package/dist/lib/hybrid-search.js +8 -8
  232. package/dist/lib/identity.js +3 -3
  233. package/dist/lib/keychain.js +1 -1
  234. package/dist/lib/license.js +2 -2
  235. package/dist/lib/messaging.js +13 -13
  236. package/dist/lib/post-tool-memory.js +3 -3
  237. package/dist/lib/registry-proxy.js +1 -1
  238. package/dist/lib/reminders.js +4 -4
  239. package/dist/lib/schedules.js +8 -8
  240. package/dist/lib/session-registry.js +5 -5
  241. package/dist/lib/skill-learning.js +5 -5
  242. package/dist/lib/store.js +7 -7
  243. package/dist/lib/task-router.js +4 -4
  244. package/dist/lib/tasks.js +14 -13
  245. package/dist/lib/tmux-routing.js +12 -12
  246. package/dist/lib/token-spend.js +4 -4
  247. package/dist/lib/ws-client.js +1 -1
  248. package/dist/{license-gate-XJDIL6OZ.js → license-gate-6JQQFBHS.js} +3 -3
  249. package/dist/mcp/register-tools.js +68 -67
  250. package/dist/mcp/server.js +70 -69
  251. package/dist/mcp/tools/complete-reminder.js +5 -5
  252. package/dist/mcp/tools/create-reminder.js +5 -5
  253. package/dist/mcp/tools/create-task.js +16 -15
  254. package/dist/mcp/tools/deactivate-behavior.js +6 -6
  255. package/dist/mcp/tools/list-reminders.js +5 -5
  256. package/dist/mcp/tools/list-tasks.js +16 -15
  257. package/dist/mcp/tools/send-message.js +15 -15
  258. package/dist/mcp/tools/update-task.js +15 -14
  259. package/dist/{mcp-http-config-BXX3RZPR.js → mcp-http-config-XIJR5P2Z.js} +4 -4
  260. package/dist/{memory-cards-KRTP5GFM.js → memory-cards-H4BJJ5OK.js} +3 -3
  261. package/dist/{memory-graph-extractor-G532PUHC.js → memory-graph-extractor-SDGM3GVR.js} +4 -4
  262. package/dist/{memory-poisoning-defense-HJM3FQA3.js → memory-poisoning-defense-UVU67DGJ.js} +3 -3
  263. package/dist/{memory-queue-FTNBWLS4.js → memory-queue-FNT5WHXP.js} +2 -2
  264. package/dist/{memory-queue-client-DHSHEIHQ.js → memory-queue-client-JZCFYTWQ.js} +5 -5
  265. package/dist/{memory-reflection-RANRFUQL.js → memory-reflection-GGB5K35L.js} +3 -3
  266. package/dist/{notifications-4P2PVEOT.js → notifications-P3XQZDTH.js} +12 -12
  267. package/dist/{orchestration-events-IYTASMSN.js → orchestration-events-25WEKUKH.js} +4 -4
  268. package/dist/{orchestration-phase-SGA7PJ5G.js → orchestration-phase-C26XVKLZ.js} +2 -2
  269. package/dist/{orchestrator-VKVHZ4MV.js → orchestrator-VIXTY4E4.js} +14 -14
  270. package/dist/{pipeline-router-E4L5BDXN.js → pipeline-router-S5PE5U6B.js} +4 -4
  271. package/dist/{plan-limits-5O5QG55H.js → plan-limits-DGIVM42H.js} +5 -5
  272. package/dist/{prediction-log-OMWHW7FL.js → prediction-log-DOEOHDHS.js} +1 -1
  273. package/dist/{project-boot-WMI6CWRX.js → project-boot-4ZL2W7DN.js} +12 -2
  274. package/dist/{projection-worker-54KRNQSO.js → projection-worker-GG2W5OM3.js} +3 -3
  275. package/dist/{push-notifications-E2XXEWJZ.js → push-notifications-AMHVR6DF.js} +2 -2
  276. package/dist/{reranker-4NTUFNYT.js → reranker-UCPLQZE2.js} +2 -2
  277. package/dist/{review-polling-BFRJDLUA.js → review-polling-P2MWEXLR.js} +13 -13
  278. package/dist/runtime/index.js +15 -15
  279. package/dist/{session-events-KCZCWGE4.js → session-events-5CD66R6U.js} +13 -13
  280. package/dist/{session-kill-telemetry-TMNIDYWY.js → session-kill-telemetry-7FBHTEDN.js} +4 -4
  281. package/dist/{session-scope-DRZBQ32Y.js → session-scope-VMIPAZU7.js} +12 -12
  282. package/dist/{setup-wizard-TQKGDAHO.js → setup-wizard-BNR47URR.js} +3 -3
  283. package/dist/{shard-manager-G6MHCO7X.js → shard-manager-VGA2TYHM.js} +2 -2
  284. package/dist/{skill-refinement-Z5SWD3AM.js → skill-refinement-NRG4WWRW.js} +3 -3
  285. package/dist/stack-release-PFZI22WC.js +521 -0
  286. package/dist/{stack-update-NO5MNARG.js → stack-update-7F2E2MBJ.js} +3 -3
  287. package/dist/{steward-gate-7DWYS5AT.js → steward-gate-L7DJMF4C.js} +4 -4
  288. package/dist/{task-enforcement-2VL5J6JJ.js → task-enforcement-XQL77PZH.js} +52 -12
  289. package/dist/{task-scope-YHALISIB.js → task-scope-R3XKBIHL.js} +12 -12
  290. package/dist/{tasks-crud-JXZEBZFR.js → tasks-crud-DQOG2NPG.js} +12 -12
  291. package/dist/tasks-notify-4EQYG52H.js +37 -0
  292. package/dist/{tasks-review-PGPYJQF5.js → tasks-review-XPFJ4DSJ.js} +12 -12
  293. package/dist/{telemetry-upload-H7OJNBIF.js → telemetry-upload-OT5B5HUY.js} +7 -7
  294. package/dist/{token-budget-JJ7JQIA2.js → token-budget-D2LQKCAV.js} +3 -3
  295. package/dist/{tool-capability-index-WIV4K3FB.js → tool-capability-index-FAJ5ZHDF.js} +1 -1
  296. package/dist/{tool-telemetry-W4LFCHFT.js → tool-telemetry-QIF5BCLF.js} +1 -1
  297. package/dist/tui/App.js +26 -26
  298. package/dist/{tui-data-72U6N2DC.js → tui-data-UEV2QOR3.js} +108 -12
  299. package/dist/{whatsapp-config-W63RQ3AU.js → whatsapp-config-GOSELKTE.js} +7 -0
  300. package/dist/{worker-gate-SCSN6IHI.js → worker-gate-PRCKA23W.js} +2 -2
  301. package/dist/{workflow-engine-OICYBE4F.js → workflow-engine-7X6LLH3M.js} +2 -2
  302. package/dist/{worktree-JXN4RCWC.js → worktree-RICSCT2S.js} +5 -5
  303. package/package.json +1 -1
  304. package/release-notes.json +210 -298
  305. package/stack.release.json +4 -3
  306. package/dist/preflight-EAH2MI76.js +0 -287
  307. /package/dist/{chunk-H42LEGLB.js → chunk-AQBEG33D.js} +0 -0
  308. /package/dist/{chunk-AU5426YP.js → chunk-B7JGEDVE.js} +0 -0
  309. /package/dist/{chunk-YFDDTHNM.js → chunk-JXI4XUTV.js} +0 -0
  310. /package/dist/{chunk-SNYDRHV3.js → chunk-U3DUFHOT.js} +0 -0
  311. /package/dist/{chunk-N2XUH2HQ.js → chunk-VBPC7IC7.js} +0 -0
  312. /package/dist/{chunk-HTUJBTBM.js → chunk-VUS6WXQ3.js} +0 -0
  313. /package/dist/{chunk-NOLIN2YI.js → chunk-XAYRZHLV.js} +0 -0
  314. /package/dist/{core-memory-VOBGGB2Q.js → core-memory-4KAIKQRQ.js} +0 -0
  315. /package/dist/{message-queue-client-KAJN6TIJ.js → message-queue-client-S6W5VMJV.js} +0 -0
  316. /package/dist/{oauth-server-QEXRSXEP.js → oauth-server-2ESBZB7F.js} +0 -0
  317. /package/dist/{webhook-pipe-LY4XEDL7.js → webhook-pipe-ZRUVOG5H.js} +0 -0
  318. /package/dist/{wiki-acl-M3OR547L.js → wiki-acl-MFLSS6DE.js} +0 -0
  319. /package/dist/{wiki-client-MAFYBXCQ.js → wiki-client-GBPR45BQ.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fastDbInit
4
- } from "../chunk-H42LEGLB.js";
4
+ } from "../chunk-AQBEG33D.js";
5
5
  import "../chunk-MLKGABMK.js";
6
6
 
7
7
  // src/bin/intercom-check.ts
@@ -17,7 +17,7 @@ async function main() {
17
17
  }
18
18
  if (isCoordinator) {
19
19
  try {
20
- const { listPendingReviews, cleanupOrphanedReviews, formatAge, isStale } = await import("../tasks-review-PGPYJQF5.js");
20
+ const { listPendingReviews, cleanupOrphanedReviews, formatAge, isStale } = await import("../tasks-review-XPFJ4DSJ.js");
21
21
  const { extractRootExe } = await import("../lib/tmux-routing.js");
22
22
  let sessionScope = process.env.EXE_SESSION ? extractRootExe(process.env.EXE_SESSION) ?? void 0 : void 0;
23
23
  if (!sessionScope) {
@@ -94,7 +94,7 @@ async function main() {
94
94
  }
95
95
  if (!isCoordinator) {
96
96
  try {
97
- const { listBehaviors } = await import("../behaviors-6BGALYGW.js");
97
+ const { listBehaviors } = await import("../behaviors-BL3QCHBT.js");
98
98
  const sessionStart = process.env.EXE_SESSION_START_ISO ?? "";
99
99
  if (sessionStart) {
100
100
  const behaviors = await listBehaviors(agent);
@@ -113,7 +113,7 @@ async function main() {
113
113
  }
114
114
  }
115
115
  try {
116
- const { readUnreadNotifications, markAsRead } = await import("../notifications-4P2PVEOT.js");
116
+ const { readUnreadNotifications, markAsRead } = await import("../notifications-P3XQZDTH.js");
117
117
  const { resolveExeSession } = await import("../lib/tmux-routing.js");
118
118
  const sessionScope = resolveExeSession();
119
119
  const notifications = await readUnreadNotifications(agent, sessionScope);
@@ -45,10 +45,10 @@ async function collectSessions() {
45
45
  const registryMap = new Map(registry.map((r) => [r.windowName, r]));
46
46
  const taskMap = /* @__PURE__ */ new Map();
47
47
  try {
48
- const { fastDbInit } = await import("../fast-db-init-HIJWWKAO.js");
48
+ const { fastDbInit } = await import("../fast-db-init-YSR7RMVZ.js");
49
49
  await fastDbInit();
50
50
  const { getClient } = await import("../lib/database.js");
51
- const { sessionScopeFilter } = await import("../task-scope-YHALISIB.js");
51
+ const { sessionScopeFilter } = await import("../task-scope-R3XKBIHL.js");
52
52
  const client = getClient();
53
53
  const scope = sessionScopeFilter();
54
54
  const result = await client.execute({
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fastDbInit
4
- } from "../chunk-H42LEGLB.js";
4
+ } from "../chunk-AQBEG33D.js";
5
5
  import {
6
6
  formatOrchestrationMetrics,
7
7
  getOrchestrationMetrics
8
- } from "../chunk-5NJ4A4ZA.js";
9
- import "../chunk-2H55BIV2.js";
10
- import "../chunk-WSHMBME6.js";
8
+ } from "../chunk-HCBMPZDT.js";
9
+ import "../chunk-CEJO7244.js";
10
+ import "../chunk-AWRL5FGM.js";
11
11
  import "../chunk-FXU7JOXK.js";
12
- import "../chunk-TRZ5KA2R.js";
12
+ import "../chunk-VXIMSRTO.js";
13
13
  import "../chunk-LYH5HE24.js";
14
14
  import {
15
15
  isMainModule
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  buildReflectionCheckpoint
4
- } from "../chunk-YPYDLW75.js";
5
- import "../chunk-NOLIN2YI.js";
4
+ } from "../chunk-OEMX65EA.js";
5
+ import "../chunk-XAYRZHLV.js";
6
6
  import {
7
7
  pgSslConfig
8
8
  } from "../chunk-EQSQ4HBW.js";
9
9
  import {
10
10
  politeBatchPause,
11
11
  startManagedJob
12
- } from "../chunk-BRFH5X7G.js";
13
- import "../chunk-TRZ5KA2R.js";
12
+ } from "../chunk-Z7VDUS6L.js";
13
+ import "../chunk-VXIMSRTO.js";
14
14
  import "../chunk-LYH5HE24.js";
15
15
  import "../chunk-MLKGABMK.js";
16
16
 
@@ -2,15 +2,15 @@
2
2
  import {
3
3
  inferSemanticLabel,
4
4
  stableId
5
- } from "../chunk-NOLIN2YI.js";
5
+ } from "../chunk-XAYRZHLV.js";
6
6
  import {
7
7
  pgSslConfig
8
8
  } from "../chunk-EQSQ4HBW.js";
9
9
  import {
10
10
  politeBatchPause,
11
11
  startManagedJob
12
- } from "../chunk-BRFH5X7G.js";
13
- import "../chunk-TRZ5KA2R.js";
12
+ } from "../chunk-Z7VDUS6L.js";
13
+ import "../chunk-VXIMSRTO.js";
14
14
  import "../chunk-LYH5HE24.js";
15
15
  import "../chunk-MLKGABMK.js";
16
16
 
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  registryProxyOptionsFromEnv,
4
4
  runRegistryProxy
5
- } from "../chunk-SVXDCELZ.js";
5
+ } from "../chunk-SHN5O73O.js";
6
6
  import {
7
7
  isMainModule
8
8
  } from "../chunk-6Y4B3QF6.js";
@@ -1,31 +1,31 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  queryTaskRows
4
- } from "../chunk-HNLPLLE6.js";
5
- import "../chunk-YFE6W75D.js";
6
- import "../chunk-QI4IXJN7.js";
4
+ } from "../chunk-F7JLZXHC.js";
5
+ import "../chunk-ZKFPHJIJ.js";
6
+ import "../chunk-5CHYEKMH.js";
7
7
  import "../chunk-4JERP7NT.js";
8
- import "../chunk-BZNI4OK5.js";
8
+ import "../chunk-GHEWRYMY.js";
9
9
  import "../chunk-MVW62NIZ.js";
10
10
  import "../chunk-OYNKIAVW.js";
11
11
  import "../chunk-CX6GL3ZJ.js";
12
- import "../chunk-5NJ4A4ZA.js";
13
- import "../chunk-6OJJF4WP.js";
12
+ import "../chunk-HCBMPZDT.js";
13
+ import "../chunk-XJUUWHVN.js";
14
14
  import "../chunk-NGP6LSV2.js";
15
- import "../chunk-IQSCZDBQ.js";
15
+ import "../chunk-I5PIBL56.js";
16
16
  import {
17
17
  getSessionRuntime
18
18
  } from "../chunk-CVYC6DUW.js";
19
19
  import "../chunk-OPU3NYOO.js";
20
20
  import "../chunk-GJV3WDWM.js";
21
21
  import "../chunk-MP2AFCGL.js";
22
- import "../chunk-4SC65UBG.js";
22
+ import "../chunk-JLNXKG3K.js";
23
23
  import "../chunk-HYZV25LY.js";
24
- import "../chunk-2H55BIV2.js";
25
- import "../chunk-WSHMBME6.js";
24
+ import "../chunk-CEJO7244.js";
25
+ import "../chunk-AWRL5FGM.js";
26
26
  import "../chunk-FXU7JOXK.js";
27
- import "../chunk-D5C56WO3.js";
28
- import "../chunk-TRZ5KA2R.js";
27
+ import "../chunk-MOZ2YQ54.js";
28
+ import "../chunk-VXIMSRTO.js";
29
29
  import "../chunk-LYH5HE24.js";
30
30
  import {
31
31
  isMainModule
@@ -73,7 +73,7 @@ function checkMcpHealth() {
73
73
  }
74
74
  }
75
75
  async function scanFromDb(agentId, tmuxSession, projectName) {
76
- const { fastDbInit } = await import("../fast-db-init-HIJWWKAO.js");
76
+ const { fastDbInit } = await import("../fast-db-init-YSR7RMVZ.js");
77
77
  try {
78
78
  await fastDbInit();
79
79
  } catch (err) {
package/dist/bin/setup.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runSetupWizard
4
- } from "../chunk-DHVC4RN7.js";
5
- import "../chunk-KDJRFJDL.js";
6
- import "../chunk-TRZ5KA2R.js";
4
+ } from "../chunk-CBDPEJOR.js";
5
+ import "../chunk-K333WOW4.js";
6
+ import "../chunk-VXIMSRTO.js";
7
7
  import "../chunk-LYH5HE24.js";
8
8
  import "../chunk-MLKGABMK.js";
9
9
 
@@ -4,24 +4,24 @@ import {
4
4
  getReadyShardClient,
5
5
  getShardsDir,
6
6
  initShardManager
7
- } from "../chunk-2ORPA23Y.js";
7
+ } from "../chunk-YMXXD2GW.js";
8
8
  import {
9
9
  disposeStore,
10
10
  initStore
11
- } from "../chunk-FGJUGDNM.js";
11
+ } from "../chunk-222SI7QC.js";
12
12
  import "../chunk-CHCA3ZM2.js";
13
- import "../chunk-4HROS3GJ.js";
14
- import "../chunk-F7LU65PQ.js";
13
+ import "../chunk-IZVKWBIP.js";
14
+ import "../chunk-Y25OJWOQ.js";
15
15
  import "../chunk-MP2AFCGL.js";
16
16
  import {
17
17
  getClient
18
- } from "../chunk-2H55BIV2.js";
19
- import "../chunk-WSHMBME6.js";
18
+ } from "../chunk-CEJO7244.js";
19
+ import "../chunk-AWRL5FGM.js";
20
20
  import "../chunk-FXU7JOXK.js";
21
21
  import {
22
22
  getMasterKey
23
- } from "../chunk-KDJRFJDL.js";
24
- import "../chunk-TRZ5KA2R.js";
23
+ } from "../chunk-K333WOW4.js";
24
+ import "../chunk-VXIMSRTO.js";
25
25
  import "../chunk-LYH5HE24.js";
26
26
  import "../chunk-MLKGABMK.js";
27
27
 
@@ -10,9 +10,19 @@ import {
10
10
  loadStackManifest,
11
11
  patchEnv,
12
12
  runStackUpdate
13
- } from "../chunk-F4TCKCKK.js";
14
- import "../chunk-D5C56WO3.js";
15
- import "../chunk-TRZ5KA2R.js";
13
+ } from "../chunk-BYCNUKII.js";
14
+ import {
15
+ runVerifyStack
16
+ } from "../chunk-IRHNV4GY.js";
17
+ import {
18
+ preDeployBackup
19
+ } from "../chunk-5DMAMQNU.js";
20
+ import {
21
+ logResult,
22
+ runHealthGate
23
+ } from "../chunk-TD5CADZ5.js";
24
+ import "../chunk-MOZ2YQ54.js";
25
+ import "../chunk-VXIMSRTO.js";
16
26
  import "../chunk-LYH5HE24.js";
17
27
  import {
18
28
  isMainModule
@@ -20,10 +30,304 @@ import {
20
30
  import "../chunk-MLKGABMK.js";
21
31
 
22
32
  // src/bin/stack-update.ts
23
- import { readFileSync } from "fs";
33
+ import { readFileSync as readFileSync2 } from "fs";
34
+ import { spawnSync as spawnSync2 } from "child_process";
35
+ import path2 from "path";
36
+ import { existsSync as existsSync2 } from "fs";
37
+
38
+ // src/bin/preflight.ts
39
+ import { existsSync, readFileSync, writeFileSync } from "fs";
24
40
  import { spawnSync } from "child_process";
25
41
  import path from "path";
26
- import { existsSync } from "fs";
42
+ var REQUIRED_ENV_VARS = [
43
+ "POSTGRES_USER",
44
+ "POSTGRES_PASSWORD",
45
+ "POSTGRES_DB",
46
+ "GOTRUE_JWT_SECRET",
47
+ "EXE_LICENSE_KEY",
48
+ "EXED_MCP_TOKEN",
49
+ "EXE_GATEWAY_AUTH_TOKEN",
50
+ "EXE_GATEWAY_WHATSAPP_VERIFY_TOKEN",
51
+ "WIKI_AUTH_TOKEN",
52
+ "WIKI_JWT_SECRET",
53
+ "WIKI_SIG_KEY",
54
+ "WIKI_SIG_SALT",
55
+ "REDIS_PASSWORD",
56
+ "CLICKHOUSE_PASSWORD",
57
+ "CRM_APP_SECRET"
58
+ ];
59
+ var CONDITIONAL_ENV_VARS = [
60
+ {
61
+ key: "ANTHROPIC_API_KEY",
62
+ condition: (env) => env.get("BYOK_ENABLED") === "true",
63
+ reason: "BYOK_ENABLED=true requires ANTHROPIC_API_KEY"
64
+ },
65
+ {
66
+ key: "API_ROUTER_URL",
67
+ condition: (env) => env.get("BYOK_ENABLED") !== "true",
68
+ reason: "API Router mode (BYOK_ENABLED!=true) requires API_ROUTER_URL"
69
+ },
70
+ {
71
+ key: "API_ROUTER_KEY",
72
+ condition: (env) => env.get("BYOK_ENABLED") !== "true",
73
+ reason: "API Router mode (BYOK_ENABLED!=true) requires API_ROUTER_KEY"
74
+ }
75
+ ];
76
+ var VOLUME_REQUIREMENTS = [
77
+ { service: "exe-db", description: "PostgreSQL data" },
78
+ { service: "redis", description: "Redis AOF/RDB" },
79
+ { service: "exe-gateway", description: "Baileys WhatsApp auth state" },
80
+ { service: "exe-wiki", description: "Wiki document storage" },
81
+ { service: "exe-os", description: "Daemon state + memories DB" },
82
+ { service: "exe-monitor-hub", description: "PocketBase monitoring data" }
83
+ ];
84
+ function parseEnvFile(content) {
85
+ const env = /* @__PURE__ */ new Map();
86
+ for (const line of content.split("\n")) {
87
+ const trimmed = line.trim();
88
+ if (!trimmed || trimmed.startsWith("#")) continue;
89
+ const eqIdx = trimmed.indexOf("=");
90
+ if (eqIdx < 0) continue;
91
+ const key = trimmed.slice(0, eqIdx);
92
+ let value = trimmed.slice(eqIdx + 1);
93
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
94
+ value = value.slice(1, -1);
95
+ }
96
+ env.set(key, value);
97
+ }
98
+ return env;
99
+ }
100
+ function checkImageIdentity(image) {
101
+ if (!image) return { check: "image_identity", status: "skip", message: "No --image specified, skipping" };
102
+ try {
103
+ const pull = spawnSync("docker", ["pull", image], { encoding: "utf8", timeout: 12e4 });
104
+ if (pull.status !== 0) {
105
+ return { check: "image_identity", status: "fail", message: `Failed to pull ${image}: ${pull.stderr?.slice(0, 200)}` };
106
+ }
107
+ const inspect = spawnSync("docker", [
108
+ "run",
109
+ "--rm",
110
+ "--entrypoint",
111
+ "cat",
112
+ image,
113
+ "/app/package.json"
114
+ ], { encoding: "utf8", timeout: 3e4 });
115
+ if (inspect.status !== 0) {
116
+ return { check: "image_identity", status: "warn", message: "Could not read package.json from image (non-Node image?)" };
117
+ }
118
+ const pkg = JSON.parse(inspect.stdout);
119
+ const expectedRepo = image.includes("exe-gateway") ? "exe-gateway" : image.includes("exe-wiki") ? "exe-wiki" : image.includes("exe-crm") ? "exe-crm" : image.includes("exe-os") ? "exe-os" : null;
120
+ if (expectedRepo && !pkg.name?.includes(expectedRepo)) {
121
+ return {
122
+ check: "image_identity",
123
+ status: "fail",
124
+ message: `Image identity mismatch: expected ${expectedRepo} but package.json name is "${pkg.name}"`
125
+ };
126
+ }
127
+ return { check: "image_identity", status: "pass", message: `Image identity verified: ${pkg.name}@${pkg.version}` };
128
+ } catch (e) {
129
+ return { check: "image_identity", status: "fail", message: `Image identity check failed: ${e instanceof Error ? e.message : String(e)}` };
130
+ }
131
+ }
132
+ function checkVolumePreservation(composeContent) {
133
+ const missing = [];
134
+ for (const req of VOLUME_REQUIREMENTS) {
135
+ const serviceRegex = new RegExp(`^\\s+${req.service}:`, "m");
136
+ if (!serviceRegex.test(composeContent)) continue;
137
+ const lines = composeContent.split("\n");
138
+ let serviceBlock = "";
139
+ let inService = false;
140
+ let serviceIndent = -1;
141
+ for (const line of lines) {
142
+ if (!inService) {
143
+ const headerMatch = line.match(new RegExp(`^(\\s+)${req.service}:\\s*`));
144
+ if (headerMatch) {
145
+ inService = true;
146
+ serviceIndent = headerMatch[1].length;
147
+ serviceBlock += line + "\n";
148
+ }
149
+ continue;
150
+ }
151
+ if (line.trim() === "" || line.trim().startsWith("#")) {
152
+ serviceBlock += line + "\n";
153
+ continue;
154
+ }
155
+ const currentIndent = line.match(/^(\s*)/)?.[1]?.length ?? 0;
156
+ if (currentIndent <= serviceIndent) {
157
+ break;
158
+ }
159
+ serviceBlock += line + "\n";
160
+ }
161
+ if (serviceBlock && !serviceBlock.includes("volumes:")) {
162
+ missing.push(`${req.service} (${req.description})`);
163
+ }
164
+ }
165
+ if (missing.length > 0) {
166
+ return {
167
+ check: "volume_preservation",
168
+ status: "fail",
169
+ message: `Stateful services without volume mounts: ${missing.join(", ")}`
170
+ };
171
+ }
172
+ return { check: "volume_preservation", status: "pass", message: "All stateful services have volume mounts" };
173
+ }
174
+ function checkEnvContract(envContent) {
175
+ const env = parseEnvFile(envContent);
176
+ const issues = [];
177
+ for (const key of REQUIRED_ENV_VARS) {
178
+ const val = env.get(key);
179
+ if (!val || val === "CHANGEME" || val === "") {
180
+ issues.push(key);
181
+ }
182
+ }
183
+ for (const cond of CONDITIONAL_ENV_VARS) {
184
+ if (cond.condition(env)) {
185
+ const val = env.get(cond.key);
186
+ if (!val || val === "CHANGEME" || val === "") {
187
+ issues.push(`${cond.key} (${cond.reason})`);
188
+ }
189
+ }
190
+ }
191
+ if (issues.length > 0) {
192
+ return {
193
+ check: "env_contract",
194
+ status: "fail",
195
+ message: `Missing or placeholder env vars: ${issues.join(", ")}`
196
+ };
197
+ }
198
+ return { check: "env_contract", status: "pass", message: `All ${REQUIRED_ENV_VARS.length} required env vars present` };
199
+ }
200
+ function checkSmoke(composeFile, envFile) {
201
+ const ps = spawnSync("docker", [
202
+ "compose",
203
+ "--file",
204
+ composeFile,
205
+ "--env-file",
206
+ envFile,
207
+ "ps",
208
+ "--format",
209
+ "json"
210
+ ], { encoding: "utf8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] });
211
+ if (ps.status !== 0) {
212
+ return { check: "smoke_test", status: "skip", message: "Docker compose not available or stack not running" };
213
+ }
214
+ const lines = ps.stdout.trim().split("\n").filter(Boolean);
215
+ if (lines.length === 0) {
216
+ return { check: "smoke_test", status: "skip", message: "No containers running \u2014 fresh deploy" };
217
+ }
218
+ const unhealthy = [];
219
+ for (const line of lines) {
220
+ try {
221
+ const container = JSON.parse(line);
222
+ if (container.State !== "running") {
223
+ unhealthy.push(`${container.Name} (${container.State})`);
224
+ } else if (container.Health && container.Health !== "healthy" && container.Health !== "") {
225
+ unhealthy.push(`${container.Name} (${container.Health})`);
226
+ }
227
+ } catch {
228
+ }
229
+ }
230
+ if (unhealthy.length > 0) {
231
+ return { check: "smoke_test", status: "warn", message: `Unhealthy containers: ${unhealthy.join(", ")}` };
232
+ }
233
+ return { check: "smoke_test", status: "pass", message: `${lines.length} containers running and healthy` };
234
+ }
235
+ function checkRollbackSnapshot(composeFile, envFile, stackDir) {
236
+ const rollbackFile = path.join(stackDir, ".rollback.json");
237
+ try {
238
+ const envContent = readFileSync(envFile, "utf8");
239
+ const env = parseEnvFile(envContent);
240
+ const imageTags = {};
241
+ for (const [key, val] of env) {
242
+ if (key.endsWith("_IMAGE_TAG") || key.endsWith("_IMAGE")) {
243
+ imageTags[key] = val;
244
+ }
245
+ }
246
+ const snapshot = {
247
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
248
+ images: imageTags,
249
+ envFile,
250
+ composeFile
251
+ };
252
+ writeFileSync(rollbackFile, JSON.stringify(snapshot, null, 2) + "\n", { mode: 384 });
253
+ return {
254
+ check: "rollback_snapshot",
255
+ status: "pass",
256
+ message: `Rollback snapshot saved: ${Object.keys(imageTags).length} image tags \u2192 ${rollbackFile}`
257
+ };
258
+ } catch (e) {
259
+ return {
260
+ check: "rollback_snapshot",
261
+ status: "warn",
262
+ message: `Could not save rollback snapshot: ${e instanceof Error ? e.message : String(e)}`
263
+ };
264
+ }
265
+ }
266
+ function runPreflight(options) {
267
+ const results = [];
268
+ const stackDir = path.dirname(options.envFile);
269
+ results.push(checkImageIdentity(options.image));
270
+ if (existsSync(options.composeFile)) {
271
+ const composeContent = readFileSync(options.composeFile, "utf8");
272
+ results.push(checkVolumePreservation(composeContent));
273
+ } else {
274
+ results.push({ check: "volume_preservation", status: "skip", message: "Compose file not found" });
275
+ }
276
+ if (existsSync(options.envFile)) {
277
+ const envContent = readFileSync(options.envFile, "utf8");
278
+ results.push(checkEnvContract(envContent));
279
+ } else {
280
+ results.push({ check: "env_contract", status: "fail", message: ".env file not found" });
281
+ }
282
+ results.push(checkSmoke(options.composeFile, options.envFile));
283
+ results.push(checkRollbackSnapshot(options.composeFile, options.envFile, stackDir));
284
+ const passed = results.every((r) => r.status === "pass" || r.status === "skip" || r.status === "warn");
285
+ return {
286
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
287
+ results,
288
+ passed
289
+ };
290
+ }
291
+ function printReport(report) {
292
+ console.log("\n\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
293
+ console.log("\u2551 exe-os preflight report \u2551");
294
+ console.log("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\n");
295
+ const icons = { pass: "\u2705", fail: "\u274C", warn: "\u26A0\uFE0F ", skip: "\u23ED\uFE0F " };
296
+ for (const r of report.results) {
297
+ console.log(` ${icons[r.status]} ${r.check}: ${r.message}`);
298
+ }
299
+ console.log("");
300
+ if (report.passed) {
301
+ console.log(" \u2705 PREFLIGHT PASSED \u2014 safe to deploy\n");
302
+ } else {
303
+ console.log(" \u274C PREFLIGHT BLOCKED \u2014 fix issues before deploying\n");
304
+ }
305
+ }
306
+ if (process.argv[1]?.endsWith("preflight.ts") || process.argv[1]?.endsWith("preflight.js")) {
307
+ const args = process.argv.slice(2);
308
+ const getArg = (flag) => {
309
+ const idx = args.indexOf(flag);
310
+ return idx >= 0 && idx + 1 < args.length ? args[idx + 1] : void 0;
311
+ };
312
+ const composeFile = getArg("--compose") ?? "/opt/exe-stack/docker-compose.yml";
313
+ const envFile = getArg("--env") ?? "/opt/exe-stack/.env";
314
+ const image = getArg("--image");
315
+ const report = runPreflight({ composeFile, envFile, image });
316
+ printReport(report);
317
+ process.exit(report.passed ? 0 : 1);
318
+ }
319
+
320
+ // src/bin/stack-update.ts
321
+ function withRuntimeHooks(opts) {
322
+ return {
323
+ ...opts,
324
+ preflight: runPreflight,
325
+ preDeployBackup,
326
+ healthGate: runHealthGate,
327
+ logHealthGateResult: logResult,
328
+ verifyStack: runVerifyStack
329
+ };
330
+ }
27
331
  function parseArgs(args) {
28
332
  const defaults = defaultStackPaths();
29
333
  const opts = {
@@ -57,8 +361,8 @@ function parseArgs(args) {
57
361
  else if (arg === "--env-file" || arg === "--stack-env-file") opts.envFile = next();
58
362
  else if (arg.startsWith("--env-file=") || arg.startsWith("--stack-env-file=")) opts.envFile = arg.split("=").slice(1).join("=");
59
363
  else if (arg === "--lock-file") opts.lockFile = next();
60
- else if (arg === "--public-key") opts.manifestPublicKey = readFileSync(next(), "utf8");
61
- else if (arg.startsWith("--public-key=")) opts.manifestPublicKey = readFileSync(arg.split("=").slice(1).join("="), "utf8");
364
+ else if (arg === "--public-key") opts.manifestPublicKey = readFileSync2(next(), "utf8");
365
+ else if (arg.startsWith("--public-key=")) opts.manifestPublicKey = readFileSync2(arg.split("=").slice(1).join("="), "utf8");
62
366
  else if (arg === "--auth-token") opts.manifestAuthToken = next();
63
367
  else if (arg.startsWith("--auth-token=")) opts.manifestAuthToken = arg.split("=").slice(1).join("=");
64
368
  else if (arg === "--auth-token-env") opts.manifestAuthToken = process.env[next()] ?? "";
@@ -139,9 +443,9 @@ Options:
139
443
  `);
140
444
  }
141
445
  function readInstalledVersion(lockFile) {
142
- if (!existsSync(lockFile)) return void 0;
446
+ if (!existsSync2(lockFile)) return void 0;
143
447
  try {
144
- const parsed = JSON.parse(readFileSync(lockFile, "utf8"));
448
+ const parsed = JSON.parse(readFileSync2(lockFile, "utf8"));
145
449
  return parsed.stackVersion;
146
450
  } catch {
147
451
  return void 0;
@@ -184,7 +488,7 @@ function printChanges(changes, composeFile, envFile) {
184
488
  }
185
489
  function areCliContainersRunning(composeFile, envFile) {
186
490
  try {
187
- const result = spawnSync("docker", ["compose", "--file", composeFile, "--env-file", envFile, "ps", "-q"], {
491
+ const result = spawnSync2("docker", ["compose", "--file", composeFile, "--env-file", envFile, "ps", "-q"], {
188
492
  stdio: ["pipe", "pipe", "pipe"],
189
493
  timeout: 15e3
190
494
  });
@@ -195,7 +499,7 @@ function areCliContainersRunning(composeFile, envFile) {
195
499
  }
196
500
  function getContainerHealth(composeFile, envFile) {
197
501
  try {
198
- const result = spawnSync(
502
+ const result = spawnSync2(
199
503
  "docker",
200
504
  ["compose", "--file", composeFile, "--env-file", envFile, "ps", "--format", "json"],
201
505
  { stdio: ["pipe", "pipe", "pipe"], timeout: 15e3 }
@@ -258,13 +562,37 @@ function printHostReport(report) {
258
562
  if (report.envRemainingPlaceholders.length > 0) console.log(` Remaining placeholders: ${report.envRemainingPlaceholders.join(", ")}`);
259
563
  console.log("");
260
564
  }
565
+ function readKeyFromEnvFile(envFile, key) {
566
+ try {
567
+ const raw = readFileSync2(envFile, "utf8");
568
+ for (const line of raw.split(/\r?\n/)) {
569
+ const trimmed = line.trim();
570
+ if (trimmed.startsWith("#") || !trimmed) continue;
571
+ const idx = trimmed.indexOf("=");
572
+ if (idx <= 0) continue;
573
+ if (trimmed.slice(0, idx).trim() === key) {
574
+ const value = trimmed.slice(idx + 1).trim();
575
+ return value && !/CHANGEME/.test(value) ? value : void 0;
576
+ }
577
+ }
578
+ } catch {
579
+ }
580
+ return void 0;
581
+ }
261
582
  async function main(args = process.argv.slice(2)) {
262
583
  const opts = parseArgs(args);
584
+ if (!opts.licenseKey && existsSync2(opts.envFile)) {
585
+ const stackLicense = readKeyFromEnvFile(opts.envFile, "EXE_LICENSE_KEY");
586
+ if (stackLicense) {
587
+ opts.licenseKey = stackLicense;
588
+ if (!opts.manifestAuthToken) opts.manifestAuthToken = stackLicense;
589
+ }
590
+ }
263
591
  let usingPackagedCheckTemplates = false;
264
592
  if (opts.check && !opts.noBootstrap && !existsForCli(opts.composeFile) && !existsForCli(opts.envFile)) {
265
- const packageRoot = path.resolve(new URL("../..", import.meta.url).pathname);
266
- opts.composeFile = path.join(packageRoot, "deploy", "compose", "docker-compose.yml");
267
- opts.envFile = path.join(packageRoot, "deploy", "compose", ".env.customer.example");
593
+ const packageRoot = path2.resolve(new URL("../..", import.meta.url).pathname);
594
+ opts.composeFile = path2.join(packageRoot, "deploy", "compose", "docker-compose.yml");
595
+ opts.envFile = path2.join(packageRoot, "deploy", "compose", ".env.customer.example");
268
596
  opts.noBootstrap = true;
269
597
  usingPackagedCheckTemplates = true;
270
598
  }
@@ -273,7 +601,7 @@ async function main(args = process.argv.slice(2)) {
273
601
  console.error("Refusing to rollback without --yes.");
274
602
  process.exit(2);
275
603
  }
276
- const result2 = await runStackUpdate(opts);
604
+ const result2 = await runStackUpdate(withRuntimeHooks(opts));
277
605
  console.log(`\u2705 Stack rollback attempted using backup: ${result2.backupEnvFile ?? "latest backup"}`);
278
606
  return;
279
607
  }
@@ -284,14 +612,14 @@ async function main(args = process.argv.slice(2)) {
284
612
  if (!opts.check && !opts.dryRun) assertHostReadyForApply(hostReport);
285
613
  }
286
614
  const manifest = await loadStackManifest(opts.manifestRef, void 0, opts.manifestPublicKey, opts.manifestAuthToken);
287
- const envRaw = readFileSync(opts.envFile, "utf8");
288
- const lockFile = opts.lockFile ?? path.join(path.dirname(opts.envFile), ".exe-stack-lock.json");
615
+ const envRaw = readFileSync2(opts.envFile, "utf8");
616
+ const lockFile = opts.lockFile ?? path2.join(path2.dirname(opts.envFile), ".exe-stack-lock.json");
289
617
  const installedVersion = readInstalledVersion(lockFile);
290
618
  const effectiveTarget = opts.targetVersion ?? installedVersion;
291
619
  const plan = createStackUpdatePlan(manifest, envRaw, effectiveTarget);
292
620
  assertDeploymentScopeAllowed(plan, opts.deploymentPersona);
293
621
  const plannedEnvRaw = patchEnv(envRaw, Object.fromEntries(plan.changes.map((c) => [c.key, c.after])));
294
- assertProductionDeployGate(plan, plannedEnvRaw, readFileSync(opts.composeFile, "utf8"), {
622
+ assertProductionDeployGate(plan, plannedEnvRaw, readFileSync2(opts.composeFile, "utf8"), {
295
623
  breakGlassReason: opts.breakGlassReason,
296
624
  breakGlassAuditFile: opts.breakGlassAuditFile,
297
625
  envFile: opts.envFile
@@ -347,7 +675,7 @@ async function main(args = process.argv.slice(2)) {
347
675
  console.error("\nRefusing to update without --yes. Re-run with --yes after reviewing the plan.");
348
676
  process.exit(2);
349
677
  }
350
- const result = await runStackUpdate(opts);
678
+ const result = await runStackUpdate(withRuntimeHooks(opts));
351
679
  console.log(`
352
680
  \u2705 Stack ${result.status}: ${result.targetVersion}`);
353
681
  if (result.backupEnvFile) console.log(`Backup env: ${result.backupEnvFile}`);
@@ -355,7 +683,7 @@ async function main(args = process.argv.slice(2)) {
355
683
  }
356
684
  function existsForCli(filePath) {
357
685
  try {
358
- readFileSync(filePath);
686
+ readFileSync2(filePath);
359
687
  return true;
360
688
  } catch {
361
689
  return false;