@askexenow/exe-os 0.9.299 → 0.9.301

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 (499) hide show
  1. package/deploy/compose/.env.customer.example +1 -1
  2. package/deploy/compose/.env.example +1 -1
  3. package/deploy/compose/docker-compose.yml +31 -5
  4. package/deploy/compose/erp-nginx/nginx.conf +6 -3
  5. package/deploy/compose/generate-env.ts +1 -1
  6. package/deploy/compose/observability/otel-collector-config.yaml +10 -1
  7. package/deploy/compose/setup.sh +1 -1
  8. package/dist/active-agent-56J56WW5.js +27 -0
  9. package/dist/active-agent-UNJO6AJ2.js +27 -0
  10. package/dist/active-agent-VDWK7TES.js +28 -0
  11. package/dist/active-agent-Y5LSIMVC.js +28 -0
  12. package/dist/agentic-ontology-MZ4WHFDE.js +25 -0
  13. package/dist/agentic-ontology-QEV7GI3T.js +25 -0
  14. package/dist/assets/com.askexe.exed.plist +6 -5
  15. package/dist/backfill-metadata-IHKI5GXV.js +600 -0
  16. package/dist/backfill-metadata-RQZ4BN7G.js +600 -0
  17. package/dist/backfill-metadata-ZU3SZNBD.js +600 -0
  18. package/dist/behaviors-A3L5CWMK.js +46 -0
  19. package/dist/behaviors-G4KWGS24.js +46 -0
  20. package/dist/behaviors-WO67R6C4.js +46 -0
  21. package/dist/bin/agentic-ontology-backfill.js +5 -5
  22. package/dist/bin/agentic-reflection-backfill.js +6 -6
  23. package/dist/bin/agentic-semantic-label.js +5 -5
  24. package/dist/bin/backfill-conversations.js +6 -6
  25. package/dist/bin/backfill-responses.js +6 -6
  26. package/dist/bin/backfill-vectors.js +8 -8
  27. package/dist/bin/bulk-sync-postgres.js +13 -7
  28. package/dist/bin/cc-doctor.js +5 -5
  29. package/dist/bin/cleanup-stale-review-tasks.js +10 -10
  30. package/dist/bin/cli.js +16 -16
  31. package/dist/bin/deferred-daemon-restart.js +1 -1
  32. package/dist/bin/exe-agent-config.js +2 -2
  33. package/dist/bin/exe-agent.js +10 -10
  34. package/dist/bin/exe-assign.js +8 -8
  35. package/dist/bin/exe-boot.js +36 -21
  36. package/dist/bin/exe-call.js +4 -4
  37. package/dist/bin/exe-cloud.js +13 -7
  38. package/dist/bin/exe-dispatch.js +10 -10
  39. package/dist/bin/exe-doctor.js +2 -2
  40. package/dist/bin/exe-export-behaviors.js +7 -7
  41. package/dist/bin/exe-forget.js +6 -6
  42. package/dist/bin/exe-gateway.js +7 -7
  43. package/dist/bin/exe-healthcheck.js +5 -5
  44. package/dist/bin/exe-heartbeat.js +10 -10
  45. package/dist/bin/exe-kill.js +13 -13
  46. package/dist/bin/exe-launch-agent.js +29 -19
  47. package/dist/bin/exe-new-employee.js +6 -6
  48. package/dist/bin/exe-pending-messages.js +11 -11
  49. package/dist/bin/exe-pending-notifications.js +10 -10
  50. package/dist/bin/exe-pending-reviews.js +10 -10
  51. package/dist/bin/exe-rename.js +4 -4
  52. package/dist/bin/exe-review.js +12 -12
  53. package/dist/bin/exe-search.js +5 -5
  54. package/dist/bin/exe-session-cleanup.js +15 -15
  55. package/dist/bin/exe-settings.js +13 -7
  56. package/dist/bin/exe-start-codex.js +11 -11
  57. package/dist/bin/exe-start-opencode.js +8 -8
  58. package/dist/bin/exe-status.js +11 -11
  59. package/dist/bin/exe-team.js +3 -3
  60. package/dist/bin/exe-watchdog.js +3 -3
  61. package/dist/bin/git-sweep.js +11 -11
  62. package/dist/bin/graph-backfill.js +6 -6
  63. package/dist/bin/graph-export.js +5 -5
  64. package/dist/bin/import-history.js +9 -9
  65. package/dist/bin/install-launchd.js +7 -3
  66. package/dist/bin/install.js +19 -15
  67. package/dist/bin/intercom-check.js +4 -4
  68. package/dist/bin/mcp-sessions.js +2 -2
  69. package/dist/bin/orchestration-metrics.js +4 -4
  70. package/dist/bin/postgres-agentic-reflection-backfill.js +2 -2
  71. package/dist/bin/postgres-agentic-semantic-backfill.js +1 -1
  72. package/dist/bin/pre-publish.js +24 -1
  73. package/dist/bin/scan-tasks.js +10 -10
  74. package/dist/bin/setup.js +1 -1
  75. package/dist/bin/shard-migrate.js +4 -4
  76. package/dist/bin/stack-update.js +123 -3
  77. package/dist/bin/vps-health-gate.js +1 -1
  78. package/dist/capability-cards-VTGDTOZ4.js +89 -0
  79. package/dist/capability-cards-XAQSL26B.js +89 -0
  80. package/dist/capacity-monitor-6MQLFFQT.js +51 -0
  81. package/dist/capacity-monitor-BB3LKJLE.js +51 -0
  82. package/dist/capacity-monitor-G2MAJPRP.js +51 -0
  83. package/dist/catchup-brief-BQSL5M5S.js +175 -0
  84. package/dist/catchup-brief-COALBX6L.js +175 -0
  85. package/dist/catchup-brief-VBGEJQRS.js +175 -0
  86. package/dist/cc-binary-detect-B5JDCJ5J.js +19 -0
  87. package/dist/chunk-22LDUTY7.js +14597 -0
  88. package/dist/chunk-24JVDLQJ.js +345 -0
  89. package/dist/chunk-24M4AJPG.js +128 -0
  90. package/dist/chunk-2B7RCTPT.js +85 -0
  91. package/dist/chunk-2QBA6YE6.js +127 -0
  92. package/dist/chunk-2RGDEBZC.js +731 -0
  93. package/dist/chunk-2T3OYZMR.js +1158 -0
  94. package/dist/chunk-32DBQWR5.js +333 -0
  95. package/dist/chunk-3ABY3QDX.js +199 -0
  96. package/dist/chunk-3EOPMTG2.js +128 -0
  97. package/dist/chunk-3G3ECFB5.js +668 -0
  98. package/dist/chunk-3LHOFGHT.js +280 -0
  99. package/dist/chunk-3NS4V4JW.js +382 -0
  100. package/dist/chunk-3NYY2NZ3.js +836 -0
  101. package/dist/chunk-3RA62PNQ.js +58 -0
  102. package/dist/chunk-3ROUD5WA.js +97 -0
  103. package/dist/chunk-3RY2ARDN.js +129 -0
  104. package/dist/chunk-3XRS5AVV.js +567 -0
  105. package/dist/chunk-3Y5IRIRU.js +290 -0
  106. package/dist/chunk-3YK7X5FD.js +1186 -0
  107. package/dist/chunk-3ZWWUKBI.js +210 -0
  108. package/dist/chunk-463G3VAH.js +122 -0
  109. package/dist/chunk-4L6PVYFE.js +54 -0
  110. package/dist/chunk-4LC7BFI2.js +76 -0
  111. package/dist/chunk-4O67LBMK.js +377 -0
  112. package/dist/chunk-4OIU3N6U.js +167 -0
  113. package/dist/chunk-4Z3FWLOE.js +836 -0
  114. package/dist/chunk-5BAU4T5G.js +208 -0
  115. package/dist/chunk-5FP7YHCG.js +1158 -0
  116. package/dist/chunk-5SYYMNPE.js +30 -0
  117. package/dist/chunk-5TO5PH7O.js +304 -0
  118. package/dist/chunk-5U3JZP62.js +1352 -0
  119. package/dist/chunk-5VNFXIGF.js +85 -0
  120. package/dist/chunk-5XD2Y463.js +402 -0
  121. package/dist/chunk-63AENHJC.js +123 -0
  122. package/dist/chunk-673IFJYB.js +731 -0
  123. package/dist/chunk-6UVUJNLY.js +1186 -0
  124. package/dist/chunk-7AWH47AR.js +448 -0
  125. package/dist/chunk-7KPWYWYL.js +290 -0
  126. package/dist/chunk-7P4B6AEP.js +227 -0
  127. package/dist/chunk-7URNGDEY.js +2145 -0
  128. package/dist/chunk-7VHOALNC.js +244 -0
  129. package/dist/chunk-ADZQBZOX.js +122 -0
  130. package/dist/chunk-APSZAEDO.js +1186 -0
  131. package/dist/chunk-ASHF6VO4.js +2265 -0
  132. package/dist/chunk-ASJHCAVL.js +38 -0
  133. package/dist/chunk-BT2LEHIW.js +448 -0
  134. package/dist/chunk-BTS5QUWB.js +50 -0
  135. package/dist/chunk-BWJDJ3BS.js +604 -0
  136. package/dist/chunk-CME46VWP.js +150 -0
  137. package/dist/chunk-D3ICCKXY.js +54 -0
  138. package/dist/chunk-D3IOU3NO.js +377 -0
  139. package/dist/chunk-DFGXRKI2.js +221 -0
  140. package/dist/chunk-DICIFTCS.js +150 -0
  141. package/dist/chunk-DIFI5JDC.js +76 -0
  142. package/dist/chunk-DO65VHQZ.js +128 -0
  143. package/dist/chunk-DPOIJ5SM.js +284 -0
  144. package/dist/chunk-E2OMUBXQ.js +567 -0
  145. package/dist/chunk-ECMXIV6N.js +97 -0
  146. package/dist/chunk-EDMVA3PT.js +727 -0
  147. package/dist/chunk-F5OSXH4A.js +4388 -0
  148. package/dist/chunk-F5OWHPRG.js +236 -0
  149. package/dist/chunk-F7MZA3QP.js +199 -0
  150. package/dist/chunk-FAZNXNA5.js +33 -0
  151. package/dist/chunk-FCHG5RC4.js +197 -0
  152. package/dist/chunk-FFKSPZO2.js +157 -0
  153. package/dist/chunk-FNHYH5U6.js +331 -0
  154. package/dist/chunk-FRNXQSB4.js +134 -0
  155. package/dist/chunk-FTAASABV.js +362 -0
  156. package/dist/chunk-FWPDAQ6Q.js +1350 -0
  157. package/dist/chunk-FZB73QOI.js +210 -0
  158. package/dist/chunk-GBL5QSTM.js +197 -0
  159. package/dist/chunk-GJBR6QLD.js +630 -0
  160. package/dist/chunk-GRSYAHKI.js +535 -0
  161. package/dist/chunk-GRXWINOW.js +244 -0
  162. package/dist/chunk-GUPNVUG5.js +348 -0
  163. package/dist/chunk-GY66UPMX.js +167 -0
  164. package/dist/chunk-HCCG67BY.js +43 -0
  165. package/dist/chunk-HCSZZXZZ.js +197 -0
  166. package/dist/chunk-HNGNZU62.js +240 -0
  167. package/dist/chunk-HP2D5LIE.js +214 -0
  168. package/dist/chunk-HUABQHDC.js +1352 -0
  169. package/dist/chunk-HYKO2LNW.js +157 -0
  170. package/dist/chunk-IFL6DG2K.js +181 -0
  171. package/dist/chunk-IKPQRHVQ.js +304 -0
  172. package/dist/chunk-J5HFRVNW.js +362 -0
  173. package/dist/chunk-J6SD7LT2.js +171 -0
  174. package/dist/chunk-JCWA3X6A.js +402 -0
  175. package/dist/chunk-JHPK33IP.js +2162 -0
  176. package/dist/chunk-JURL2S27.js +128 -0
  177. package/dist/chunk-JWGDH5I2.js +127 -0
  178. package/dist/chunk-KBXQFXYM.js +567 -0
  179. package/dist/chunk-KGY5QIOJ.js +1350 -0
  180. package/dist/chunk-KLES22FB.js +1094 -0
  181. package/dist/chunk-KPUYYOFS.js +122 -0
  182. package/dist/chunk-KY43UELJ.js +331 -0
  183. package/dist/chunk-L32V4O5Z.js +58 -0
  184. package/dist/chunk-LAFARYU5.js +456 -0
  185. package/dist/chunk-LC7ETNTJ.js +1350 -0
  186. package/dist/chunk-LEJ5FKIK.js +55 -0
  187. package/dist/chunk-LNLLCAI4.js +377 -0
  188. package/dist/chunk-LQWZYMNU.js +448 -0
  189. package/dist/chunk-LSDXEHKL.js +381 -0
  190. package/dist/chunk-LY3SOO73.js +76 -0
  191. package/dist/chunk-M6CIHXXB.js +159 -0
  192. package/dist/chunk-MJOQ35DX.js +427 -0
  193. package/dist/chunk-MO5HER5Y.js +345 -0
  194. package/dist/chunk-MS2EOZJQ.js +290 -0
  195. package/dist/chunk-MUIMJGSQ.js +128 -0
  196. package/dist/chunk-MY4TGLT6.js +284 -0
  197. package/dist/chunk-N3ARGCVG.js +345 -0
  198. package/dist/chunk-N4XG2M2U.js +735 -0
  199. package/dist/chunk-N72JNFJ4.js +535 -0
  200. package/dist/chunk-NJMPNYBS.js +427 -0
  201. package/dist/chunk-NM3AUMFE.js +2145 -0
  202. package/dist/chunk-NPPQ3TR4.js +735 -0
  203. package/dist/chunk-NTWF4DAF.js +581 -0
  204. package/dist/chunk-NXL3VKXM.js +331 -0
  205. package/dist/chunk-OJACH2JF.js +128 -0
  206. package/dist/chunk-OMSLHEEF.js +456 -0
  207. package/dist/chunk-OO4IFABD.js +382 -0
  208. package/dist/chunk-OYIP3QVN.js +167 -0
  209. package/dist/chunk-P2IOW54H.js +668 -0
  210. package/dist/chunk-P5KXQ3RN.js +731 -0
  211. package/dist/chunk-P5UXP53T.js +81 -0
  212. package/dist/chunk-PH6VRRFR.js +395 -0
  213. package/dist/chunk-Q3GKOF7Z.js +85 -0
  214. package/dist/chunk-Q65NCNL4.js +1352 -0
  215. package/dist/chunk-QIGS2LRT.js +735 -0
  216. package/dist/chunk-QKBN3CY2.js +381 -0
  217. package/dist/chunk-QNNAVMQH.js +1094 -0
  218. package/dist/chunk-QODDW4YI.js +171 -0
  219. package/dist/chunk-QPAYPTSH.js +2162 -0
  220. package/dist/chunk-QRWDJ5RI.js +381 -0
  221. package/dist/chunk-RBFZCHVB.js +105 -0
  222. package/dist/chunk-RCEULTPF.js +185 -0
  223. package/dist/chunk-RCGHXBCX.js +630 -0
  224. package/dist/chunk-ROSCLRTH.js +204 -0
  225. package/dist/chunk-RYAOSGUW.js +227 -0
  226. package/dist/chunk-S2SPGHPY.js +38 -0
  227. package/dist/chunk-S73ZAJ2S.js +262 -0
  228. package/dist/chunk-SBPEWD7Z.js +171 -0
  229. package/dist/chunk-SDPUWZP5.js +333 -0
  230. package/dist/chunk-SJ4UF7YK.js +1094 -0
  231. package/dist/chunk-SOZ7D77I.js +204 -0
  232. package/dist/chunk-SVLSHDNL.js +54 -0
  233. package/dist/chunk-SVUYBT5N.js +262 -0
  234. package/dist/chunk-T7PTLVJV.js +284 -0
  235. package/dist/chunk-TDX2LK2M.js +240 -0
  236. package/dist/chunk-TGUSLO4B.js +50 -0
  237. package/dist/chunk-TPJH6PE6.js +1158 -0
  238. package/dist/chunk-TVW7EDOJ.js +382 -0
  239. package/dist/chunk-TYRUIE6P.js +58 -0
  240. package/dist/chunk-U5RKGLV6.js +50 -0
  241. package/dist/chunk-UFGTHBHP.js +127 -0
  242. package/dist/chunk-ULCYWCPI.js +1079 -0
  243. package/dist/chunk-UN5EPVBN.js +14597 -0
  244. package/dist/chunk-URLH7ZVR.js +70 -0
  245. package/dist/chunk-USYRTGR7.js +402 -0
  246. package/dist/chunk-V4ABCEHM.js +30 -0
  247. package/dist/chunk-V6LOEOXG.js +3372 -0
  248. package/dist/chunk-VAZOVAW4.js +2162 -0
  249. package/dist/chunk-VEUQVKKT.js +185 -0
  250. package/dist/chunk-VIDDJ5RF.js +214 -0
  251. package/dist/chunk-VKCNXOQ6.js +214 -0
  252. package/dist/chunk-VNB4ROYG.js +348 -0
  253. package/dist/chunk-VWUQFZFB.js +395 -0
  254. package/dist/chunk-W77GRCNA.js +85 -0
  255. package/dist/chunk-WB2B25UM.js +230 -0
  256. package/dist/chunk-WCUZX7F7.js +204 -0
  257. package/dist/chunk-WL5RMOZQ.js +362 -0
  258. package/dist/chunk-WPAXAOHD.js +1079 -0
  259. package/dist/chunk-WVMG4ZRH.js +14597 -0
  260. package/dist/chunk-WYVOTRRZ.js +129 -0
  261. package/dist/chunk-XABJRAUW.js +3346 -0
  262. package/dist/chunk-XQQ7D4I4.js +85 -0
  263. package/dist/chunk-YDFY6YCH.js +280 -0
  264. package/dist/chunk-YGUMRYCN.js +33 -0
  265. package/dist/chunk-YHJPTIPR.js +836 -0
  266. package/dist/chunk-YJSP5PPG.js +128 -0
  267. package/dist/chunk-YLKS7KKC.js +2145 -0
  268. package/dist/chunk-YOMETWOJ.js +4388 -0
  269. package/dist/chunk-YU3KEVCO.js +333 -0
  270. package/dist/chunk-Z4FVFSE3.js +81 -0
  271. package/dist/chunk-Z4TLSNUW.js +244 -0
  272. package/dist/chunk-ZDPU3JTF.js +221 -0
  273. package/dist/chunk-ZDY4LYAJ.js +81 -0
  274. package/dist/chunk-ZG33AACD.js +70 -0
  275. package/dist/chunk-ZKHPZ6KN.js +181 -0
  276. package/dist/chunk-ZO2TM5N5.js +97 -0
  277. package/dist/chunk-ZP6T5K6I.js +535 -0
  278. package/dist/chunk-ZR6ZJT32.js +123 -0
  279. package/dist/chunk-ZSUACDQC.js +4388 -0
  280. package/dist/co-activation-JGF5YIDU.js +74 -0
  281. package/dist/co-activation-XM25BLZM.js +74 -0
  282. package/dist/co-occurrence-CKEMDPWO.js +95 -0
  283. package/dist/co-occurrence-HLLC6GT2.js +95 -0
  284. package/dist/co-occurrence-W2LIAPHI.js +95 -0
  285. package/dist/code-context-index-FCL47WKE.js +30 -0
  286. package/dist/conversation-entity-extractor-WC2RU6RS.js +114 -0
  287. package/dist/core-memory-CRSR2PSL.js +110 -0
  288. package/dist/core-memory-VSKFRMEV.js +110 -0
  289. package/dist/core-memory-ZDA76EU3.js +110 -0
  290. package/dist/crdt-sync-6VH2YDVY.js +33 -0
  291. package/dist/crdt-sync-BJKZB6T6.js +33 -0
  292. package/dist/crm-webhook-E5PAFAUN.js +10 -0
  293. package/dist/crm-webhook-RXFPZJXP.js +10 -0
  294. package/dist/crm-webhook-Z26LEFKG.js +10 -0
  295. package/dist/cto-delegation-gate-45IBLPTK.js +280 -0
  296. package/dist/cto-delegation-gate-EMY6ZZ2F.js +280 -0
  297. package/dist/cto-delegation-gate-SF4EUB2Q.js +280 -0
  298. package/dist/daemon-orchestration-VB3BLYIT.js +143 -0
  299. package/dist/daemon-orchestration-W66UYGUD.js +143 -0
  300. package/dist/daemon-orchestration-Y5Y6YNE3.js +143 -0
  301. package/dist/db-backup-HFJ53IBU.js +43 -0
  302. package/dist/db-backup-NVUTS7L5.js +43 -0
  303. package/dist/doc-graph-extractor-ID45AQ2P.js +133 -0
  304. package/dist/doc-graph-extractor-MLYQYT4B.js +133 -0
  305. package/dist/doc-graph-extractor-SVFSXKL6.js +133 -0
  306. package/dist/dreaming-AZYRAGKA.js +34 -0
  307. package/dist/dreaming-N6B7KBIE.js +34 -0
  308. package/dist/dreaming-WG5CDUHX.js +34 -0
  309. package/dist/entity-boost-XAFCDDB6.js +375 -0
  310. package/dist/exe-drift-3SGA53CL.js +70 -0
  311. package/dist/exe-drift-CPUEAPIU.js +70 -0
  312. package/dist/exe-export-4RTGDV53.js +77 -0
  313. package/dist/exe-export-APUNLKWF.js +77 -0
  314. package/dist/exe-export-NM4SXB3P.js +77 -0
  315. package/dist/exe-import-6GLNCP62.js +80 -0
  316. package/dist/exe-import-AZMIF34Z.js +80 -0
  317. package/dist/exe-import-U4H4ES3Z.js +80 -0
  318. package/dist/exe-key-FIPXUTMF.js +673 -0
  319. package/dist/exe-key-LJV23AJI.js +673 -0
  320. package/dist/exe-key-WTLCMOYJ.js +673 -0
  321. package/dist/exe-snapshot-ILO3WSEC.js +338 -0
  322. package/dist/exe-snapshot-IODRQLBX.js +338 -0
  323. package/dist/exe-snapshot-ZOZBW7V6.js +338 -0
  324. package/dist/fast-db-init-7LYYUCSJ.js +7 -0
  325. package/dist/fast-db-init-ATRZGHOL.js +7 -0
  326. package/dist/fast-db-init-IU7GYFWB.js +7 -0
  327. package/dist/gateway/index.js +11 -11
  328. package/dist/git-staleness-GGCFPHQ5.js +112 -0
  329. package/dist/git-staleness-XNOKI4D3.js +112 -0
  330. package/dist/git-task-sweep-3MO4OVND.js +42 -0
  331. package/dist/git-task-sweep-M3SWXFKJ.js +42 -0
  332. package/dist/git-task-sweep-Y6KNWB67.js +42 -0
  333. package/dist/global-procedures-626WAU3I.js +22 -0
  334. package/dist/global-procedures-EBAPPWGZ.js +22 -0
  335. package/dist/graph-auto-extract-TKHQ4OR3.js +183 -0
  336. package/dist/graph-auto-extract-VGFEWFZX.js +183 -0
  337. package/dist/graph-auto-extract-VJOUQBPK.js +183 -0
  338. package/dist/graph-rag-KECA5TE4.js +35 -0
  339. package/dist/hooks/bug-report-worker.js +12 -12
  340. package/dist/hooks/codex-stop-task-finalizer.js +12 -12
  341. package/dist/hooks/commit-complete.js +12 -12
  342. package/dist/hooks/error-recall.js +6 -6
  343. package/dist/hooks/exe-heartbeat-hook.js +3 -3
  344. package/dist/hooks/ingest-worker.js +3 -3
  345. package/dist/hooks/ingest.js +6 -6
  346. package/dist/hooks/instructions-loaded.js +4 -4
  347. package/dist/hooks/manifest.json +20 -20
  348. package/dist/hooks/notification.js +4 -4
  349. package/dist/hooks/post-compact.js +12 -12
  350. package/dist/hooks/post-tool-combined.js +6 -6
  351. package/dist/hooks/pre-compact.js +16 -16
  352. package/dist/hooks/pre-tool-use.js +15 -15
  353. package/dist/hooks/prompt-submit.js +28 -26
  354. package/dist/hooks/session-end.js +20 -20
  355. package/dist/hooks/session-start.js +12 -12
  356. package/dist/hooks/stop.js +18 -18
  357. package/dist/hooks/subagent-stop.js +11 -11
  358. package/dist/hooks/summary-worker.js +18 -18
  359. package/dist/index.js +20 -20
  360. package/dist/installer-37KFNAWE.js +344 -0
  361. package/dist/installer-3FB5EMPB.js +40 -0
  362. package/dist/installer-BRQ42CPB.js +344 -0
  363. package/dist/installer-F55NR4E2.js +298 -0
  364. package/dist/installer-KOYBUS4J.js +40 -0
  365. package/dist/installer-PXZJG256.js +298 -0
  366. package/dist/lib/cloud-sync.js +13 -7
  367. package/dist/lib/consolidation.js +7 -7
  368. package/dist/lib/database.js +6 -4
  369. package/dist/lib/db-daemon-client.js +11 -202
  370. package/dist/lib/db.js +6 -4
  371. package/dist/lib/embedder.js +3 -3
  372. package/dist/lib/employee-templates.js +4 -4
  373. package/dist/lib/employees.js +2 -2
  374. package/dist/lib/exe-daemon-client.js +2 -2
  375. package/dist/lib/exe-daemon.js +53 -51
  376. package/dist/lib/hybrid-search.js +5 -5
  377. package/dist/lib/identity.js +2 -2
  378. package/dist/lib/messaging.js +10 -10
  379. package/dist/lib/reminders.js +3 -3
  380. package/dist/lib/schedules.js +5 -5
  381. package/dist/lib/session-registry.js +4 -4
  382. package/dist/lib/skill-learning.js +6 -6
  383. package/dist/lib/store.js +4 -4
  384. package/dist/lib/task-router.js +3 -3
  385. package/dist/lib/tasks.js +11 -11
  386. package/dist/lib/tmux-routing.js +9 -9
  387. package/dist/lib/token-spend.js +3 -3
  388. package/dist/mcp/register-tools.js +65 -63
  389. package/dist/mcp/server.js +66 -64
  390. package/dist/mcp/tools/complete-reminder.js +4 -4
  391. package/dist/mcp/tools/create-reminder.js +4 -4
  392. package/dist/mcp/tools/create-task.js +13 -13
  393. package/dist/mcp/tools/deactivate-behavior.js +7 -7
  394. package/dist/mcp/tools/list-reminders.js +4 -4
  395. package/dist/mcp/tools/list-tasks.js +13 -13
  396. package/dist/mcp/tools/send-message.js +12 -12
  397. package/dist/mcp/tools/update-task.js +12 -12
  398. package/dist/mcp-http-config-7KJZI7UD.js +31 -0
  399. package/dist/mcp-http-config-OF3MB7M5.js +31 -0
  400. package/dist/memory-cards-CPIZVXWI.js +180 -0
  401. package/dist/memory-cards-ZIT7ZKL5.js +180 -0
  402. package/dist/memory-graph-extractor-JIYWLBFF.js +22 -0
  403. package/dist/memory-graph-extractor-LY2VORZT.js +22 -0
  404. package/dist/memory-graph-extractor-MDPSLZDM.js +22 -0
  405. package/dist/memory-poisoning-defense-5UZT3WWA.js +224 -0
  406. package/dist/memory-poisoning-defense-SEM25TY5.js +224 -0
  407. package/dist/memory-queue-client-WKWRFERJ.js +16 -0
  408. package/dist/memory-reflection-J2W7CJ7C.js +244 -0
  409. package/dist/memory-reflection-TA2VQYPH.js +244 -0
  410. package/dist/message-queue-client-IFQQ2HI7.js +92 -0
  411. package/dist/notifications-CZBQ3H5T.js +47 -0
  412. package/dist/notifications-EIIL2EQV.js +47 -0
  413. package/dist/notifications-RLMSI4YE.js +47 -0
  414. package/dist/orchestration-events-TGQYA72K.js +27 -0
  415. package/dist/orchestration-events-VUYR6MXE.js +27 -0
  416. package/dist/orchestrator-JQD5G3CW.js +35 -0
  417. package/dist/orchestrator-MAMR4C37.js +35 -0
  418. package/dist/orchestrator-VE5WHEJH.js +35 -0
  419. package/dist/pipeline-router-3Q3YBYSM.js +15 -0
  420. package/dist/pipeline-router-DKXD6DJO.js +15 -0
  421. package/dist/pipeline-router-YNW63BY5.js +15 -0
  422. package/dist/plan-limits-YGXTYCW4.js +28 -0
  423. package/dist/plan-limits-ZM4MNZKY.js +28 -0
  424. package/dist/project-boot-E2TWYTAC.js +299 -0
  425. package/dist/project-boot-TDOZKKDR.js +299 -0
  426. package/dist/projection-worker-TMKUSVGD.js +1084 -0
  427. package/dist/projection-worker-WFPRM4AI.js +1084 -0
  428. package/dist/projection-worker-YKV3PFCV.js +1084 -0
  429. package/dist/prospective-memory-CNJDBNWF.js +232 -0
  430. package/dist/prospective-memory-OAFZUODU.js +232 -0
  431. package/dist/reranker-AFU75HEX.js +19 -0
  432. package/dist/reranker-RYNSJNDF.js +19 -0
  433. package/dist/reranker-YQIRNGDM.js +19 -0
  434. package/dist/retrieval-health-M5BVB7EV.js +12 -0
  435. package/dist/retrieval-health-RSQEIYIB.js +12 -0
  436. package/dist/review-polling-LGX7DUNT.js +126 -0
  437. package/dist/review-polling-MJBCYV4I.js +126 -0
  438. package/dist/review-polling-ZMB3OBPC.js +126 -0
  439. package/dist/runtime/index.js +16 -16
  440. package/dist/services/codex-reviewd/index.js +855 -0
  441. package/dist/session-events-5N47BRFK.js +38 -0
  442. package/dist/session-events-PT6SVS2P.js +38 -0
  443. package/dist/session-events-UTMCKDIN.js +38 -0
  444. package/dist/session-kill-telemetry-FRQA5MVD.js +31 -0
  445. package/dist/session-kill-telemetry-HKL2NQMR.js +31 -0
  446. package/dist/session-scope-2BD6QLNI.js +88 -0
  447. package/dist/session-scope-GQNCM6UQ.js +88 -0
  448. package/dist/session-scope-MMGM232A.js +88 -0
  449. package/dist/setup-wizard-SELXXVLD.js +12 -0
  450. package/dist/setup-wizard-W64I6SHC.js +12 -0
  451. package/dist/setup-wizard-X7YSRDNQ.js +12 -0
  452. package/dist/skill-refinement-CCP4ULZ3.js +159 -0
  453. package/dist/skill-refinement-FXCXTUS2.js +159 -0
  454. package/dist/skill-refinement-WCPDNHZ5.js +159 -0
  455. package/dist/stack-update-5VSGG36W.js +84 -0
  456. package/dist/steward-gate-JDR3SLH3.js +15 -0
  457. package/dist/steward-gate-PIXNK4BK.js +15 -0
  458. package/dist/task-enforcement-LEBWCYZT.js +506 -0
  459. package/dist/task-enforcement-VOSQRAQB.js +506 -0
  460. package/dist/task-enforcement-WCEA4FZI.js +506 -0
  461. package/dist/task-scope-CQZ33PRU.js +37 -0
  462. package/dist/task-scope-JTTEZKDU.js +37 -0
  463. package/dist/task-scope-L5GDL2AV.js +37 -0
  464. package/dist/tasks-crud-DC4GCXQQ.js +79 -0
  465. package/dist/tasks-crud-S36AFYYM.js +79 -0
  466. package/dist/tasks-crud-T32IRPXF.js +79 -0
  467. package/dist/tasks-notify-OBFVHJDP.js +40 -0
  468. package/dist/tasks-notify-OUQWUM6W.js +40 -0
  469. package/dist/tasks-notify-W2W2BJRB.js +40 -0
  470. package/dist/tasks-review-34WV7BX2.js +49 -0
  471. package/dist/tasks-review-N33MTHWJ.js +49 -0
  472. package/dist/tasks-review-OSBG2YN2.js +49 -0
  473. package/dist/telemetry-upload-3CSVO3J7.js +741 -0
  474. package/dist/telemetry-upload-EYHEWTKG.js +741 -0
  475. package/dist/telemetry-upload-XLBW4DRP.js +741 -0
  476. package/dist/token-budget-I6FMMDFX.js +86 -0
  477. package/dist/token-budget-ZG2MQ5GD.js +86 -0
  478. package/dist/tool-capability-index-IWQBQKM7.js +10 -0
  479. package/dist/tool-telemetry-2E3Z7CRV.js +17 -0
  480. package/dist/tool-telemetry-ODL4F2CW.js +17 -0
  481. package/dist/tui/App.js +17 -17
  482. package/dist/tui-data-VWT4Q5UT.js +260 -0
  483. package/dist/tui-data-XFBFBSBE.js +260 -0
  484. package/dist/tui-data-Z5UF7KEI.js +260 -0
  485. package/dist/wiki-acl-EUOPNUIQ.js +111 -0
  486. package/dist/wiki-acl-SZFHCEC4.js +111 -0
  487. package/dist/worker-gate-OOO6BWZ6.js +21 -0
  488. package/dist/worker-gate-OQMKAMP7.js +21 -0
  489. package/dist/worker-gate-ZPP3SZK6.js +21 -0
  490. package/dist/workflow-engine-P7WYJP2B.js +28 -0
  491. package/dist/workflow-engine-QY3IFFR2.js +28 -0
  492. package/dist/workflow-engine-UYNB5RTB.js +28 -0
  493. package/dist/worktree-CNOQZBNT.js +28 -0
  494. package/dist/worktree-H5C4LMQR.js +28 -0
  495. package/dist/worktree-sweep-KFWF3XZD.js +21 -0
  496. package/dist/worktree-sweep-SE7ITXC4.js +21 -0
  497. package/package.json +1 -1
  498. package/release-notes.json +117 -191
  499. package/src/commands/exe.md +18 -1
@@ -0,0 +1,1084 @@
1
+ import {
2
+ extractGoalCandidates,
3
+ inferIntention,
4
+ inferOntologyEventType,
5
+ inferOutcome,
6
+ inferSemanticLabel,
7
+ ontologyPayload
8
+ } from "./chunk-S73ZAJ2S.js";
9
+ import {
10
+ processCRMEvent
11
+ } from "./chunk-OO4IFABD.js";
12
+ import {
13
+ loadConfig
14
+ } from "./chunk-R36FAN53.js";
15
+ import "./chunk-LYH5HE24.js";
16
+ import "./chunk-MLKGABMK.js";
17
+
18
+ // src/lib/projection-worker.ts
19
+ import os from "os";
20
+ import path from "path";
21
+ import { existsSync } from "fs";
22
+ import { createRequire } from "module";
23
+ import { pathToFileURL } from "url";
24
+ var GRAPH_SCHEMA = "graph";
25
+ var prismaPromise = null;
26
+ var ontologySchemaReady = false;
27
+ var filteredSchemaReady = false;
28
+ function loadPrisma() {
29
+ if (!prismaPromise) {
30
+ prismaPromise = (async () => {
31
+ const explicitPath = process.env.EXE_OS_PRISMA_CLIENT_PATH;
32
+ if (explicitPath) {
33
+ const mod = await import(pathToFileURL(explicitPath).href);
34
+ const Ctor = mod.PrismaClient ?? mod.default?.PrismaClient;
35
+ if (!Ctor) throw new Error(`No PrismaClient at ${explicitPath}`);
36
+ return new Ctor();
37
+ }
38
+ const exeDbRoot = process.env.EXE_DB_ROOT ?? path.join(os.homedir(), "exe-db");
39
+ const packagePath = path.join(exeDbRoot, "package.json");
40
+ if (existsSync(packagePath)) {
41
+ const req = createRequire(packagePath);
42
+ const entry = req.resolve("@prisma/client");
43
+ const mod = await import(pathToFileURL(entry).href);
44
+ const Ctor = mod.PrismaClient ?? mod.default?.PrismaClient;
45
+ if (!Ctor) throw new Error(`No PrismaClient in ${entry}`);
46
+ return new Ctor();
47
+ }
48
+ const { Pool } = await import("pg");
49
+ const { pgSslConfig } = await import("./pg-ssl-7JXQFL4I.js");
50
+ const pool = new Pool({ connectionString: process.env.DATABASE_URL, ...pgSslConfig() });
51
+ return {
52
+ async $queryRawUnsafe(query, ...values) {
53
+ const result = await pool.query(query, values);
54
+ return result.rows;
55
+ },
56
+ async $executeRawUnsafe(query, ...values) {
57
+ const result = await pool.query(query, values);
58
+ return result.rowCount ?? 0;
59
+ },
60
+ async $disconnect() {
61
+ await pool.end();
62
+ }
63
+ };
64
+ })();
65
+ }
66
+ return prismaPromise;
67
+ }
68
+ function setProjectionWorkerPrismaClientForTests(client) {
69
+ prismaPromise = client ? Promise.resolve(client) : null;
70
+ }
71
+ function resetProjectionWorkerForTests() {
72
+ running = false;
73
+ if (pollTimer) {
74
+ clearTimeout(pollTimer);
75
+ pollTimer = null;
76
+ }
77
+ consecutivePollErrors = 0;
78
+ prismaPromise = null;
79
+ ontologySchemaReady = false;
80
+ filteredSchemaReady = false;
81
+ lastWikiApiPushAt = 0;
82
+ }
83
+ function stableId(input) {
84
+ let h1 = 3735928559;
85
+ let h2 = 1103547991;
86
+ for (let i = 0; i < input.length; i++) {
87
+ const ch = input.charCodeAt(i);
88
+ h1 = Math.imul(h1 ^ ch, 2654435761);
89
+ h2 = Math.imul(h2 ^ ch, 1597334677);
90
+ }
91
+ h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
92
+ h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
93
+ let h3 = 305419896;
94
+ let h4 = 2596069104;
95
+ for (let i = 0; i < input.length; i++) {
96
+ const ch = input.charCodeAt(i);
97
+ h3 = Math.imul(h3 ^ ch, 2246822507);
98
+ h4 = Math.imul(h4 ^ ch, 3266489909);
99
+ }
100
+ h3 = Math.imul(h3 ^ h3 >>> 16, 2654435761) ^ Math.imul(h4 ^ h4 >>> 13, 1597334677);
101
+ h4 = Math.imul(h4 ^ h4 >>> 16, 2654435761) ^ Math.imul(h3 ^ h3 >>> 13, 1597334677);
102
+ const a = (h1 >>> 0).toString(16).padStart(8, "0");
103
+ const b = (h2 >>> 0).toString(16).padStart(8, "0");
104
+ const c = (h3 >>> 0).toString(16).padStart(8, "0");
105
+ const d = (h4 >>> 0).toString(16).padStart(8, "0");
106
+ const hex = a + b + c + d;
107
+ return hex.slice(0, 8) + "-" + hex.slice(8, 12) + "-4" + hex.slice(13, 16) + "-" + (parseInt(hex[16], 16) & 3 | 8).toString(16) + hex.slice(17, 20) + "-" + hex.slice(20, 32);
108
+ }
109
+ function graphEntityId(name, type) {
110
+ return stableId(`${name.toLowerCase()}::${type.toLowerCase()}`);
111
+ }
112
+ function normalizeEntityName(name) {
113
+ return name.trim().replace(/\s+/g, " ").slice(0, 160);
114
+ }
115
+ function addGraphEntity(entities, name, type, properties = {}) {
116
+ if (typeof name !== "string") return null;
117
+ const normalized = normalizeEntityName(name);
118
+ if (!normalized || normalized.length < 2) return null;
119
+ const id = graphEntityId(normalized, type);
120
+ if (!entities.has(id)) entities.set(id, { id, name: normalized, type, properties });
121
+ return id;
122
+ }
123
+ function addGraphRelationship(relationships, sourceId, targetId, type, confidence = 0.7, properties = {}) {
124
+ if (!sourceId || !targetId || sourceId === targetId) return;
125
+ const id = graphEntityId(`${sourceId}->${type}->${targetId}`, "relationship");
126
+ if (!relationships.has(id)) relationships.set(id, { id, sourceId, targetId, type, confidence, properties });
127
+ }
128
+ function deriveLightweightMemoryGraph(payload) {
129
+ const entities = /* @__PURE__ */ new Map();
130
+ const relationships = /* @__PURE__ */ new Map();
131
+ const memoryId = typeof payload.id === "string" ? payload.id : "";
132
+ const rawText = typeof payload.raw_text === "string" ? payload.raw_text : "";
133
+ const memoryEntity = addGraphEntity(entities, memoryId || stableId(rawText.slice(0, 256)), "memory", {
134
+ source: "cloud_sync",
135
+ version: payload.version
136
+ });
137
+ const agentEntity = addGraphEntity(entities, payload.agent_id, "person", { role: payload.agent_role });
138
+ const projectEntity = addGraphEntity(entities, payload.project_name, "project");
139
+ const toolEntity = addGraphEntity(entities, payload.tool_name, "tool");
140
+ const taskEntity = addGraphEntity(entities, payload.task_id, "task");
141
+ const domainEntity = addGraphEntity(entities, payload.domain, "concept");
142
+ const memoryTypeEntity = addGraphEntity(entities, payload.memory_type, "concept", { kind: "memory_type" });
143
+ addGraphRelationship(relationships, agentEntity, projectEntity, "worked_on", 0.8);
144
+ addGraphRelationship(relationships, agentEntity, toolEntity, "uses", 0.9);
145
+ addGraphRelationship(relationships, memoryEntity, agentEntity, "created_by", 0.9);
146
+ addGraphRelationship(relationships, memoryEntity, projectEntity, "part_of", 0.9);
147
+ addGraphRelationship(relationships, memoryEntity, toolEntity, "uses", 0.8);
148
+ addGraphRelationship(relationships, memoryEntity, taskEntity, "part_of", 0.8);
149
+ addGraphRelationship(relationships, memoryEntity, domainEntity, "about", 0.7);
150
+ addGraphRelationship(relationships, memoryEntity, memoryTypeEntity, "classified_as", 0.7);
151
+ const pathRegex = /(?:\/[\w .@-]+)+(?:\.[A-Za-z0-9]{1,10})|(?:[\w@.-]+\/)+[\w@.-]+\.(?:ts|tsx|js|jsx|json|md|yml|yaml|sql|py|go|rs|sh|css|html)/g;
152
+ const fileMatches = new Set((rawText.match(pathRegex) ?? []).slice(0, 8));
153
+ for (const filePath of fileMatches) {
154
+ const fileEntity = addGraphEntity(entities, filePath, "file", { source: "raw_text" });
155
+ addGraphRelationship(relationships, memoryEntity, fileEntity, "references", 0.75);
156
+ addGraphRelationship(relationships, projectEntity, fileEntity, "uses", 0.55);
157
+ }
158
+ const backtickMatches = [...rawText.matchAll(/`([^`\n]{2,80})`/g)].map((m) => m[1]).slice(0, 8);
159
+ for (const term of backtickMatches) {
160
+ if (!term || /[\s]{30,}/.test(term)) continue;
161
+ const conceptEntity = addGraphEntity(entities, term, term.includes("/") || term.includes(".") ? "file" : "concept", { source: "backtick" });
162
+ addGraphRelationship(relationships, memoryEntity, conceptEntity, "references", 0.65);
163
+ }
164
+ return { entities: [...entities.values()], relationships: [...relationships.values()] };
165
+ }
166
+ async function projectMemoryGraph(prisma, payload, memoryId, timestamp) {
167
+ const graph = deriveLightweightMemoryGraph(payload);
168
+ if (graph.entities.length === 0) return { entities: 0, relationships: 0 };
169
+ let entities = 0;
170
+ let relationships = 0;
171
+ const actualEntityIds = /* @__PURE__ */ new Map();
172
+ for (const entity of graph.entities) {
173
+ const inserted = await prisma.$queryRawUnsafe(
174
+ `INSERT INTO "${GRAPH_SCHEMA}"."entities" ("id", "name", "type", "first_seen", "last_seen", "properties")
175
+ VALUES ($1, $2, $3, $4, $4, $5::jsonb)
176
+ ON CONFLICT ("name", "type") DO UPDATE SET
177
+ "last_seen" = GREATEST("${GRAPH_SCHEMA}"."entities"."last_seen", EXCLUDED."last_seen"),
178
+ "properties" = "${GRAPH_SCHEMA}"."entities"."properties" || EXCLUDED."properties"
179
+ RETURNING "id"`,
180
+ entity.id,
181
+ entity.name,
182
+ entity.type,
183
+ timestamp,
184
+ JSON.stringify(entity.properties ?? {})
185
+ );
186
+ const actualId = inserted[0]?.id ?? entity.id;
187
+ actualEntityIds.set(entity.id, actualId);
188
+ await prisma.$executeRawUnsafe(
189
+ `INSERT INTO "${GRAPH_SCHEMA}"."entity_memories" ("entity_id", "memory_id")
190
+ VALUES ($1, $2)
191
+ ON CONFLICT DO NOTHING`,
192
+ actualId,
193
+ memoryId
194
+ );
195
+ entities++;
196
+ }
197
+ for (const relationship of graph.relationships) {
198
+ const sourceId = actualEntityIds.get(relationship.sourceId) ?? relationship.sourceId;
199
+ const targetId = actualEntityIds.get(relationship.targetId) ?? relationship.targetId;
200
+ const relId = graphEntityId(`${sourceId}->${relationship.type}->${targetId}`, "relationship");
201
+ await prisma.$executeRawUnsafe(
202
+ `INSERT INTO "${GRAPH_SCHEMA}"."relationships" ("id", "source_entity_id", "target_entity_id", "type", "weight", "confidence", "timestamp", "properties")
203
+ VALUES ($1, $2, $3, $4, 1.0, $5, $6, $7::jsonb)
204
+ ON CONFLICT ("source_entity_id", "target_entity_id", "type")
205
+ DO UPDATE SET "weight" = LEAST("${GRAPH_SCHEMA}"."relationships"."weight" + 0.1, 2.0),
206
+ "confidence" = GREATEST("${GRAPH_SCHEMA}"."relationships"."confidence", EXCLUDED."confidence"),
207
+ "timestamp" = GREATEST("${GRAPH_SCHEMA}"."relationships"."timestamp", EXCLUDED."timestamp"),
208
+ "properties" = "${GRAPH_SCHEMA}"."relationships"."properties" || EXCLUDED."properties"`,
209
+ relId,
210
+ sourceId,
211
+ targetId,
212
+ relationship.type,
213
+ relationship.confidence,
214
+ timestamp,
215
+ JSON.stringify(relationship.properties ?? {})
216
+ );
217
+ relationships++;
218
+ }
219
+ return { entities, relationships };
220
+ }
221
+ async function ensurePostgresOntologySchema(prisma) {
222
+ if (ontologySchemaReady) return;
223
+ await prisma.$executeRawUnsafe(`
224
+ CREATE TABLE IF NOT EXISTS "${GRAPH_SCHEMA}"."agent_sessions" (
225
+ "id" text PRIMARY KEY,
226
+ "agent_id" text NOT NULL,
227
+ "project_name" text,
228
+ "started_at" timestamp(3) NOT NULL,
229
+ "last_event_at" timestamp(3) NOT NULL,
230
+ "event_count" integer NOT NULL DEFAULT 0,
231
+ "properties" jsonb NOT NULL DEFAULT '{}'::jsonb
232
+ )`);
233
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_sessions_agent_time" ON "${GRAPH_SCHEMA}"."agent_sessions" ("agent_id", "started_at")`);
234
+ await prisma.$executeRawUnsafe(`
235
+ CREATE TABLE IF NOT EXISTS "${GRAPH_SCHEMA}"."agent_goals" (
236
+ "id" text PRIMARY KEY,
237
+ "statement" text NOT NULL,
238
+ "owner_agent_id" text,
239
+ "project_name" text,
240
+ "status" text NOT NULL DEFAULT 'open',
241
+ "priority" integer NOT NULL DEFAULT 5,
242
+ "success_criteria" text,
243
+ "parent_goal_id" text,
244
+ "due_at" timestamp(3),
245
+ "achieved_at" timestamp(3),
246
+ "supersedes_id" text,
247
+ "created_at" timestamp(3) NOT NULL,
248
+ "updated_at" timestamp(3) NOT NULL,
249
+ "source_memory_id" text
250
+ )`);
251
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_goals_project_status" ON "${GRAPH_SCHEMA}"."agent_goals" ("project_name", "status", "priority")`);
252
+ await prisma.$executeRawUnsafe(`
253
+ CREATE TABLE IF NOT EXISTS "${GRAPH_SCHEMA}"."agent_events" (
254
+ "id" text PRIMARY KEY,
255
+ "event_type" text NOT NULL,
256
+ "occurred_at" timestamp(3) NOT NULL,
257
+ "sequence_index" integer NOT NULL,
258
+ "actor_agent_id" text,
259
+ "agent_role" text,
260
+ "project_name" text,
261
+ "session_id" text,
262
+ "task_id" text,
263
+ "goal_id" text,
264
+ "parent_event_id" text,
265
+ "intention" text,
266
+ "outcome" text,
267
+ "evidence_memory_id" text,
268
+ "impact" text,
269
+ "payload" jsonb NOT NULL DEFAULT '{}'::jsonb,
270
+ "created_at" timestamp(3) NOT NULL
271
+ )`);
272
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_events_time" ON "${GRAPH_SCHEMA}"."agent_events" ("occurred_at", "sequence_index")`);
273
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_events_session_seq" ON "${GRAPH_SCHEMA}"."agent_events" ("session_id", "sequence_index")`);
274
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_events_goal_time" ON "${GRAPH_SCHEMA}"."agent_events" ("goal_id", "occurred_at")`);
275
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_events_memory" ON "${GRAPH_SCHEMA}"."agent_events" ("evidence_memory_id")`);
276
+ await prisma.$executeRawUnsafe(`
277
+ CREATE TABLE IF NOT EXISTS "${GRAPH_SCHEMA}"."agent_goal_links" (
278
+ "id" text PRIMARY KEY,
279
+ "goal_id" text NOT NULL,
280
+ "link_type" text NOT NULL,
281
+ "target_id" text NOT NULL,
282
+ "target_type" text NOT NULL,
283
+ "created_at" timestamp(3) NOT NULL
284
+ )`);
285
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_goal_links_goal" ON "${GRAPH_SCHEMA}"."agent_goal_links" ("goal_id", "target_type")`);
286
+ await prisma.$executeRawUnsafe(`
287
+ CREATE TABLE IF NOT EXISTS "${GRAPH_SCHEMA}"."agent_semantic_labels" (
288
+ "id" text PRIMARY KEY,
289
+ "source_memory_id" text NOT NULL,
290
+ "event_id" text,
291
+ "labeler" text NOT NULL,
292
+ "schema_version" integer NOT NULL DEFAULT 1,
293
+ "confidence" double precision NOT NULL DEFAULT 0,
294
+ "labels" jsonb NOT NULL,
295
+ "created_at" timestamp(3) NOT NULL,
296
+ "updated_at" timestamp(3) NOT NULL
297
+ )`);
298
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_semantic_labels_memory" ON "${GRAPH_SCHEMA}"."agent_semantic_labels" ("source_memory_id", "labeler")`);
299
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_semantic_labels_event" ON "${GRAPH_SCHEMA}"."agent_semantic_labels" ("event_id")`);
300
+ await prisma.$executeRawUnsafe(`
301
+ CREATE TABLE IF NOT EXISTS "${GRAPH_SCHEMA}"."agent_reflection_checkpoints" (
302
+ "id" text PRIMARY KEY,
303
+ "project_name" text,
304
+ "session_id" text,
305
+ "window_start_at" timestamp(3) NOT NULL,
306
+ "window_end_at" timestamp(3) NOT NULL,
307
+ "event_count" integer NOT NULL DEFAULT 0,
308
+ "goal_count" integer NOT NULL DEFAULT 0,
309
+ "success_count" integer NOT NULL DEFAULT 0,
310
+ "failure_count" integer NOT NULL DEFAULT 0,
311
+ "risk_count" integer NOT NULL DEFAULT 0,
312
+ "summary" text NOT NULL,
313
+ "learnings" jsonb NOT NULL DEFAULT '[]'::jsonb,
314
+ "next_actions" jsonb NOT NULL DEFAULT '[]'::jsonb,
315
+ "evidence_event_ids" jsonb NOT NULL DEFAULT '[]'::jsonb,
316
+ "confidence" double precision NOT NULL DEFAULT 0,
317
+ "created_at" timestamp(3) NOT NULL
318
+ )`);
319
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_reflection_project_time" ON "${GRAPH_SCHEMA}"."agent_reflection_checkpoints" ("project_name", "window_end_at")`);
320
+ await prisma.$executeRawUnsafe(`CREATE INDEX IF NOT EXISTS "idx_agent_reflection_session_time" ON "${GRAPH_SCHEMA}"."agent_reflection_checkpoints" ("session_id", "window_end_at")`);
321
+ ontologySchemaReady = true;
322
+ }
323
+ async function ensureFilteredSchema(prisma) {
324
+ if (filteredSchemaReady) return;
325
+ await prisma.$executeRawUnsafe(`CREATE SCHEMA IF NOT EXISTS filtered`);
326
+ await prisma.$executeRawUnsafe(`
327
+ CREATE TABLE IF NOT EXISTS "filtered"."documents" (
328
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
329
+ "title" TEXT NOT NULL,
330
+ "content" TEXT NOT NULL,
331
+ "doc_type" TEXT NOT NULL DEFAULT 'memory',
332
+ "source" TEXT NOT NULL DEFAULT 'exe-os',
333
+ "source_id" TEXT,
334
+ "metadata" JSONB DEFAULT '{}',
335
+ "created_at" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
336
+ UNIQUE("source", "source_id")
337
+ )`);
338
+ await prisma.$executeRawUnsafe(`
339
+ CREATE TABLE IF NOT EXISTS "filtered"."contacts" (
340
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
341
+ "name" TEXT,
342
+ "phone" TEXT,
343
+ "email" TEXT,
344
+ "platform" TEXT NOT NULL DEFAULT 'whatsapp',
345
+ "platform_id" TEXT,
346
+ "metadata" JSONB DEFAULT '{}',
347
+ "first_seen" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
348
+ "last_seen" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
349
+ UNIQUE("platform", "platform_id")
350
+ )`);
351
+ await prisma.$executeRawUnsafe(`
352
+ CREATE TABLE IF NOT EXISTS "filtered"."conversations" (
353
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
354
+ "contact_id" UUID REFERENCES "filtered"."contacts"("id"),
355
+ "platform" TEXT NOT NULL DEFAULT 'whatsapp',
356
+ "thread_id" TEXT,
357
+ "direction" TEXT NOT NULL DEFAULT 'inbound',
358
+ "content" TEXT NOT NULL,
359
+ "message_type" TEXT NOT NULL DEFAULT 'text',
360
+ "metadata" JSONB DEFAULT '{}',
361
+ "sent_at" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
362
+ "source_ref" TEXT
363
+ )`);
364
+ await selfHealFilteredSchema(prisma);
365
+ filteredSchemaReady = true;
366
+ }
367
+ async function selfHealFilteredSchema(prisma) {
368
+ const stmts = [
369
+ // --- filtered.contacts: ensure new-generation columns ---
370
+ `ALTER TABLE "filtered"."contacts" ADD COLUMN IF NOT EXISTS "name" TEXT`,
371
+ `ALTER TABLE "filtered"."contacts" ADD COLUMN IF NOT EXISTS "platform" TEXT DEFAULT 'whatsapp'`,
372
+ `ALTER TABLE "filtered"."contacts" ADD COLUMN IF NOT EXISTS "platform_id" TEXT`,
373
+ `ALTER TABLE "filtered"."contacts" ADD COLUMN IF NOT EXISTS "first_seen" TIMESTAMPTZ DEFAULT NOW()`,
374
+ `ALTER TABLE "filtered"."contacts" ADD COLUMN IF NOT EXISTS "last_seen" TIMESTAMPTZ DEFAULT NOW()`,
375
+ // Legacy NOT NULL columns the new worker never writes — relax if present.
376
+ `DO $$ BEGIN
377
+ IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='filtered' AND table_name='contacts' AND column_name='display_name' AND is_nullable='NO') THEN
378
+ ALTER TABLE "filtered"."contacts" ALTER COLUMN "display_name" DROP NOT NULL;
379
+ END IF;
380
+ END $$`,
381
+ // Backfill new columns from legacy ones where possible, then enforce upsert key.
382
+ `DO $$ BEGIN
383
+ IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='filtered' AND table_name='contacts' AND column_name='display_name') THEN
384
+ UPDATE "filtered"."contacts" SET
385
+ "name" = COALESCE("name", "display_name"),
386
+ "platform" = COALESCE("platform", "source", 'whatsapp'),
387
+ "platform_id" = COALESCE("platform_id", "source_id", "phone"),
388
+ "first_seen" = COALESCE("first_seen", "first_seen_at", NOW()),
389
+ "last_seen" = COALESCE("last_seen", "last_seen_at", NOW())
390
+ WHERE "platform" IS NULL OR "platform_id" IS NULL;
391
+ END IF;
392
+ END $$`,
393
+ `CREATE UNIQUE INDEX IF NOT EXISTS "contacts_platform_platform_id_uq" ON "filtered"."contacts"("platform", "platform_id")`,
394
+ // --- filtered.conversations: ensure new-generation columns ---
395
+ `ALTER TABLE "filtered"."conversations" ADD COLUMN IF NOT EXISTS "thread_id" TEXT`,
396
+ `ALTER TABLE "filtered"."conversations" ADD COLUMN IF NOT EXISTS "message_type" TEXT DEFAULT 'text'`,
397
+ `ALTER TABLE "filtered"."conversations" ADD COLUMN IF NOT EXISTS "sent_at" TIMESTAMPTZ DEFAULT NOW()`,
398
+ `ALTER TABLE "filtered"."conversations" ADD COLUMN IF NOT EXISTS "source_ref" TEXT`,
399
+ `DO $$ BEGIN
400
+ IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='filtered' AND table_name='conversations' AND column_name='timestamp' AND is_nullable='NO') THEN
401
+ ALTER TABLE "filtered"."conversations" ALTER COLUMN "timestamp" DROP NOT NULL;
402
+ END IF;
403
+ END $$`,
404
+ `DO $$ BEGIN
405
+ IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='filtered' AND table_name='conversations' AND column_name='remote_jid') THEN
406
+ UPDATE "filtered"."conversations" SET
407
+ "thread_id" = COALESCE("thread_id", "remote_jid"),
408
+ "sent_at" = COALESCE("sent_at", "timestamp", NOW())
409
+ WHERE "thread_id" IS NULL OR "sent_at" IS NULL;
410
+ END IF;
411
+ END $$`,
412
+ // Retire the weak same-second dedup key; keep a plain index for queries.
413
+ `ALTER TABLE "filtered"."conversations" DROP CONSTRAINT IF EXISTS "conversations_platform_thread_id_sent_at_key"`,
414
+ `DROP INDEX IF EXISTS "filtered"."conversations_platform_thread_sent_uq"`,
415
+ `CREATE INDEX IF NOT EXISTS "conversations_platform_thread_sent_idx" ON "filtered"."conversations"("platform", "thread_id", "sent_at")`,
416
+ `CREATE UNIQUE INDEX IF NOT EXISTS "conversations_platform_source_ref_uq" ON "filtered"."conversations"("platform", "source_ref")`,
417
+ // --- raw.raw_events: retry-model columns required by the poll loop ---
418
+ `ALTER TABLE "raw"."raw_events" ADD COLUMN IF NOT EXISTS "retry_count" INTEGER NOT NULL DEFAULT 0`,
419
+ `ALTER TABLE "raw"."raw_events" ADD COLUMN IF NOT EXISTS "failed_at" TIMESTAMPTZ`,
420
+ `ALTER TABLE "raw"."raw_events" ADD COLUMN IF NOT EXISTS "error" TEXT`,
421
+ `ALTER TABLE "raw"."raw_events" ADD COLUMN IF NOT EXISTS "projections" JSONB`
422
+ ];
423
+ for (const stmt of stmts) {
424
+ try {
425
+ await prisma.$executeRawUnsafe(stmt);
426
+ } catch (err) {
427
+ console.error(
428
+ `[projection-worker] schema self-heal statement failed (continuing): ${err instanceof Error ? err.message.split("\n")[0] : String(err)}`
429
+ );
430
+ }
431
+ }
432
+ }
433
+ async function projectAgenticOntology(prisma, payload, memoryId, timestamp) {
434
+ await ensurePostgresOntologySchema(prisma);
435
+ const row = {
436
+ id: memoryId,
437
+ agent_id: String(payload.agent_id ?? "system"),
438
+ agent_role: String(payload.agent_role ?? "ingest"),
439
+ session_id: String(payload.session_id ?? "projection-worker"),
440
+ timestamp: timestamp.toISOString(),
441
+ tool_name: String(payload.tool_name ?? "cloud_sync"),
442
+ project_name: String(payload.project_name ?? "exe-os"),
443
+ has_error: payload.has_error ? 1 : 0,
444
+ raw_text: String(payload.raw_text ?? JSON.stringify(payload)),
445
+ version: typeof payload.version === "number" ? payload.version : Number(payload.version ?? 0),
446
+ task_id: typeof payload.task_id === "string" ? payload.task_id : null,
447
+ intent: typeof payload.intent === "string" ? payload.intent : null,
448
+ outcome: typeof payload.outcome === "string" ? payload.outcome : null,
449
+ domain: typeof payload.domain === "string" ? payload.domain : null,
450
+ trajectory: typeof payload.trajectory === "string" ? payload.trajectory : null
451
+ };
452
+ const eventId = stableId(`event:${memoryId}`);
453
+ const sequence = Number(row.version ?? 0) || Math.floor(timestamp.getTime() / 1e3);
454
+ const intention = inferIntention(row);
455
+ const outcome = inferOutcome(row);
456
+ const now = /* @__PURE__ */ new Date();
457
+ await prisma.$executeRawUnsafe(
458
+ `INSERT INTO "${GRAPH_SCHEMA}"."agent_sessions" ("id", "agent_id", "project_name", "started_at", "last_event_at", "event_count", "properties")
459
+ VALUES ($1, $2, $3, $4, $4, 1, $5::jsonb)
460
+ ON CONFLICT ("id") DO UPDATE SET "last_event_at" = GREATEST("${GRAPH_SCHEMA}"."agent_sessions"."last_event_at", EXCLUDED."last_event_at"),
461
+ "event_count" = "${GRAPH_SCHEMA}"."agent_sessions"."event_count" + 1`,
462
+ row.session_id,
463
+ row.agent_id,
464
+ row.project_name,
465
+ timestamp,
466
+ JSON.stringify({ agent_role: row.agent_role })
467
+ );
468
+ await prisma.$executeRawUnsafe(
469
+ `INSERT INTO "${GRAPH_SCHEMA}"."agent_events"
470
+ ("id", "event_type", "occurred_at", "sequence_index", "actor_agent_id", "agent_role", "project_name",
471
+ "session_id", "task_id", "goal_id", "parent_event_id", "intention", "outcome", "evidence_memory_id",
472
+ "impact", "payload", "created_at")
473
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, NULL, NULL, $10, $11, $12, $13, $14::jsonb, $15)
474
+ ON CONFLICT ("id") DO NOTHING`,
475
+ eventId,
476
+ inferOntologyEventType(row),
477
+ timestamp,
478
+ sequence,
479
+ row.agent_id,
480
+ row.agent_role,
481
+ row.project_name,
482
+ row.session_id,
483
+ row.task_id ?? null,
484
+ intention,
485
+ outcome,
486
+ row.id,
487
+ row.has_error ? "negative" : outcome === "success_signal" ? "positive" : "neutral",
488
+ JSON.stringify(ontologyPayload(row)),
489
+ now
490
+ );
491
+ const semantic = inferSemanticLabel(row);
492
+ await prisma.$executeRawUnsafe(
493
+ `INSERT INTO "${GRAPH_SCHEMA}"."agent_semantic_labels"
494
+ ("id", "source_memory_id", "event_id", "labeler", "schema_version", "confidence", "labels", "created_at", "updated_at")
495
+ VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb, $8, $8)
496
+ ON CONFLICT ("id") DO UPDATE SET "confidence" = EXCLUDED."confidence",
497
+ "labels" = EXCLUDED."labels", "updated_at" = EXCLUDED."updated_at"`,
498
+ stableId(`semantic:${row.id}:${semantic.labeler}:${semantic.schemaVersion}`),
499
+ row.id,
500
+ eventId,
501
+ semantic.labeler,
502
+ semantic.schemaVersion,
503
+ semantic.confidence,
504
+ JSON.stringify(semantic),
505
+ now
506
+ );
507
+ let goals = 0;
508
+ for (const statement of extractGoalCandidates(row)) {
509
+ const goalId = stableId(`goal:${row.project_name}:${statement.toLowerCase()}`);
510
+ await prisma.$executeRawUnsafe(
511
+ `INSERT INTO "${GRAPH_SCHEMA}"."agent_goals"
512
+ ("id", "statement", "owner_agent_id", "project_name", "status", "priority", "created_at", "updated_at", "source_memory_id")
513
+ VALUES ($1, $2, $3, $4, 'open', 5, $5, $5, $6)
514
+ ON CONFLICT ("id") DO UPDATE SET "updated_at" = EXCLUDED."updated_at"`,
515
+ goalId,
516
+ statement,
517
+ row.agent_id,
518
+ row.project_name,
519
+ now,
520
+ row.id
521
+ );
522
+ await prisma.$executeRawUnsafe(
523
+ `INSERT INTO "${GRAPH_SCHEMA}"."agent_goal_links" ("id", "goal_id", "link_type", "target_id", "target_type", "created_at")
524
+ VALUES ($1, $2, 'evidence', $3, 'memory', $4)
525
+ ON CONFLICT ("id") DO NOTHING`,
526
+ stableId(`goal_link:${goalId}:${row.id}:memory`),
527
+ goalId,
528
+ row.id,
529
+ now
530
+ );
531
+ await prisma.$executeRawUnsafe(
532
+ `INSERT INTO "${GRAPH_SCHEMA}"."agent_goal_links" ("id", "goal_id", "link_type", "target_id", "target_type", "created_at")
533
+ VALUES ($1, $2, 'event', $3, 'event', $4)
534
+ ON CONFLICT ("id") DO NOTHING`,
535
+ stableId(`goal_link:${goalId}:${eventId}:event`),
536
+ goalId,
537
+ eventId,
538
+ now
539
+ );
540
+ goals++;
541
+ }
542
+ return { events: 1, goals };
543
+ }
544
+ var WIKI_PROJECTABLE_TOOLS = /* @__PURE__ */ new Set(["manual", "auto-decision", "SessionEnd", "AssistantResponse"]);
545
+ var WIKI_MIN_TEXT_LENGTH = 100;
546
+ async function ensureWikiWorkspace(prisma, projectName) {
547
+ const slug = projectName.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-");
548
+ const existing = await prisma.$queryRawUnsafe(
549
+ `SELECT "id" FROM "wiki"."workspaces" WHERE "slug" = $1`,
550
+ slug
551
+ );
552
+ if (existing.length > 0) return existing[0].id;
553
+ const inserted = await prisma.$queryRawUnsafe(
554
+ `INSERT INTO "wiki"."workspaces" ("name", "slug", "chat_mode", "updated_at")
555
+ VALUES ($1, $2, 'chat', NOW())
556
+ ON CONFLICT ("slug") DO UPDATE SET "name" = EXCLUDED."name"
557
+ RETURNING "id"`,
558
+ projectName,
559
+ slug
560
+ );
561
+ return inserted[0].id;
562
+ }
563
+ function isWikiWorthy(payload) {
564
+ const toolName = String(payload.tool_name ?? "");
565
+ const rawText = String(payload.raw_text ?? "");
566
+ const importance = typeof payload.importance === "number" ? payload.importance : 5;
567
+ const memoryType = String(payload.memory_type ?? "raw");
568
+ if (memoryType === "decision" || memoryType === "procedure") return true;
569
+ if (WIKI_PROJECTABLE_TOOLS.has(toolName)) return true;
570
+ if (importance >= 7 && rawText.length >= WIKI_MIN_TEXT_LENGTH) return true;
571
+ return false;
572
+ }
573
+ async function projectToWiki(prisma, payload, timestamp) {
574
+ if (!isWikiWorthy(payload)) return { documents: 0 };
575
+ const rawText = String(payload.raw_text ?? "");
576
+ if (rawText.length < WIKI_MIN_TEXT_LENGTH) return { documents: 0 };
577
+ const projectName = String(payload.project_name ?? "exe-os");
578
+ const agentId = String(payload.agent_id ?? "system");
579
+ const toolName = String(payload.tool_name ?? "unknown");
580
+ const memoryId = String(payload.id ?? "");
581
+ const docId = memoryId || stableId(rawText.slice(0, 512));
582
+ const firstLine = rawText.split("\n")[0]?.slice(0, 120)?.replace(/[^a-zA-Z0-9 _-]/g, "") || "untitled";
583
+ const filename = `${agentId}-${firstLine.slice(0, 80).trim().replace(/\s+/g, "-").toLowerCase()}.md`;
584
+ const docpath = `${projectName}/${filename}`;
585
+ const workspaceId = await ensureWikiWorkspace(prisma, projectName);
586
+ await prisma.$executeRawUnsafe(
587
+ `INSERT INTO "wiki"."workspace_documents" ("doc_id", "filename", "docpath", "workspace_id", "metadata", "pinned")
588
+ VALUES ($1, $2, $3, $4, $5, false)
589
+ ON CONFLICT ("doc_id") DO UPDATE SET
590
+ "filename" = EXCLUDED."filename",
591
+ "metadata" = EXCLUDED."metadata"`,
592
+ docId,
593
+ filename,
594
+ docpath,
595
+ workspaceId,
596
+ JSON.stringify({
597
+ agent_id: agentId,
598
+ tool_name: toolName,
599
+ memory_type: payload.memory_type ?? "raw",
600
+ importance: payload.importance ?? 5,
601
+ timestamp: timestamp.toISOString(),
602
+ content_preview: rawText.slice(0, 500)
603
+ })
604
+ );
605
+ return { documents: 1 };
606
+ }
607
+ var lastWikiApiPushAt = 0;
608
+ var WIKI_API_MIN_INTERVAL_MS = 500;
609
+ async function pushToWikiApi(payload, _timestamp) {
610
+ const now = Date.now();
611
+ if (now - lastWikiApiPushAt < WIKI_API_MIN_INTERVAL_MS) {
612
+ return false;
613
+ }
614
+ try {
615
+ const { createWikiClient, uploadDocumentToWiki } = await import("./wiki-client-Q4O6EMTP.js");
616
+ const client = await createWikiClient();
617
+ if (!client) return false;
618
+ const rawText = String(payload.raw_text ?? "");
619
+ const projectName = String(payload.project_name ?? "exe-os");
620
+ const agentId = String(payload.agent_id ?? "system");
621
+ const firstLine = rawText.split("\n")[0]?.slice(0, 120) ?? "Untitled";
622
+ const title = `[${agentId}] ${firstLine}`;
623
+ const slug = projectName.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-");
624
+ const result = await uploadDocumentToWiki(client, slug, title, rawText);
625
+ lastWikiApiPushAt = Date.now();
626
+ if (!result.success) {
627
+ process.stderr.write(`[projection-worker] Wiki API push failed: ${result.error}
628
+ `);
629
+ }
630
+ return result.success;
631
+ } catch (err) {
632
+ process.stderr.write(`[projection-worker] Wiki API push error: ${err instanceof Error ? err.message : String(err)}
633
+ `);
634
+ return false;
635
+ }
636
+ }
637
+ function resetLastWikiApiPushAtForTests() {
638
+ lastWikiApiPushAt = 0;
639
+ }
640
+ var projectionHandlers = {
641
+ async whatsapp(event, prisma) {
642
+ const targets = [];
643
+ const payload = event.payload;
644
+ await prisma.$executeRawUnsafe(
645
+ `INSERT INTO "${GRAPH_SCHEMA}"."memory_records" ("id", "agent_id", "agent_role", "session_id", "tool_name", "project_name", "raw_text", "memory_type", "source_type", "intent")
646
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
647
+ ON CONFLICT ("id") DO NOTHING`,
648
+ crypto.randomUUID(),
649
+ "system",
650
+ "ingest",
651
+ "projection-worker",
652
+ "projection_worker",
653
+ "exe-os",
654
+ JSON.stringify(payload),
655
+ "raw",
656
+ "whatsapp",
657
+ event.event_type
658
+ );
659
+ targets.push("graph");
660
+ await ensureFilteredSchema(prisma);
661
+ const senderName = payload.sender_name ?? payload.contact_name ?? null;
662
+ const rawSender = payload.from ?? payload.phone ?? null;
663
+ const threadId = payload.conversation_id ?? payload.chat_id ?? event.source_id;
664
+ if (rawSender) {
665
+ const bareSender = rawSender.replace(/@.*$/, "");
666
+ const phone = !rawSender.endsWith("@lid") && /^\+?\d{6,20}$/.test(bareSender) ? bareSender : null;
667
+ const name = senderName ?? phone ?? "Unknown (WhatsApp)";
668
+ const contactResult = await prisma.$queryRawUnsafe(
669
+ `INSERT INTO "filtered"."contacts" ("name", "phone", "platform", "platform_id", "last_seen")
670
+ VALUES ($1, $2, 'whatsapp', $3, $4)
671
+ ON CONFLICT ("platform", "platform_id") DO UPDATE SET
672
+ "name" = CASE
673
+ WHEN EXCLUDED."name" IS NOT NULL AND EXCLUDED."name" <> 'Unknown (WhatsApp)' THEN EXCLUDED."name"
674
+ WHEN "filtered"."contacts"."name" ~ '@(lid|s\\.whatsapp\\.net)$' THEN EXCLUDED."name"
675
+ ELSE "filtered"."contacts"."name"
676
+ END,
677
+ "phone" = COALESCE(EXCLUDED."phone", "filtered"."contacts"."phone"),
678
+ "last_seen" = GREATEST("filtered"."contacts"."last_seen", EXCLUDED."last_seen")
679
+ RETURNING "id"`,
680
+ name,
681
+ phone,
682
+ rawSender,
683
+ event.timestamp
684
+ );
685
+ const contactId = contactResult[0]?.id;
686
+ targets.push("filtered.contacts");
687
+ const messageContent = payload.message ?? payload.text ?? payload.body ?? JSON.stringify(payload);
688
+ const direction = payload.direction ?? "inbound";
689
+ if (contactId && messageContent) {
690
+ const sourceRef = event.source_id ?? event.id;
691
+ await prisma.$executeRawUnsafe(
692
+ `INSERT INTO "filtered"."conversations" ("contact_id", "platform", "thread_id", "direction", "content", "message_type", "sent_at", "source_ref")
693
+ VALUES ($1::uuid, 'whatsapp', $2, $3, $4, $5, $6, $7)
694
+ ON CONFLICT ("platform", "source_ref") DO NOTHING`,
695
+ contactId,
696
+ threadId,
697
+ direction,
698
+ typeof messageContent === "string" ? messageContent : JSON.stringify(messageContent),
699
+ payload.type ?? "text",
700
+ event.timestamp,
701
+ String(sourceRef)
702
+ );
703
+ targets.push("filtered.conversations");
704
+ }
705
+ }
706
+ return { targets };
707
+ },
708
+ async shopify(event, prisma) {
709
+ const targets = [];
710
+ const payload = event.payload;
711
+ await prisma.$executeRawUnsafe(
712
+ `INSERT INTO "${GRAPH_SCHEMA}"."memory_records" ("id", "agent_id", "agent_role", "session_id", "tool_name", "project_name", "raw_text", "memory_type", "source_type", "intent")
713
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
714
+ ON CONFLICT ("id") DO NOTHING`,
715
+ crypto.randomUUID(),
716
+ "system",
717
+ "ingest",
718
+ "projection-worker",
719
+ "projection_worker",
720
+ "exe-os",
721
+ JSON.stringify(payload),
722
+ "raw",
723
+ "shopify",
724
+ event.event_type
725
+ );
726
+ targets.push("graph");
727
+ return { targets };
728
+ },
729
+ async cloud_sync(event, prisma) {
730
+ const targets = [];
731
+ const payload = event.payload;
732
+ const memoryId = payload.id ?? crypto.randomUUID();
733
+ await prisma.$executeRawUnsafe(
734
+ `INSERT INTO "${GRAPH_SCHEMA}"."memory_records" ("id", "agent_id", "agent_role", "session_id", "tool_name", "project_name", "raw_text", "memory_type", "source_type", "intent", "domain")
735
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
736
+ ON CONFLICT ("id") DO NOTHING`,
737
+ memoryId,
738
+ payload.agent_id ?? "system",
739
+ payload.agent_role ?? "ingest",
740
+ payload.session_id ?? "projection-worker",
741
+ payload.tool_name ?? "cloud_sync",
742
+ payload.project_name ?? "exe-os",
743
+ payload.raw_text ?? JSON.stringify(payload),
744
+ payload.memory_type ?? "raw",
745
+ "cloud_sync",
746
+ event.event_type,
747
+ payload.domain ?? null
748
+ );
749
+ targets.push("memory");
750
+ const graph = await projectMemoryGraph(prisma, payload, memoryId, event.timestamp);
751
+ if (graph.entities > 0 || graph.relationships > 0) targets.push("graph");
752
+ const ontology = await projectAgenticOntology(prisma, payload, memoryId, event.timestamp);
753
+ if (ontology.events > 0) targets.push("ontology");
754
+ const wiki = await projectToWiki(prisma, payload, event.timestamp);
755
+ if (wiki.documents > 0) {
756
+ targets.push("wiki");
757
+ await pushToWikiApi(payload, event.timestamp);
758
+ }
759
+ await ensureFilteredSchema(prisma);
760
+ const rawText = payload.raw_text ?? "";
761
+ if (rawText.length > 50) {
762
+ await prisma.$executeRawUnsafe(
763
+ `INSERT INTO "filtered"."documents" ("title", "content", "doc_type", "source", "source_id", "metadata", "created_at")
764
+ VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7)
765
+ ON CONFLICT ("source", "source_id") DO NOTHING`,
766
+ rawText.slice(0, 80),
767
+ rawText,
768
+ payload.tool_name ?? "memory",
769
+ "exe-os",
770
+ memoryId,
771
+ JSON.stringify({
772
+ agent_id: payload.agent_id,
773
+ project_name: payload.project_name
774
+ }),
775
+ event.timestamp
776
+ );
777
+ targets.push("filtered.documents");
778
+ }
779
+ return { targets };
780
+ },
781
+ async external_agent(event, prisma) {
782
+ const targets = [];
783
+ const payload = event.payload;
784
+ await prisma.$executeRawUnsafe(
785
+ `INSERT INTO "${GRAPH_SCHEMA}"."memory_records" ("id", "agent_id", "agent_role", "session_id", "tool_name", "project_name", "raw_text", "memory_type", "source_type", "intent", "domain")
786
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
787
+ ON CONFLICT ("id") DO NOTHING`,
788
+ crypto.randomUUID(),
789
+ "system",
790
+ "ingest",
791
+ "projection-worker",
792
+ "projection_worker",
793
+ "exe-os",
794
+ JSON.stringify(payload),
795
+ "raw",
796
+ "external_agent",
797
+ event.event_type,
798
+ payload.domain ?? null
799
+ );
800
+ targets.push("graph");
801
+ return { targets };
802
+ },
803
+ async erp(event, prisma) {
804
+ const targets = [];
805
+ const payload = event.payload;
806
+ await prisma.$executeRawUnsafe(
807
+ `INSERT INTO "${GRAPH_SCHEMA}"."memory_records" ("id", "agent_id", "agent_role", "session_id", "tool_name", "project_name", "raw_text", "memory_type", "source_type", "intent", "domain")
808
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
809
+ ON CONFLICT ("id") DO NOTHING`,
810
+ crypto.randomUUID(),
811
+ "system",
812
+ "ingest",
813
+ "projection-worker",
814
+ "projection_worker",
815
+ payload.project_name ?? "exe-erp",
816
+ JSON.stringify(payload),
817
+ "raw",
818
+ "erp",
819
+ event.event_type,
820
+ payload.domain ?? "business"
821
+ );
822
+ targets.push("graph");
823
+ await ensureFilteredSchema(prisma);
824
+ const rawText = typeof payload.description === "string" ? payload.description : JSON.stringify(payload);
825
+ if (rawText.length > 50) {
826
+ await prisma.$executeRawUnsafe(
827
+ `INSERT INTO "filtered"."documents" ("title", "content", "doc_type", "source", "source_id", "metadata", "created_at")
828
+ VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7)
829
+ ON CONFLICT ("source", "source_id") DO NOTHING`,
830
+ rawText.length > 80 ? rawText.slice(0, 77) + "..." : rawText,
831
+ rawText,
832
+ event.event_type,
833
+ "erp",
834
+ event.source_id ?? event.id,
835
+ JSON.stringify({
836
+ erp_doctype: payload.doctype,
837
+ erp_name: payload.name,
838
+ event_type: event.event_type
839
+ }),
840
+ event.timestamp
841
+ );
842
+ targets.push("filtered.documents");
843
+ }
844
+ const erpPayload = payload;
845
+ const doctype = String(erpPayload.doctype ?? erpPayload.docType ?? erpPayload.object_type ?? "Unknown");
846
+ const normalizedObjectType = doctype.charAt(0).toUpperCase() + doctype.slice(1);
847
+ const triggerEvent = {
848
+ eventType: event.event_type.replace(/^.*\./, ""),
849
+ // "sales_order.created" -> "created"
850
+ objectType: normalizedObjectType,
851
+ record: erpPayload
852
+ };
853
+ try {
854
+ const logs = await processCRMEvent(triggerEvent);
855
+ if (logs.length > 0) {
856
+ targets.push("triggers");
857
+ process.stderr.write(
858
+ `[projection-worker] ERP event ${normalizedObjectType}.${triggerEvent.eventType} fired ${logs.length} trigger(s)
859
+ `
860
+ );
861
+ }
862
+ } catch (err) {
863
+ process.stderr.write(
864
+ `[projection-worker] ERP trigger evaluation failed: ${err instanceof Error ? err.message : String(err)}
865
+ `
866
+ );
867
+ }
868
+ return { targets };
869
+ }
870
+ };
871
+ var projectionHandlersForTests = projectionHandlers;
872
+ var defaultHandler = async (event, prisma) => {
873
+ await prisma.$executeRawUnsafe(
874
+ `INSERT INTO "${GRAPH_SCHEMA}"."memory_records" ("id", "agent_id", "agent_role", "session_id", "tool_name", "project_name", "raw_text", "memory_type", "source_type", "intent")
875
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
876
+ ON CONFLICT ("id") DO NOTHING`,
877
+ crypto.randomUUID(),
878
+ "system",
879
+ "ingest",
880
+ "projection-worker",
881
+ "projection_worker",
882
+ "exe-os",
883
+ JSON.stringify(event.payload),
884
+ "raw",
885
+ event.source,
886
+ event.event_type
887
+ );
888
+ return { targets: ["memory"] };
889
+ };
890
+ var BATCH_SIZE = 50;
891
+ var POLL_INTERVAL_MS = 1e4;
892
+ var MAX_POLL_BACKOFF_MS = 5 * 6e4;
893
+ var MAX_PROJECTION_RETRIES = 5;
894
+ function isTruthyEnv(value) {
895
+ return /^(1|true|yes|on)$/i.test(value ?? "");
896
+ }
897
+ var running = false;
898
+ var pollTimer = null;
899
+ var consecutivePollErrors = 0;
900
+ async function processBatch() {
901
+ const prisma = await loadPrisma();
902
+ await ensureFilteredSchema(prisma);
903
+ const events = await prisma.$queryRawUnsafe(
904
+ `SELECT "id", "source", "source_id", "event_type", "payload", "metadata", "timestamp"
905
+ FROM "raw"."raw_events"
906
+ WHERE "processed_at" IS NULL
907
+ AND ("failed_at" IS NULL OR (
908
+ "retry_count" < $2
909
+ AND "failed_at" < NOW() - make_interval(secs => POWER(2, LEAST("retry_count", 8))::int)
910
+ ))
911
+ ORDER BY "timestamp" ASC
912
+ LIMIT $1`,
913
+ BATCH_SIZE,
914
+ MAX_PROJECTION_RETRIES
915
+ );
916
+ if (events.length === 0) return 0;
917
+ let processed = 0;
918
+ for (const event of events) {
919
+ try {
920
+ const handler = projectionHandlers[event.source] ?? defaultHandler;
921
+ const result = await handler(event, prisma);
922
+ await prisma.$executeRawUnsafe(
923
+ `UPDATE "raw"."raw_events"
924
+ SET "processed_at" = NOW(), "projections" = $1::jsonb
925
+ WHERE "id" = $2`,
926
+ JSON.stringify({ targets: [...new Set(result.targets)], skipped: result.skipped }),
927
+ event.id
928
+ );
929
+ processed++;
930
+ } catch (err) {
931
+ const message = err instanceof Error ? err.message : String(err);
932
+ process.stderr.write(
933
+ `[projection-worker] Error processing event ${event.id}: ${message}
934
+ `
935
+ );
936
+ await prisma.$executeRawUnsafe(
937
+ `UPDATE "raw"."raw_events"
938
+ SET "failed_at" = NOW(),
939
+ "retry_count" = COALESCE("retry_count", 0) + 1,
940
+ "error" = $1,
941
+ "projections" = $2::jsonb
942
+ WHERE "id" = $3`,
943
+ message,
944
+ JSON.stringify({ error: message }),
945
+ event.id
946
+ );
947
+ }
948
+ }
949
+ return processed;
950
+ }
951
+ async function shouldStartProjectionWorker() {
952
+ try {
953
+ const config = await loadConfig();
954
+ const envEnabled = isTruthyEnv(process.env.EXE_CLOUD_SYNC_TO_POSTGRES);
955
+ if (!envEnabled && config.cloud?.syncToPostgres !== true) {
956
+ return { start: false, reason: "cloud.syncToPostgres is not enabled" };
957
+ }
958
+ } catch (err) {
959
+ return { start: false, reason: `config unavailable: ${err instanceof Error ? err.message : String(err)}` };
960
+ }
961
+ if (!process.env.DATABASE_URL) {
962
+ return { start: false, reason: "DATABASE_URL is not set" };
963
+ }
964
+ const exeDbRoot = process.env.EXE_DB_ROOT ?? path.join(os.homedir(), "exe-db");
965
+ if (!existsSync(path.join(exeDbRoot, "package.json")) && !process.env.EXE_OS_PRISMA_CLIENT_PATH) {
966
+ try {
967
+ await import("pg");
968
+ } catch {
969
+ return { start: false, reason: "no exe-db Prisma client or pg adapter available" };
970
+ }
971
+ }
972
+ return { start: true };
973
+ }
974
+ function computeProjectionBackoffMs(errorCount) {
975
+ if (errorCount <= 0) return POLL_INTERVAL_MS;
976
+ return Math.min(POLL_INTERVAL_MS * 2 ** Math.min(errorCount, 5), MAX_POLL_BACKOFF_MS);
977
+ }
978
+ function startProjectionWorker() {
979
+ if (running) return;
980
+ void (async () => {
981
+ const decision = await shouldStartProjectionWorker();
982
+ if (!decision.start) {
983
+ process.stderr.write(`[projection-worker] Skipped \u2014 ${decision.reason}.
984
+ `);
985
+ return;
986
+ }
987
+ running = true;
988
+ consecutivePollErrors = 0;
989
+ process.stderr.write("[projection-worker] Starting...\n");
990
+ if (isTruthyEnv(process.env.EXE_PROJECTION_REQUEUE_ON_START)) {
991
+ try {
992
+ await requeueRetryExhausted({
993
+ source: process.env.EXE_PROJECTION_REQUEUE_SOURCE || void 0,
994
+ eventType: process.env.EXE_PROJECTION_REQUEUE_EVENT_TYPE || void 0
995
+ });
996
+ } catch (err) {
997
+ process.stderr.write(
998
+ `[projection-worker] Requeue-on-start failed (continuing): ${err instanceof Error ? err.message : String(err)}
999
+ `
1000
+ );
1001
+ }
1002
+ }
1003
+ const tick = async () => {
1004
+ if (!running) return;
1005
+ let nextDelay = POLL_INTERVAL_MS;
1006
+ try {
1007
+ const count = await processBatch();
1008
+ consecutivePollErrors = 0;
1009
+ if (count > 0) {
1010
+ process.stderr.write(`[projection-worker] Processed ${count} events.
1011
+ `);
1012
+ }
1013
+ } catch (err) {
1014
+ consecutivePollErrors++;
1015
+ nextDelay = computeProjectionBackoffMs(consecutivePollErrors);
1016
+ process.stderr.write(
1017
+ `[projection-worker] Poll error (${consecutivePollErrors}; next retry ${Math.round(nextDelay / 1e3)}s): ${err instanceof Error ? err.message : String(err)}
1018
+ `
1019
+ );
1020
+ }
1021
+ if (running) {
1022
+ pollTimer = setTimeout(tick, nextDelay);
1023
+ }
1024
+ };
1025
+ void tick();
1026
+ })();
1027
+ }
1028
+ function stopProjectionWorker() {
1029
+ running = false;
1030
+ if (pollTimer) {
1031
+ clearTimeout(pollTimer);
1032
+ pollTimer = null;
1033
+ }
1034
+ process.stderr.write("[projection-worker] Stopped.\n");
1035
+ }
1036
+ async function processProjectionBatch() {
1037
+ return processBatch();
1038
+ }
1039
+ async function requeueRetryExhausted(opts = {}) {
1040
+ const prisma = await loadPrisma();
1041
+ await ensureFilteredSchema(prisma);
1042
+ const conditions = [
1043
+ `"processed_at" IS NULL`,
1044
+ `"retry_count" >= $1`
1045
+ ];
1046
+ const params = [MAX_PROJECTION_RETRIES];
1047
+ if (opts.source) {
1048
+ params.push(opts.source);
1049
+ conditions.push(`"source" = $${params.length}`);
1050
+ }
1051
+ if (opts.eventType) {
1052
+ params.push(opts.eventType);
1053
+ conditions.push(`"event_type" = $${params.length}`);
1054
+ }
1055
+ const result = await prisma.$executeRawUnsafe(
1056
+ `UPDATE "raw"."raw_events"
1057
+ SET "failed_at" = NULL,
1058
+ "retry_count" = 0,
1059
+ "error" = NULL
1060
+ WHERE ${conditions.join(" AND ")}`,
1061
+ ...params
1062
+ );
1063
+ const count = typeof result === "number" ? result : 0;
1064
+ if (count > 0) {
1065
+ const scope = [opts.source && `source=${opts.source}`, opts.eventType && `event_type=${opts.eventType}`].filter(Boolean).join(" ") || "all sources";
1066
+ process.stderr.write(
1067
+ `[projection-worker] Requeued ${count} retry-exhausted event(s) (${scope}).
1068
+ `
1069
+ );
1070
+ }
1071
+ return count;
1072
+ }
1073
+ export {
1074
+ computeProjectionBackoffMs,
1075
+ processProjectionBatch,
1076
+ projectionHandlersForTests,
1077
+ requeueRetryExhausted,
1078
+ resetLastWikiApiPushAtForTests,
1079
+ resetProjectionWorkerForTests,
1080
+ setProjectionWorkerPrismaClientForTests,
1081
+ shouldStartProjectionWorker,
1082
+ startProjectionWorker,
1083
+ stopProjectionWorker
1084
+ };