@askexenow/exe-os 0.9.267 → 0.9.268

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 (333) hide show
  1. package/deploy/compose/.env.customer.example +10 -0
  2. package/deploy/compose/docker-compose.yml +5 -6
  3. package/dist/active-agent-CA6YCKRU.js +25 -0
  4. package/dist/active-agent-S55CV6MK.js +26 -0
  5. package/dist/active-agent-T4IMZLH4.js +25 -0
  6. package/dist/active-agent-USYNCT45.js +26 -0
  7. package/dist/agentic-ontology-AZVW3ZYE.js +25 -0
  8. package/dist/backfill-metadata-556UWRQK.js +597 -0
  9. package/dist/backfill-metadata-Q5QBN45Z.js +597 -0
  10. package/dist/behaviors-CPS3PGWK.js +25 -0
  11. package/dist/bin/agentic-ontology-backfill.js +5 -5
  12. package/dist/bin/agentic-reflection-backfill.js +6 -6
  13. package/dist/bin/agentic-semantic-label.js +5 -5
  14. package/dist/bin/backfill-conversations.js +5 -5
  15. package/dist/bin/backfill-responses.js +5 -5
  16. package/dist/bin/backfill-vectors.js +6 -6
  17. package/dist/bin/bulk-sync-postgres.js +6 -6
  18. package/dist/bin/cc-doctor.js +4 -4
  19. package/dist/bin/cleanup-stale-review-tasks.js +9 -9
  20. package/dist/bin/cli.js +16 -16
  21. package/dist/bin/exe-agent-config.js +2 -2
  22. package/dist/bin/exe-agent.js +4 -4
  23. package/dist/bin/exe-assign.js +7 -7
  24. package/dist/bin/exe-boot.js +16 -16
  25. package/dist/bin/exe-call.js +4 -4
  26. package/dist/bin/exe-cloud.js +4 -4
  27. package/dist/bin/exe-dispatch.js +9 -9
  28. package/dist/bin/exe-doctor.js +1 -1
  29. package/dist/bin/exe-export-behaviors.js +7 -7
  30. package/dist/bin/exe-forget.js +6 -6
  31. package/dist/bin/exe-gateway.js +7 -7
  32. package/dist/bin/exe-healthcheck.js +4 -4
  33. package/dist/bin/exe-heartbeat.js +9 -9
  34. package/dist/bin/exe-kill.js +12 -12
  35. package/dist/bin/exe-launch-agent.js +16 -16
  36. package/dist/bin/exe-new-employee.js +6 -6
  37. package/dist/bin/exe-pending-messages.js +10 -10
  38. package/dist/bin/exe-pending-notifications.js +9 -9
  39. package/dist/bin/exe-pending-reviews.js +9 -9
  40. package/dist/bin/exe-rename.js +4 -4
  41. package/dist/bin/exe-review.js +11 -11
  42. package/dist/bin/exe-search.js +5 -5
  43. package/dist/bin/exe-session-cleanup.js +14 -14
  44. package/dist/bin/exe-settings.js +4 -4
  45. package/dist/bin/exe-start-codex.js +11 -11
  46. package/dist/bin/exe-start-opencode.js +8 -8
  47. package/dist/bin/exe-status.js +10 -10
  48. package/dist/bin/exe-team.js +3 -3
  49. package/dist/bin/git-sweep.js +10 -10
  50. package/dist/bin/graph-backfill.js +4 -4
  51. package/dist/bin/graph-export.js +5 -5
  52. package/dist/bin/import-history.js +7 -7
  53. package/dist/bin/install.js +6 -6
  54. package/dist/bin/intercom-check.js +4 -4
  55. package/dist/bin/mcp-sessions.js +2 -2
  56. package/dist/bin/orchestration-metrics.js +4 -4
  57. package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
  58. package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
  59. package/dist/bin/scan-tasks.js +9 -9
  60. package/dist/bin/setup.js +1 -1
  61. package/dist/bin/shard-migrate.js +4 -4
  62. package/dist/bin/stack-update.js +2 -2
  63. package/dist/bin/vps-health-gate.js +1 -1
  64. package/dist/capacity-monitor-WP4XXR7R.js +49 -0
  65. package/dist/capacity-monitor-ZGQ54TJG.js +49 -0
  66. package/dist/catchup-brief-X6O7W2YR.js +151 -0
  67. package/dist/catchup-brief-Z7SNTGLV.js +151 -0
  68. package/dist/chunk-23MJ2AJJ.js +227 -0
  69. package/dist/chunk-2NIJORQE.js +1335 -0
  70. package/dist/chunk-32RG5ZJN.js +3955 -0
  71. package/dist/chunk-3VTC7TJF.js +128 -0
  72. package/dist/chunk-3ZXL2KBT.js +1073 -0
  73. package/dist/chunk-44MXQ47E.js +185 -0
  74. package/dist/chunk-474SY5VD.js +159 -0
  75. package/dist/chunk-4LMI7RAW.js +1345 -0
  76. package/dist/chunk-4OH73UXH.js +1090 -0
  77. package/dist/chunk-4TOJXBXG.js +1073 -0
  78. package/dist/chunk-52UCKTIS.js +333 -0
  79. package/dist/chunk-5CHJKN6Y.js +668 -0
  80. package/dist/chunk-5MOYMGS5.js +818 -0
  81. package/dist/chunk-5ZSES6UA.js +363 -0
  82. package/dist/chunk-6HTXA4IM.js +394 -0
  83. package/dist/chunk-6L5DS7XO.js +394 -0
  84. package/dist/chunk-6TZCFZNG.js +171 -0
  85. package/dist/chunk-6WKV4F6L.js +1021 -0
  86. package/dist/chunk-7EOWAMTZ.js +69 -0
  87. package/dist/chunk-7MKEEX3T.js +2091 -0
  88. package/dist/chunk-7QYTIVXO.js +1051 -0
  89. package/dist/chunk-7SLLNRR3.js +129 -0
  90. package/dist/chunk-7V53QH5T.js +204 -0
  91. package/dist/chunk-7XDVTUTI.js +50 -0
  92. package/dist/chunk-A2E2TBDU.js +330 -0
  93. package/dist/chunk-A4DKFB77.js +159 -0
  94. package/dist/chunk-AUUJONUS.js +58 -0
  95. package/dist/chunk-B4YGGOCL.js +284 -0
  96. package/dist/chunk-BVYP37Y3.js +1345 -0
  97. package/dist/chunk-BXY5Y3RI.js +3955 -0
  98. package/dist/chunk-C3MK24X5.js +13696 -0
  99. package/dist/chunk-C74ZXYPJ.js +123 -0
  100. package/dist/chunk-CBO7IM7Q.js +135 -0
  101. package/dist/chunk-DIZLK77N.js +240 -0
  102. package/dist/chunk-DLTODKBW.js +1921 -0
  103. package/dist/chunk-DNJVH7A7.js +221 -0
  104. package/dist/chunk-E2FPTCL5.js +297 -0
  105. package/dist/chunk-E5USG7Z4.js +54 -0
  106. package/dist/chunk-E64IJVDT.js +85 -0
  107. package/dist/chunk-EFGQ72GA.js +76 -0
  108. package/dist/chunk-EODAYF7M.js +97 -0
  109. package/dist/chunk-EOKBXGMP.js +495 -0
  110. package/dist/chunk-EPYHCDZZ.js +551 -0
  111. package/dist/chunk-FHLIK2XG.js +38 -0
  112. package/dist/chunk-FO6CLTAL.js +128 -0
  113. package/dist/chunk-FSBNZ5YU.js +244 -0
  114. package/dist/chunk-FSGO7ADD.js +333 -0
  115. package/dist/chunk-G5L6YLG4.js +85 -0
  116. package/dist/chunk-GHPZEKDK.js +447 -0
  117. package/dist/chunk-GLSNVF6N.js +97 -0
  118. package/dist/chunk-GQ2XYRG3.js +163 -0
  119. package/dist/chunk-HGTXRRBK.js +230 -0
  120. package/dist/chunk-HILKCYA4.js +97 -0
  121. package/dist/chunk-HYI4PN4J.js +1148 -0
  122. package/dist/chunk-IDMLHBCK.js +1090 -0
  123. package/dist/chunk-IOVGBFTA.js +159 -0
  124. package/dist/chunk-ISAHJV4Z.js +346 -0
  125. package/dist/chunk-IXQ3XIG2.js +197 -0
  126. package/dist/chunk-JJ4VDZ5E.js +377 -0
  127. package/dist/chunk-JJOBSWJY.js +214 -0
  128. package/dist/chunk-JNRIWD5S.js +604 -0
  129. package/dist/chunk-JP45GCVR.js +630 -0
  130. package/dist/chunk-JWMFB6XM.js +244 -0
  131. package/dist/chunk-K7W4TYMT.js +33 -0
  132. package/dist/chunk-KFYOA37Q.js +562 -0
  133. package/dist/chunk-KUACUU74.js +58 -0
  134. package/dist/chunk-LHBWJIFR.js +290 -0
  135. package/dist/chunk-LMUDBSYR.js +551 -0
  136. package/dist/chunk-LSV3ODBA.js +13696 -0
  137. package/dist/chunk-M7GR2WO4.js +81 -0
  138. package/dist/chunk-MCBSXDR4.js +513 -0
  139. package/dist/chunk-MGJ2Z7QJ.js +127 -0
  140. package/dist/chunk-MUA24YMF.js +382 -0
  141. package/dist/chunk-MWDTPILI.js +204 -0
  142. package/dist/chunk-N4OGW6LW.js +731 -0
  143. package/dist/chunk-NBXL2BL5.js +330 -0
  144. package/dist/chunk-NT6A3EBV.js +1051 -0
  145. package/dist/chunk-ONEJTZID.js +348 -0
  146. package/dist/chunk-OREDDY5Y.js +513 -0
  147. package/dist/chunk-OSXQTCW5.js +55 -0
  148. package/dist/chunk-P2Q6UT2C.js +128 -0
  149. package/dist/chunk-PDIODWQM.js +731 -0
  150. package/dist/chunk-Q3NKXRHX.js +30 -0
  151. package/dist/chunk-QIEJRCF3.js +1148 -0
  152. package/dist/chunk-QILNBNN2.js +284 -0
  153. package/dist/chunk-QS7R2M4A.js +54 -0
  154. package/dist/chunk-RSIDQBIG.js +210 -0
  155. package/dist/chunk-SD6UFZRH.js +280 -0
  156. package/dist/chunk-SDL5IADB.js +76 -0
  157. package/dist/chunk-SFSGDC7D.js +81 -0
  158. package/dist/chunk-SHXHDHAX.js +127 -0
  159. package/dist/chunk-SQ5NFDBG.js +197 -0
  160. package/dist/chunk-SR34TKRT.js +214 -0
  161. package/dist/chunk-SYKAF5B3.js +185 -0
  162. package/dist/chunk-T2WWBFOX.js +447 -0
  163. package/dist/chunk-TINMRD3X.js +157 -0
  164. package/dist/chunk-TMV776ZJ.js +244 -0
  165. package/dist/chunk-TN45CTOI.js +70 -0
  166. package/dist/chunk-TYXB66FM.js +56 -0
  167. package/dist/chunk-UNCGZXPU.js +3556 -0
  168. package/dist/chunk-VAYBTLN4.js +50 -0
  169. package/dist/chunk-VGYL7CN2.js +260 -0
  170. package/dist/chunk-VIGJN5ZP.js +75 -0
  171. package/dist/chunk-WCFKKE7C.js +1921 -0
  172. package/dist/chunk-WEUOMPUC.js +346 -0
  173. package/dist/chunk-WRL6CIH2.js +262 -0
  174. package/dist/chunk-WS77NXRB.js +89 -0
  175. package/dist/chunk-XSRBNOLY.js +377 -0
  176. package/dist/chunk-XZLMH7QF.js +371 -0
  177. package/dist/chunk-YAITGMJO.js +89 -0
  178. package/dist/chunk-YDT3SUWK.js +171 -0
  179. package/dist/chunk-YG77F6MB.js +382 -0
  180. package/dist/chunk-YLWI3SAX.js +495 -0
  181. package/dist/chunk-YML4D7JL.js +818 -0
  182. package/dist/co-activation-V4G7RCBA.js +72 -0
  183. package/dist/co-occurrence-7AQY66CT.js +74 -0
  184. package/dist/code-context-index-GWAZ4PKV.js +30 -0
  185. package/dist/core-memory-FEVKN2AT.js +110 -0
  186. package/dist/core-memory-ISYNYO7T.js +110 -0
  187. package/dist/crdt-sync-INN5CLWY.js +33 -0
  188. package/dist/crm-webhook-2WGEYYAM.js +10 -0
  189. package/dist/crm-webhook-D7IORFLD.js +10 -0
  190. package/dist/cto-delegation-gate-2CMVCQW4.js +206 -0
  191. package/dist/cto-delegation-gate-DIMFA42F.js +206 -0
  192. package/dist/daemon-orchestration-G5HGOMGQ.js +135 -0
  193. package/dist/daemon-orchestration-IDK4LYVS.js +135 -0
  194. package/dist/db-backup-QDXIAYHX.js +33 -0
  195. package/dist/dreaming-A5QYLE67.js +32 -0
  196. package/dist/dreaming-CPFMD5SH.js +32 -0
  197. package/dist/entity-boost-BEVW2KFT.js +356 -0
  198. package/dist/exe-drift-Y6SN4EXZ.js +68 -0
  199. package/dist/exe-export-K4ZU3KZO.js +73 -0
  200. package/dist/exe-export-MZXEN45T.js +73 -0
  201. package/dist/exe-import-PWVIL5NW.js +76 -0
  202. package/dist/exe-import-R3AKAHWQ.js +76 -0
  203. package/dist/exe-key-BQVOD3YE.js +579 -0
  204. package/dist/exe-key-HXOWRGJT.js +579 -0
  205. package/dist/exe-snapshot-6URR2ANA.js +164 -0
  206. package/dist/exe-snapshot-C5JSC536.js +164 -0
  207. package/dist/fast-db-init-2CWMIQWR.js +7 -0
  208. package/dist/fast-db-init-UVZ2J5GS.js +7 -0
  209. package/dist/gateway/index.js +8 -8
  210. package/dist/git-staleness-VM6FPEQB.js +110 -0
  211. package/dist/git-task-sweep-ANHNEX7E.js +40 -0
  212. package/dist/git-task-sweep-R5BYJC3Y.js +40 -0
  213. package/dist/global-procedures-TLT6PO6L.js +20 -0
  214. package/dist/graph-auto-extract-BULI4PBB.js +162 -0
  215. package/dist/hooks/bug-report-worker.js +11 -11
  216. package/dist/hooks/codex-stop-task-finalizer.js +11 -11
  217. package/dist/hooks/commit-complete.js +11 -11
  218. package/dist/hooks/error-recall.js +6 -6
  219. package/dist/hooks/exe-heartbeat-hook.js +3 -3
  220. package/dist/hooks/ingest-worker.js +2 -2
  221. package/dist/hooks/ingest.js +6 -6
  222. package/dist/hooks/instructions-loaded.js +4 -4
  223. package/dist/hooks/manifest.json +20 -20
  224. package/dist/hooks/notification.js +4 -4
  225. package/dist/hooks/post-compact.js +10 -10
  226. package/dist/hooks/post-tool-combined.js +6 -6
  227. package/dist/hooks/pre-compact.js +13 -13
  228. package/dist/hooks/pre-tool-use.js +14 -14
  229. package/dist/hooks/prompt-submit.js +21 -21
  230. package/dist/hooks/session-end.js +18 -18
  231. package/dist/hooks/session-start.js +10 -10
  232. package/dist/hooks/stop.js +17 -17
  233. package/dist/hooks/subagent-stop.js +10 -10
  234. package/dist/hooks/summary-worker.js +16 -16
  235. package/dist/index.js +17 -17
  236. package/dist/installer-BEMMHBG5.js +342 -0
  237. package/dist/installer-CZWRBJ3Y.js +38 -0
  238. package/dist/installer-H43E54BM.js +38 -0
  239. package/dist/installer-HXKOP4YR.js +296 -0
  240. package/dist/installer-JAEYJUZW.js +342 -0
  241. package/dist/installer-ZPA6QLAX.js +296 -0
  242. package/dist/lib/cloud-sync.js +4 -4
  243. package/dist/lib/consolidation.js +5 -5
  244. package/dist/lib/database.js +2 -2
  245. package/dist/lib/db-daemon-client.js +1 -1
  246. package/dist/lib/db.js +2 -2
  247. package/dist/lib/embedder.js +2 -2
  248. package/dist/lib/employee-templates.js +4 -4
  249. package/dist/lib/employees.js +2 -2
  250. package/dist/lib/exe-daemon-client.js +1 -1
  251. package/dist/lib/exe-daemon.js +35 -35
  252. package/dist/lib/hybrid-search.js +5 -5
  253. package/dist/lib/identity.js +2 -2
  254. package/dist/lib/messaging.js +9 -9
  255. package/dist/lib/reminders.js +3 -3
  256. package/dist/lib/schedules.js +5 -5
  257. package/dist/lib/session-registry.js +4 -4
  258. package/dist/lib/skill-learning.js +4 -4
  259. package/dist/lib/store.js +4 -4
  260. package/dist/lib/task-router.js +3 -3
  261. package/dist/lib/tasks.js +10 -10
  262. package/dist/lib/tmux-routing.js +8 -8
  263. package/dist/lib/token-spend.js +3 -3
  264. package/dist/mcp/register-tools.js +57 -57
  265. package/dist/mcp/server.js +58 -58
  266. package/dist/mcp/tools/complete-reminder.js +4 -4
  267. package/dist/mcp/tools/create-reminder.js +4 -4
  268. package/dist/mcp/tools/create-task.js +12 -12
  269. package/dist/mcp/tools/deactivate-behavior.js +5 -5
  270. package/dist/mcp/tools/list-reminders.js +4 -4
  271. package/dist/mcp/tools/list-tasks.js +12 -12
  272. package/dist/mcp/tools/send-message.js +11 -11
  273. package/dist/mcp/tools/update-task.js +11 -11
  274. package/dist/mcp-http-config-44D7MOF6.js +27 -0
  275. package/dist/mcp-http-config-TCDXI6LL.js +27 -0
  276. package/dist/memory-cards-NNFQKOQI.js +174 -0
  277. package/dist/memory-graph-extractor-6VIBIUZM.js +17 -0
  278. package/dist/memory-poisoning-defense-P6WG3SNX.js +225 -0
  279. package/dist/memory-queue-client-O57KWE6B.js +16 -0
  280. package/dist/memory-reflection-FDJQ5ZDA.js +238 -0
  281. package/dist/message-queue-client-NITLPOBU.js +92 -0
  282. package/dist/notifications-4NS7LYYR.js +45 -0
  283. package/dist/notifications-L4NHSF2U.js +45 -0
  284. package/dist/orchestration-events-SSAWHTVL.js +25 -0
  285. package/dist/orchestrator-P3BTGGVB.js +33 -0
  286. package/dist/orchestrator-WNQFM4DU.js +33 -0
  287. package/dist/pipeline-router-AYPUBNHD.js +13 -0
  288. package/dist/pipeline-router-I7SA5NCJ.js +13 -0
  289. package/dist/plan-limits-GW3HHMGQ.js +26 -0
  290. package/dist/project-boot-TLNZDC2S.js +299 -0
  291. package/dist/projection-worker-MZFBSWCU.js +964 -0
  292. package/dist/reranker-IP2FXTLK.js +19 -0
  293. package/dist/reranker-RZB6XAOK.js +19 -0
  294. package/dist/review-polling-PRKTKLVD.js +124 -0
  295. package/dist/review-polling-TLFRX3H3.js +124 -0
  296. package/dist/runtime/index.js +11 -11
  297. package/dist/session-events-SOGVDZH6.js +36 -0
  298. package/dist/session-events-WHSKIP26.js +36 -0
  299. package/dist/session-kill-telemetry-AHFZUYJG.js +29 -0
  300. package/dist/session-scope-DNCP34ND.js +86 -0
  301. package/dist/session-scope-YWB765YV.js +86 -0
  302. package/dist/setup-wizard-IZSKLVWW.js +12 -0
  303. package/dist/skill-refinement-34DIUMPK.js +157 -0
  304. package/dist/skill-refinement-KB7RN46L.js +157 -0
  305. package/dist/stack-update-PQGX7KLH.js +52 -0
  306. package/dist/steward-gate-GX35HOTT.js +13 -0
  307. package/dist/task-enforcement-7NLUA7NZ.js +333 -0
  308. package/dist/task-enforcement-CO3UKUD3.js +333 -0
  309. package/dist/task-scope-4NTALPYO.js +35 -0
  310. package/dist/task-scope-J4QQT3DP.js +35 -0
  311. package/dist/tasks-crud-OJNNAL4F.js +77 -0
  312. package/dist/tasks-crud-T5DP4DUU.js +77 -0
  313. package/dist/tasks-notify-22255SAJ.js +38 -0
  314. package/dist/tasks-notify-ZVA4WIY5.js +38 -0
  315. package/dist/tasks-review-HMSWMG5X.js +47 -0
  316. package/dist/tasks-review-ODCDMDYP.js +47 -0
  317. package/dist/telemetry-upload-LCDD763H.js +739 -0
  318. package/dist/telemetry-upload-ZJOGSCD3.js +739 -0
  319. package/dist/token-budget-KQDJ5ZE5.js +84 -0
  320. package/dist/tool-capability-index-ZDDBVQT5.js +10 -0
  321. package/dist/tool-telemetry-AAUJQIIB.js +17 -0
  322. package/dist/tui/App.js +16 -16
  323. package/dist/tui-data-OYJAJYE4.js +258 -0
  324. package/dist/tui-data-QFMDLK6B.js +258 -0
  325. package/dist/wiki-acl-SH3BRQC2.js +111 -0
  326. package/dist/worker-gate-C366DEJR.js +21 -0
  327. package/dist/worker-gate-UZKHTBG7.js +21 -0
  328. package/dist/workflow-engine-5WGLCTKB.js +28 -0
  329. package/dist/workflow-engine-LNQ6G5E2.js +28 -0
  330. package/dist/worktree-BD7NDIDS.js +26 -0
  331. package/dist/worktree-sweep-6QFFMZUV.js +19 -0
  332. package/package.json +2 -2
  333. package/release-notes.json +30 -13
@@ -0,0 +1,163 @@
1
+ import {
2
+ recordOrchestrationEventBestEffort
3
+ } from "./chunk-JP45GCVR.js";
4
+
5
+ // src/lib/session-registry.ts
6
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
7
+ import { execSync } from "child_process";
8
+ import path from "path";
9
+ import os from "os";
10
+ var REGISTRY_PATH = path.join(os.homedir(), ".exe-os", "session-registry.json");
11
+ function registerSession(entry) {
12
+ const dir = path.dirname(REGISTRY_PATH);
13
+ if (!existsSync(dir)) {
14
+ mkdirSync(dir, { recursive: true });
15
+ }
16
+ const sessions = listSessions();
17
+ const idx = sessions.findIndex((s) => s.windowName === entry.windowName);
18
+ if (idx >= 0) {
19
+ sessions[idx] = entry;
20
+ } else {
21
+ sessions.push(entry);
22
+ }
23
+ writeFileSync(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
24
+ recordOrchestrationEventBestEffort({
25
+ eventType: "registry.registered",
26
+ source: "session-registry.registerSession",
27
+ agentId: entry.agentId,
28
+ sessionScope: entry.parentExe,
29
+ tmuxSession: entry.windowName,
30
+ payload: { hasProjectDir: Boolean(entry.projectDir) }
31
+ });
32
+ }
33
+ function refreshSessionProject(windowName, projectDir) {
34
+ const sessions = listSessions();
35
+ const entry = sessions.find((s) => s.windowName === windowName);
36
+ if (!entry || entry.projectDir === projectDir) return;
37
+ entry.projectDir = projectDir;
38
+ try {
39
+ writeFileSync(REGISTRY_PATH, JSON.stringify(sessions, null, 2));
40
+ } catch {
41
+ }
42
+ }
43
+ function listSessions() {
44
+ try {
45
+ const raw = readFileSync(REGISTRY_PATH, "utf8");
46
+ return JSON.parse(raw);
47
+ } catch {
48
+ return [];
49
+ }
50
+ }
51
+ function pruneStaleSessions() {
52
+ const sessions = listSessions();
53
+ if (sessions.length === 0) return 0;
54
+ let liveSessions = [];
55
+ try {
56
+ liveSessions = execSync("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
57
+ encoding: "utf8"
58
+ }).trim().split("\n").filter(Boolean);
59
+ } catch {
60
+ return 0;
61
+ }
62
+ const liveSet = new Set(liveSessions);
63
+ const alive = sessions.filter((s) => liveSet.has(s.windowName));
64
+ const staleSessions = sessions.filter((s) => !liveSet.has(s.windowName));
65
+ if (staleSessions.length > 0) {
66
+ recordOrchestrationEventBestEffort({
67
+ eventType: "registry.missing_tmux",
68
+ source: "session-registry.pruneStaleSessions",
69
+ severity: "warn",
70
+ attempt: staleSessions.length,
71
+ payload: {
72
+ count: staleSessions.length,
73
+ examples: staleSessions.slice(0, 5).map((s) => s.windowName)
74
+ }
75
+ });
76
+ }
77
+ const pruned = sessions.length - alive.length;
78
+ if (pruned > 0) {
79
+ writeFileSync(REGISTRY_PATH, JSON.stringify(alive, null, 2));
80
+ }
81
+ return pruned;
82
+ }
83
+ function checkSessionRegistryConsistency(liveSessionsOverride) {
84
+ const sessions = listSessions();
85
+ const result = { missingTmux: 0, missingRegistry: 0 };
86
+ let liveSessions = liveSessionsOverride;
87
+ if (!liveSessions) {
88
+ try {
89
+ liveSessions = execSync("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
90
+ encoding: "utf8"
91
+ }).trim().split("\n").filter(Boolean);
92
+ } catch {
93
+ return result;
94
+ }
95
+ }
96
+ const liveSet = new Set(liveSessions);
97
+ const registeredSet = new Set(sessions.map((s) => s.windowName));
98
+ const missingTmuxExamples = [];
99
+ const missingRegistryExamples = [];
100
+ for (const entry of sessions) {
101
+ if (liveSet.has(entry.windowName)) continue;
102
+ result.missingTmux++;
103
+ if (missingTmuxExamples.length < 5) missingTmuxExamples.push(entry.windowName);
104
+ }
105
+ for (const live of liveSessions) {
106
+ if (registeredSet.has(live)) continue;
107
+ if (!looksLikeExeOsSession(live)) continue;
108
+ result.missingRegistry++;
109
+ if (missingRegistryExamples.length < 5) missingRegistryExamples.push(live);
110
+ }
111
+ if (result.missingTmux > 0) {
112
+ recordOrchestrationEventBestEffort({
113
+ eventType: "registry.missing_tmux",
114
+ source: "session-registry.checkSessionRegistryConsistency",
115
+ severity: "warn",
116
+ attempt: result.missingTmux,
117
+ payload: {
118
+ count: result.missingTmux,
119
+ examples: missingTmuxExamples
120
+ }
121
+ });
122
+ }
123
+ if (result.missingRegistry > 0) {
124
+ recordOrchestrationEventBestEffort({
125
+ eventType: "registry.missing_entry",
126
+ source: "session-registry.checkSessionRegistryConsistency",
127
+ severity: "warn",
128
+ attempt: result.missingRegistry,
129
+ payload: {
130
+ count: result.missingRegistry,
131
+ examples: missingRegistryExamples
132
+ }
133
+ });
134
+ }
135
+ return result;
136
+ }
137
+ function looksLikeExeOsSession(sessionName) {
138
+ const coordName = getCoordinatorNameCached();
139
+ const escaped = coordName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
140
+ const coordPattern = new RegExp(`^${escaped}\\d*$`);
141
+ const employeePattern = new RegExp(`-${escaped}\\d*$`);
142
+ return coordPattern.test(sessionName) || employeePattern.test(sessionName);
143
+ }
144
+ function getCoordinatorNameCached() {
145
+ try {
146
+ const rosterPath = path.join(os.homedir(), ".exe-os", "exe-employees.json");
147
+ if (existsSync(rosterPath)) {
148
+ const roster = JSON.parse(readFileSync(rosterPath, "utf8"));
149
+ const coo = roster.find((e) => (e.role ?? "").toUpperCase() === "COO");
150
+ if (coo?.name) return coo.name;
151
+ }
152
+ } catch {
153
+ }
154
+ return "exe";
155
+ }
156
+
157
+ export {
158
+ registerSession,
159
+ refreshSessionProject,
160
+ listSessions,
161
+ pruneStaleSessions,
162
+ checkSessionRegistryConsistency
163
+ };
@@ -0,0 +1,230 @@
1
+ // src/bin/vps-health-gate.ts
2
+ import { spawnSync } from "child_process";
3
+ import { appendFileSync, existsSync, mkdirSync, readdirSync } from "fs";
4
+ import http from "http";
5
+ import path from "path";
6
+ var DEPLOY_LOG = "/opt/exe-stack/deploy-log.jsonl";
7
+ var BACKUP_DIR = "/opt/exe-stack/backups";
8
+ async function checkCRM() {
9
+ const start = Date.now();
10
+ try {
11
+ const status = await httpGet("http://localhost:3000/api");
12
+ return {
13
+ check: "crm",
14
+ status: status >= 200 && status < 400 ? "pass" : "fail",
15
+ message: status >= 200 && status < 400 ? `CRM healthy (HTTP ${status})` : `CRM unhealthy (HTTP ${status})`,
16
+ durationMs: Date.now() - start
17
+ };
18
+ } catch (err) {
19
+ return {
20
+ check: "crm",
21
+ status: "fail",
22
+ message: `CRM unreachable: ${err instanceof Error ? err.message : err}`,
23
+ durationMs: Date.now() - start
24
+ };
25
+ }
26
+ }
27
+ async function checkGateway() {
28
+ const start = Date.now();
29
+ try {
30
+ const status = await httpGet("http://localhost:3100/health");
31
+ return {
32
+ check: "gateway",
33
+ status: status >= 200 && status < 300 ? "pass" : "fail",
34
+ message: status >= 200 && status < 300 ? `Gateway healthy (HTTP ${status})` : `Gateway unhealthy (HTTP ${status})`,
35
+ durationMs: Date.now() - start
36
+ };
37
+ } catch (err) {
38
+ return {
39
+ check: "gateway",
40
+ status: "fail",
41
+ message: `Gateway unreachable: ${err instanceof Error ? err.message : err}`,
42
+ durationMs: Date.now() - start
43
+ };
44
+ }
45
+ }
46
+ function checkPostgres() {
47
+ const start = Date.now();
48
+ const databaseUrl = process.env.DATABASE_URL || "postgres://exe@localhost:5432/exedb";
49
+ const result = spawnSync("psql", [databaseUrl, "-c", "SELECT 1"], {
50
+ encoding: "utf8",
51
+ stdio: ["pipe", "pipe", "pipe"],
52
+ timeout: 1e4
53
+ });
54
+ return {
55
+ check: "postgres",
56
+ status: result.status === 0 ? "pass" : "fail",
57
+ message: result.status === 0 ? "Postgres responding" : `Postgres failed: ${result.stderr?.trim() || `exit ${result.status}`}`,
58
+ durationMs: Date.now() - start
59
+ };
60
+ }
61
+ function checkRawEvents() {
62
+ const start = Date.now();
63
+ const databaseUrl = process.env.DATABASE_URL || "postgres://exe@localhost:5432/exedb";
64
+ const result = spawnSync(
65
+ "psql",
66
+ [databaseUrl, "-t", "-c", "SELECT count(*) FROM raw.raw_events"],
67
+ {
68
+ encoding: "utf8",
69
+ stdio: ["pipe", "pipe", "pipe"],
70
+ timeout: 1e4
71
+ }
72
+ );
73
+ if (result.status !== 0) {
74
+ return {
75
+ check: "raw_events",
76
+ status: "fail",
77
+ message: `raw.raw_events query failed: ${result.stderr?.trim() || `exit ${result.status}`}`,
78
+ durationMs: Date.now() - start
79
+ };
80
+ }
81
+ const count = parseInt(result.stdout?.trim() || "0", 10);
82
+ return {
83
+ check: "raw_events",
84
+ status: count > 0 ? "pass" : "fail",
85
+ message: count > 0 ? `raw.raw_events has ${count} rows` : "raw.raw_events is empty",
86
+ durationMs: Date.now() - start
87
+ };
88
+ }
89
+ async function checkGoTrue() {
90
+ const start = Date.now();
91
+ try {
92
+ const status = await httpGet("http://localhost:9999/health");
93
+ return {
94
+ check: "gotrue",
95
+ status: status >= 200 && status < 300 ? "pass" : "fail",
96
+ message: status >= 200 && status < 300 ? `GoTrue healthy (HTTP ${status})` : `GoTrue unhealthy (HTTP ${status})`,
97
+ durationMs: Date.now() - start
98
+ };
99
+ } catch (err) {
100
+ return {
101
+ check: "gotrue",
102
+ status: "fail",
103
+ message: `GoTrue unreachable: ${err instanceof Error ? err.message : err}`,
104
+ durationMs: Date.now() - start
105
+ };
106
+ }
107
+ }
108
+ async function runHealthGate() {
109
+ console.log("[health-gate] Running post-deploy health checks...\n");
110
+ const results = [];
111
+ results.push(checkPostgres());
112
+ results.push(checkRawEvents());
113
+ results.push(await checkCRM());
114
+ results.push(await checkGateway());
115
+ results.push(await checkGoTrue());
116
+ const passed = results.every((r) => r.status === "pass");
117
+ for (const r of results) {
118
+ const icon = r.status === "pass" ? "\u2713" : "\u2717";
119
+ const color = r.status === "pass" ? "\x1B[32m" : "\x1B[31m";
120
+ console.log(` ${color}${icon}\x1B[0m ${r.check.padEnd(12)} ${r.message} (${r.durationMs}ms)`);
121
+ }
122
+ console.log("");
123
+ const result = {
124
+ passed,
125
+ results,
126
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
127
+ };
128
+ return result;
129
+ }
130
+ function logResult(result) {
131
+ mkdirSync(path.dirname(DEPLOY_LOG), { recursive: true });
132
+ const line = JSON.stringify({
133
+ ...result,
134
+ type: "health_gate"
135
+ }) + "\n";
136
+ try {
137
+ appendFileSync(DEPLOY_LOG, line);
138
+ console.log(`[health-gate] Result logged to ${DEPLOY_LOG}`);
139
+ } catch (err) {
140
+ console.warn(`[health-gate] Failed to write deploy log: ${err instanceof Error ? err.message : err}`);
141
+ }
142
+ }
143
+ function restorePreDeployBackup() {
144
+ if (!existsSync(BACKUP_DIR)) return false;
145
+ const backups = readdirSync(BACKUP_DIR).filter((f) => f.startsWith("pg-pre-deploy-") && f.endsWith(".dump")).sort().reverse();
146
+ if (backups.length === 0) {
147
+ console.warn("[health-gate] No pre-deploy backup found to restore");
148
+ return false;
149
+ }
150
+ const latest = backups[0];
151
+ const filepath = path.join(BACKUP_DIR, latest);
152
+ const databaseUrl = process.env.DATABASE_URL || "postgres://exe@localhost:5432/exedb";
153
+ console.log(`[health-gate] Restoring pre-deploy backup: ${latest}`);
154
+ const result = spawnSync("pg_restore", ["-d", databaseUrl, "--clean", "--if-exists", filepath], {
155
+ encoding: "utf8",
156
+ stdio: ["pipe", "pipe", "pipe"],
157
+ timeout: 3e5
158
+ });
159
+ if (result.status !== 0) {
160
+ console.error(`[health-gate] pg_restore failed: ${result.stderr?.trim() || `exit ${result.status}`}`);
161
+ return false;
162
+ }
163
+ console.log("[health-gate] \u2713 Pre-deploy backup restored");
164
+ return true;
165
+ }
166
+ function httpGet(url) {
167
+ return new Promise((resolve, reject) => {
168
+ const req = http.request(url, { method: "GET", timeout: 1e4 }, (res) => {
169
+ res.resume();
170
+ resolve(res.statusCode ?? 0);
171
+ });
172
+ req.on("timeout", () => req.destroy(new Error("timeout")));
173
+ req.on("error", reject);
174
+ req.end();
175
+ });
176
+ }
177
+ async function main(args) {
178
+ if (args.includes("--help") || args.includes("-h")) {
179
+ console.log(`
180
+ exe-os vps-health-gate \u2014 Post-deploy health checks
181
+
182
+ Runs 5 checks: Postgres, raw_events, CRM, Gateway, GoTrue.
183
+ If any check fails, triggers rollback and exits with code 1.
184
+
185
+ Usage:
186
+ exe-os vps-health-gate Run health gate
187
+ exe-os vps-health-gate --check-only Run checks without rollback on failure
188
+ `);
189
+ return;
190
+ }
191
+ const checkOnly = args.includes("--check-only");
192
+ const result = await runHealthGate();
193
+ logResult(result);
194
+ if (result.passed) {
195
+ console.log("[health-gate] \u2713 All checks passed \u2014 deploy is healthy");
196
+ return;
197
+ }
198
+ const failed = result.results.filter((r) => r.status === "fail");
199
+ console.error(`[health-gate] \u2717 ${failed.length} check(s) failed`);
200
+ if (checkOnly) {
201
+ process.exitCode = 1;
202
+ return;
203
+ }
204
+ console.log("[health-gate] Starting rollback...");
205
+ restorePreDeployBackup();
206
+ try {
207
+ const { rollbackStackUpdate, defaultStackPaths } = await import("./stack-update-PQGX7KLH.js");
208
+ const paths = defaultStackPaths();
209
+ await rollbackStackUpdate({
210
+ manifestRef: paths.manifestRef,
211
+ composeFile: paths.composeFile,
212
+ envFile: paths.envFile
213
+ });
214
+ console.log("[health-gate] \u2713 Stack rolled back to previous version");
215
+ } catch (err) {
216
+ console.error(`[health-gate] Stack rollback failed: ${err instanceof Error ? err.message : err}`);
217
+ }
218
+ process.exitCode = 1;
219
+ }
220
+
221
+ export {
222
+ checkCRM,
223
+ checkGateway,
224
+ checkPostgres,
225
+ checkRawEvents,
226
+ checkGoTrue,
227
+ runHealthGate,
228
+ logResult,
229
+ main
230
+ };
@@ -0,0 +1,97 @@
1
+ import {
2
+ loadEmployeesSync
3
+ } from "./chunk-UNCGZXPU.js";
4
+
5
+ // src/adapters/mcp-http-config.ts
6
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
7
+ import { randomBytes } from "crypto";
8
+ import { execFileSync } from "child_process";
9
+ import path from "path";
10
+ import os from "os";
11
+ var DEFAULT_MCP_HTTP_PORT = "48739";
12
+ function resolveDefaultAgentId() {
13
+ if (process.env.AGENT_ID && process.env.AGENT_ID !== "default") return process.env.AGENT_ID;
14
+ try {
15
+ const coo = loadEmployeesSync().find((e) => e.role === "COO");
16
+ if (coo) return coo.name;
17
+ } catch {
18
+ }
19
+ return "exe";
20
+ }
21
+ var DEFAULT_MCP_HTTP_AGENT_ID = resolveDefaultAgentId();
22
+ var DEFAULT_MCP_HTTP_AGENT_ROLE = "COO";
23
+ function mcpHttpPort() {
24
+ const raw = process.env.EXE_MCP_PORT?.trim();
25
+ if (!raw) return DEFAULT_MCP_HTTP_PORT;
26
+ if (!/^\d+$/.test(raw)) return DEFAULT_MCP_HTTP_PORT;
27
+ const port = Number(raw);
28
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) return DEFAULT_MCP_HTTP_PORT;
29
+ return raw;
30
+ }
31
+ function mcpHttpUrl() {
32
+ return `http://127.0.0.1:${mcpHttpPort()}/mcp`;
33
+ }
34
+ function readOrCreateDaemonToken(homeDir = os.homedir()) {
35
+ const exeDir = path.join(homeDir, ".exe-os");
36
+ const tokenPath = path.join(exeDir, "exed.token");
37
+ if (existsSync(tokenPath)) {
38
+ try {
39
+ const token2 = readFileSync(tokenPath, "utf-8").trim();
40
+ if (/^[a-f0-9]{64}$/i.test(token2)) return token2;
41
+ } catch {
42
+ }
43
+ }
44
+ const token = randomBytes(32).toString("hex");
45
+ mkdirSync(exeDir, { recursive: true });
46
+ writeFileSync(tokenPath, `${token}
47
+ `, "utf-8");
48
+ try {
49
+ chmodSync(tokenPath, 384);
50
+ } catch {
51
+ }
52
+ return token;
53
+ }
54
+ function buildMcpHttpHeaders(homeDir = os.homedir(), opts = {}) {
55
+ const agentId = opts.useShellPlaceholders ? "${AGENT_ID:-exe}" : opts.agentId ?? DEFAULT_MCP_HTTP_AGENT_ID;
56
+ const agentRole = opts.useShellPlaceholders ? "${AGENT_ROLE:-COO}" : opts.agentRole ?? DEFAULT_MCP_HTTP_AGENT_ROLE;
57
+ let sessionName = process.env.EXE_SESSION_NAME ?? "";
58
+ if (!sessionName && !opts.useShellPlaceholders) {
59
+ try {
60
+ const sock = process.env.EXE_TMUX_SOCKET;
61
+ const tmuxArgs = sock ? ["-L", sock, "display-message", "-p", "#{session_name}"] : ["display-message", "-p", "#{session_name}"];
62
+ const tmuxSession = execFileSync("tmux", tmuxArgs, {
63
+ encoding: "utf8",
64
+ timeout: 2e3
65
+ }).trim();
66
+ if (tmuxSession) sessionName = tmuxSession;
67
+ } catch {
68
+ }
69
+ }
70
+ const headers = {
71
+ Authorization: `Bearer ${readOrCreateDaemonToken(homeDir)}`,
72
+ "X-Agent-Id": agentId,
73
+ "X-Agent-Role": agentRole
74
+ };
75
+ if (sessionName && !opts.useShellPlaceholders) headers["X-Exe-Session"] = sessionName;
76
+ return headers;
77
+ }
78
+ function buildClaudeHttpMcpEntry(homeDir = os.homedir()) {
79
+ const entry = {
80
+ type: "http",
81
+ url: mcpHttpUrl(),
82
+ headers: buildMcpHttpHeaders(homeDir, { useShellPlaceholders: true })
83
+ };
84
+ delete entry.headers["X-Exe-Session"];
85
+ return entry;
86
+ }
87
+
88
+ export {
89
+ DEFAULT_MCP_HTTP_PORT,
90
+ DEFAULT_MCP_HTTP_AGENT_ID,
91
+ DEFAULT_MCP_HTTP_AGENT_ROLE,
92
+ mcpHttpPort,
93
+ mcpHttpUrl,
94
+ readOrCreateDaemonToken,
95
+ buildMcpHttpHeaders,
96
+ buildClaudeHttpMcpEntry
97
+ };