openryoko 0.9.4-ryoko.2

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 (514) hide show
  1. package/dist/bin/jimmy.d.ts +3 -0
  2. package/dist/bin/jimmy.d.ts.map +1 -0
  3. package/dist/bin/jimmy.js +149 -0
  4. package/dist/bin/jimmy.js.map +1 -0
  5. package/dist/package.json +54 -0
  6. package/dist/src/cli/__tests__/migrate.test.d.ts +2 -0
  7. package/dist/src/cli/__tests__/migrate.test.d.ts.map +1 -0
  8. package/dist/src/cli/__tests__/migrate.test.js +79 -0
  9. package/dist/src/cli/__tests__/migrate.test.js.map +1 -0
  10. package/dist/src/cli/chrome-allow.d.ts +5 -0
  11. package/dist/src/cli/chrome-allow.d.ts.map +1 -0
  12. package/dist/src/cli/chrome-allow.js +250 -0
  13. package/dist/src/cli/chrome-allow.js.map +1 -0
  14. package/dist/src/cli/create.d.ts +2 -0
  15. package/dist/src/cli/create.d.ts.map +1 -0
  16. package/dist/src/cli/create.js +72 -0
  17. package/dist/src/cli/create.js.map +1 -0
  18. package/dist/src/cli/instances.d.ts +14 -0
  19. package/dist/src/cli/instances.d.ts.map +1 -0
  20. package/dist/src/cli/instances.js +43 -0
  21. package/dist/src/cli/instances.js.map +1 -0
  22. package/dist/src/cli/list.d.ts +2 -0
  23. package/dist/src/cli/list.d.ts.map +1 -0
  24. package/dist/src/cli/list.js +38 -0
  25. package/dist/src/cli/list.js.map +1 -0
  26. package/dist/src/cli/migrate.d.ts +5 -0
  27. package/dist/src/cli/migrate.d.ts.map +1 -0
  28. package/dist/src/cli/migrate.js +222 -0
  29. package/dist/src/cli/migrate.js.map +1 -0
  30. package/dist/src/cli/nuke.d.ts +2 -0
  31. package/dist/src/cli/nuke.d.ts.map +1 -0
  32. package/dist/src/cli/nuke.js +91 -0
  33. package/dist/src/cli/nuke.js.map +1 -0
  34. package/dist/src/cli/remove.d.ts +4 -0
  35. package/dist/src/cli/remove.d.ts.map +1 -0
  36. package/dist/src/cli/remove.js +47 -0
  37. package/dist/src/cli/remove.js.map +1 -0
  38. package/dist/src/cli/setup.d.ts +4 -0
  39. package/dist/src/cli/setup.d.ts.map +1 -0
  40. package/dist/src/cli/setup.js +491 -0
  41. package/dist/src/cli/setup.js.map +1 -0
  42. package/dist/src/cli/skills.d.ts +28 -0
  43. package/dist/src/cli/skills.d.ts.map +1 -0
  44. package/dist/src/cli/skills.js +284 -0
  45. package/dist/src/cli/skills.js.map +1 -0
  46. package/dist/src/cli/start.d.ts +5 -0
  47. package/dist/src/cli/start.d.ts.map +1 -0
  48. package/dist/src/cli/start.js +34 -0
  49. package/dist/src/cli/start.js.map +1 -0
  50. package/dist/src/cli/status.d.ts +2 -0
  51. package/dist/src/cli/status.d.ts.map +1 -0
  52. package/dist/src/cli/status.js +69 -0
  53. package/dist/src/cli/status.js.map +1 -0
  54. package/dist/src/cli/stop.d.ts +2 -0
  55. package/dist/src/cli/stop.d.ts.map +1 -0
  56. package/dist/src/cli/stop.js +11 -0
  57. package/dist/src/cli/stop.js.map +1 -0
  58. package/dist/src/connectors/cron/index.d.ts +21 -0
  59. package/dist/src/connectors/cron/index.d.ts.map +1 -0
  60. package/dist/src/connectors/cron/index.js +75 -0
  61. package/dist/src/connectors/cron/index.js.map +1 -0
  62. package/dist/src/connectors/discord/format.d.ts +3 -0
  63. package/dist/src/connectors/discord/format.d.ts.map +1 -0
  64. package/dist/src/connectors/discord/format.js +33 -0
  65. package/dist/src/connectors/discord/format.js.map +1 -0
  66. package/dist/src/connectors/discord/index.d.ts +47 -0
  67. package/dist/src/connectors/discord/index.d.ts.map +1 -0
  68. package/dist/src/connectors/discord/index.js +308 -0
  69. package/dist/src/connectors/discord/index.js.map +1 -0
  70. package/dist/src/connectors/discord/remote.d.ts +33 -0
  71. package/dist/src/connectors/discord/remote.d.ts.map +1 -0
  72. package/dist/src/connectors/discord/remote.js +89 -0
  73. package/dist/src/connectors/discord/remote.js.map +1 -0
  74. package/dist/src/connectors/discord/threads.d.ts +5 -0
  75. package/dist/src/connectors/discord/threads.d.ts.map +1 -0
  76. package/dist/src/connectors/discord/threads.js +22 -0
  77. package/dist/src/connectors/discord/threads.js.map +1 -0
  78. package/dist/src/connectors/slack/__tests__/active-threads.test.d.ts +2 -0
  79. package/dist/src/connectors/slack/__tests__/active-threads.test.d.ts.map +1 -0
  80. package/dist/src/connectors/slack/__tests__/active-threads.test.js +57 -0
  81. package/dist/src/connectors/slack/__tests__/active-threads.test.js.map +1 -0
  82. package/dist/src/connectors/slack/__tests__/format.test.d.ts +2 -0
  83. package/dist/src/connectors/slack/__tests__/format.test.d.ts.map +1 -0
  84. package/dist/src/connectors/slack/__tests__/format.test.js +115 -0
  85. package/dist/src/connectors/slack/__tests__/format.test.js.map +1 -0
  86. package/dist/src/connectors/slack/__tests__/speaker.test.d.ts +2 -0
  87. package/dist/src/connectors/slack/__tests__/speaker.test.d.ts.map +1 -0
  88. package/dist/src/connectors/slack/__tests__/speaker.test.js +59 -0
  89. package/dist/src/connectors/slack/__tests__/speaker.test.js.map +1 -0
  90. package/dist/src/connectors/slack/__tests__/triage-prompt.test.d.ts +2 -0
  91. package/dist/src/connectors/slack/__tests__/triage-prompt.test.d.ts.map +1 -0
  92. package/dist/src/connectors/slack/__tests__/triage-prompt.test.js +102 -0
  93. package/dist/src/connectors/slack/__tests__/triage-prompt.test.js.map +1 -0
  94. package/dist/src/connectors/slack/__tests__/triage.test.d.ts +2 -0
  95. package/dist/src/connectors/slack/__tests__/triage.test.d.ts.map +1 -0
  96. package/dist/src/connectors/slack/__tests__/triage.test.js +88 -0
  97. package/dist/src/connectors/slack/__tests__/triage.test.js.map +1 -0
  98. package/dist/src/connectors/slack/active-threads.d.ts +39 -0
  99. package/dist/src/connectors/slack/active-threads.d.ts.map +1 -0
  100. package/dist/src/connectors/slack/active-threads.js +71 -0
  101. package/dist/src/connectors/slack/active-threads.js.map +1 -0
  102. package/dist/src/connectors/slack/format.d.ts +17 -0
  103. package/dist/src/connectors/slack/format.d.ts.map +1 -0
  104. package/dist/src/connectors/slack/format.js +85 -0
  105. package/dist/src/connectors/slack/format.js.map +1 -0
  106. package/dist/src/connectors/slack/index.d.ts +51 -0
  107. package/dist/src/connectors/slack/index.d.ts.map +1 -0
  108. package/dist/src/connectors/slack/index.js +562 -0
  109. package/dist/src/connectors/slack/index.js.map +1 -0
  110. package/dist/src/connectors/slack/speaker.d.ts +39 -0
  111. package/dist/src/connectors/slack/speaker.d.ts.map +1 -0
  112. package/dist/src/connectors/slack/speaker.js +30 -0
  113. package/dist/src/connectors/slack/speaker.js.map +1 -0
  114. package/dist/src/connectors/slack/threads.d.ts +12 -0
  115. package/dist/src/connectors/slack/threads.d.ts.map +1 -0
  116. package/dist/src/connectors/slack/threads.js +41 -0
  117. package/dist/src/connectors/slack/threads.js.map +1 -0
  118. package/dist/src/connectors/slack/threads.test.d.ts +2 -0
  119. package/dist/src/connectors/slack/threads.test.d.ts.map +1 -0
  120. package/dist/src/connectors/slack/threads.test.js +79 -0
  121. package/dist/src/connectors/slack/threads.test.js.map +1 -0
  122. package/dist/src/connectors/slack/triage-prompt.d.ts +50 -0
  123. package/dist/src/connectors/slack/triage-prompt.d.ts.map +1 -0
  124. package/dist/src/connectors/slack/triage-prompt.js +127 -0
  125. package/dist/src/connectors/slack/triage-prompt.js.map +1 -0
  126. package/dist/src/connectors/slack/triage.d.ts +41 -0
  127. package/dist/src/connectors/slack/triage.d.ts.map +1 -0
  128. package/dist/src/connectors/slack/triage.js +120 -0
  129. package/dist/src/connectors/slack/triage.js.map +1 -0
  130. package/dist/src/connectors/telegram/__tests__/connector.test.d.ts +2 -0
  131. package/dist/src/connectors/telegram/__tests__/connector.test.d.ts.map +1 -0
  132. package/dist/src/connectors/telegram/__tests__/connector.test.js +257 -0
  133. package/dist/src/connectors/telegram/__tests__/connector.test.js.map +1 -0
  134. package/dist/src/connectors/telegram/__tests__/format.test.d.ts +2 -0
  135. package/dist/src/connectors/telegram/__tests__/format.test.d.ts.map +1 -0
  136. package/dist/src/connectors/telegram/__tests__/format.test.js +79 -0
  137. package/dist/src/connectors/telegram/__tests__/format.test.js.map +1 -0
  138. package/dist/src/connectors/telegram/__tests__/threads.test.d.ts +2 -0
  139. package/dist/src/connectors/telegram/__tests__/threads.test.d.ts.map +1 -0
  140. package/dist/src/connectors/telegram/__tests__/threads.test.js +51 -0
  141. package/dist/src/connectors/telegram/__tests__/threads.test.js.map +1 -0
  142. package/dist/src/connectors/telegram/format.d.ts +12 -0
  143. package/dist/src/connectors/telegram/format.d.ts.map +1 -0
  144. package/dist/src/connectors/telegram/format.js +61 -0
  145. package/dist/src/connectors/telegram/format.js.map +1 -0
  146. package/dist/src/connectors/telegram/index.d.ts +28 -0
  147. package/dist/src/connectors/telegram/index.d.ts.map +1 -0
  148. package/dist/src/connectors/telegram/index.js +213 -0
  149. package/dist/src/connectors/telegram/index.js.map +1 -0
  150. package/dist/src/connectors/telegram/threads.d.ts +29 -0
  151. package/dist/src/connectors/telegram/threads.d.ts.map +1 -0
  152. package/dist/src/connectors/telegram/threads.js +26 -0
  153. package/dist/src/connectors/telegram/threads.js.map +1 -0
  154. package/dist/src/connectors/whatsapp/__tests__/format.test.d.ts +2 -0
  155. package/dist/src/connectors/whatsapp/__tests__/format.test.d.ts.map +1 -0
  156. package/dist/src/connectors/whatsapp/__tests__/format.test.js +70 -0
  157. package/dist/src/connectors/whatsapp/__tests__/format.test.js.map +1 -0
  158. package/dist/src/connectors/whatsapp/format.d.ts +12 -0
  159. package/dist/src/connectors/whatsapp/format.d.ts.map +1 -0
  160. package/dist/src/connectors/whatsapp/format.js +53 -0
  161. package/dist/src/connectors/whatsapp/format.js.map +1 -0
  162. package/dist/src/connectors/whatsapp/index.d.ts +42 -0
  163. package/dist/src/connectors/whatsapp/index.d.ts.map +1 -0
  164. package/dist/src/connectors/whatsapp/index.js +279 -0
  165. package/dist/src/connectors/whatsapp/index.js.map +1 -0
  166. package/dist/src/cron/jobs.d.ts +5 -0
  167. package/dist/src/cron/jobs.d.ts.map +1 -0
  168. package/dist/src/cron/jobs.js +23 -0
  169. package/dist/src/cron/jobs.js.map +1 -0
  170. package/dist/src/cron/runner.d.ts +4 -0
  171. package/dist/src/cron/runner.d.ts.map +1 -0
  172. package/dist/src/cron/runner.js +88 -0
  173. package/dist/src/cron/runner.js.map +1 -0
  174. package/dist/src/cron/scheduler.d.ts +8 -0
  175. package/dist/src/cron/scheduler.d.ts.map +1 -0
  176. package/dist/src/cron/scheduler.js +64 -0
  177. package/dist/src/cron/scheduler.js.map +1 -0
  178. package/dist/src/engines/__tests__/gemini.test.d.ts +2 -0
  179. package/dist/src/engines/__tests__/gemini.test.d.ts.map +1 -0
  180. package/dist/src/engines/__tests__/gemini.test.js +404 -0
  181. package/dist/src/engines/__tests__/gemini.test.js.map +1 -0
  182. package/dist/src/engines/claude.d.ts +20 -0
  183. package/dist/src/engines/claude.d.ts.map +1 -0
  184. package/dist/src/engines/claude.js +520 -0
  185. package/dist/src/engines/claude.js.map +1 -0
  186. package/dist/src/engines/codex.d.ts +15 -0
  187. package/dist/src/engines/codex.d.ts.map +1 -0
  188. package/dist/src/engines/codex.js +351 -0
  189. package/dist/src/engines/codex.js.map +1 -0
  190. package/dist/src/engines/gemini.d.ts +32 -0
  191. package/dist/src/engines/gemini.d.ts.map +1 -0
  192. package/dist/src/engines/gemini.js +328 -0
  193. package/dist/src/engines/gemini.js.map +1 -0
  194. package/dist/src/engines/mock.d.ts +16 -0
  195. package/dist/src/engines/mock.d.ts.map +1 -0
  196. package/dist/src/engines/mock.js +47 -0
  197. package/dist/src/engines/mock.js.map +1 -0
  198. package/dist/src/gateway/__tests__/api-last-n.test.d.ts +2 -0
  199. package/dist/src/gateway/__tests__/api-last-n.test.d.ts.map +1 -0
  200. package/dist/src/gateway/__tests__/api-last-n.test.js +32 -0
  201. package/dist/src/gateway/__tests__/api-last-n.test.js.map +1 -0
  202. package/dist/src/gateway/__tests__/costs.test.d.ts +2 -0
  203. package/dist/src/gateway/__tests__/costs.test.d.ts.map +1 -0
  204. package/dist/src/gateway/__tests__/costs.test.js +32 -0
  205. package/dist/src/gateway/__tests__/costs.test.js.map +1 -0
  206. package/dist/src/gateway/__tests__/org-hierarchy.test.d.ts +2 -0
  207. package/dist/src/gateway/__tests__/org-hierarchy.test.d.ts.map +1 -0
  208. package/dist/src/gateway/__tests__/org-hierarchy.test.js +161 -0
  209. package/dist/src/gateway/__tests__/org-hierarchy.test.js.map +1 -0
  210. package/dist/src/gateway/__tests__/org-update.test.d.ts +2 -0
  211. package/dist/src/gateway/__tests__/org-update.test.d.ts.map +1 -0
  212. package/dist/src/gateway/__tests__/org-update.test.js +99 -0
  213. package/dist/src/gateway/__tests__/org-update.test.js.map +1 -0
  214. package/dist/src/gateway/__tests__/org.test.d.ts +2 -0
  215. package/dist/src/gateway/__tests__/org.test.d.ts.map +1 -0
  216. package/dist/src/gateway/__tests__/org.test.js +77 -0
  217. package/dist/src/gateway/__tests__/org.test.js.map +1 -0
  218. package/dist/src/gateway/__tests__/services.test.d.ts +2 -0
  219. package/dist/src/gateway/__tests__/services.test.d.ts.map +1 -0
  220. package/dist/src/gateway/__tests__/services.test.js +153 -0
  221. package/dist/src/gateway/__tests__/services.test.js.map +1 -0
  222. package/dist/src/gateway/api.d.ts +19 -0
  223. package/dist/src/gateway/api.d.ts.map +1 -0
  224. package/dist/src/gateway/api.js +2261 -0
  225. package/dist/src/gateway/api.js.map +1 -0
  226. package/dist/src/gateway/budgets.d.ts +16 -0
  227. package/dist/src/gateway/budgets.d.ts.map +1 -0
  228. package/dist/src/gateway/budgets.js +39 -0
  229. package/dist/src/gateway/budgets.js.map +1 -0
  230. package/dist/src/gateway/costs.d.ts +19 -0
  231. package/dist/src/gateway/costs.d.ts.map +1 -0
  232. package/dist/src/gateway/costs.js +39 -0
  233. package/dist/src/gateway/costs.js.map +1 -0
  234. package/dist/src/gateway/daemon-entry.d.ts +2 -0
  235. package/dist/src/gateway/daemon-entry.d.ts.map +1 -0
  236. package/dist/src/gateway/daemon-entry.js +12 -0
  237. package/dist/src/gateway/daemon-entry.js.map +1 -0
  238. package/dist/src/gateway/files.d.ts +6 -0
  239. package/dist/src/gateway/files.d.ts.map +1 -0
  240. package/dist/src/gateway/files.js +442 -0
  241. package/dist/src/gateway/files.js.map +1 -0
  242. package/dist/src/gateway/goals.d.ts +11 -0
  243. package/dist/src/gateway/goals.d.ts.map +1 -0
  244. package/dist/src/gateway/goals.js +72 -0
  245. package/dist/src/gateway/goals.js.map +1 -0
  246. package/dist/src/gateway/lifecycle.d.ts +10 -0
  247. package/dist/src/gateway/lifecycle.d.ts.map +1 -0
  248. package/dist/src/gateway/lifecycle.js +152 -0
  249. package/dist/src/gateway/lifecycle.js.map +1 -0
  250. package/dist/src/gateway/org-hierarchy.d.ts +5 -0
  251. package/dist/src/gateway/org-hierarchy.d.ts.map +1 -0
  252. package/dist/src/gateway/org-hierarchy.js +174 -0
  253. package/dist/src/gateway/org-hierarchy.js.map +1 -0
  254. package/dist/src/gateway/org.d.ts +17 -0
  255. package/dist/src/gateway/org.d.ts.map +1 -0
  256. package/dist/src/gateway/org.js +136 -0
  257. package/dist/src/gateway/org.js.map +1 -0
  258. package/dist/src/gateway/server.d.ts +4 -0
  259. package/dist/src/gateway/server.d.ts.map +1 -0
  260. package/dist/src/gateway/server.js +764 -0
  261. package/dist/src/gateway/server.js.map +1 -0
  262. package/dist/src/gateway/services.d.ts +28 -0
  263. package/dist/src/gateway/services.d.ts.map +1 -0
  264. package/dist/src/gateway/services.js +112 -0
  265. package/dist/src/gateway/services.js.map +1 -0
  266. package/dist/src/gateway/watcher.d.ts +14 -0
  267. package/dist/src/gateway/watcher.d.ts.map +1 -0
  268. package/dist/src/gateway/watcher.js +111 -0
  269. package/dist/src/gateway/watcher.js.map +1 -0
  270. package/dist/src/index.d.ts +5 -0
  271. package/dist/src/index.d.ts.map +1 -0
  272. package/dist/src/index.js +4 -0
  273. package/dist/src/index.js.map +1 -0
  274. package/dist/src/mcp/gateway-server.d.ts +13 -0
  275. package/dist/src/mcp/gateway-server.d.ts.map +1 -0
  276. package/dist/src/mcp/gateway-server.js +376 -0
  277. package/dist/src/mcp/gateway-server.js.map +1 -0
  278. package/dist/src/mcp/resolver.d.ts +19 -0
  279. package/dist/src/mcp/resolver.d.ts.map +1 -0
  280. package/dist/src/mcp/resolver.js +159 -0
  281. package/dist/src/mcp/resolver.js.map +1 -0
  282. package/dist/src/sessions/__tests__/callbacks.test.d.ts +2 -0
  283. package/dist/src/sessions/__tests__/callbacks.test.d.ts.map +1 -0
  284. package/dist/src/sessions/__tests__/callbacks.test.js +154 -0
  285. package/dist/src/sessions/__tests__/callbacks.test.js.map +1 -0
  286. package/dist/src/sessions/callbacks.d.ts +31 -0
  287. package/dist/src/sessions/callbacks.d.ts.map +1 -0
  288. package/dist/src/sessions/callbacks.js +112 -0
  289. package/dist/src/sessions/callbacks.js.map +1 -0
  290. package/dist/src/sessions/context.d.ts +36 -0
  291. package/dist/src/sessions/context.d.ts.map +1 -0
  292. package/dist/src/sessions/context.js +741 -0
  293. package/dist/src/sessions/context.js.map +1 -0
  294. package/dist/src/sessions/fork.d.ts +30 -0
  295. package/dist/src/sessions/fork.d.ts.map +1 -0
  296. package/dist/src/sessions/fork.js +178 -0
  297. package/dist/src/sessions/fork.js.map +1 -0
  298. package/dist/src/sessions/manager.d.ts +27 -0
  299. package/dist/src/sessions/manager.d.ts.map +1 -0
  300. package/dist/src/sessions/manager.js +751 -0
  301. package/dist/src/sessions/manager.js.map +1 -0
  302. package/dist/src/sessions/queue.d.ts +36 -0
  303. package/dist/src/sessions/queue.d.ts.map +1 -0
  304. package/dist/src/sessions/queue.js +101 -0
  305. package/dist/src/sessions/queue.js.map +1 -0
  306. package/dist/src/sessions/queue.test.d.ts +2 -0
  307. package/dist/src/sessions/queue.test.d.ts.map +1 -0
  308. package/dist/src/sessions/queue.test.js +28 -0
  309. package/dist/src/sessions/queue.test.js.map +1 -0
  310. package/dist/src/sessions/registry.d.ts +116 -0
  311. package/dist/src/sessions/registry.d.ts.map +1 -0
  312. package/dist/src/sessions/registry.js +480 -0
  313. package/dist/src/sessions/registry.js.map +1 -0
  314. package/dist/src/sessions/registry.test.d.ts +2 -0
  315. package/dist/src/sessions/registry.test.d.ts.map +1 -0
  316. package/dist/src/sessions/registry.test.js +41 -0
  317. package/dist/src/sessions/registry.test.js.map +1 -0
  318. package/dist/src/shared/__tests__/rateLimit.test.d.ts +2 -0
  319. package/dist/src/shared/__tests__/rateLimit.test.d.ts.map +1 -0
  320. package/dist/src/shared/__tests__/rateLimit.test.js +108 -0
  321. package/dist/src/shared/__tests__/rateLimit.test.js.map +1 -0
  322. package/dist/src/shared/__tests__/usageAwareness.test.d.ts +2 -0
  323. package/dist/src/shared/__tests__/usageAwareness.test.d.ts.map +1 -0
  324. package/dist/src/shared/__tests__/usageAwareness.test.js +58 -0
  325. package/dist/src/shared/__tests__/usageAwareness.test.js.map +1 -0
  326. package/dist/src/shared/config.d.ts +3 -0
  327. package/dist/src/shared/config.d.ts.map +1 -0
  328. package/dist/src/shared/config.js +11 -0
  329. package/dist/src/shared/config.js.map +1 -0
  330. package/dist/src/shared/effort.d.ts +17 -0
  331. package/dist/src/shared/effort.d.ts.map +1 -0
  332. package/dist/src/shared/effort.js +44 -0
  333. package/dist/src/shared/effort.js.map +1 -0
  334. package/dist/src/shared/logger.d.ts +12 -0
  335. package/dist/src/shared/logger.d.ts.map +1 -0
  336. package/dist/src/shared/logger.js +35 -0
  337. package/dist/src/shared/logger.js.map +1 -0
  338. package/dist/src/shared/paths.d.ts +31 -0
  339. package/dist/src/shared/paths.d.ts.map +1 -0
  340. package/dist/src/shared/paths.js +92 -0
  341. package/dist/src/shared/paths.js.map +1 -0
  342. package/dist/src/shared/rateLimit.d.ts +20 -0
  343. package/dist/src/shared/rateLimit.d.ts.map +1 -0
  344. package/dist/src/shared/rateLimit.js +61 -0
  345. package/dist/src/shared/rateLimit.js.map +1 -0
  346. package/dist/src/shared/types.d.ts +448 -0
  347. package/dist/src/shared/types.d.ts.map +1 -0
  348. package/dist/src/shared/types.js +4 -0
  349. package/dist/src/shared/types.js.map +1 -0
  350. package/dist/src/shared/usageAwareness.d.ts +10 -0
  351. package/dist/src/shared/usageAwareness.d.ts.map +1 -0
  352. package/dist/src/shared/usageAwareness.js +69 -0
  353. package/dist/src/shared/usageAwareness.js.map +1 -0
  354. package/dist/src/shared/version.d.ts +15 -0
  355. package/dist/src/shared/version.d.ts.map +1 -0
  356. package/dist/src/shared/version.js +56 -0
  357. package/dist/src/shared/version.js.map +1 -0
  358. package/dist/src/stt/stt.d.ts +24 -0
  359. package/dist/src/stt/stt.d.ts.map +1 -0
  360. package/dist/src/stt/stt.js +203 -0
  361. package/dist/src/stt/stt.js.map +1 -0
  362. package/dist/web/404.html +1 -0
  363. package/dist/web/__next.__PAGE__.txt +9 -0
  364. package/dist/web/__next._full.txt +19 -0
  365. package/dist/web/__next._head.txt +6 -0
  366. package/dist/web/__next._index.txt +6 -0
  367. package/dist/web/__next._tree.txt +2 -0
  368. package/dist/web/_next/static/chunks/00yn.jp4tr9l6.js +62 -0
  369. package/dist/web/_next/static/chunks/0398g9fy2i2l..js +5 -0
  370. package/dist/web/_next/static/chunks/03~yq9q893hmn.js +1 -0
  371. package/dist/web/_next/static/chunks/07t-qdutaizlf.js +5 -0
  372. package/dist/web/_next/static/chunks/0_pxvi.u4tzw1.js +5 -0
  373. package/dist/web/_next/static/chunks/0dtbl8648b3u9.js +7 -0
  374. package/dist/web/_next/static/chunks/0e3pdjkorr5zl.js +2 -0
  375. package/dist/web/_next/static/chunks/0ewpxy-mzj3j3.js +1 -0
  376. package/dist/web/_next/static/chunks/0ihbb7~gq42g~.js +5 -0
  377. package/dist/web/_next/static/chunks/0j4uz-g9x1_~s.js +1 -0
  378. package/dist/web/_next/static/chunks/0mlo32yrc7ziu.css +1 -0
  379. package/dist/web/_next/static/chunks/0ru56x83x4rkk.js +1 -0
  380. package/dist/web/_next/static/chunks/0svvev77pb2gu.js +1 -0
  381. package/dist/web/_next/static/chunks/0tf9kpygstdls.js +1 -0
  382. package/dist/web/_next/static/chunks/0wzpea61sn2-k.js +5 -0
  383. package/dist/web/_next/static/chunks/0y3dnnq~kxyz_.js +1 -0
  384. package/dist/web/_next/static/chunks/0y~qqhmf2o7pt.js +1 -0
  385. package/dist/web/_next/static/chunks/0~6m1p5hnsx2f.js +1 -0
  386. package/dist/web/_next/static/chunks/10-liamt-ipcu.js +1 -0
  387. package/dist/web/_next/static/chunks/10l08hq.acixl.js +5 -0
  388. package/dist/web/_next/static/chunks/11rbefjn.e-3-.js +1 -0
  389. package/dist/web/_next/static/chunks/11rodb4s1x4of.js +1 -0
  390. package/dist/web/_next/static/chunks/12_uxtnrqhoo1.js +1 -0
  391. package/dist/web/_next/static/chunks/12h4dws.tz7yb.js +5 -0
  392. package/dist/web/_next/static/chunks/13juizw904g.e.js +1 -0
  393. package/dist/web/_next/static/chunks/14ge_q22f0n.f.js +1 -0
  394. package/dist/web/_next/static/chunks/16b0jvgccyt2i.js +5 -0
  395. package/dist/web/_next/static/chunks/17-u9c_weg12-.js +31 -0
  396. package/dist/web/_next/static/chunks/turbopack-0dt987bw_1nyf.js +1 -0
  397. package/dist/web/_next/static/media/apple-icon.0.wpl4.d-5bkf.jpg +0 -0
  398. package/dist/web/_next/static/media/icon.0.wpl4.d-5bkf.jpg +0 -0
  399. package/dist/web/_next/static/uwjABwQIFELOHhVlstvOe/_buildManifest.js +11 -0
  400. package/dist/web/_next/static/uwjABwQIFELOHhVlstvOe/_clientMiddlewareManifest.js +1 -0
  401. package/dist/web/_next/static/uwjABwQIFELOHhVlstvOe/_ssgManifest.js +1 -0
  402. package/dist/web/_not-found/__next._full.txt +17 -0
  403. package/dist/web/_not-found/__next._head.txt +6 -0
  404. package/dist/web/_not-found/__next._index.txt +6 -0
  405. package/dist/web/_not-found/__next._not-found.__PAGE__.txt +5 -0
  406. package/dist/web/_not-found/__next._not-found.txt +5 -0
  407. package/dist/web/_not-found/__next._tree.txt +2 -0
  408. package/dist/web/_not-found.html +1 -0
  409. package/dist/web/_not-found.txt +17 -0
  410. package/dist/web/apple-icon.jpg +0 -0
  411. package/dist/web/chat/__next._full.txt +21 -0
  412. package/dist/web/chat/__next._head.txt +6 -0
  413. package/dist/web/chat/__next._index.txt +6 -0
  414. package/dist/web/chat/__next._tree.txt +2 -0
  415. package/dist/web/chat/__next.chat.__PAGE__.txt +9 -0
  416. package/dist/web/chat/__next.chat.txt +5 -0
  417. package/dist/web/chat.html +1 -0
  418. package/dist/web/chat.txt +21 -0
  419. package/dist/web/cron/__next._full.txt +21 -0
  420. package/dist/web/cron/__next._head.txt +6 -0
  421. package/dist/web/cron/__next._index.txt +6 -0
  422. package/dist/web/cron/__next._tree.txt +2 -0
  423. package/dist/web/cron/__next.cron.__PAGE__.txt +9 -0
  424. package/dist/web/cron/__next.cron.txt +5 -0
  425. package/dist/web/cron.html +1 -0
  426. package/dist/web/cron.txt +21 -0
  427. package/dist/web/icon.jpg +0 -0
  428. package/dist/web/index.html +1 -0
  429. package/dist/web/index.txt +19 -0
  430. package/dist/web/kanban/__next._full.txt +21 -0
  431. package/dist/web/kanban/__next._head.txt +6 -0
  432. package/dist/web/kanban/__next._index.txt +6 -0
  433. package/dist/web/kanban/__next._tree.txt +2 -0
  434. package/dist/web/kanban/__next.kanban.__PAGE__.txt +9 -0
  435. package/dist/web/kanban/__next.kanban.txt +5 -0
  436. package/dist/web/kanban.html +1 -0
  437. package/dist/web/kanban.txt +21 -0
  438. package/dist/web/logs/__next._full.txt +21 -0
  439. package/dist/web/logs/__next._head.txt +6 -0
  440. package/dist/web/logs/__next._index.txt +6 -0
  441. package/dist/web/logs/__next._tree.txt +2 -0
  442. package/dist/web/logs/__next.logs.__PAGE__.txt +9 -0
  443. package/dist/web/logs/__next.logs.txt +5 -0
  444. package/dist/web/logs.html +7 -0
  445. package/dist/web/logs.txt +21 -0
  446. package/dist/web/org/__next._full.txt +21 -0
  447. package/dist/web/org/__next._head.txt +6 -0
  448. package/dist/web/org/__next._index.txt +6 -0
  449. package/dist/web/org/__next._tree.txt +2 -0
  450. package/dist/web/org/__next.org.__PAGE__.txt +9 -0
  451. package/dist/web/org/__next.org.txt +5 -0
  452. package/dist/web/org.html +1 -0
  453. package/dist/web/org.txt +21 -0
  454. package/dist/web/sessions/__next._full.txt +18 -0
  455. package/dist/web/sessions/__next._head.txt +6 -0
  456. package/dist/web/sessions/__next._index.txt +6 -0
  457. package/dist/web/sessions/__next._tree.txt +2 -0
  458. package/dist/web/sessions/__next.sessions.__PAGE__.txt +6 -0
  459. package/dist/web/sessions/__next.sessions.txt +5 -0
  460. package/dist/web/sessions.html +1 -0
  461. package/dist/web/sessions.txt +18 -0
  462. package/dist/web/settings/__next._full.txt +21 -0
  463. package/dist/web/settings/__next._head.txt +6 -0
  464. package/dist/web/settings/__next._index.txt +6 -0
  465. package/dist/web/settings/__next._tree.txt +2 -0
  466. package/dist/web/settings/__next.settings.__PAGE__.txt +9 -0
  467. package/dist/web/settings/__next.settings.txt +5 -0
  468. package/dist/web/settings.html +1 -0
  469. package/dist/web/settings.txt +21 -0
  470. package/dist/web/skills/__next._full.txt +21 -0
  471. package/dist/web/skills/__next._head.txt +6 -0
  472. package/dist/web/skills/__next._index.txt +6 -0
  473. package/dist/web/skills/__next._tree.txt +2 -0
  474. package/dist/web/skills/__next.skills.__PAGE__.txt +9 -0
  475. package/dist/web/skills/__next.skills.txt +5 -0
  476. package/dist/web/skills.html +1 -0
  477. package/dist/web/skills.txt +21 -0
  478. package/package.json +54 -0
  479. package/template/AGENTS.md +285 -0
  480. package/template/CLAUDE.md +285 -0
  481. package/template/config.default.yaml +71 -0
  482. package/template/docs/architecture.md +74 -0
  483. package/template/docs/connectors.md +72 -0
  484. package/template/docs/cron.md +137 -0
  485. package/template/docs/mcp.md +108 -0
  486. package/template/docs/org.md +105 -0
  487. package/template/docs/overview.md +39 -0
  488. package/template/docs/self-modification.md +65 -0
  489. package/template/docs/skills.md +58 -0
  490. package/template/knowledge/.gitkeep +0 -0
  491. package/template/migrations/.gitkeep +0 -0
  492. package/template/migrations/0.1.0/MIGRATION.md +25 -0
  493. package/template/migrations/0.2.0/MIGRATION.md +41 -0
  494. package/template/migrations/0.2.0/files/config.default.yaml +30 -0
  495. package/template/migrations/0.3.0/MIGRATION.md +57 -0
  496. package/template/migrations/0.3.0/files/config.default.yaml +62 -0
  497. package/template/migrations/0.3.0/files/docs/mcp.md +108 -0
  498. package/template/migrations/0.7.3/MIGRATION.md +63 -0
  499. package/template/migrations/0.7.3/files/AGENTS.md +188 -0
  500. package/template/migrations/0.7.3/files/CLAUDE.md +127 -0
  501. package/template/migrations/0.7.5/MIGRATION.md +78 -0
  502. package/template/migrations/0.8.0/MIGRATION.md +73 -0
  503. package/template/migrations/0.9.0/MIGRATION.md +82 -0
  504. package/template/skills/cron-manager/SKILL.md +127 -0
  505. package/template/skills/find-and-install/SKILL.md +92 -0
  506. package/template/skills/management/SKILL.md +226 -0
  507. package/template/skills/migrate/SKILL.md +154 -0
  508. package/template/skills/new/SKILL.md +19 -0
  509. package/template/skills/onboarding/SKILL.md +106 -0
  510. package/template/skills/self-heal/SKILL.md +114 -0
  511. package/template/skills/skill-creator/SKILL.md +112 -0
  512. package/template/skills/status/SKILL.md +19 -0
  513. package/template/skills/sync/SKILL.md +67 -0
  514. package/template/skills.json +3 -0
@@ -0,0 +1,764 @@
1
+ import http from "node:http";
2
+ import { spawn } from "node:child_process";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { randomUUID } from "node:crypto";
7
+ import { WebSocketServer } from "ws";
8
+ import { loadConfig } from "../shared/config.js";
9
+ import { configureLogger, logger } from "../shared/logger.js";
10
+ import { initDb, recoverStaleSessions, recoverStaleQueueItems, getInterruptedSessions, listSessions, updateSession } from "../sessions/registry.js";
11
+ import { SessionManager } from "../sessions/manager.js";
12
+ import { ClaudeEngine } from "../engines/claude.js";
13
+ import { CodexEngine } from "../engines/codex.js";
14
+ import { GeminiEngine } from "../engines/gemini.js";
15
+ import { handleApiRequest, resumePendingWebQueueItems } from "./api.js";
16
+ import { ensureFilesDir } from "./files.js";
17
+ import { initStt } from "../stt/stt.js";
18
+ import { startWatchers, stopWatchers, syncSkillSymlinks } from "./watcher.js";
19
+ import { SlackConnector } from "../connectors/slack/index.js";
20
+ import { DiscordConnector } from "../connectors/discord/index.js";
21
+ import { RemoteDiscordConnector } from "../connectors/discord/remote.js";
22
+ import { WhatsAppConnector } from "../connectors/whatsapp/index.js";
23
+ import { TelegramConnector } from "../connectors/telegram/index.js";
24
+ import { loadJobs } from "../cron/jobs.js";
25
+ import { startScheduler, reloadScheduler, stopScheduler } from "../cron/scheduler.js";
26
+ import { scanOrg } from "./org.js";
27
+ const __filename = fileURLToPath(import.meta.url);
28
+ const __dirname = path.dirname(__filename);
29
+ const MIME_TYPES = {
30
+ ".html": "text/html",
31
+ ".js": "application/javascript",
32
+ ".css": "text/css",
33
+ ".json": "application/json",
34
+ ".png": "image/png",
35
+ ".svg": "image/svg+xml",
36
+ ".ico": "image/x-icon",
37
+ ".woff": "font/woff",
38
+ ".woff2": "font/woff2",
39
+ };
40
+ function serveStatic(req, res, webDir) {
41
+ if (!fs.existsSync(webDir))
42
+ return false;
43
+ // Strip query string before resolving file path
44
+ const urlPath = (req.url || "/").split("?")[0];
45
+ let filePath = path.join(webDir, urlPath);
46
+ if (filePath.endsWith("/"))
47
+ filePath = path.join(filePath, "index.html");
48
+ // Prevent directory traversal
49
+ const resolved = path.resolve(filePath);
50
+ if (!resolved.startsWith(path.resolve(webDir))) {
51
+ res.writeHead(403);
52
+ res.end("Forbidden");
53
+ return true;
54
+ }
55
+ if (!fs.existsSync(resolved) || fs.statSync(resolved).isDirectory()) {
56
+ // Next.js static export produces /chat.html, /sessions.html, etc.
57
+ // Try appending .html before falling back to index.html
58
+ const htmlPath = resolved.endsWith("/")
59
+ ? path.join(resolved, "index.html")
60
+ : resolved + ".html";
61
+ if (fs.existsSync(htmlPath) && !fs.statSync(htmlPath).isDirectory()) {
62
+ res.writeHead(200, { "Content-Type": "text/html" });
63
+ fs.createReadStream(htmlPath).pipe(res);
64
+ return true;
65
+ }
66
+ // SPA fallback: serve index.html for non-API, non-WS routes
67
+ const indexPath = path.join(webDir, "index.html");
68
+ if (fs.existsSync(indexPath)) {
69
+ res.writeHead(200, { "Content-Type": "text/html" });
70
+ fs.createReadStream(indexPath).pipe(res);
71
+ return true;
72
+ }
73
+ return false;
74
+ }
75
+ const ext = path.extname(resolved);
76
+ const contentType = MIME_TYPES[ext] || "application/octet-stream";
77
+ res.writeHead(200, { "Content-Type": contentType });
78
+ fs.createReadStream(resolved).pipe(res);
79
+ return true;
80
+ }
81
+ export async function startGateway(config) {
82
+ const bootId = randomUUID().slice(0, 8);
83
+ // Configure logging
84
+ configureLogger({
85
+ level: config.logging.level,
86
+ stdout: config.logging.stdout,
87
+ file: config.logging.file,
88
+ });
89
+ const gatewayName = config.portal?.portalName || "Ryoko";
90
+ logger.info(`Starting ${gatewayName} gateway (boot ${bootId}, pid ${process.pid})...`);
91
+ // Initialize database and recover any sessions stuck from a previous run
92
+ initDb();
93
+ ensureFilesDir();
94
+ const recovered = recoverStaleSessions();
95
+ if (recovered > 0) {
96
+ logger.info(`Recovered ${recovered} stale session(s) — marked as "interrupted" for resume`);
97
+ }
98
+ // Log resumable sessions so operators know what can be picked up
99
+ const resumable = getInterruptedSessions();
100
+ if (resumable.length > 0) {
101
+ logger.info(`${resumable.length} interrupted session(s) available for resume:`);
102
+ for (const s of resumable) {
103
+ logger.info(` - ${s.id} (engine: ${s.engine}, employee: ${s.employee || "none"}, engineSessionId: ${s.engineSessionId})`);
104
+ }
105
+ }
106
+ const recoveredQueue = recoverStaleQueueItems();
107
+ if (recoveredQueue > 0) {
108
+ logger.info(`Recovered ${recoveredQueue} in-flight queue item(s) from previous run — reset to pending`);
109
+ }
110
+ // Set up engines
111
+ const claudeEngine = new ClaudeEngine();
112
+ const codexEngine = new CodexEngine();
113
+ const geminiEngine = new GeminiEngine();
114
+ const engines = new Map();
115
+ engines.set("claude", claudeEngine);
116
+ engines.set("codex", codexEngine);
117
+ engines.set("gemini", geminiEngine);
118
+ // Derive connector names from config
119
+ const connectorNames = [];
120
+ if (config.connectors?.slack?.appToken && config.connectors?.slack?.botToken) {
121
+ connectorNames.push("slack");
122
+ }
123
+ if (config.connectors?.discord?.botToken || config.connectors?.discord?.proxyVia) {
124
+ connectorNames.push("discord");
125
+ }
126
+ if (config.connectors?.telegram?.botToken) {
127
+ connectorNames.push("telegram");
128
+ }
129
+ if (config.connectors?.whatsapp) {
130
+ connectorNames.push("whatsapp");
131
+ }
132
+ // Session manager
133
+ const sessionManager = new SessionManager(config, engines, connectorNames);
134
+ // Build employee registry
135
+ let employeeRegistry = scanOrg();
136
+ logger.info(`Loaded ${employeeRegistry.size} employee(s) from org directory`);
137
+ // Start connectors
138
+ const connectors = [];
139
+ const connectorMap = new Map();
140
+ /** IDs of connectors created from config.connectors.instances[] (vs legacy top-level connectors) */
141
+ const instanceConnectorIds = new Set();
142
+ if (config.connectors?.slack?.appToken && config.connectors?.slack?.botToken) {
143
+ try {
144
+ const slack = new SlackConnector({
145
+ appToken: config.connectors.slack.appToken,
146
+ botToken: config.connectors.slack.botToken,
147
+ allowFrom: config.connectors.slack.allowFrom,
148
+ ignoreOldMessagesOnBoot: config.connectors.slack.ignoreOldMessagesOnBoot,
149
+ triage: config.connectors.slack.triage,
150
+ }, {
151
+ portalName: config.portal?.portalName,
152
+ operatorName: config.portal?.operatorName,
153
+ });
154
+ slack.onMessage((msg) => {
155
+ const routeOpts = {};
156
+ if (config.connectors.slack?.employee) {
157
+ const emp = employeeRegistry.get(config.connectors.slack.employee);
158
+ if (emp)
159
+ routeOpts.employee = emp;
160
+ }
161
+ sessionManager.route(msg, slack, routeOpts).catch((err) => {
162
+ logger.error(`Slack route error: ${err instanceof Error ? err.message : err}`);
163
+ });
164
+ });
165
+ await slack.start();
166
+ connectors.push(slack);
167
+ connectorMap.set("slack", slack);
168
+ }
169
+ catch (err) {
170
+ logger.error(`Failed to start Slack connector: ${err instanceof Error ? err.message : err}`);
171
+ }
172
+ }
173
+ if (config.connectors?.discord?.proxyVia) {
174
+ // Remote mode: proxy all Discord operations through the primary instance
175
+ try {
176
+ const discord = new RemoteDiscordConnector({
177
+ proxyVia: config.connectors.discord.proxyVia,
178
+ channelId: config.connectors.discord.channelId,
179
+ });
180
+ discord.onMessage((msg) => {
181
+ const routeOpts = {};
182
+ if (config.connectors.discord?.employee) {
183
+ const emp = employeeRegistry.get(config.connectors.discord.employee);
184
+ if (emp)
185
+ routeOpts.employee = emp;
186
+ }
187
+ sessionManager.route(msg, discord, routeOpts).catch((err) => {
188
+ logger.error(`Discord route error: ${err instanceof Error ? err.message : err}`);
189
+ });
190
+ });
191
+ await discord.start();
192
+ connectors.push(discord);
193
+ connectorMap.set("discord", discord);
194
+ logger.info("Discord remote connector started");
195
+ }
196
+ catch (err) {
197
+ logger.error(`Failed to start remote Discord connector: ${err instanceof Error ? err.message : err}`);
198
+ }
199
+ }
200
+ else if (config.connectors?.discord?.botToken) {
201
+ // Primary mode: direct Discord bot connection
202
+ try {
203
+ const discord = new DiscordConnector(config.connectors.discord);
204
+ discord.onMessage((msg) => {
205
+ const routeOpts = {};
206
+ if (config.connectors.discord?.employee) {
207
+ const emp = employeeRegistry.get(config.connectors.discord.employee);
208
+ if (emp)
209
+ routeOpts.employee = emp;
210
+ }
211
+ sessionManager.route(msg, discord, routeOpts).catch((err) => {
212
+ logger.error(`Discord route error: ${err instanceof Error ? err.message : err}`);
213
+ });
214
+ });
215
+ await discord.start();
216
+ connectors.push(discord);
217
+ connectorMap.set("discord", discord);
218
+ logger.info("Discord connector started");
219
+ }
220
+ catch (err) {
221
+ logger.error(`Failed to start Discord connector: ${err instanceof Error ? err.message : err}`);
222
+ }
223
+ }
224
+ else if (config.connectors?.discord?.proxyVia) {
225
+ try {
226
+ const discord = new RemoteDiscordConnector({ proxyVia: config.connectors.discord.proxyVia });
227
+ discord.onMessage((msg) => {
228
+ const routeOpts = {};
229
+ if (config.connectors.discord?.employee) {
230
+ const emp = employeeRegistry.get(config.connectors.discord.employee);
231
+ if (emp)
232
+ routeOpts.employee = emp;
233
+ }
234
+ sessionManager.route(msg, discord, routeOpts).catch((err) => {
235
+ logger.error(`Discord (remote) route error: ${err instanceof Error ? err.message : err}`);
236
+ });
237
+ });
238
+ await discord.start();
239
+ connectors.push(discord);
240
+ connectorMap.set("discord", discord);
241
+ logger.info(`Discord connector started in remote mode (via ${config.connectors.discord.proxyVia})`);
242
+ }
243
+ catch (err) {
244
+ logger.error(`Failed to start remote Discord connector: ${err instanceof Error ? err.message : err}`);
245
+ }
246
+ }
247
+ if (config.connectors?.telegram?.botToken) {
248
+ try {
249
+ const telegram = new TelegramConnector({
250
+ botToken: config.connectors.telegram.botToken,
251
+ allowFrom: config.connectors.telegram.allowFrom,
252
+ ignoreOldMessagesOnBoot: config.connectors.telegram.ignoreOldMessagesOnBoot,
253
+ });
254
+ telegram.onMessage((msg) => {
255
+ const routeOpts = {};
256
+ if (config.connectors.telegram?.employee) {
257
+ const emp = employeeRegistry.get(config.connectors.telegram.employee);
258
+ if (emp)
259
+ routeOpts.employee = emp;
260
+ }
261
+ sessionManager.route(msg, telegram, routeOpts).catch((err) => {
262
+ logger.error(`Telegram route error: ${err instanceof Error ? err.message : err}`);
263
+ });
264
+ });
265
+ await telegram.start();
266
+ connectors.push(telegram);
267
+ connectorMap.set("telegram", telegram);
268
+ }
269
+ catch (err) {
270
+ logger.error(`Failed to start Telegram connector: ${err instanceof Error ? err.message : err}`);
271
+ }
272
+ }
273
+ if (config.connectors?.whatsapp) {
274
+ try {
275
+ const whatsapp = new WhatsAppConnector(config.connectors.whatsapp ?? {});
276
+ whatsapp.onMessage((msg) => {
277
+ const routeOpts = {};
278
+ if (config.connectors.whatsapp?.employee) {
279
+ const emp = employeeRegistry.get(config.connectors.whatsapp.employee);
280
+ if (emp)
281
+ routeOpts.employee = emp;
282
+ }
283
+ sessionManager.route(msg, whatsapp, routeOpts).catch((err) => {
284
+ logger.error(`WhatsApp route error: ${err instanceof Error ? err.message : err}`);
285
+ });
286
+ });
287
+ await whatsapp.start();
288
+ connectors.push(whatsapp);
289
+ connectorMap.set("whatsapp", whatsapp);
290
+ logger.info("WhatsApp connector started (scan QR code if first run)");
291
+ }
292
+ catch (err) {
293
+ logger.error(`Failed to start WhatsApp connector: ${err instanceof Error ? err.message : err}`);
294
+ }
295
+ }
296
+ // Process named connector instances (allows multiple connectors of the same type)
297
+ if (config.connectors?.instances) {
298
+ for (const instance of config.connectors.instances) {
299
+ const { id, type, employee, ...typeConfig } = instance;
300
+ if (!id || !type) {
301
+ logger.warn(`Skipping connector instance without id or type`);
302
+ continue;
303
+ }
304
+ if (connectorMap.has(id)) {
305
+ logger.warn(`Duplicate connector instance id "${id}", skipping`);
306
+ continue;
307
+ }
308
+ try {
309
+ let connector;
310
+ switch (type) {
311
+ case "discord": {
312
+ const discordConfig = { ...typeConfig, id };
313
+ const discord = new DiscordConnector(discordConfig);
314
+ discord.onMessage((msg) => {
315
+ const routeOpts = {};
316
+ if (employee) {
317
+ const emp = employeeRegistry.get(employee);
318
+ if (emp)
319
+ routeOpts.employee = emp;
320
+ }
321
+ sessionManager.route(msg, discord, routeOpts).catch((err) => {
322
+ logger.error(`${id} route error: ${err instanceof Error ? err.message : err}`);
323
+ });
324
+ });
325
+ await discord.start();
326
+ connector = discord;
327
+ break;
328
+ }
329
+ case "slack": {
330
+ const slackConfig = { ...typeConfig, id };
331
+ const slack = new SlackConnector(slackConfig, {
332
+ portalName: config.portal?.portalName,
333
+ operatorName: config.portal?.operatorName,
334
+ });
335
+ slack.onMessage((msg) => {
336
+ const routeOpts = {};
337
+ if (employee) {
338
+ const emp = employeeRegistry.get(employee);
339
+ if (emp)
340
+ routeOpts.employee = emp;
341
+ }
342
+ sessionManager.route(msg, slack, routeOpts).catch((err) => {
343
+ logger.error(`${id} route error: ${err instanceof Error ? err.message : err}`);
344
+ });
345
+ });
346
+ await slack.start();
347
+ connector = slack;
348
+ break;
349
+ }
350
+ case "whatsapp": {
351
+ const whatsapp = new WhatsAppConnector({ ...typeConfig });
352
+ whatsapp.onMessage((msg) => {
353
+ const routeOpts = {};
354
+ if (employee) {
355
+ const emp = employeeRegistry.get(employee);
356
+ if (emp)
357
+ routeOpts.employee = emp;
358
+ }
359
+ sessionManager.route(msg, whatsapp, routeOpts).catch((err) => {
360
+ logger.error(`${id} route error: ${err instanceof Error ? err.message : err}`);
361
+ });
362
+ });
363
+ await whatsapp.start();
364
+ connector = whatsapp;
365
+ break;
366
+ }
367
+ case "telegram": {
368
+ const telegramConfig = { ...typeConfig, id };
369
+ const tg = new TelegramConnector(telegramConfig);
370
+ tg.onMessage((msg) => {
371
+ const routeOpts = {};
372
+ if (employee) {
373
+ const emp = employeeRegistry.get(employee);
374
+ if (emp)
375
+ routeOpts.employee = emp;
376
+ }
377
+ sessionManager.route(msg, tg, routeOpts).catch((err) => {
378
+ logger.error(`${id} route error: ${err instanceof Error ? err.message : err}`);
379
+ });
380
+ });
381
+ await tg.start();
382
+ connector = tg;
383
+ break;
384
+ }
385
+ default:
386
+ logger.warn(`Unknown connector type "${type}" for instance "${id}"`);
387
+ continue;
388
+ }
389
+ connectors.push(connector);
390
+ connectorMap.set(id, connector);
391
+ instanceConnectorIds.add(id);
392
+ logger.info(`Connector instance "${id}" (type: ${type}, employee: ${employee || "default"}) started`);
393
+ }
394
+ catch (err) {
395
+ logger.error(`Failed to start connector instance "${id}": ${err instanceof Error ? err.message : err}`);
396
+ }
397
+ }
398
+ }
399
+ sessionManager.setConnectorProvider(() => connectorMap);
400
+ // Reload connector instances from config (stop old instances, start new ones)
401
+ async function reloadConnectorInstances() {
402
+ const freshConfig = loadConfig();
403
+ const started = [];
404
+ const stopped = [];
405
+ const errors = [];
406
+ // Find instance-based connectors (keys that came from instances array)
407
+ const instanceIds = new Set();
408
+ if (freshConfig.connectors?.instances) {
409
+ for (const inst of freshConfig.connectors.instances) {
410
+ if (inst.id)
411
+ instanceIds.add(inst.id);
412
+ }
413
+ }
414
+ // Stop old instance connectors that are no longer in config or need refresh
415
+ for (const [id, connector] of connectorMap.entries()) {
416
+ // Skip legacy (top-level) connectors — only reload instance-based ones
417
+ if (!instanceConnectorIds.has(id))
418
+ continue;
419
+ try {
420
+ await connector.stop();
421
+ connectorMap.delete(id);
422
+ instanceConnectorIds.delete(id);
423
+ const idx = connectors.indexOf(connector);
424
+ if (idx >= 0)
425
+ connectors.splice(idx, 1);
426
+ stopped.push(id);
427
+ logger.info(`Stopped connector instance "${id}" for reload`);
428
+ }
429
+ catch (err) {
430
+ errors.push(`Failed to stop ${id}: ${err instanceof Error ? err.message : err}`);
431
+ }
432
+ }
433
+ // Start new instances from fresh config
434
+ if (freshConfig.connectors?.instances) {
435
+ for (const instance of freshConfig.connectors.instances) {
436
+ const { id, type, employee, ...typeConfig } = instance;
437
+ if (!id || !type)
438
+ continue;
439
+ if (connectorMap.has(id))
440
+ continue;
441
+ try {
442
+ let connector;
443
+ switch (type) {
444
+ case "discord": {
445
+ const discordConfig = { ...typeConfig, id };
446
+ const discord = new DiscordConnector(discordConfig);
447
+ discord.onMessage((msg) => {
448
+ const routeOpts = {};
449
+ if (employee) {
450
+ const emp = employeeRegistry.get(employee);
451
+ if (emp)
452
+ routeOpts.employee = emp;
453
+ }
454
+ sessionManager.route(msg, discord, routeOpts).catch((err) => {
455
+ logger.error(`${id} route error: ${err instanceof Error ? err.message : err}`);
456
+ });
457
+ });
458
+ await discord.start();
459
+ connector = discord;
460
+ break;
461
+ }
462
+ case "slack": {
463
+ const slackConfig = { ...typeConfig, id };
464
+ const slack = new SlackConnector(slackConfig, {
465
+ portalName: config.portal?.portalName,
466
+ operatorName: config.portal?.operatorName,
467
+ });
468
+ slack.onMessage((msg) => {
469
+ const routeOpts = {};
470
+ if (employee) {
471
+ const emp = employeeRegistry.get(employee);
472
+ if (emp)
473
+ routeOpts.employee = emp;
474
+ }
475
+ sessionManager.route(msg, slack, routeOpts).catch((err) => {
476
+ logger.error(`${id} route error: ${err instanceof Error ? err.message : err}`);
477
+ });
478
+ });
479
+ await slack.start();
480
+ connector = slack;
481
+ break;
482
+ }
483
+ case "whatsapp": {
484
+ const whatsapp = new WhatsAppConnector({ ...typeConfig });
485
+ whatsapp.onMessage((msg) => {
486
+ const routeOpts = {};
487
+ if (employee) {
488
+ const emp = employeeRegistry.get(employee);
489
+ if (emp)
490
+ routeOpts.employee = emp;
491
+ }
492
+ sessionManager.route(msg, whatsapp, routeOpts).catch((err) => {
493
+ logger.error(`${id} route error: ${err instanceof Error ? err.message : err}`);
494
+ });
495
+ });
496
+ await whatsapp.start();
497
+ connector = whatsapp;
498
+ break;
499
+ }
500
+ case "telegram": {
501
+ const telegramConfig = { ...typeConfig, id };
502
+ const tg = new TelegramConnector(telegramConfig);
503
+ tg.onMessage((msg) => {
504
+ const routeOpts = {};
505
+ if (employee) {
506
+ const emp = employeeRegistry.get(employee);
507
+ if (emp)
508
+ routeOpts.employee = emp;
509
+ }
510
+ sessionManager.route(msg, tg, routeOpts).catch((err) => {
511
+ logger.error(`${id} route error: ${err instanceof Error ? err.message : err}`);
512
+ });
513
+ });
514
+ await tg.start();
515
+ connector = tg;
516
+ break;
517
+ }
518
+ default:
519
+ errors.push(`Unknown connector type "${type}" for instance "${id}"`);
520
+ continue;
521
+ }
522
+ connectors.push(connector);
523
+ connectorMap.set(id, connector);
524
+ instanceConnectorIds.add(id);
525
+ started.push(id);
526
+ logger.info(`Connector instance "${id}" (type: ${type}, employee: ${employee || "default"}) started`);
527
+ }
528
+ catch (err) {
529
+ errors.push(`Failed to start "${id}": ${err instanceof Error ? err.message : err}`);
530
+ logger.error(`Failed to start connector instance "${id}": ${err instanceof Error ? err.message : err}`);
531
+ }
532
+ }
533
+ }
534
+ return { started, stopped, errors };
535
+ }
536
+ // Start cron scheduler
537
+ const cronJobs = loadJobs();
538
+ startScheduler(cronJobs, sessionManager, config, connectorMap);
539
+ logger.info(`Loaded ${cronJobs.length} cron job(s)`);
540
+ // Mutable config reference for hot-reload
541
+ let currentConfig = config;
542
+ const startTime = Date.now();
543
+ // Broadcast function (defined early so apiContext can reference it)
544
+ const wsClients = new Set();
545
+ const emit = (event, payload) => {
546
+ const message = JSON.stringify({ event, payload, ts: Date.now() });
547
+ for (const client of wsClients) {
548
+ if (client.readyState === 1) {
549
+ try {
550
+ client.send(message);
551
+ }
552
+ catch (err) {
553
+ logger.warn(`WebSocket send failed, removing dead client: ${err instanceof Error ? err.message : err}`);
554
+ wsClients.delete(client);
555
+ }
556
+ }
557
+ }
558
+ };
559
+ // API context
560
+ const apiContext = {
561
+ config: currentConfig,
562
+ sessionManager,
563
+ startTime,
564
+ getConfig: () => currentConfig,
565
+ emit,
566
+ connectors: connectorMap,
567
+ reloadConnectorInstances,
568
+ };
569
+ // Replay any pending web queue items (e.g. gateway restart mid-run)
570
+ resumePendingWebQueueItems(apiContext);
571
+ // Resolve web UI directory — bundled into dist/web/ by postbuild script
572
+ // At runtime __dirname is dist/src/gateway/, so ../../web resolves to dist/web/
573
+ const webDir = path.resolve(__dirname, "..", "..", "web");
574
+ // Create HTTP server
575
+ const server = http.createServer((req, res) => {
576
+ const url = req.url || "/";
577
+ // CORS headers for development
578
+ res.setHeader("Access-Control-Allow-Origin", "*");
579
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
580
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type");
581
+ if (req.method === "OPTIONS") {
582
+ res.writeHead(204);
583
+ res.end();
584
+ return;
585
+ }
586
+ // API routes
587
+ if (url.startsWith("/api/")) {
588
+ handleApiRequest(req, res, apiContext);
589
+ return;
590
+ }
591
+ // Static files for web UI
592
+ if (!serveStatic(req, res, webDir)) {
593
+ if (url === "/" || url === "/index.html") {
594
+ res.writeHead(503, { "Content-Type": "text/html" });
595
+ res.end("<html><body><h1>Web UI not built</h1><p>Run <code>pnpm build</code> from the project root to build the web UI.</p></body></html>");
596
+ }
597
+ else {
598
+ res.writeHead(404, { "Content-Type": "application/json" });
599
+ res.end(JSON.stringify({ error: "Not found" }));
600
+ }
601
+ }
602
+ });
603
+ // WebSocket server
604
+ const wss = new WebSocketServer({ noServer: true });
605
+ wss.on("connection", (ws) => {
606
+ wsClients.add(ws);
607
+ logger.info(`WebSocket client connected (${wsClients.size} total)`);
608
+ ws.on("close", () => {
609
+ wsClients.delete(ws);
610
+ logger.info(`WebSocket client disconnected (${wsClients.size} total)`);
611
+ });
612
+ ws.on("error", (err) => {
613
+ logger.error(`WebSocket error: ${err.message}`);
614
+ wsClients.delete(ws);
615
+ });
616
+ });
617
+ server.on("upgrade", (req, socket, head) => {
618
+ if (req.url === "/ws") {
619
+ wss.handleUpgrade(req, socket, head, (ws) => {
620
+ wss.emit("connection", ws, req);
621
+ });
622
+ }
623
+ else {
624
+ socket.destroy();
625
+ }
626
+ });
627
+ // Sync skill symlinks to .claude/skills/ and .agents/skills/
628
+ syncSkillSymlinks();
629
+ // Initialize STT model symlinks
630
+ try {
631
+ initStt();
632
+ }
633
+ catch (err) {
634
+ logger.warn(`STT init skipped: ${err instanceof Error ? err.message : err}`);
635
+ }
636
+ // Start file watchers
637
+ startWatchers({
638
+ onConfigReload: () => {
639
+ try {
640
+ currentConfig = loadConfig();
641
+ apiContext.config = currentConfig;
642
+ logger.info("Config reloaded successfully");
643
+ emit("config:reloaded", {});
644
+ }
645
+ catch (err) {
646
+ logger.error(`Failed to reload config: ${err instanceof Error ? err.message : err}`);
647
+ }
648
+ },
649
+ onCronReload: () => {
650
+ const updatedJobs = loadJobs();
651
+ reloadScheduler(updatedJobs);
652
+ logger.info(`Cron jobs reloaded (${updatedJobs.length} job(s))`);
653
+ emit("cron:reloaded", {});
654
+ },
655
+ onOrgChange: () => {
656
+ employeeRegistry = scanOrg();
657
+ logger.info(`Org directory changed, reloaded ${employeeRegistry.size} employee(s)`);
658
+ emit("org:changed", {});
659
+ },
660
+ onSkillsChange: () => {
661
+ logger.info("Skills changed, notifying clients");
662
+ emit("skills:changed", {});
663
+ },
664
+ });
665
+ // Start listening
666
+ const port = config.gateway.port || 7777;
667
+ const host = config.gateway.host || "127.0.0.1";
668
+ await new Promise((resolve, reject) => {
669
+ server.on("error", (err) => {
670
+ if (err.code === "EADDRINUSE") {
671
+ const msg = `Port ${port} is already in use.`;
672
+ logger.error(msg);
673
+ console.error(`\nError: ${msg}`);
674
+ console.error(`\nTry: jinn start -p ${port + 1}`);
675
+ console.error(`Or update the port in config.yaml\n`);
676
+ process.exit(1);
677
+ }
678
+ reject(err);
679
+ });
680
+ server.listen(port, host, () => {
681
+ logger.info(`${gatewayName} gateway listening on http://${host}:${port} (boot ${bootId})`);
682
+ resolve();
683
+ });
684
+ });
685
+ // Notify connected WebSocket clients about interrupted sessions available for resume
686
+ if (resumable.length > 0) {
687
+ // Small delay to let WebSocket clients connect after server starts
688
+ setTimeout(() => {
689
+ emit("sessions:interrupted", {
690
+ count: resumable.length,
691
+ sessions: resumable.map((s) => ({
692
+ id: s.id,
693
+ engine: s.engine,
694
+ employee: s.employee,
695
+ title: s.title,
696
+ lastActivity: s.lastActivity,
697
+ })),
698
+ });
699
+ }, 1000);
700
+ }
701
+ // Prevent macOS from sleeping while the gateway is running
702
+ let caffeinate = null;
703
+ if (process.platform === "darwin") {
704
+ caffeinate = spawn("caffeinate", ["-s"], {
705
+ stdio: "ignore",
706
+ detached: false,
707
+ });
708
+ caffeinate.unref();
709
+ caffeinate.on("error", (err) => {
710
+ logger.warn(`caffeinate failed to start: ${err.message}`);
711
+ caffeinate = null;
712
+ });
713
+ logger.info("caffeinate started — macOS sleep prevention active");
714
+ }
715
+ // Return cleanup function
716
+ return async () => {
717
+ logger.info("Gateway cleanup starting...");
718
+ // Stop caffeinate
719
+ if (caffeinate && caffeinate.exitCode === null) {
720
+ caffeinate.kill();
721
+ logger.info("caffeinate stopped");
722
+ }
723
+ // Mark all running sessions as "interrupted" before killing engine processes.
724
+ // This preserves their engine_session_id so they can be resumed on next startup.
725
+ const runningSessions = listSessions({ status: "running" });
726
+ for (const session of runningSessions) {
727
+ updateSession(session.id, {
728
+ status: "interrupted",
729
+ lastActivity: new Date().toISOString(),
730
+ lastError: "Interrupted: gateway shutting down gracefully",
731
+ });
732
+ logger.info(`Marked session ${session.id} as interrupted for resume`);
733
+ }
734
+ // Terminate live engine subprocesses after marking sessions.
735
+ claudeEngine.killAll();
736
+ codexEngine.killAll();
737
+ // Stop cron scheduler
738
+ stopScheduler();
739
+ // Stop connectors
740
+ for (const connector of connectors) {
741
+ try {
742
+ await connector.stop();
743
+ }
744
+ catch (err) {
745
+ logger.error(`Failed to stop ${connector.name} connector: ${err instanceof Error ? err.message : err}`);
746
+ }
747
+ }
748
+ // Stop watchers
749
+ await stopWatchers();
750
+ // Close WebSocket connections
751
+ for (const client of wsClients) {
752
+ client.close(1001, "Server shutting down");
753
+ }
754
+ wsClients.clear();
755
+ // Close WebSocket server
756
+ await new Promise((resolve) => wss.close(() => resolve()));
757
+ // Close HTTP server
758
+ await new Promise((resolve, reject) => {
759
+ server.close((err) => (err ? reject(err) : resolve()));
760
+ });
761
+ logger.info("Gateway shutdown complete");
762
+ };
763
+ }
764
+ //# sourceMappingURL=server.js.map