@askexenow/exe-os 0.9.127 → 0.9.129

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 (373) hide show
  1. package/dist/active-agent-3FDJYREJ.js +22 -0
  2. package/dist/active-agent-WC7YK3L5.js +23 -0
  3. package/dist/agent-context-CDWUZEXY.js +11 -0
  4. package/dist/agent-loop-G4VUR5ME.js +10 -0
  5. package/dist/agentic-ontology-2VYNTMNO.js +25 -0
  6. package/dist/backfill-metadata-OJWOCLSZ.js +601 -0
  7. package/dist/background-jobs-LGRDXGXC.js +25 -0
  8. package/dist/bash-Y5PEW5UQ.js +8 -0
  9. package/dist/behaviors-CSB2YLDT.js +22 -0
  10. package/dist/bin/age-ontology-load.js +10 -258
  11. package/dist/bin/agentic-ontology-backfill.js +23 -5296
  12. package/dist/bin/agentic-reflection-backfill.js +19 -4739
  13. package/dist/bin/agentic-semantic-label.js +28 -4723
  14. package/dist/bin/backfill-conversations.js +42 -5543
  15. package/dist/bin/backfill-responses.js +41 -5542
  16. package/dist/bin/backfill-vectors.js +43 -4795
  17. package/dist/bin/bulk-sync-postgres.js +22 -5313
  18. package/dist/bin/cc-doctor.js +10 -602
  19. package/dist/bin/cleanup-stale-review-tasks.js +32 -6803
  20. package/dist/bin/cli.js +169 -38993
  21. package/dist/bin/exe-agent-config.js +21 -253
  22. package/dist/bin/exe-agent.js +63 -2429
  23. package/dist/bin/exe-assign.js +34 -5810
  24. package/dist/bin/exe-boot.js +180 -12726
  25. package/dist/bin/exe-call.js +48 -1409
  26. package/dist/bin/exe-cloud.js +64 -8516
  27. package/dist/bin/exe-dispatch.js +35 -10818
  28. package/dist/bin/exe-doctor.js +24 -7537
  29. package/dist/bin/exe-export-behaviors.js +18 -6122
  30. package/dist/bin/exe-forget.js +22 -6274
  31. package/dist/bin/exe-gateway.js +62 -15286
  32. package/dist/bin/exe-healthcheck.js +9 -602
  33. package/dist/bin/exe-heartbeat.js +51 -6898
  34. package/dist/bin/exe-kill.js +30 -5961
  35. package/dist/bin/exe-launch-agent.js +101 -6788
  36. package/dist/bin/exe-new-employee.js +42 -3774
  37. package/dist/bin/exe-pending-messages.js +28 -6833
  38. package/dist/bin/exe-pending-notifications.js +31 -6869
  39. package/dist/bin/exe-pending-reviews.js +38 -6910
  40. package/dist/bin/exe-rename.js +57 -5766
  41. package/dist/bin/exe-review.js +29 -5948
  42. package/dist/bin/exe-search.js +22 -7692
  43. package/dist/bin/exe-session-cleanup.js +52 -11147
  44. package/dist/bin/exe-settings.js +35 -524
  45. package/dist/bin/exe-start-codex.js +70 -6641
  46. package/dist/bin/exe-start-opencode.js +54 -6584
  47. package/dist/bin/exe-status.js +26 -7081
  48. package/dist/bin/exe-support.js +10 -546
  49. package/dist/bin/exe-team.js +18 -5942
  50. package/dist/bin/git-sweep.js +26 -10909
  51. package/dist/bin/graph-backfill.js +24 -5979
  52. package/dist/bin/graph-export.js +31 -6128
  53. package/dist/bin/graph-layer-benchmark.js +4 -8
  54. package/dist/bin/install.js +47 -2322
  55. package/dist/bin/intercom-check.js +25 -11501
  56. package/dist/bin/list-providers.js +4 -18
  57. package/dist/bin/postgres-agentic-reflection-backfill.js +14 -357
  58. package/dist/bin/postgres-agentic-semantic-backfill.js +14 -404
  59. package/dist/bin/pre-publish.js +4 -298
  60. package/dist/bin/registry-proxy.js +8 -172
  61. package/dist/bin/scan-tasks.js +47 -10881
  62. package/dist/bin/setup.js +6 -9492
  63. package/dist/bin/shard-migrate.js +30 -5149
  64. package/dist/bin/stack-update.js +75 -203
  65. package/dist/bin/update.js +20 -654
  66. package/dist/capacity-monitor-3GZIHLB4.js +46 -0
  67. package/dist/catchup-brief-67QDCINS.js +148 -0
  68. package/dist/chunk-2QD7KBJN.js +664 -0
  69. package/dist/chunk-2WGSIVI4.js +149 -0
  70. package/dist/chunk-35TVNLJI.js +57 -0
  71. package/dist/chunk-3SYV36U5.js +47 -0
  72. package/dist/chunk-46SQTBQW.js +207 -0
  73. package/dist/chunk-4CMVLKEI.js +171 -0
  74. package/dist/chunk-4FLUOZTR.js +116 -0
  75. package/dist/chunk-4NYQAS33.js +17 -0
  76. package/dist/chunk-4QNPADWL.js +902 -0
  77. package/dist/chunk-4Y6QZBEO.js +58 -0
  78. package/dist/chunk-557C2IGL.js +0 -0
  79. package/dist/chunk-55S56YDO.js +305 -0
  80. package/dist/chunk-5BS5ELMC.js +85 -0
  81. package/dist/chunk-5DHM77JE.js +256 -0
  82. package/dist/chunk-5QTWQKNF.js +137 -0
  83. package/dist/chunk-6A7P74QV.js +53 -0
  84. package/dist/chunk-6BFIFI5F.js +45 -0
  85. package/dist/chunk-6KFICEAT.js +20 -0
  86. package/dist/chunk-6LKDJ5WX.js +317 -0
  87. package/dist/chunk-6M5II4EV.js +148 -0
  88. package/dist/chunk-6QEFN3DV.js +302 -0
  89. package/dist/chunk-6WTMJAG3.js +171 -0
  90. package/dist/chunk-6Y4B3QF6.js +19 -0
  91. package/dist/chunk-7RK3AYJE.js +163 -0
  92. package/dist/chunk-7TCP2XTP.js +390 -0
  93. package/dist/chunk-A2NZP64U.js +2307 -0
  94. package/dist/chunk-AFYIYM2K.js +322 -0
  95. package/dist/chunk-AJWFPKQS.js +573 -0
  96. package/dist/chunk-AVE2B4DQ.js +140 -0
  97. package/dist/chunk-B4TT2QQA.js +87 -0
  98. package/dist/chunk-BCMOO4OQ.js +1066 -0
  99. package/dist/chunk-BU3ID2WT.js +432 -0
  100. package/dist/chunk-CFIM43JH.js +862 -0
  101. package/dist/chunk-CURJUF3W.js +66 -0
  102. package/dist/chunk-DC4ZD76Y.js +288 -0
  103. package/dist/chunk-DL52JPGF.js +706 -0
  104. package/dist/chunk-DRSC6ZRA.js +36 -0
  105. package/dist/chunk-E2Q4Y22A.js +86 -0
  106. package/dist/chunk-ECGTESAP.js +236 -0
  107. package/dist/chunk-EHOJUXYG.js +365 -0
  108. package/dist/chunk-EIT6J37V.js +119 -0
  109. package/dist/chunk-ELE2C7L4.js +31 -0
  110. package/dist/chunk-EQSQ4HBW.js +9 -0
  111. package/dist/chunk-FWFFZGSC.js +94 -0
  112. package/dist/chunk-GCNWCYJI.js +249 -0
  113. package/dist/chunk-GGTUUI7J.js +6 -0
  114. package/dist/chunk-GU56L7OY.js +223 -0
  115. package/dist/chunk-HF25XPZE.js +83 -0
  116. package/dist/chunk-HOKOOBDL.js +52 -0
  117. package/dist/chunk-HP43GLZ6.js +89 -0
  118. package/dist/chunk-HSRM6PNM.js +682 -0
  119. package/dist/chunk-HVRTW3OP.js +164 -0
  120. package/dist/chunk-IHDHL5ML.js +125 -0
  121. package/dist/chunk-IHF5RXJM.js +168 -0
  122. package/dist/chunk-IJ73YE73.js +409 -0
  123. package/dist/chunk-INO4ZD5Y.js +162 -0
  124. package/dist/chunk-IRQTM7DY.js +475 -0
  125. package/dist/chunk-JD4FAPYG.js +1208 -0
  126. package/dist/chunk-JN44LQ53.js +316 -0
  127. package/dist/chunk-JQ6TLNIV.js +133 -0
  128. package/dist/chunk-JT76KRZQ.js +35 -0
  129. package/dist/chunk-K6OEWZTB.js +262 -0
  130. package/dist/chunk-KCUYRZSX.js +72 -0
  131. package/dist/chunk-KFQGP6VL.js +33 -0
  132. package/dist/chunk-KRLOFIPI.js +83 -0
  133. package/dist/chunk-KVPG5UT6.js +305 -0
  134. package/dist/chunk-L3TB7CC3.js +170 -0
  135. package/dist/chunk-L4X5EUHR.js +283 -0
  136. package/dist/chunk-LAN26C3W.js +655 -0
  137. package/dist/chunk-LPGBKR4H.js +54 -0
  138. package/dist/chunk-LVNMOVGD.js +132 -0
  139. package/dist/chunk-LX5WEEZ7.js +157 -0
  140. package/dist/chunk-MBH42QNH.js +295 -0
  141. package/dist/chunk-MFO7MNSD.js +102 -0
  142. package/dist/chunk-MILTNDZH.js +736 -0
  143. package/dist/chunk-MJAE4NB7.js +1090 -0
  144. package/dist/chunk-MLCUPTP7.js +132 -0
  145. package/dist/chunk-MPURH6JI.js +445 -0
  146. package/dist/chunk-MVBWW2EO.js +89 -0
  147. package/dist/chunk-MZIGUUDQ.js +42 -0
  148. package/dist/chunk-N3DTSVKE.js +157 -0
  149. package/dist/chunk-N5RRQOAC.js +134 -0
  150. package/dist/chunk-N7L33TED.js +1664 -0
  151. package/dist/chunk-NDYSNVI5.js +122 -0
  152. package/dist/chunk-NEAHEC5G.js +155 -0
  153. package/dist/chunk-NGVOA6ZQ.js +84 -0
  154. package/dist/chunk-NHK5KW6Y.js +193 -0
  155. package/dist/chunk-NMQKGFEP.js +458 -0
  156. package/dist/chunk-NPT4EHZK.js +352 -0
  157. package/dist/chunk-NXFJHTED.js +55 -0
  158. package/dist/chunk-NZLCDI6Y.js +216 -0
  159. package/dist/chunk-O377P7GM.js +100 -0
  160. package/dist/chunk-O4VFZRA5.js +33 -0
  161. package/dist/chunk-O7YD7JYE.js +237 -0
  162. package/dist/chunk-OFK72LTZ.js +81 -0
  163. package/dist/chunk-ORCCI2VV.js +140 -0
  164. package/dist/chunk-OVQR4KMC.js +579 -0
  165. package/dist/chunk-P3CVUMEH.js +54 -0
  166. package/dist/chunk-P4HIF72O.js +30 -0
  167. package/dist/chunk-PEDLSJBL.js +1039 -0
  168. package/dist/chunk-PFICKZZ5.js +219 -0
  169. package/dist/chunk-PGW7TIV6.js +142 -0
  170. package/dist/chunk-PJHHFJAN.js +63 -0
  171. package/dist/chunk-PP4SNOJ5.js +471 -0
  172. package/dist/chunk-PRKVT4KN.js +90 -0
  173. package/dist/chunk-Q2O4VJHH.js +305 -0
  174. package/dist/chunk-Q36CMZIX.js +38 -0
  175. package/dist/chunk-Q3V7K4ME.js +149 -0
  176. package/dist/chunk-QGYPJGHB.js +81 -0
  177. package/dist/chunk-R23EMFJV.js +198 -0
  178. package/dist/chunk-R4M6XCMU.js +39 -0
  179. package/dist/chunk-R4WMF32C.js +81 -0
  180. package/dist/chunk-RJT7H2KR.js +349 -0
  181. package/dist/chunk-RJZMRZNV.js +280 -0
  182. package/dist/chunk-RMFDPCA2.js +72 -0
  183. package/dist/chunk-RUG3N6P4.js +292 -0
  184. package/dist/chunk-RWO327FJ.js +84 -0
  185. package/dist/chunk-SG7EFHQ7.js +108 -0
  186. package/dist/chunk-SH45SJQW.js +0 -0
  187. package/dist/chunk-SPKE5ANC.js +42 -0
  188. package/dist/chunk-SVMFVPBF.js +104 -0
  189. package/dist/chunk-SVXDCELZ.js +163 -0
  190. package/dist/chunk-TMEE7AT7.js +72 -0
  191. package/dist/chunk-TWYEE4FB.js +125 -0
  192. package/dist/chunk-TYLF4LSW.js +110 -0
  193. package/dist/chunk-V4TZI6EO.js +60 -0
  194. package/dist/chunk-VFZTXKQI.js +372 -0
  195. package/dist/chunk-VQ4K2MLM.js +199 -0
  196. package/dist/chunk-VU447UAO.js +173 -0
  197. package/dist/chunk-WMC3TXJF.js +50 -0
  198. package/dist/chunk-WPOA7XAE.js +84 -0
  199. package/dist/chunk-WZQ4CPRG.js +64 -0
  200. package/dist/chunk-X2IMCCM5.js +49 -0
  201. package/dist/chunk-X2Z5GT3V.js +118 -0
  202. package/dist/chunk-XEKO37NM.js +43 -0
  203. package/dist/chunk-XUHFQHGZ.js +505 -0
  204. package/dist/chunk-YGAAZN3E.js +47 -0
  205. package/dist/chunk-YKOW7KMK.js +558 -0
  206. package/dist/chunk-YOQKMB6N.js +145 -0
  207. package/dist/chunk-YZFZDJWZ.js +107 -0
  208. package/dist/chunk-ZBY4AUD4.js +10342 -0
  209. package/dist/chunk-ZOJYPNCM.js +127 -0
  210. package/dist/chunk-ZS7MGQSD.js +1494 -0
  211. package/dist/chunk-ZTZQ5A6B.js +191 -0
  212. package/dist/code-context-index-HXGC4IJL.js +28 -0
  213. package/dist/content-extractor-UVZXRIPC.js +8 -0
  214. package/dist/conversation-entity-extractor-HKSNDF4L.js +113 -0
  215. package/dist/conversation-wiki-populator-NKDAQEZ5.js +105 -0
  216. package/dist/crdt-sync-T7MHVQCS.js +33 -0
  217. package/dist/crm-bridge-Q5JBVJ6P.js +19 -0
  218. package/dist/crm-webhook-OAFTLJYA.js +10 -0
  219. package/dist/cto-delegation-gate-XWHZCUJH.js +208 -0
  220. package/dist/daemon-auth-GWUXTUYO.js +15 -0
  221. package/dist/daemon-orchestration-2C3TVOHO.js +91 -0
  222. package/dist/daemon-protocol-RLH2XM2K.js +19 -0
  223. package/dist/db-backup-CH2KG3JY.js +23 -0
  224. package/dist/devtools-PLJCAU53.js +8 -0
  225. package/dist/discord-G4BQJ2VX.js +7 -0
  226. package/dist/email-XMRNMFXR.js +137 -0
  227. package/dist/entity-boost-IOER4VRR.js +249 -0
  228. package/dist/exe-drift-2IJFQV43.js +68 -0
  229. package/dist/exe-export-Y2RFXGNB.js +71 -0
  230. package/dist/exe-import-LN6PE2YT.js +74 -0
  231. package/dist/exe-key-DHKBWLIT.js +571 -0
  232. package/dist/exe-org-F7LZRHFB.js +73 -0
  233. package/dist/factory-YTD23AW7.js +67 -0
  234. package/dist/fast-db-init-IIP6EGWT.js +7 -0
  235. package/dist/file-edit-FJVEO7XZ.js +8 -0
  236. package/dist/file-read-Q2NH3J35.js +8 -0
  237. package/dist/file-write-UNSFXNH4.js +8 -0
  238. package/dist/gateway/index.js +87 -16563
  239. package/dist/gateway-client-APTYJNCL.js +11 -0
  240. package/dist/git-staleness-I2BUEDE2.js +111 -0
  241. package/dist/git-task-sweep-UEOTXRW4.js +35 -0
  242. package/dist/glob-GRMXLDMB.js +7 -0
  243. package/dist/global-procedures-MFE5LGRF.js +19 -0
  244. package/dist/graph-query-657O5JYJ.js +25 -0
  245. package/dist/graph-rag-ZE5N7C65.js +28 -0
  246. package/dist/grep-NBV6SKYZ.js +7 -0
  247. package/dist/hooks/bug-report-worker.js +41 -10823
  248. package/dist/hooks/codex-stop-task-finalizer.js +38 -9055
  249. package/dist/hooks/commit-complete.js +32 -10914
  250. package/dist/hooks/error-recall.js +35 -7955
  251. package/dist/hooks/exe-heartbeat-hook.js +17 -327
  252. package/dist/hooks/ingest-worker.js +16 -565
  253. package/dist/hooks/ingest.js +98 -11436
  254. package/dist/hooks/instructions-loaded.js +25 -6209
  255. package/dist/hooks/notification.js +16 -6098
  256. package/dist/hooks/post-compact.js +34 -7041
  257. package/dist/hooks/post-tool-combined.js +27 -9751
  258. package/dist/hooks/pre-compact.js +38 -11130
  259. package/dist/hooks/pre-tool-use.js +61 -7233
  260. package/dist/hooks/prompt-submit.js +113 -13358
  261. package/dist/hooks/session-end.js +57 -11503
  262. package/dist/hooks/session-start.js +46 -9423
  263. package/dist/hooks/stop.js +70 -7210
  264. package/dist/hooks/subagent-stop.js +33 -6897
  265. package/dist/hooks/summary-worker.js +86 -8629
  266. package/dist/hooks-KD3N2D7P.js +9 -0
  267. package/dist/imessage-L7WKA2WD.js +7 -0
  268. package/dist/index.js +49 -19391
  269. package/dist/installer-5N24GXFB.js +32 -0
  270. package/dist/installer-QSD76YRY.js +291 -0
  271. package/dist/installer-ZPQUKHU5.js +331 -0
  272. package/dist/intercom-queue-PEEGAJ33.js +19 -0
  273. package/dist/key-backup-status-57UB74DU.js +41 -0
  274. package/dist/lib/agent-config.js +19 -224
  275. package/dist/lib/cloud-sync.js +44 -5398
  276. package/dist/lib/cloudflare-dns.js +7 -111
  277. package/dist/lib/config.js +18 -278
  278. package/dist/lib/consolidation.js +21 -1047
  279. package/dist/lib/crypto.js +7 -45
  280. package/dist/lib/database.js +20 -2932
  281. package/dist/lib/db-daemon-client.js +24 -460
  282. package/dist/lib/db.js +22 -2932
  283. package/dist/lib/device-registry.js +20 -2992
  284. package/dist/lib/embedder.js +14 -822
  285. package/dist/lib/employee-templates.js +21 -1102
  286. package/dist/lib/employees.js +30 -497
  287. package/dist/lib/error-detector.js +9 -149
  288. package/dist/lib/exe-daemon-client.js +16 -570
  289. package/dist/lib/exe-daemon.js +509 -18398
  290. package/dist/lib/file-grep.js +2 -0
  291. package/dist/lib/hybrid-search.js +18 -7674
  292. package/dist/lib/identity-templates.js +2 -0
  293. package/dist/lib/identity.js +13 -309
  294. package/dist/lib/keychain.js +9 -499
  295. package/dist/lib/license.js +21 -549
  296. package/dist/lib/messaging.js +35 -1631
  297. package/dist/lib/post-tool-memory.js +8 -370
  298. package/dist/lib/registry-proxy.js +8 -155
  299. package/dist/lib/reminders.js +11 -231
  300. package/dist/lib/runtime-table.js +7 -20
  301. package/dist/lib/schedules.js +16 -4614
  302. package/dist/lib/session-registry.js +9 -57
  303. package/dist/lib/session-wrappers.js +3 -127
  304. package/dist/lib/skill-learning.js +20 -2101
  305. package/dist/lib/status-brief.js +4 -368
  306. package/dist/lib/store.js +25 -5593
  307. package/dist/lib/task-router.js +12 -254
  308. package/dist/lib/tasks.js +44 -5801
  309. package/dist/lib/tmux-routing.js +45 -5804
  310. package/dist/lib/tmux-status.js +16 -248
  311. package/dist/lib/tmux-transport.js +6 -90
  312. package/dist/lib/token-spend.js +9 -337
  313. package/dist/lib/transport.js +8 -134
  314. package/dist/lib/ws-auth.js +6 -14
  315. package/dist/lib/ws-client.js +4 -22
  316. package/dist/license-gate-NXXDOOAQ.js +14 -0
  317. package/dist/mcp/register-tools.js +90 -32454
  318. package/dist/mcp/server.js +139 -32625
  319. package/dist/mcp/tools/complete-reminder.js +10 -237
  320. package/dist/mcp/tools/create-reminder.js +10 -222
  321. package/dist/mcp/tools/create-task.js +28 -6730
  322. package/dist/mcp/tools/deactivate-behavior.js +13 -476
  323. package/dist/mcp/tools/list-reminders.js +10 -232
  324. package/dist/mcp/tools/list-tasks.js +28 -1571
  325. package/dist/mcp/tools/send-message.js +25 -1672
  326. package/dist/mcp/tools/update-task.js +27 -6123
  327. package/dist/mcp-diagnostics-OOZ3TDPY.js +200 -0
  328. package/dist/memory-cards-RIL5BZHK.js +175 -0
  329. package/dist/memory-queue-JYIJ7TMQ.js +13 -0
  330. package/dist/memory-queue-client-PE7757HU.js +14 -0
  331. package/dist/notifications-CJFULBMN.js +42 -0
  332. package/dist/orchestration-phase-Y2TYNW5H.js +23 -0
  333. package/dist/orchestrator-RXIPT6PZ.js +29 -0
  334. package/dist/permission-presets-WI524OSE.js +25 -0
  335. package/dist/permissions-TYT6YMNZ.js +14 -0
  336. package/dist/pg-ssl-KFHNJPGO.js +7 -0
  337. package/dist/plan-limits-5WY5YK6X.js +27 -0
  338. package/dist/preferences-MW3BYTQ5.js +10 -0
  339. package/dist/project-name-PL2ZDWNU.js +11 -0
  340. package/dist/projection-worker-OY4WYZW6.js +661 -0
  341. package/dist/reranker-LFJ73RRS.js +19 -0
  342. package/dist/review-gate-E6K7QQE5.js +120 -0
  343. package/dist/runtime/index.js +82 -13408
  344. package/dist/self-query-router-IZANO632.js +83 -0
  345. package/dist/session-events-TQ6S5KQN.js +32 -0
  346. package/dist/session-kill-telemetry-46YIJWE2.js +30 -0
  347. package/dist/session-scope-3MYK3YRV.js +34 -0
  348. package/dist/setup-wizard-ZJ7UCRBP.js +12 -0
  349. package/dist/shard-manager-RCFZ6RXY.js +29 -0
  350. package/dist/signal-XN2C7PIG.js +7 -0
  351. package/dist/slack-Z77TFJCK.js +7 -0
  352. package/dist/task-enforcement-337DZI3I.js +252 -0
  353. package/dist/task-scanner-IMIR3T7T.js +11 -0
  354. package/dist/task-scope-MUU4KXE6.js +32 -0
  355. package/dist/tasks-crud-PMLK3MM4.js +53 -0
  356. package/dist/tasks-review-56LVKKNL.js +44 -0
  357. package/dist/telegram-CRPZO7JT.js +7 -0
  358. package/dist/telemetry-SPVGPKU7.js +9 -0
  359. package/dist/tool-capability-index-XNBSDCH3.js +10 -0
  360. package/dist/tool-gates-LGH6CSY4.js +14 -0
  361. package/dist/tool-gates-W7SZCYTX.js +13 -0
  362. package/dist/tool-registry-436LVVLY.js +11 -0
  363. package/dist/tool-telemetry-L77WNAYT.js +15 -0
  364. package/dist/tui/App.js +253 -14668
  365. package/dist/tui-data-SB45REYU.js +161 -0
  366. package/dist/update-check-LZGZISRJ.js +11 -0
  367. package/dist/webhook-VVP7KQVC.js +96 -0
  368. package/dist/whatsapp-J6QNDBGY.js +9 -0
  369. package/dist/whatsapp-accounts-RTJF3LM6.js +15 -0
  370. package/dist/wiki-client-EKCIKCVC.js +136 -0
  371. package/dist/worker-gate-UYNN62GJ.js +19 -0
  372. package/dist/worktree-4T4BPWPN.js +205 -0
  373. package/package.json +1 -1
@@ -0,0 +1,1208 @@
1
+ import {
2
+ initCRMBridge
3
+ } from "./chunk-GCNWCYJI.js";
4
+ import {
5
+ init_state_bus,
6
+ orgBus
7
+ } from "./chunk-WZQ4CPRG.js";
8
+ import {
9
+ getClient,
10
+ init_database
11
+ } from "./chunk-A2NZP64U.js";
12
+
13
+ // src/gateway/router.ts
14
+ function matchesPlatform(msgPlatform, matchPlatform) {
15
+ if (!matchPlatform) return true;
16
+ const platforms = Array.isArray(matchPlatform) ? matchPlatform : [matchPlatform];
17
+ return platforms.includes(msgPlatform);
18
+ }
19
+ function matchesChannel(msgChannel, matchChannel) {
20
+ if (!matchChannel) return true;
21
+ const channels = Array.isArray(matchChannel) ? matchChannel : [matchChannel];
22
+ return channels.includes(msgChannel);
23
+ }
24
+ var MAX_REGEX_LENGTH = 200;
25
+ function safeRegExp(pattern, flags) {
26
+ if (pattern.length > MAX_REGEX_LENGTH) return null;
27
+ try {
28
+ return new RegExp(pattern, flags);
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+ function matchesSender(msgSender, matchSender) {
34
+ if (!matchSender) return true;
35
+ const re = safeRegExp(matchSender);
36
+ return re ? re.test(msgSender) : false;
37
+ }
38
+ function matchesTextPattern(msgText, matchPattern) {
39
+ if (!matchPattern) return true;
40
+ const re = safeRegExp(matchPattern, "i");
41
+ return re ? re.test(msgText) : false;
42
+ }
43
+ function matchesRoute(msg, match) {
44
+ return matchesPlatform(msg.platform, match.platform) && matchesChannel(msg.channelId, match.channelId) && matchesSender(msg.senderId, match.senderId) && matchesTextPattern(msg.text, match.textPattern);
45
+ }
46
+ function routeMessage(msg, config) {
47
+ for (const route of config.routes) {
48
+ if (matchesRoute(msg, route.match)) {
49
+ return {
50
+ employee: route.target,
51
+ modelTier: route.modelTier,
52
+ permissions: route.permissions,
53
+ routeName: route.name
54
+ };
55
+ }
56
+ }
57
+ return {
58
+ employee: config.defaultRoute,
59
+ modelTier: config.defaultModelTier,
60
+ permissions: config.defaultPermissions,
61
+ routeName: "default"
62
+ };
63
+ }
64
+ function validateGatewayConfig(config) {
65
+ const warnings = [];
66
+ if (!config.routes.length) {
67
+ warnings.push("No routes configured \u2014 all messages will use default route");
68
+ }
69
+ if (!config.defaultRoute) {
70
+ warnings.push("No default route specified");
71
+ }
72
+ const names = /* @__PURE__ */ new Set();
73
+ for (const route of config.routes) {
74
+ if (names.has(route.name)) {
75
+ warnings.push(`Duplicate route name: "${route.name}"`);
76
+ }
77
+ names.add(route.name);
78
+ if (!route.target) {
79
+ warnings.push(`Route "${route.name}" has no target employee`);
80
+ }
81
+ if (route.match.senderId && !safeRegExp(route.match.senderId)) {
82
+ warnings.push(`Route "${route.name}" has invalid senderId regex: ${route.match.senderId}`);
83
+ }
84
+ if (route.match.textPattern && !safeRegExp(route.match.textPattern, "i")) {
85
+ warnings.push(`Route "${route.name}" has invalid textPattern regex: ${route.match.textPattern}`);
86
+ }
87
+ const isEmptyMatch = !route.match.platform && !route.match.channelId && !route.match.senderId && !route.match.textPattern;
88
+ if (isEmptyMatch && config.routes.indexOf(route) !== config.routes.length - 1) {
89
+ warnings.push(
90
+ `Route "${route.name}" matches everything but is not the last route \u2014 routes after it will never match`
91
+ );
92
+ }
93
+ }
94
+ return warnings;
95
+ }
96
+
97
+ // src/gateway/reliability.ts
98
+ var DEFAULT_RETRY = {
99
+ maxRetries: 3,
100
+ baseDelayMs: 1e3,
101
+ maxDelayMs: 4e3
102
+ };
103
+ async function retryWithBackoff(fn, config = {}) {
104
+ const { maxRetries, baseDelayMs, maxDelayMs } = {
105
+ ...DEFAULT_RETRY,
106
+ ...config
107
+ };
108
+ let lastError;
109
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
110
+ try {
111
+ return await fn();
112
+ } catch (err) {
113
+ lastError = err instanceof Error ? err : new Error(String(err));
114
+ if (attempt < maxRetries) {
115
+ const delay = Math.min(baseDelayMs * 2 ** attempt, maxDelayMs);
116
+ await new Promise((r) => setTimeout(r, delay));
117
+ }
118
+ }
119
+ }
120
+ throw lastError;
121
+ }
122
+ var DEFAULT_CIRCUIT = {
123
+ windowMs: 6e4,
124
+ failureThreshold: 0.5,
125
+ minimumRequests: 5,
126
+ halfOpenAfterMs: 3e4
127
+ };
128
+ var CircuitBreaker = class {
129
+ state = "closed";
130
+ records = [];
131
+ lastStateChange = Date.now();
132
+ config;
133
+ name;
134
+ constructor(name, config = {}) {
135
+ this.name = name;
136
+ this.config = { ...DEFAULT_CIRCUIT, ...config };
137
+ }
138
+ /** Check if a request should be allowed through */
139
+ canRequest() {
140
+ this.pruneRecords();
141
+ if (this.state === "closed") return true;
142
+ if (this.state === "open") {
143
+ const elapsed = Date.now() - this.lastStateChange;
144
+ if (elapsed >= this.config.halfOpenAfterMs) {
145
+ this.transition("half-open");
146
+ return true;
147
+ }
148
+ return false;
149
+ }
150
+ return true;
151
+ }
152
+ /** Record a successful request */
153
+ recordSuccess() {
154
+ this.records.push({ timestamp: Date.now(), success: true });
155
+ if (this.state === "half-open") {
156
+ this.transition("closed");
157
+ }
158
+ }
159
+ /** Record a failed request */
160
+ recordFailure() {
161
+ this.records.push({ timestamp: Date.now(), success: false });
162
+ if (this.state === "half-open") {
163
+ this.transition("open");
164
+ return;
165
+ }
166
+ if (this.state === "closed") {
167
+ this.pruneRecords();
168
+ if (this.records.length >= this.config.minimumRequests) {
169
+ const failures = this.records.filter((r) => !r.success).length;
170
+ const rate = failures / this.records.length;
171
+ if (rate >= this.config.failureThreshold) {
172
+ this.transition("open");
173
+ }
174
+ }
175
+ }
176
+ }
177
+ /** Get current circuit state */
178
+ getState() {
179
+ if (this.state === "open") {
180
+ const elapsed = Date.now() - this.lastStateChange;
181
+ if (elapsed >= this.config.halfOpenAfterMs) {
182
+ this.transition("half-open");
183
+ }
184
+ }
185
+ return this.state;
186
+ }
187
+ /** Get failure rate in current window */
188
+ getFailureRate() {
189
+ this.pruneRecords();
190
+ if (this.records.length === 0) return 0;
191
+ const failures = this.records.filter((r) => !r.success).length;
192
+ return failures / this.records.length;
193
+ }
194
+ /** Reset the circuit breaker */
195
+ reset() {
196
+ this.records = [];
197
+ this.transition("closed");
198
+ }
199
+ transition(newState) {
200
+ this.state = newState;
201
+ this.lastStateChange = Date.now();
202
+ }
203
+ pruneRecords() {
204
+ const cutoff = Date.now() - this.config.windowMs;
205
+ while (this.records.length > 0 && this.records[0].timestamp < cutoff) {
206
+ this.records.shift();
207
+ }
208
+ }
209
+ };
210
+ function buildDegradationMessage() {
211
+ return "I'm having trouble right now. Let me get a human to help you.";
212
+ }
213
+
214
+ // src/gateway/gateway.ts
215
+ init_state_bus();
216
+
217
+ // src/lib/pipeline-router.ts
218
+ init_database();
219
+ import crypto from "crypto";
220
+ async function sinkConversationStore(msg, agentResponse, agentName) {
221
+ try {
222
+ const client = getClient();
223
+ const id = crypto.randomUUID();
224
+ const mediaJson = msg.media ? JSON.stringify(msg.media) : null;
225
+ await client.execute({
226
+ sql: `INSERT INTO conversations
227
+ (id, platform, external_id, sender_id, sender_name, sender_phone, sender_email,
228
+ recipient_id, channel_id, thread_id, reply_to_id,
229
+ content_text, content_media, agent_response, agent_name,
230
+ timestamp, ingested_at)
231
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
232
+ args: [
233
+ id,
234
+ msg.platform,
235
+ msg.messageId,
236
+ msg.senderId,
237
+ msg.senderName ?? null,
238
+ msg.senderPhone ?? null,
239
+ msg.senderEmail ?? null,
240
+ msg.accountId ?? null,
241
+ msg.channelId,
242
+ msg.threadId ?? `${msg.platform}:${msg.channelId}`,
243
+ msg.replyTo?.messageId ?? null,
244
+ msg.text ?? null,
245
+ mediaJson,
246
+ agentResponse ?? null,
247
+ agentName ?? null,
248
+ msg.timestamp,
249
+ (/* @__PURE__ */ new Date()).toISOString()
250
+ ]
251
+ });
252
+ return true;
253
+ } catch (err) {
254
+ process.stderr.write(
255
+ `[pipeline] conversation-store error: ${err instanceof Error ? err.message : String(err)}
256
+ `
257
+ );
258
+ return false;
259
+ }
260
+ }
261
+ async function sinkMemory(msg, agentResponse, agentName) {
262
+ try {
263
+ const { embed } = await import("./lib/embedder.js");
264
+ const { writeMemory, flushBatch } = await import("./lib/store.js");
265
+ const direction = agentResponse ? "conversation" : "inbound";
266
+ const rawText = [
267
+ `[${msg.platform}] ${direction} from ${msg.senderName ?? msg.senderId}`,
268
+ msg.text ? `Message: ${msg.text}` : null,
269
+ agentResponse ? `Agent (${agentName ?? "unknown"}): ${agentResponse}` : null
270
+ ].filter(Boolean).join("\n");
271
+ const vector = await embed(rawText);
272
+ await writeMemory({
273
+ id: crypto.randomUUID(),
274
+ agent_id: agentName ?? "gateway",
275
+ agent_role: "gateway",
276
+ session_id: `gateway-${msg.platform}`,
277
+ timestamp: msg.timestamp,
278
+ tool_name: `gateway-${msg.platform}`,
279
+ project_name: "exe-os",
280
+ has_error: false,
281
+ raw_text: rawText,
282
+ vector,
283
+ importance: 4,
284
+ confidence: 0.8
285
+ });
286
+ await flushBatch();
287
+ return true;
288
+ } catch (err) {
289
+ process.stderr.write(
290
+ `[pipeline] memory-sink error: ${err instanceof Error ? err.message : String(err)}
291
+ `
292
+ );
293
+ return false;
294
+ }
295
+ }
296
+ async function sinkCRM(msg, agentResponse, agentName) {
297
+ try {
298
+ const { isCRMBridgeEnabled, pushConversationToCRM, pushInboundMessageToCRM } = await import("./crm-bridge-Q5JBVJ6P.js");
299
+ if (!isCRMBridgeEnabled()) return false;
300
+ if (agentResponse) {
301
+ await pushConversationToCRM({
302
+ platform: msg.platform,
303
+ senderId: msg.senderId,
304
+ senderName: msg.senderName,
305
+ messageText: msg.text,
306
+ agentResponse,
307
+ agentName: agentName ?? "unknown",
308
+ timestamp: msg.timestamp,
309
+ accountId: msg.accountId
310
+ });
311
+ } else {
312
+ await pushInboundMessageToCRM({
313
+ platform: msg.platform,
314
+ senderId: msg.senderId,
315
+ senderName: msg.senderName,
316
+ messageText: msg.text,
317
+ timestamp: msg.timestamp,
318
+ accountId: msg.accountId
319
+ });
320
+ }
321
+ return true;
322
+ } catch (err) {
323
+ process.stderr.write(
324
+ `[pipeline] crm-sink error: ${err instanceof Error ? err.message : String(err)}
325
+ `
326
+ );
327
+ return false;
328
+ }
329
+ }
330
+ async function sinkWiki(msg, agentResponse) {
331
+ try {
332
+ const { createWikiClient } = await import("./wiki-client-EKCIKCVC.js");
333
+ const client = await createWikiClient();
334
+ if (!client) return false;
335
+ const content = msg.text ?? "";
336
+ if (content.length < 50) return false;
337
+ const { chatInWorkspace } = await import("./wiki-client-EKCIKCVC.js");
338
+ const ingestText = [
339
+ `[${msg.platform}] Message from ${msg.senderName ?? msg.senderId} (${msg.timestamp}):`,
340
+ content,
341
+ agentResponse ? `
342
+ Agent response: ${agentResponse}` : ""
343
+ ].join("\n");
344
+ await chatInWorkspace(client, "conversations", ingestText, "chat");
345
+ return true;
346
+ } catch (err) {
347
+ process.stderr.write(
348
+ `[pipeline] wiki-sink error: ${err instanceof Error ? err.message : String(err)}
349
+ `
350
+ );
351
+ return false;
352
+ }
353
+ }
354
+ async function sinkEntityExtraction(msg, agentResponse, agentName) {
355
+ try {
356
+ const { extractFromConversation } = await import("./conversation-entity-extractor-HKSNDF4L.js");
357
+ const { storeExtraction } = await import("./graph-rag-ZE5N7C65.js");
358
+ if ((msg.text?.length ?? 0) < 20) return false;
359
+ if (msg.isHistorical) return false;
360
+ const extraction = await extractFromConversation(msg, agentResponse, agentName);
361
+ if (extraction.entities.length === 0) return false;
362
+ const client = getClient();
363
+ const memoryId = `conv:${msg.messageId}`;
364
+ await storeExtraction(client, extraction, memoryId, msg.timestamp);
365
+ import("./conversation-wiki-populator-NKDAQEZ5.js").then(
366
+ ({ populateWikiFromExtraction }) => populateWikiFromExtraction(extraction, msg, agentResponse, agentName)
367
+ ).catch((err) => {
368
+ process.stderr.write(
369
+ `[pipeline] wiki-population error: ${err instanceof Error ? err.message : String(err)}
370
+ `
371
+ );
372
+ });
373
+ return true;
374
+ } catch (err) {
375
+ process.stderr.write(
376
+ `[pipeline] entity-extraction-sink error: ${err instanceof Error ? err.message : String(err)}
377
+ `
378
+ );
379
+ return false;
380
+ }
381
+ }
382
+ async function ingest(msg, agentResponse, agentName) {
383
+ const errors = [];
384
+ const [conversationStored, memorySunk, crmSunk, wikiSunk, entityExtracted] = await Promise.all([
385
+ sinkConversationStore(msg, agentResponse, agentName).catch((e) => {
386
+ errors.push(`conversation: ${e}`);
387
+ return false;
388
+ }),
389
+ sinkMemory(msg, agentResponse, agentName).catch((e) => {
390
+ errors.push(`memory: ${e}`);
391
+ return false;
392
+ }),
393
+ sinkCRM(msg, agentResponse, agentName).catch((e) => {
394
+ errors.push(`crm: ${e}`);
395
+ return false;
396
+ }),
397
+ sinkWiki(msg, agentResponse).catch((e) => {
398
+ errors.push(`wiki: ${e}`);
399
+ return false;
400
+ }),
401
+ sinkEntityExtraction(msg, agentResponse, agentName).catch((e) => {
402
+ errors.push(`entity-extraction: ${e}`);
403
+ return false;
404
+ })
405
+ ]);
406
+ if (errors.length > 0) {
407
+ process.stderr.write(
408
+ `[pipeline] ${errors.length} sink error(s): ${errors.join("; ")}
409
+ `
410
+ );
411
+ }
412
+ return { conversationStored, memorySunk, crmSunk, wikiSunk, entityExtracted, errors };
413
+ }
414
+
415
+ // src/gateway/gateway.ts
416
+ var Gateway = class {
417
+ config;
418
+ adapters = /* @__PURE__ */ new Map();
419
+ platformConfigs;
420
+ botRegistry;
421
+ rateLimiter;
422
+ sessionStore;
423
+ analytics;
424
+ alertMonitor;
425
+ failover;
426
+ customerStore;
427
+ startedAt = 0;
428
+ constructor(options) {
429
+ this.config = options.config;
430
+ this.platformConfigs = options.platformConfigs;
431
+ this.botRegistry = options.botRegistry;
432
+ this.rateLimiter = options.rateLimiter;
433
+ this.sessionStore = options.sessionStore;
434
+ this.analytics = options.analytics;
435
+ this.alertMonitor = options.alertMonitor;
436
+ this.failover = options.failover;
437
+ this.customerStore = options.customerStore;
438
+ }
439
+ registerAdapter(adapter) {
440
+ this.adapters.set(adapter.platform, adapter);
441
+ adapter.onMessage((msg) => this.handleMessage(msg));
442
+ }
443
+ async start() {
444
+ this.startedAt = Date.now();
445
+ initCRMBridge();
446
+ const startPromises = [];
447
+ for (const [platform, adapter] of this.adapters) {
448
+ const config = this.platformConfigs.get(platform);
449
+ if (!config) {
450
+ console.error(`[gateway] No config for platform: ${platform}`);
451
+ continue;
452
+ }
453
+ console.log(`[gateway] Connecting ${platform}...`);
454
+ startPromises.push(
455
+ adapter.connect(config).then(() => {
456
+ console.log(`[gateway] ${platform} connected`);
457
+ }).catch((err) => {
458
+ console.error(`[gateway] ${platform} connection failed:`, err);
459
+ this.alertMonitor?.alertAdapterDisconnected(
460
+ platform,
461
+ err instanceof Error ? err.message : String(err)
462
+ );
463
+ })
464
+ );
465
+ }
466
+ await Promise.allSettled(startPromises);
467
+ console.log(
468
+ `[gateway] Started with ${this.botRegistry.list().length} bots: ${this.botRegistry.list().join(", ")}`
469
+ );
470
+ }
471
+ async stop() {
472
+ const stopPromises = [...this.adapters.values()].map(
473
+ (a) => a.disconnect()
474
+ );
475
+ await Promise.allSettled(stopPromises);
476
+ console.log("[gateway] Stopped");
477
+ }
478
+ async handleMessage(msg) {
479
+ const start = Date.now();
480
+ if (this.rateLimiter) {
481
+ const limitResult = this.rateLimiter.check(msg.senderId);
482
+ if (!limitResult.allowed) {
483
+ const adapter2 = this.adapters.get(msg.platform);
484
+ if (adapter2) {
485
+ await adapter2.sendText(msg.channelId, limitResult.reason ?? "Please slow down.");
486
+ }
487
+ return;
488
+ }
489
+ }
490
+ this.customerStore?.resolve(msg.platform, msg.senderId);
491
+ ingest(msg).catch((err) => {
492
+ console.error("[gateway] Pipeline inbound ingest error:", err);
493
+ });
494
+ const route = routeMessage(msg, this.config);
495
+ console.log(
496
+ `[gateway] ${msg.platform}/${msg.senderId} \u2192 ${route.employee} (${route.routeName})`
497
+ );
498
+ orgBus.emit({
499
+ type: "gateway_message",
500
+ platform: msg.platform,
501
+ senderId: msg.senderId,
502
+ botId: route.employee,
503
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
504
+ });
505
+ const bot = this.botRegistry.get(route.employee);
506
+ if (!bot) {
507
+ console.error(`[gateway] No bot registered for target: ${route.employee}`);
508
+ const adapter2 = this.adapters.get(msg.platform);
509
+ if (adapter2) {
510
+ await adapter2.sendText(msg.channelId, "Sorry, I'm not available right now.");
511
+ }
512
+ return;
513
+ }
514
+ const adapter = this.adapters.get(msg.platform);
515
+ if (!adapter) return;
516
+ await adapter.sendTyping(msg.channelId);
517
+ const session = this.sessionStore?.getOrCreate(
518
+ msg.senderId,
519
+ route.employee,
520
+ msg.platform
521
+ );
522
+ if (session) {
523
+ this.sessionStore.addMessage(session.sessionId, {
524
+ role: "user",
525
+ content: msg.text
526
+ });
527
+ }
528
+ if (session?.messageCount === 1) {
529
+ this.analytics?.conversationStarted(msg.platform, route.employee);
530
+ }
531
+ try {
532
+ const response = await bot.processMessage(msg, route.permissions);
533
+ const latencyMs = Date.now() - start;
534
+ if (session) {
535
+ this.sessionStore.addMessage(session.sessionId, {
536
+ role: "assistant",
537
+ content: response
538
+ });
539
+ }
540
+ this.analytics?.responseRecorded(
541
+ msg.platform,
542
+ route.employee,
543
+ latencyMs,
544
+ 0,
545
+ // Token counts not available from BotRuntime yet
546
+ 0,
547
+ "anthropic",
548
+ true
549
+ );
550
+ this.alertMonitor?.recordEvent(latencyMs, true);
551
+ await adapter.sendText(msg.channelId, response, {
552
+ replyToMessageId: msg.messageId
553
+ });
554
+ ingest(msg, response, route.employee).catch((err) => {
555
+ console.error("[gateway] Pipeline conversation ingest error:", err);
556
+ });
557
+ } catch (err) {
558
+ const latencyMs = Date.now() - start;
559
+ this.alertMonitor?.recordEvent(latencyMs, false);
560
+ this.analytics?.responseRecorded(
561
+ msg.platform,
562
+ route.employee,
563
+ latencyMs,
564
+ 0,
565
+ 0,
566
+ "anthropic",
567
+ false
568
+ );
569
+ console.error(`[gateway] Error processing message:`, err);
570
+ await adapter.sendText(
571
+ msg.channelId,
572
+ buildDegradationMessage()
573
+ );
574
+ }
575
+ }
576
+ /** Health check all adapters + provider health */
577
+ async healthCheck() {
578
+ const adapterHealth = /* @__PURE__ */ new Map();
579
+ for (const [platform, adapter] of this.adapters) {
580
+ adapterHealth.set(platform, await adapter.healthCheck());
581
+ }
582
+ return {
583
+ adapters: adapterHealth,
584
+ providers: this.failover?.getProviderHealth(),
585
+ bots: this.botRegistry.list(),
586
+ uptime: this.startedAt > 0 ? Date.now() - this.startedAt : 0,
587
+ sessions: this.sessionStore?.stats(),
588
+ alerts: this.alertMonitor?.getActiveAlerts().length
589
+ };
590
+ }
591
+ };
592
+
593
+ // src/gateway/types.ts
594
+ var FULL_ACCESS = {
595
+ canRead: true,
596
+ canWrite: true,
597
+ canExecute: true
598
+ };
599
+ var READ_ONLY = {
600
+ canRead: true,
601
+ canWrite: false,
602
+ canExecute: false
603
+ };
604
+ var READ_TOOLS = [
605
+ "ask_team_memory",
606
+ "recall_my_memory",
607
+ "list_tasks",
608
+ "get_session_context",
609
+ "get_memory_by_id",
610
+ "list_reminders",
611
+ "query_conversations"
612
+ ];
613
+ var WRITE_TOOLS = [
614
+ "create_task",
615
+ "update_task",
616
+ "send_message",
617
+ "store_memory",
618
+ "store_behavior",
619
+ "create_reminder",
620
+ "complete_reminder"
621
+ ];
622
+ var EXECUTE_TOOLS = ["close_task"];
623
+
624
+ // src/gateway/permission-guard.ts
625
+ var TOOL_CLASSIFICATION = /* @__PURE__ */ new Map();
626
+ for (const tool of READ_TOOLS) TOOL_CLASSIFICATION.set(tool, "canRead");
627
+ for (const tool of WRITE_TOOLS) TOOL_CLASSIFICATION.set(tool, "canWrite");
628
+ for (const tool of EXECUTE_TOOLS) TOOL_CLASSIFICATION.set(tool, "canExecute");
629
+ function classifyTool(toolName) {
630
+ return TOOL_CLASSIFICATION.get(toolName) ?? null;
631
+ }
632
+ function checkToolPermission(toolName, permissions) {
633
+ const classification = classifyTool(toolName);
634
+ if (!classification) {
635
+ return {
636
+ allowed: false,
637
+ tool: toolName,
638
+ requiredPermission: "canExecute",
639
+ reason: `Unknown tool "${toolName}" is not in the allowed tool list`
640
+ };
641
+ }
642
+ const allowed = permissions[classification];
643
+ return {
644
+ allowed,
645
+ tool: toolName,
646
+ requiredPermission: classification,
647
+ reason: allowed ? void 0 : `Tool "${toolName}" requires ${classification} permission, which is not granted on this channel`
648
+ };
649
+ }
650
+ function guardToolUseBlocks(blocks, permissions) {
651
+ const allowed = [];
652
+ const blocked = [];
653
+ for (const block of blocks) {
654
+ const result = checkToolPermission(block.name, permissions);
655
+ if (result.allowed) {
656
+ allowed.push(block);
657
+ } else {
658
+ blocked.push({ block, check: result });
659
+ }
660
+ }
661
+ return { allowed, blocked };
662
+ }
663
+ function buildPermissionContext(platform, permissions) {
664
+ if (permissions.canRead && permissions.canWrite && permissions.canExecute) {
665
+ return `[FULL ACCESS \u2014 you can read, write, and execute via ${platform}]`;
666
+ }
667
+ if (permissions.canRead && !permissions.canWrite && !permissions.canExecute) {
668
+ return `[READ-ONLY \u2014 this ${platform} channel cannot create tasks, send messages, or execute commands. Tell the founder to use Signal for commands.]`;
669
+ }
670
+ const parts = [];
671
+ if (permissions.canRead) parts.push("read");
672
+ if (permissions.canWrite) parts.push("write");
673
+ if (permissions.canExecute) parts.push("execute");
674
+ return `[${platform.toUpperCase()} \u2014 allowed: ${parts.join(", ")}]`;
675
+ }
676
+
677
+ // src/gateway/bot-errors.ts
678
+ var FatalBotError = class extends Error {
679
+ constructor(message, cause) {
680
+ super(message);
681
+ this.cause = cause;
682
+ this.name = "FatalBotError";
683
+ }
684
+ fatal = true;
685
+ };
686
+ var RecoverableBotError = class extends Error {
687
+ constructor(message, toolName, cause) {
688
+ super(message);
689
+ this.toolName = toolName;
690
+ this.cause = cause;
691
+ this.name = "RecoverableBotError";
692
+ }
693
+ recoverable = true;
694
+ };
695
+ var MaxStepsError = class extends Error {
696
+ constructor(stepsTaken, maxSteps) {
697
+ super(
698
+ `Reached maximum steps (${stepsTaken}/${maxSteps}). Returning partial result.`
699
+ );
700
+ this.stepsTaken = stepsTaken;
701
+ this.maxSteps = maxSteps;
702
+ this.name = "MaxStepsError";
703
+ }
704
+ };
705
+ function classifyError(err, toolName) {
706
+ if (err instanceof FatalBotError) return err;
707
+ if (err instanceof RecoverableBotError) return err;
708
+ const message = err instanceof Error ? err.message : String(err);
709
+ if (message.includes("401") || message.includes("403") || message.includes("authentication") || message.includes("rate_limit")) {
710
+ return new FatalBotError(message, err);
711
+ }
712
+ return new RecoverableBotError(message, toolName, err);
713
+ }
714
+
715
+ // src/gateway/bot-runtime.ts
716
+ import Anthropic from "@anthropic-ai/sdk";
717
+ var DEFAULT_MODEL = "claude-sonnet-4-20250514";
718
+ var MAX_TURNS = 10;
719
+ var MAX_HISTORY = 50;
720
+ var DEFAULT_PLANNING_INTERVAL = 3;
721
+ function buildExecAssistantSystemPrompt(platform, permissions) {
722
+ const permContext = buildPermissionContext(platform, permissions);
723
+ return `You are the founder's executive assistant (agent_id: "ea").
724
+
725
+ You are a relay between the founder and their AI team. You have access to team memories, task lists, and session context. Your job is to answer the founder's questions by querying the team and presenting clear, synthesized answers.
726
+
727
+ ${permContext}
728
+
729
+ Your personality:
730
+ - Direct and concise \u2014 the founder is busy
731
+ - Lead with the answer, not the process
732
+ - When summarizing team work, be specific: names, counts, what shipped
733
+ - If you don't know something, say so and suggest who might
734
+
735
+ Your tools:
736
+ - ask_team_memory: Query any employee's memories by their configured name
737
+ - recall_my_memory: Search your own past conversations with the founder
738
+ - list_tasks: See what's in progress across the org
739
+ - get_session_context: Get context from a specific session
740
+ - list_reminders: Check active reminders
741
+
742
+ ${permissions.canWrite ? "You also have write access: create_task, send_message, store_memory, etc." : "You are READ-ONLY on this channel. If the founder wants to create tasks or send commands, they should use Signal."}`;
743
+ }
744
+ function filterToolsForPermissions(tools, permissions) {
745
+ const allAllowed = /* @__PURE__ */ new Set();
746
+ if (permissions.canRead) {
747
+ for (const t of READ_TOOLS) allAllowed.add(t);
748
+ }
749
+ if (permissions.canWrite) {
750
+ for (const t of WRITE_TOOLS) allAllowed.add(t);
751
+ }
752
+ if (permissions.canExecute) {
753
+ for (const t of EXECUTE_TOOLS) allAllowed.add(t);
754
+ }
755
+ return tools.filter((t) => allAllowed.has(t.name));
756
+ }
757
+ var BotRuntime = class {
758
+ client;
759
+ config;
760
+ conversations = /* @__PURE__ */ new Map();
761
+ constructor(config) {
762
+ this.config = config;
763
+ this.client = new Anthropic({ apiKey: config.apiKey });
764
+ }
765
+ /**
766
+ * Process an incoming message and return the text response.
767
+ * Handles multi-turn tool use internally.
768
+ */
769
+ async processMessage(msg, permissions) {
770
+ const sessionKey = msg.chatType === "group" ? msg.channelId : msg.senderId;
771
+ const history = this.getHistory(sessionKey);
772
+ history.push({ role: "user", content: msg.text, frameType: "task" });
773
+ const systemPrompt = this.config.systemPrompt + "\n\n" + buildPermissionContext(msg.platform, permissions);
774
+ const allowedTools = filterToolsForPermissions(
775
+ this.config.tools,
776
+ permissions
777
+ );
778
+ const model = this.config.model ?? DEFAULT_MODEL;
779
+ const maxTurns = this.config.maxTurns ?? MAX_TURNS;
780
+ const planningInterval = this.config.planningInterval ?? DEFAULT_PLANNING_INTERVAL;
781
+ let turns = 0;
782
+ while (turns < maxTurns) {
783
+ turns++;
784
+ if (planningInterval > 0 && turns > 1 && turns % planningInterval === 1 && maxTurns - turns >= 2) {
785
+ history.push({
786
+ role: "user",
787
+ content: "[Planning checkpoint] Review what you know so far. What facts have you gathered? What is your plan for the remaining steps? Be concise.",
788
+ frameType: "planning"
789
+ });
790
+ }
791
+ let response;
792
+ try {
793
+ response = await this.client.messages.create({
794
+ model,
795
+ max_tokens: 4096,
796
+ system: systemPrompt,
797
+ messages: history.map((m) => ({
798
+ role: m.role,
799
+ content: m.content
800
+ })),
801
+ tools: allowedTools.map((t) => ({
802
+ name: t.name,
803
+ description: t.description,
804
+ input_schema: t.input_schema
805
+ }))
806
+ });
807
+ } catch (err) {
808
+ const classified = classifyError(err);
809
+ if (classified instanceof FatalBotError) {
810
+ const errorMsg = `Bot error: ${classified.message}`;
811
+ history.push({ role: "assistant", content: errorMsg, frameType: "error" });
812
+ this.trimHistory(sessionKey);
813
+ return errorMsg;
814
+ }
815
+ history.push({
816
+ role: "assistant",
817
+ content: `[API error \u2014 retrying] ${classified.message}`,
818
+ frameType: "error"
819
+ });
820
+ continue;
821
+ }
822
+ const toolUseBlocks = response.content.filter(
823
+ (b) => b.type === "tool_use"
824
+ );
825
+ if (toolUseBlocks.length === 0) {
826
+ const textContent = response.content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
827
+ history.push({ role: "assistant", content: textContent, frameType: "assistant" });
828
+ this.trimHistory(sessionKey);
829
+ return textContent;
830
+ }
831
+ const { allowed, blocked } = guardToolUseBlocks(
832
+ toolUseBlocks,
833
+ permissions
834
+ );
835
+ history.push({
836
+ role: "assistant",
837
+ content: response.content,
838
+ frameType: "assistant"
839
+ });
840
+ const toolResults = [];
841
+ let hadFatalError = false;
842
+ for (const block of allowed) {
843
+ try {
844
+ const result = await this.config.toolExecutor(
845
+ block.name,
846
+ block.input
847
+ );
848
+ toolResults.push({
849
+ type: "tool_result",
850
+ tool_use_id: block.id,
851
+ content: result
852
+ });
853
+ } catch (err) {
854
+ const classified = classifyError(err, block.name);
855
+ if (classified instanceof FatalBotError) {
856
+ toolResults.push({
857
+ type: "tool_result",
858
+ tool_use_id: block.id,
859
+ content: `Fatal error: ${classified.message}`,
860
+ is_error: true
861
+ });
862
+ hadFatalError = true;
863
+ } else {
864
+ toolResults.push({
865
+ type: "tool_result",
866
+ tool_use_id: block.id,
867
+ content: `Error (recoverable): ${classified.message}`,
868
+ is_error: true
869
+ });
870
+ }
871
+ }
872
+ }
873
+ for (const { block, check } of blocked) {
874
+ toolResults.push({
875
+ type: "tool_result",
876
+ tool_use_id: block.id,
877
+ content: `Permission denied: ${check.reason}`,
878
+ is_error: true
879
+ });
880
+ }
881
+ history.push({
882
+ role: "user",
883
+ content: toolResults,
884
+ frameType: hadFatalError ? "error" : "tool_result"
885
+ });
886
+ if (hadFatalError) {
887
+ this.trimHistory(sessionKey);
888
+ return `A fatal error occurred during tool execution. The bot loop has been stopped.`;
889
+ }
890
+ }
891
+ const maxErr = new MaxStepsError(turns, maxTurns);
892
+ history.push({
893
+ role: "assistant",
894
+ content: maxErr.message,
895
+ frameType: "error"
896
+ });
897
+ this.trimHistory(sessionKey);
898
+ return maxErr.message;
899
+ }
900
+ getHistory(sessionKey) {
901
+ if (!this.conversations.has(sessionKey)) {
902
+ this.conversations.set(sessionKey, []);
903
+ }
904
+ return this.conversations.get(sessionKey);
905
+ }
906
+ trimHistory(sessionKey) {
907
+ const history = this.conversations.get(sessionKey);
908
+ if (!history || history.length <= MAX_HISTORY) return;
909
+ const firstTaskIdx = history.findIndex((m) => m.frameType === "task");
910
+ let trimmed = history.filter(
911
+ (m, i) => m.frameType !== "planning" || i >= history.length - MAX_HISTORY
912
+ );
913
+ if (trimmed.length > MAX_HISTORY) {
914
+ const tail = trimmed.slice(-MAX_HISTORY);
915
+ if (firstTaskIdx >= 0 && !tail.includes(history[firstTaskIdx])) {
916
+ tail[0] = history[firstTaskIdx];
917
+ }
918
+ trimmed = tail;
919
+ }
920
+ this.conversations.set(sessionKey, trimmed);
921
+ }
922
+ /** Clear conversation history for a session */
923
+ clearHistory(sessionKey) {
924
+ this.conversations.delete(sessionKey);
925
+ }
926
+ };
927
+ function buildExecAssistantTools() {
928
+ return [
929
+ {
930
+ name: "ask_team_memory",
931
+ description: "Search another employee's memories. Use this to find what a team member worked on, learned, or solved.",
932
+ input_schema: {
933
+ type: "object",
934
+ properties: {
935
+ team_member: {
936
+ type: "string",
937
+ description: "Configured name of the team member"
938
+ },
939
+ query: { type: "string", description: "What to search for" },
940
+ project_name: {
941
+ type: "string",
942
+ description: "Filter by project name"
943
+ },
944
+ limit: { type: "number", description: "Max results (default 10)" }
945
+ },
946
+ required: ["team_member", "query"]
947
+ }
948
+ },
949
+ {
950
+ name: "recall_my_memory",
951
+ description: "Search your own past memories using semantic search. Returns memory IDs; use get_memory_by_id for full long records.",
952
+ input_schema: {
953
+ type: "object",
954
+ properties: {
955
+ query: { type: "string", description: "What to search for" },
956
+ project_name: {
957
+ type: "string",
958
+ description: "Filter by project name"
959
+ },
960
+ limit: { type: "number", description: "Max results (default 10)" },
961
+ body_chars: { type: "number", description: "Max characters per memory body, up to 50000" }
962
+ },
963
+ required: ["query"]
964
+ }
965
+ },
966
+ {
967
+ name: "get_memory_by_id",
968
+ description: "Fetch one memory by ID with the full untruncated raw_text body.",
969
+ input_schema: {
970
+ type: "object",
971
+ properties: {
972
+ id: { type: "string", description: "Memory UUID from recall_my_memory" }
973
+ },
974
+ required: ["id"]
975
+ }
976
+ },
977
+ {
978
+ name: "list_tasks",
979
+ description: "List tasks across the organization.",
980
+ input_schema: {
981
+ type: "object",
982
+ properties: {
983
+ assigned_to: {
984
+ type: "string",
985
+ description: "Filter by assignee"
986
+ },
987
+ status: {
988
+ type: "string",
989
+ description: "Filter by status (open, in_progress, done)"
990
+ },
991
+ project_name: {
992
+ type: "string",
993
+ description: "Filter by project"
994
+ }
995
+ }
996
+ }
997
+ },
998
+ {
999
+ name: "get_session_context",
1000
+ description: "Get context from a specific session.",
1001
+ input_schema: {
1002
+ type: "object",
1003
+ properties: {
1004
+ session_key: {
1005
+ type: "string",
1006
+ description: "Session key to look up"
1007
+ }
1008
+ },
1009
+ required: ["session_key"]
1010
+ }
1011
+ },
1012
+ {
1013
+ name: "list_reminders",
1014
+ description: "List active reminders.",
1015
+ input_schema: {
1016
+ type: "object",
1017
+ properties: {
1018
+ status: {
1019
+ type: "string",
1020
+ description: "Filter by status"
1021
+ }
1022
+ }
1023
+ }
1024
+ },
1025
+ // Write tools (only available on Signal with full access)
1026
+ {
1027
+ name: "create_task",
1028
+ description: "Create a new task and assign it to an employee.",
1029
+ input_schema: {
1030
+ type: "object",
1031
+ properties: {
1032
+ title: { type: "string", description: "Task title" },
1033
+ description: { type: "string", description: "Task description" },
1034
+ assigned_to: {
1035
+ type: "string",
1036
+ description: "Employee to assign to"
1037
+ },
1038
+ priority: {
1039
+ type: "string",
1040
+ enum: ["p0", "p1", "p2"],
1041
+ description: "Task priority"
1042
+ },
1043
+ project_name: { type: "string", description: "Project name" }
1044
+ },
1045
+ required: ["title", "assigned_to"]
1046
+ }
1047
+ },
1048
+ {
1049
+ name: "send_message",
1050
+ description: "Send a message to an employee.",
1051
+ input_schema: {
1052
+ type: "object",
1053
+ properties: {
1054
+ to: { type: "string", description: "Employee name" },
1055
+ message: { type: "string", description: "Message content" }
1056
+ },
1057
+ required: ["to", "message"]
1058
+ }
1059
+ },
1060
+ {
1061
+ name: "store_memory",
1062
+ description: "Store a memory for future reference.",
1063
+ input_schema: {
1064
+ type: "object",
1065
+ properties: {
1066
+ content: { type: "string", description: "Memory content" },
1067
+ project_name: { type: "string", description: "Project name" }
1068
+ },
1069
+ required: ["content"]
1070
+ }
1071
+ },
1072
+ {
1073
+ name: "store_behavior",
1074
+ description: "Store a behavioral directive.",
1075
+ input_schema: {
1076
+ type: "object",
1077
+ properties: {
1078
+ content: {
1079
+ type: "string",
1080
+ description: "Behavioral directive content"
1081
+ }
1082
+ },
1083
+ required: ["content"]
1084
+ }
1085
+ },
1086
+ {
1087
+ name: "update_task",
1088
+ description: "Update a task's status.",
1089
+ input_schema: {
1090
+ type: "object",
1091
+ properties: {
1092
+ task_id: { type: "string", description: "Task ID" },
1093
+ status: {
1094
+ type: "string",
1095
+ enum: ["open", "in_progress", "done", "blocked", "cancelled"],
1096
+ description: "New status"
1097
+ },
1098
+ result: { type: "string", description: "Result summary" }
1099
+ },
1100
+ required: ["task_id", "status"]
1101
+ }
1102
+ },
1103
+ {
1104
+ name: "create_reminder",
1105
+ description: "Create a reminder.",
1106
+ input_schema: {
1107
+ type: "object",
1108
+ properties: {
1109
+ content: { type: "string", description: "Reminder content" },
1110
+ due_at: { type: "string", description: "ISO 8601 due date" }
1111
+ },
1112
+ required: ["content"]
1113
+ }
1114
+ },
1115
+ {
1116
+ name: "complete_reminder",
1117
+ description: "Mark a reminder as complete.",
1118
+ input_schema: {
1119
+ type: "object",
1120
+ properties: {
1121
+ reminder_id: { type: "string", description: "Reminder ID" }
1122
+ },
1123
+ required: ["reminder_id"]
1124
+ }
1125
+ },
1126
+ {
1127
+ name: "close_task",
1128
+ description: "Reviewer-only: finalize a task after review. Only coordinators/reviewers can use this.",
1129
+ input_schema: {
1130
+ type: "object",
1131
+ properties: {
1132
+ task_id: { type: "string", description: "Task ID" },
1133
+ result: { type: "string", description: "Completion summary" }
1134
+ },
1135
+ required: ["task_id"]
1136
+ }
1137
+ }
1138
+ ];
1139
+ }
1140
+
1141
+ // src/gateway/bot-registry.ts
1142
+ var BotRegistry = class {
1143
+ bots = /* @__PURE__ */ new Map();
1144
+ /** Register a bot from a template */
1145
+ register(template, apiKey) {
1146
+ const config = {
1147
+ apiKey,
1148
+ model: template.model,
1149
+ agentId: template.agentId,
1150
+ systemPrompt: template.systemPrompt,
1151
+ tools: template.tools.map((t) => ({
1152
+ name: t.name,
1153
+ description: t.description ?? "",
1154
+ input_schema: t.input_schema
1155
+ })),
1156
+ toolExecutor: async (name, input) => {
1157
+ const handler = template.toolHandlers[name];
1158
+ if (!handler) {
1159
+ throw new Error(`No handler for tool "${name}"`);
1160
+ }
1161
+ const result = await handler(input);
1162
+ return typeof result === "string" ? result : JSON.stringify(result);
1163
+ },
1164
+ maxTurns: template.maxTurns
1165
+ };
1166
+ this.bots.set(template.name, new BotRuntime(config));
1167
+ }
1168
+ /** Register a pre-configured BotRuntime directly */
1169
+ registerRuntime(name, runtime) {
1170
+ this.bots.set(name, runtime);
1171
+ }
1172
+ /** Look up a bot by route target name */
1173
+ get(targetName) {
1174
+ return this.bots.get(targetName);
1175
+ }
1176
+ /** List registered bot names */
1177
+ list() {
1178
+ return [...this.bots.keys()];
1179
+ }
1180
+ /** Check if a bot is registered */
1181
+ has(targetName) {
1182
+ return this.bots.has(targetName);
1183
+ }
1184
+ };
1185
+
1186
+ export {
1187
+ routeMessage,
1188
+ validateGatewayConfig,
1189
+ retryWithBackoff,
1190
+ CircuitBreaker,
1191
+ Gateway,
1192
+ FULL_ACCESS,
1193
+ READ_ONLY,
1194
+ READ_TOOLS,
1195
+ WRITE_TOOLS,
1196
+ EXECUTE_TOOLS,
1197
+ checkToolPermission,
1198
+ guardToolUseBlocks,
1199
+ buildPermissionContext,
1200
+ FatalBotError,
1201
+ RecoverableBotError,
1202
+ MaxStepsError,
1203
+ classifyError,
1204
+ buildExecAssistantSystemPrompt,
1205
+ BotRuntime,
1206
+ buildExecAssistantTools,
1207
+ BotRegistry
1208
+ };