@askexenow/exe-os 0.9.239 → 0.9.243

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 (316) 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 +23 -4
  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/scan-tasks.js +13 -13
  65. package/dist/bin/setup.js +3 -3
  66. package/dist/bin/shard-migrate.js +8 -8
  67. package/dist/bin/stack-update.js +324 -20
  68. package/dist/bin/verify-stack.js +3 -383
  69. package/dist/bin/vps-backup.js +8 -160
  70. package/dist/bin/vps-health-gate.js +10 -220
  71. package/dist/{branding-I7YYX4FM.js → branding-XWMO5EDR.js} +1 -1
  72. package/dist/{capacity-monitor-IFCZKRPG.js → capacity-monitor-4CSBC7AP.js} +14 -14
  73. package/dist/{catchup-brief-PIDRWXOW.js → catchup-brief-LF5Z6Q6E.js} +17 -17
  74. package/dist/{chunk-FGJUGDNM.js → chunk-222SI7QC.js} +14 -14
  75. package/dist/{chunk-JZMVLAZ2.js → chunk-2WBBVEIB.js} +1 -1
  76. package/dist/{chunk-JDOE33C2.js → chunk-3V53HH5T.js} +4 -4
  77. package/dist/{chunk-2KZSKURT.js → chunk-57SULZJ2.js} +3 -3
  78. package/dist/{chunk-QI4IXJN7.js → chunk-5CHYEKMH.js} +7 -4
  79. package/dist/chunk-5DMAMQNU.js +168 -0
  80. package/dist/{chunk-PLQAFB3Z.js → chunk-5JIG2FP2.js} +1 -1
  81. package/dist/{chunk-UWQ3XCDG.js → chunk-5WK7X5CF.js} +2 -2
  82. package/dist/{chunk-DDPAQ4LT.js → chunk-6JAGJN77.js} +2 -2
  83. package/dist/{chunk-7F37NMKB.js → chunk-73UE2PHT.js} +1 -1
  84. package/dist/{chunk-JL3K5OTS.js → chunk-7IZWLMTP.js} +1 -1
  85. package/dist/{chunk-ELRRL2NC.js → chunk-A4K2ZT6N.js} +4 -4
  86. package/dist/{chunk-GWYADLIW.js → chunk-AHXEU5XB.js} +1 -1
  87. package/dist/{chunk-WSHMBME6.js → chunk-AWRL5FGM.js} +19 -78
  88. package/dist/{chunk-OMPCFLWA.js → chunk-BSPOEYAO.js} +1 -1
  89. package/dist/{chunk-DHVC4RN7.js → chunk-CBDPEJOR.js} +5 -5
  90. package/dist/{chunk-2H55BIV2.js → chunk-CEJO7244.js} +2 -2
  91. package/dist/{chunk-FKWZVO2T.js → chunk-CPXGLSIL.js} +3 -3
  92. package/dist/{chunk-HX5G4AS4.js → chunk-CWITU7DW.js} +2 -2
  93. package/dist/{chunk-5GG7MTRJ.js → chunk-DGBGIXCC.js} +4 -4
  94. package/dist/{chunk-IQXPMK46.js → chunk-DLZYAYVM.js} +60 -14
  95. package/dist/{chunk-PPYWQV2M.js → chunk-DR5BGWFR.js} +2 -2
  96. package/dist/{chunk-BZWKTFEB.js → chunk-ENVRFBTB.js} +2 -2
  97. package/dist/{chunk-DUVO2PUJ.js → chunk-F3GM6OOP.js} +4 -4
  98. package/dist/{chunk-HNLPLLE6.js → chunk-F7JLZXHC.js} +60 -26
  99. package/dist/{chunk-AL4DRC5H.js → chunk-FFLILAG6.js} +1 -1
  100. package/dist/{chunk-BZNI4OK5.js → chunk-GHEWRYMY.js} +18 -2
  101. package/dist/{chunk-C7SFJO5F.js → chunk-GHT4REOS.js} +5 -5
  102. package/dist/{chunk-FBWUJEXS.js → chunk-HANG6NLF.js} +4 -6
  103. package/dist/{chunk-5NJ4A4ZA.js → chunk-HCBMPZDT.js} +1 -1
  104. package/dist/chunk-HOGTZLVU.js +244 -0
  105. package/dist/{chunk-IQSCZDBQ.js → chunk-I5PIBL56.js} +3 -3
  106. package/dist/chunk-IRHNV4GY.js +388 -0
  107. package/dist/{chunk-F4TCKCKK.js → chunk-ITZVPCBQ.js} +33 -12
  108. package/dist/{chunk-4HROS3GJ.js → chunk-IZVKWBIP.js} +1 -1
  109. package/dist/{chunk-DKI5BTBC.js → chunk-J7V7LPPX.js} +2 -2
  110. package/dist/{chunk-TOZ5NN5V.js → chunk-JLKUVK5J.js} +1 -1
  111. package/dist/{chunk-4SC65UBG.js → chunk-JLNXKG3K.js} +1 -1
  112. package/dist/{chunk-KVSQOG3W.js → chunk-K2BDE2B5.js} +4 -4
  113. package/dist/{chunk-KDJRFJDL.js → chunk-K333WOW4.js} +30 -2
  114. package/dist/{chunk-6LBCUA2A.js → chunk-KEZXW3RP.js} +1 -1
  115. package/dist/{chunk-W7G3GY4I.js → chunk-KLQI7QY4.js} +3 -3
  116. package/dist/{chunk-UODVZGBQ.js → chunk-KN7LPTIB.js} +1 -1
  117. package/dist/{chunk-ESKBZN4Q.js → chunk-L4WRH3DL.js} +1 -1
  118. package/dist/{chunk-VFQKKMKE.js → chunk-LAOB5BKV.js} +2 -2
  119. package/dist/{chunk-MAN5LZQ4.js → chunk-LQSFP2BV.js} +1 -1
  120. package/dist/{chunk-EJ7LOTV2.js → chunk-LSFHEMVI.js} +9 -9
  121. package/dist/{chunk-RA2RO27E.js → chunk-MCESA5UW.js} +2 -2
  122. package/dist/{chunk-UPMHG7ET.js → chunk-MEIHREPM.js} +1 -1
  123. package/dist/{chunk-D5C56WO3.js → chunk-MOZ2YQ54.js} +1 -1
  124. package/dist/{chunk-CLGB3FGL.js → chunk-MPX3TRMQ.js} +2 -2
  125. package/dist/{chunk-5R75ODPS.js → chunk-NBY6R37W.js} +61 -232
  126. package/dist/{chunk-RWFGXC35.js → chunk-NEYQAEYU.js} +7 -7
  127. package/dist/{chunk-MBHZDXGN.js → chunk-NL35XNLI.js} +1 -1
  128. package/dist/{chunk-TPQVLYSV.js → chunk-NLGMHPEN.js} +1 -1
  129. package/dist/{chunk-5LMH4YHG.js → chunk-NRVV4Y5V.js} +4 -4
  130. package/dist/{chunk-GN5VHPPR.js → chunk-NVZR7T4E.js} +1 -1
  131. package/dist/{chunk-Y2L7RMGH.js → chunk-NWBHL5PI.js} +1 -1
  132. package/dist/{chunk-YPYDLW75.js → chunk-OEMX65EA.js} +1 -1
  133. package/dist/{chunk-UAFUGPKO.js → chunk-ONAQAL3O.js} +1 -1
  134. package/dist/{chunk-AVM7XZE4.js → chunk-OWQ3CCYJ.js} +7 -6
  135. package/dist/{chunk-K525WLL7.js → chunk-PI6V23GF.js} +5 -4
  136. package/dist/{chunk-AURM7FOT.js → chunk-Q2OAQPWY.js} +1 -1
  137. package/dist/{chunk-FB5VRO5S.js → chunk-QLDWASTX.js} +28 -32
  138. package/dist/{chunk-EPWDTS2Q.js → chunk-QMTGMCWB.js} +1 -1
  139. package/dist/{chunk-VI2FJY2M.js → chunk-QP4FHME2.js} +2 -2
  140. package/dist/{chunk-NJWK6J4N.js → chunk-QUNKPR6Y.js} +5 -5
  141. package/dist/{chunk-O6DAF2TY.js → chunk-QUZVAHO7.js} +2 -2
  142. package/dist/{chunk-VHKL4S4T.js → chunk-RRHSONV5.js} +2 -2
  143. package/dist/{chunk-GPF6X6HE.js → chunk-RYDHEWYY.js} +2 -2
  144. package/dist/{chunk-C2YS2AA6.js → chunk-U7WOVXBB.js} +2 -2
  145. package/dist/chunk-UIRWDGMB.js +230 -0
  146. package/dist/{chunk-FE45RXGC.js → chunk-V2GZMY6O.js} +1 -1
  147. package/dist/{chunk-PATCHPNY.js → chunk-VHALWCUO.js} +1 -1
  148. package/dist/{chunk-HLZSC5WK.js → chunk-VQAP35DA.js} +20 -18
  149. package/dist/{chunk-452XB7OZ.js → chunk-VRIMTCX2.js} +1 -1
  150. package/dist/{chunk-SUNYJ6YE.js → chunk-VT2B5BHM.js} +1 -1
  151. package/dist/{chunk-UZIJDYDA.js → chunk-VWVJVQDH.js} +2 -2
  152. package/dist/{chunk-TRZ5KA2R.js → chunk-VXIMSRTO.js} +2 -2
  153. package/dist/{chunk-DAZIV4QZ.js → chunk-WCXZF42W.js} +1 -1
  154. package/dist/{chunk-6OJJF4WP.js → chunk-XJUUWHVN.js} +1 -1
  155. package/dist/{chunk-F7LU65PQ.js → chunk-Y25OJWOQ.js} +14 -2
  156. package/dist/{chunk-2ORPA23Y.js → chunk-YMXXD2GW.js} +36 -8
  157. package/dist/{chunk-5WLMF6PL.js → chunk-YMZHTTOQ.js} +1 -1
  158. package/dist/{chunk-7DIDOQCX.js → chunk-YRVW57UW.js} +139 -125
  159. package/dist/{chunk-BRFH5X7G.js → chunk-Z7VDUS6L.js} +1 -1
  160. package/dist/{chunk-YFE6W75D.js → chunk-ZKFPHJIJ.js} +1 -1
  161. package/dist/{chunk-5WUTKDH6.js → chunk-ZVXJSQOR.js} +1 -1
  162. package/dist/{co-activation-VB4CJQZB.js → co-activation-L6I2LSJO.js} +3 -3
  163. package/dist/{co-occurrence-XZQJJIBM.js → co-occurrence-QARWYUAY.js} +3 -3
  164. package/dist/{code-context-index-FCQOPUEA.js → code-context-index-UIYQRDHD.js} +4 -4
  165. package/dist/{content-extractor-SPSH5X33.js → content-extractor-EYRVGD6O.js} +2 -2
  166. package/dist/{conversation-wiki-populator-YU35LNRK.js → conversation-wiki-populator-L7O6F3BB.js} +1 -1
  167. package/dist/{crdt-sync-KXETGV45.js → crdt-sync-R6YROKDH.js} +1 -1
  168. package/dist/{crm-webhook-JMOAHTJ6.js → crm-webhook-WK3PYJJK.js} +2 -2
  169. package/dist/{cto-delegation-gate-IJ3KQIKF.js → cto-delegation-gate-5JZORQIT.js} +12 -12
  170. package/dist/{daemon-auth-2IZACWSG.js → daemon-auth-2HEOL6VG.js} +2 -2
  171. package/dist/{daemon-orchestration-ZCY4GEI3.js → daemon-orchestration-BJ3T5MMF.js} +16 -15
  172. package/dist/{db-backup-HLX5OLIV.js → db-backup-EWS52P2W.js} +2 -2
  173. package/dist/{dreaming-2CJML3TU.js → dreaming-BOSBDRI3.js} +13 -13
  174. package/dist/{entity-boost-T5IYWWDZ.js → entity-boost-6ZVX7DFB.js} +26 -2
  175. package/dist/{exe-drift-P5OIRNSH.js → exe-drift-WRE6RADZ.js} +4 -4
  176. package/dist/{exe-export-QQL2H322.js → exe-export-7N5PBCMK.js} +8 -8
  177. package/dist/{exe-import-V4RJCUEP.js → exe-import-YOOE7S3H.js} +8 -8
  178. package/dist/{exe-key-MENJGDD7.js → exe-key-GXJSTCX2.js} +4 -4
  179. package/dist/{exe-org-3FNET2J7.js → exe-org-42YMQL75.js} +2 -2
  180. package/dist/{exe-snapshot-YRARQE7F.js → exe-snapshot-ODUCFW7G.js} +18 -18
  181. package/dist/{fast-db-init-HIJWWKAO.js → fast-db-init-YSR7RMVZ.js} +1 -1
  182. package/dist/{founder-context-BQ5NBDUV.js → founder-context-Q2HUCZX4.js} +2 -2
  183. package/dist/gateway/index.js +9 -9
  184. package/dist/{gateway-client-YGSA5QMC.js → gateway-client-4QXHKN5C.js} +1 -1
  185. package/dist/{git-staleness-IHTKCUMN.js → git-staleness-BJDTCDPC.js} +3 -3
  186. package/dist/{git-task-sweep-5ZPNQS7Y.js → git-task-sweep-L3U3T5HM.js} +13 -13
  187. package/dist/{global-procedures-XHDIZRJU.js → global-procedures-HCHEHKY2.js} +4 -4
  188. package/dist/{graph-auto-extract-5TPT67GP.js → graph-auto-extract-FP5C76LS.js} +3 -3
  189. package/dist/{hook-integrity-SB53Y7UK.js → hook-integrity-2OU3T6UC.js} +1 -1
  190. package/dist/hooks/bug-report-worker.js +15 -14
  191. package/dist/hooks/codex-stop-task-finalizer.js +15 -14
  192. package/dist/hooks/commit-complete.js +16 -16
  193. package/dist/hooks/error-recall.js +10 -10
  194. package/dist/hooks/exe-heartbeat-hook.js +5 -5
  195. package/dist/hooks/ingest-worker.js +8 -8
  196. package/dist/hooks/ingest.js +13 -13
  197. package/dist/hooks/instructions-loaded.js +7 -7
  198. package/dist/hooks/manifest.json +20 -20
  199. package/dist/hooks/notification.js +6 -6
  200. package/dist/hooks/post-compact.js +15 -15
  201. package/dist/hooks/post-tool-combined.js +7 -7
  202. package/dist/hooks/pre-compact.js +20 -20
  203. package/dist/hooks/pre-tool-use.js +28 -25
  204. package/dist/hooks/prompt-submit.js +62 -31
  205. package/dist/hooks/session-end.js +26 -26
  206. package/dist/hooks/session-start.js +39 -15
  207. package/dist/hooks/stop.js +22 -22
  208. package/dist/hooks/subagent-stop.js +15 -15
  209. package/dist/hooks/summary-worker.js +32 -27
  210. package/dist/index.js +21 -21
  211. package/dist/{installer-AMZM4MLS.js → installer-AWMUCRN4.js} +7 -7
  212. package/dist/{installer-KT5FW4CN.js → installer-HB3NH6FG.js} +9 -9
  213. package/dist/{installer-HW74W3IT.js → installer-RU6EVOBL.js} +6 -6
  214. package/dist/{intercom-queue-RNM6EPGA.js → intercom-queue-A6UJEFIF.js} +1 -1
  215. package/dist/{key-backup-status-OZ2CXUDW.js → key-backup-status-4YKCV4ZV.js} +1 -1
  216. package/dist/lib/agent-config.js +2 -2
  217. package/dist/lib/cloud-sync.js +10 -8
  218. package/dist/lib/config.js +1 -1
  219. package/dist/lib/consolidation.js +8 -8
  220. package/dist/lib/database.js +3 -3
  221. package/dist/lib/db-daemon-client.js +3 -3
  222. package/dist/lib/db.js +3 -3
  223. package/dist/lib/device-registry.js +1 -1
  224. package/dist/lib/embedder.js +4 -4
  225. package/dist/lib/employee-templates.js +5 -5
  226. package/dist/lib/employees.js +3 -3
  227. package/dist/lib/exe-daemon-client.js +3 -3
  228. package/dist/lib/exe-daemon.js +105 -74
  229. package/dist/lib/hybrid-search.js +8 -8
  230. package/dist/lib/identity.js +3 -3
  231. package/dist/lib/keychain.js +1 -1
  232. package/dist/lib/license.js +2 -2
  233. package/dist/lib/messaging.js +13 -13
  234. package/dist/lib/post-tool-memory.js +3 -3
  235. package/dist/lib/reminders.js +4 -4
  236. package/dist/lib/schedules.js +8 -8
  237. package/dist/lib/session-registry.js +5 -5
  238. package/dist/lib/skill-learning.js +5 -5
  239. package/dist/lib/store.js +7 -7
  240. package/dist/lib/task-router.js +4 -4
  241. package/dist/lib/tasks.js +14 -13
  242. package/dist/lib/tmux-routing.js +12 -12
  243. package/dist/lib/token-spend.js +4 -4
  244. package/dist/lib/ws-client.js +1 -1
  245. package/dist/{license-gate-XJDIL6OZ.js → license-gate-6JQQFBHS.js} +3 -3
  246. package/dist/mcp/register-tools.js +68 -67
  247. package/dist/mcp/server.js +70 -69
  248. package/dist/mcp/tools/complete-reminder.js +5 -5
  249. package/dist/mcp/tools/create-reminder.js +5 -5
  250. package/dist/mcp/tools/create-task.js +16 -15
  251. package/dist/mcp/tools/deactivate-behavior.js +6 -6
  252. package/dist/mcp/tools/list-reminders.js +5 -5
  253. package/dist/mcp/tools/list-tasks.js +16 -15
  254. package/dist/mcp/tools/send-message.js +15 -15
  255. package/dist/mcp/tools/update-task.js +15 -14
  256. package/dist/{mcp-http-config-BXX3RZPR.js → mcp-http-config-XIJR5P2Z.js} +4 -4
  257. package/dist/{memory-cards-KRTP5GFM.js → memory-cards-H4BJJ5OK.js} +3 -3
  258. package/dist/{memory-graph-extractor-G532PUHC.js → memory-graph-extractor-SDGM3GVR.js} +4 -4
  259. package/dist/{memory-poisoning-defense-HJM3FQA3.js → memory-poisoning-defense-UVU67DGJ.js} +3 -3
  260. package/dist/{memory-queue-FTNBWLS4.js → memory-queue-FNT5WHXP.js} +2 -2
  261. package/dist/{memory-queue-client-DHSHEIHQ.js → memory-queue-client-JZCFYTWQ.js} +5 -5
  262. package/dist/{memory-reflection-RANRFUQL.js → memory-reflection-GGB5K35L.js} +3 -3
  263. package/dist/{notifications-4P2PVEOT.js → notifications-P3XQZDTH.js} +12 -12
  264. package/dist/{orchestration-events-IYTASMSN.js → orchestration-events-25WEKUKH.js} +4 -4
  265. package/dist/{orchestration-phase-SGA7PJ5G.js → orchestration-phase-C26XVKLZ.js} +2 -2
  266. package/dist/{orchestrator-VKVHZ4MV.js → orchestrator-VIXTY4E4.js} +14 -14
  267. package/dist/{pipeline-router-E4L5BDXN.js → pipeline-router-S5PE5U6B.js} +4 -4
  268. package/dist/{plan-limits-5O5QG55H.js → plan-limits-DGIVM42H.js} +5 -5
  269. package/dist/{prediction-log-OMWHW7FL.js → prediction-log-DOEOHDHS.js} +1 -1
  270. package/dist/{project-boot-WMI6CWRX.js → project-boot-4ZL2W7DN.js} +12 -2
  271. package/dist/{projection-worker-54KRNQSO.js → projection-worker-GG2W5OM3.js} +3 -3
  272. package/dist/{push-notifications-E2XXEWJZ.js → push-notifications-AMHVR6DF.js} +2 -2
  273. package/dist/{reranker-4NTUFNYT.js → reranker-UCPLQZE2.js} +2 -2
  274. package/dist/{review-polling-BFRJDLUA.js → review-polling-P2MWEXLR.js} +13 -13
  275. package/dist/runtime/index.js +15 -15
  276. package/dist/{session-events-KCZCWGE4.js → session-events-5CD66R6U.js} +13 -13
  277. package/dist/{session-kill-telemetry-TMNIDYWY.js → session-kill-telemetry-7FBHTEDN.js} +4 -4
  278. package/dist/{session-scope-DRZBQ32Y.js → session-scope-VMIPAZU7.js} +12 -12
  279. package/dist/{setup-wizard-TQKGDAHO.js → setup-wizard-BNR47URR.js} +3 -3
  280. package/dist/{shard-manager-G6MHCO7X.js → shard-manager-VGA2TYHM.js} +2 -2
  281. package/dist/{skill-refinement-Z5SWD3AM.js → skill-refinement-NRG4WWRW.js} +3 -3
  282. package/dist/stack-release-PFZI22WC.js +521 -0
  283. package/dist/{stack-update-NO5MNARG.js → stack-update-JIWJGGLX.js} +3 -3
  284. package/dist/{steward-gate-7DWYS5AT.js → steward-gate-L7DJMF4C.js} +4 -4
  285. package/dist/{task-enforcement-2VL5J6JJ.js → task-enforcement-XQL77PZH.js} +52 -12
  286. package/dist/{task-scope-YHALISIB.js → task-scope-R3XKBIHL.js} +12 -12
  287. package/dist/{tasks-crud-JXZEBZFR.js → tasks-crud-DQOG2NPG.js} +12 -12
  288. package/dist/tasks-notify-4EQYG52H.js +37 -0
  289. package/dist/{tasks-review-PGPYJQF5.js → tasks-review-XPFJ4DSJ.js} +12 -12
  290. package/dist/{telemetry-upload-H7OJNBIF.js → telemetry-upload-OT5B5HUY.js} +7 -7
  291. package/dist/{token-budget-JJ7JQIA2.js → token-budget-D2LQKCAV.js} +3 -3
  292. package/dist/{tool-capability-index-WIV4K3FB.js → tool-capability-index-FAJ5ZHDF.js} +1 -1
  293. package/dist/{tool-telemetry-W4LFCHFT.js → tool-telemetry-QIF5BCLF.js} +1 -1
  294. package/dist/tui/App.js +26 -26
  295. package/dist/{tui-data-72U6N2DC.js → tui-data-UEV2QOR3.js} +108 -12
  296. package/dist/{whatsapp-config-W63RQ3AU.js → whatsapp-config-GOSELKTE.js} +7 -0
  297. package/dist/{worker-gate-SCSN6IHI.js → worker-gate-PRCKA23W.js} +2 -2
  298. package/dist/{workflow-engine-OICYBE4F.js → workflow-engine-7X6LLH3M.js} +2 -2
  299. package/dist/{worktree-JXN4RCWC.js → worktree-RICSCT2S.js} +5 -5
  300. package/package.json +1 -1
  301. package/release-notes.json +137 -297
  302. package/stack.release.json +4 -3
  303. package/dist/preflight-EAH2MI76.js +0 -287
  304. /package/dist/{chunk-H42LEGLB.js → chunk-AQBEG33D.js} +0 -0
  305. /package/dist/{chunk-AU5426YP.js → chunk-B7JGEDVE.js} +0 -0
  306. /package/dist/{chunk-YFDDTHNM.js → chunk-JXI4XUTV.js} +0 -0
  307. /package/dist/{chunk-SNYDRHV3.js → chunk-U3DUFHOT.js} +0 -0
  308. /package/dist/{chunk-N2XUH2HQ.js → chunk-VBPC7IC7.js} +0 -0
  309. /package/dist/{chunk-HTUJBTBM.js → chunk-VUS6WXQ3.js} +0 -0
  310. /package/dist/{chunk-NOLIN2YI.js → chunk-XAYRZHLV.js} +0 -0
  311. /package/dist/{core-memory-VOBGGB2Q.js → core-memory-4KAIKQRQ.js} +0 -0
  312. /package/dist/{message-queue-client-KAJN6TIJ.js → message-queue-client-S6W5VMJV.js} +0 -0
  313. /package/dist/{oauth-server-QEXRSXEP.js → oauth-server-2ESBZB7F.js} +0 -0
  314. /package/dist/{webhook-pipe-LY4XEDL7.js → webhook-pipe-ZRUVOG5H.js} +0 -0
  315. /package/dist/{wiki-acl-M3OR547L.js → wiki-acl-MFLSS6DE.js} +0 -0
  316. /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
 
@@ -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-ITZVPCBQ.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-UIRWDGMB.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 }
@@ -262,9 +566,9 @@ async function main(args = process.argv.slice(2)) {
262
566
  const opts = parseArgs(args);
263
567
  let usingPackagedCheckTemplates = false;
264
568
  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");
569
+ const packageRoot = path2.resolve(new URL("../..", import.meta.url).pathname);
570
+ opts.composeFile = path2.join(packageRoot, "deploy", "compose", "docker-compose.yml");
571
+ opts.envFile = path2.join(packageRoot, "deploy", "compose", ".env.customer.example");
268
572
  opts.noBootstrap = true;
269
573
  usingPackagedCheckTemplates = true;
270
574
  }
@@ -273,7 +577,7 @@ async function main(args = process.argv.slice(2)) {
273
577
  console.error("Refusing to rollback without --yes.");
274
578
  process.exit(2);
275
579
  }
276
- const result2 = await runStackUpdate(opts);
580
+ const result2 = await runStackUpdate(withRuntimeHooks(opts));
277
581
  console.log(`\u2705 Stack rollback attempted using backup: ${result2.backupEnvFile ?? "latest backup"}`);
278
582
  return;
279
583
  }
@@ -284,14 +588,14 @@ async function main(args = process.argv.slice(2)) {
284
588
  if (!opts.check && !opts.dryRun) assertHostReadyForApply(hostReport);
285
589
  }
286
590
  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");
591
+ const envRaw = readFileSync2(opts.envFile, "utf8");
592
+ const lockFile = opts.lockFile ?? path2.join(path2.dirname(opts.envFile), ".exe-stack-lock.json");
289
593
  const installedVersion = readInstalledVersion(lockFile);
290
594
  const effectiveTarget = opts.targetVersion ?? installedVersion;
291
595
  const plan = createStackUpdatePlan(manifest, envRaw, effectiveTarget);
292
596
  assertDeploymentScopeAllowed(plan, opts.deploymentPersona);
293
597
  const plannedEnvRaw = patchEnv(envRaw, Object.fromEntries(plan.changes.map((c) => [c.key, c.after])));
294
- assertProductionDeployGate(plan, plannedEnvRaw, readFileSync(opts.composeFile, "utf8"), {
598
+ assertProductionDeployGate(plan, plannedEnvRaw, readFileSync2(opts.composeFile, "utf8"), {
295
599
  breakGlassReason: opts.breakGlassReason,
296
600
  breakGlassAuditFile: opts.breakGlassAuditFile,
297
601
  envFile: opts.envFile
@@ -347,7 +651,7 @@ async function main(args = process.argv.slice(2)) {
347
651
  console.error("\nRefusing to update without --yes. Re-run with --yes after reviewing the plan.");
348
652
  process.exit(2);
349
653
  }
350
- const result = await runStackUpdate(opts);
654
+ const result = await runStackUpdate(withRuntimeHooks(opts));
351
655
  console.log(`
352
656
  \u2705 Stack ${result.status}: ${result.targetVersion}`);
353
657
  if (result.backupEnvFile) console.log(`Backup env: ${result.backupEnvFile}`);
@@ -355,7 +659,7 @@ async function main(args = process.argv.slice(2)) {
355
659
  }
356
660
  function existsForCli(filePath) {
357
661
  try {
358
- readFileSync(filePath);
662
+ readFileSync2(filePath);
359
663
  return true;
360
664
  } catch {
361
665
  return false;