@interactive-inc/claude-funnel 0.8.1 → 0.10.1

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 (354) hide show
  1. package/README.md +179 -80
  2. package/dist/bin.js +726 -658
  3. package/dist/connector-adapter-CXB-q_XC.d.ts +11 -0
  4. package/dist/connector-adapter-D5Utumgz.js +4 -0
  5. package/dist/connectors/discord.d.ts +76 -0
  6. package/dist/connectors/discord.js +2 -0
  7. package/dist/connectors/gh.d.ts +38 -0
  8. package/dist/connectors/gh.js +2 -0
  9. package/dist/connectors/schedule.d.ts +53 -0
  10. package/dist/connectors/schedule.js +2 -0
  11. package/dist/connectors/slack.d.ts +34 -0
  12. package/dist/connectors/slack.js +2 -0
  13. package/dist/discord-connector-schema-Dww2I4zH.d.ts +14 -0
  14. package/dist/discord-connector-schema-ygf5Df-2.js +173 -0
  15. package/dist/file-system-Co60LrmR.d.ts +74 -0
  16. package/dist/gateway/daemon.js +233 -183
  17. package/dist/gh-connector-schema-2ml29MBC.js +218 -0
  18. package/dist/gh-connector-schema-BZFAS-p-.d.ts +45 -0
  19. package/dist/index.d.ts +3881 -36
  20. package/dist/index.js +6217 -3483
  21. package/dist/logger-CTlXs7z4.d.ts +33 -0
  22. package/dist/node-logger-DQz_BGOD.js +61 -0
  23. package/dist/schedule-connector-schema-CkuIQ0JQ.js +325 -0
  24. package/dist/slack-connector-schema-Cd22WiHB.js +153 -0
  25. package/dist/slack-event-processor-CS-bAit9.d.ts +43 -0
  26. package/package.json +34 -28
  27. package/dist/cli/factory.d.ts +0 -7
  28. package/dist/cli/router/query-to-cli-args.d.ts +0 -1
  29. package/dist/cli/router/to-request.d.ts +0 -5
  30. package/dist/cli/router/validator.d.ts +0 -5
  31. package/dist/cli/routes/channels.$channel.connectors.$connector.d.ts +0 -42
  32. package/dist/cli/routes/channels.$channel.connectors.$connector.rename.$newName.d.ts +0 -46
  33. package/dist/cli/routes/channels.$channel.connectors.$connector.request.d.ts +0 -54
  34. package/dist/cli/routes/channels.$channel.connectors.$connector.schedules.add.$id.d.ts +0 -66
  35. package/dist/cli/routes/channels.$channel.connectors.$connector.schedules.d.ts +0 -42
  36. package/dist/cli/routes/channels.$channel.connectors.$connector.schedules.remove.$id.d.ts +0 -46
  37. package/dist/cli/routes/channels.$channel.connectors.add.$connector.d.ts +0 -90
  38. package/dist/cli/routes/channels.$channel.connectors.d.ts +0 -38
  39. package/dist/cli/routes/channels.$channel.connectors.remove.$connector.d.ts +0 -42
  40. package/dist/cli/routes/channels.$channel.connectors.set.$connector.d.ts +0 -62
  41. package/dist/cli/routes/channels.$channel.d.ts +0 -38
  42. package/dist/cli/routes/channels.$channel.rename.$newName.d.ts +0 -42
  43. package/dist/cli/routes/channels.$channel.set.delivery.$mode.d.ts +0 -28
  44. package/dist/cli/routes/channels.add.$channel.d.ts +0 -46
  45. package/dist/cli/routes/channels.d.ts +0 -16
  46. package/dist/cli/routes/channels.remove.$channel.d.ts +0 -38
  47. package/dist/cli/routes/claude.d.ts +0 -32
  48. package/dist/cli/routes/gateway.d.ts +0 -20
  49. package/dist/cli/routes/gateway.listeners.d.ts +0 -17
  50. package/dist/cli/routes/gateway.logs.d.ts +0 -24
  51. package/dist/cli/routes/gateway.restart.d.ts +0 -24
  52. package/dist/cli/routes/gateway.run.d.ts +0 -24
  53. package/dist/cli/routes/gateway.start.d.ts +0 -24
  54. package/dist/cli/routes/gateway.status.d.ts +0 -13
  55. package/dist/cli/routes/gateway.stop.d.ts +0 -16
  56. package/dist/cli/routes/index.d.ts +0 -1222
  57. package/dist/cli/routes/profiles.$profile.as-default.d.ts +0 -38
  58. package/dist/cli/routes/profiles.$profile.rename.$newName.d.ts +0 -42
  59. package/dist/cli/routes/profiles.$profile.run.d.ts +0 -46
  60. package/dist/cli/routes/profiles.add.$profile.d.ts +0 -54
  61. package/dist/cli/routes/profiles.d.ts +0 -16
  62. package/dist/cli/routes/profiles.remove.$profile.d.ts +0 -38
  63. package/dist/cli/routes/profiles.set.$profile.d.ts +0 -54
  64. package/dist/cli/routes/status.d.ts +0 -16
  65. package/dist/cli/routes/update.d.ts +0 -16
  66. package/dist/connectors/connector-adapter.d.ts +0 -8
  67. package/dist/connectors/connector-config-schema.d.ts +0 -43
  68. package/dist/connectors/connector-factory.d.ts +0 -32
  69. package/dist/connectors/connector-listener.d.ts +0 -17
  70. package/dist/connectors/discord-adapter.d.ts +0 -14
  71. package/dist/connectors/discord-connector-schema.d.ts +0 -10
  72. package/dist/connectors/discord-event-processor.d.ts +0 -26
  73. package/dist/connectors/discord-listener.d.ts +0 -17
  74. package/dist/connectors/gh-adapter.d.ts +0 -11
  75. package/dist/connectors/gh-connector-schema.d.ts +0 -10
  76. package/dist/connectors/gh-listener.d.ts +0 -26
  77. package/dist/connectors/match-cron.d.ts +0 -1
  78. package/dist/connectors/schedule-connector-schema.d.ts +0 -45
  79. package/dist/connectors/schedule-listener.d.ts +0 -30
  80. package/dist/connectors/schedule-state-store.d.ts +0 -19
  81. package/dist/connectors/slack-adapter.d.ts +0 -15
  82. package/dist/connectors/slack-connector-schema.d.ts +0 -11
  83. package/dist/connectors/slack-event-processor.d.ts +0 -27
  84. package/dist/connectors/slack-listener.d.ts +0 -17
  85. package/dist/engine/channels/channels.d.ts +0 -106
  86. package/dist/engine/claude/claude.d.ts +0 -49
  87. package/dist/engine/claude/gateway-controller.d.ts +0 -6
  88. package/dist/engine/fs/file-system.d.ts +0 -24
  89. package/dist/engine/fs/memory-file-system.d.ts +0 -31
  90. package/dist/engine/fs/node-file-system.d.ts +0 -15
  91. package/dist/engine/http/http-client.d.ts +0 -15
  92. package/dist/engine/http/memory-http-client.d.ts +0 -12
  93. package/dist/engine/http/node-http-client.d.ts +0 -5
  94. package/dist/engine/id/id-generator.d.ts +0 -7
  95. package/dist/engine/id/memory-id-generator.d.ts +0 -11
  96. package/dist/engine/id/node-id-generator.d.ts +0 -4
  97. package/dist/engine/logger/logger.d.ts +0 -11
  98. package/dist/engine/logger/memory-logger.d.ts +0 -14
  99. package/dist/engine/logger/node-logger.d.ts +0 -15
  100. package/dist/engine/logger/noop-logger.d.ts +0 -7
  101. package/dist/engine/mcp/channel-server.d.ts +0 -1
  102. package/dist/engine/mcp/mcp.d.ts +0 -22
  103. package/dist/engine/process/memory-process-runner.d.ts +0 -43
  104. package/dist/engine/process/node-process-runner.d.ts +0 -9
  105. package/dist/engine/process/process-runner.d.ts +0 -29
  106. package/dist/engine/profiles/profile-channel-checker.d.ts +0 -7
  107. package/dist/engine/profiles/profiles.d.ts +0 -31
  108. package/dist/engine/settings/mock-settings-reader.d.ts +0 -9
  109. package/dist/engine/settings/settings-reader.d.ts +0 -5
  110. package/dist/engine/settings/settings-schema.d.ts +0 -132
  111. package/dist/engine/settings/settings-store.d.ts +0 -18
  112. package/dist/engine/time/clock.d.ts +0 -9
  113. package/dist/engine/time/memory-clock.d.ts +0 -12
  114. package/dist/engine/time/node-clock.d.ts +0 -4
  115. package/dist/funnel.d.ts +0 -95
  116. package/dist/gateway/auth-middleware.d.ts +0 -14
  117. package/dist/gateway/broadcaster.d.ts +0 -122
  118. package/dist/gateway/daemon.d.ts +0 -2
  119. package/dist/gateway/factory.d.ts +0 -7
  120. package/dist/gateway/funnel-event-store.d.ts +0 -81
  121. package/dist/gateway/gateway-server.d.ts +0 -94
  122. package/dist/gateway/gateway-token.d.ts +0 -33
  123. package/dist/gateway/gateway.d.ts +0 -58
  124. package/dist/gateway/kill-competing-slack-gateways.d.ts +0 -9
  125. package/dist/gateway/listener-supervisor.d.ts +0 -85
  126. package/dist/gateway/listeners-client.d.ts +0 -53
  127. package/dist/gateway/resolve-daemon-script.d.ts +0 -11
  128. package/dist/gateway/routes/channels.connectors.call.d.ts +0 -41
  129. package/dist/gateway/routes/health.d.ts +0 -17
  130. package/dist/gateway/routes/index.d.ts +0 -209
  131. package/dist/gateway/routes/listeners.list.d.ts +0 -14
  132. package/dist/gateway/routes/listeners.restart.d.ts +0 -34
  133. package/dist/gateway/routes/listeners.start.d.ts +0 -34
  134. package/dist/gateway/routes/listeners.stop.d.ts +0 -34
  135. package/dist/gateway/routes/route-deps.d.ts +0 -10
  136. package/dist/gateway/routes/status.d.ts +0 -30
  137. package/dist/gateway/routes/validator.d.ts +0 -19
  138. package/dist/logger/leuco-human-file-writer.d.ts +0 -33
  139. package/dist/logger/leuco-human-logger.d.ts +0 -46
  140. package/dist/logger/leuco-human-record.d.ts +0 -15
  141. package/dist/logger/leuco-human-stdout-writer.d.ts +0 -20
  142. package/dist/logger/leuco-human-writer.d.ts +0 -13
  143. package/dist/logger/leuco-logger-memory-sink.d.ts +0 -33
  144. package/dist/logger/leuco-logger-record.d.ts +0 -13
  145. package/dist/logger/leuco-logger-sink.d.ts +0 -34
  146. package/dist/logger/leuco-logger-sqlite-sink.d.ts +0 -102
  147. package/dist/logger/leuco-logger.d.ts +0 -56
  148. package/lib/bin.ts +0 -78
  149. package/lib/cli/factory.ts +0 -10
  150. package/lib/cli/router/query-to-cli-args.ts +0 -20
  151. package/lib/cli/router/to-request.ts +0 -112
  152. package/lib/cli/router/validator.ts +0 -27
  153. package/lib/cli/routes/channels.$channel.connectors.$connector.rename.$newName.ts +0 -27
  154. package/lib/cli/routes/channels.$channel.connectors.$connector.request.ts +0 -40
  155. package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.add.$id.ts +0 -41
  156. package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.remove.$id.ts +0 -22
  157. package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.ts +0 -23
  158. package/lib/cli/routes/channels.$channel.connectors.$connector.ts +0 -26
  159. package/lib/cli/routes/channels.$channel.connectors.add.$connector.ts +0 -92
  160. package/lib/cli/routes/channels.$channel.connectors.remove.$connector.ts +0 -22
  161. package/lib/cli/routes/channels.$channel.connectors.set.$connector.ts +0 -63
  162. package/lib/cli/routes/channels.$channel.connectors.ts +0 -26
  163. package/lib/cli/routes/channels.$channel.rename.$newName.ts +0 -22
  164. package/lib/cli/routes/channels.$channel.set.delivery.$mode.ts +0 -34
  165. package/lib/cli/routes/channels.$channel.ts +0 -34
  166. package/lib/cli/routes/channels.add.$channel.ts +0 -33
  167. package/lib/cli/routes/channels.remove.$channel.ts +0 -20
  168. package/lib/cli/routes/channels.ts +0 -39
  169. package/lib/cli/routes/claude.ts +0 -69
  170. package/lib/cli/routes/gateway.listeners.ts +0 -41
  171. package/lib/cli/routes/gateway.logs.ts +0 -123
  172. package/lib/cli/routes/gateway.restart.ts +0 -50
  173. package/lib/cli/routes/gateway.run.ts +0 -41
  174. package/lib/cli/routes/gateway.start.ts +0 -50
  175. package/lib/cli/routes/gateway.status.ts +0 -19
  176. package/lib/cli/routes/gateway.stop.ts +0 -32
  177. package/lib/cli/routes/gateway.ts +0 -55
  178. package/lib/cli/routes/index.ts +0 -202
  179. package/lib/cli/routes/profiles.$profile.as-default.ts +0 -22
  180. package/lib/cli/routes/profiles.$profile.rename.$newName.ts +0 -22
  181. package/lib/cli/routes/profiles.$profile.run.ts +0 -36
  182. package/lib/cli/routes/profiles.add.$profile.ts +0 -46
  183. package/lib/cli/routes/profiles.remove.$profile.ts +0 -20
  184. package/lib/cli/routes/profiles.set.$profile.ts +0 -46
  185. package/lib/cli/routes/profiles.ts +0 -40
  186. package/lib/cli/routes/status.ts +0 -93
  187. package/lib/cli/routes/update.ts +0 -27
  188. package/lib/connectors/connector-adapter.ts +0 -9
  189. package/lib/connectors/connector-config-schema.ts +0 -16
  190. package/lib/connectors/connector-factory.ts +0 -94
  191. package/lib/connectors/connector-listener.ts +0 -20
  192. package/lib/connectors/discord-adapter.ts +0 -51
  193. package/lib/connectors/discord-connector-schema.ts +0 -12
  194. package/lib/connectors/discord-event-processor.ts +0 -48
  195. package/lib/connectors/discord-listener.ts +0 -111
  196. package/lib/connectors/gh-adapter.ts +0 -48
  197. package/lib/connectors/gh-connector-schema.ts +0 -12
  198. package/lib/connectors/gh-listener.ts +0 -137
  199. package/lib/connectors/match-cron.ts +0 -78
  200. package/lib/connectors/schedule-connector-schema.ts +0 -33
  201. package/lib/connectors/schedule-listener.ts +0 -207
  202. package/lib/connectors/schedule-state-store.ts +0 -54
  203. package/lib/connectors/slack-adapter.ts +0 -36
  204. package/lib/connectors/slack-connector-schema.ts +0 -13
  205. package/lib/connectors/slack-event-processor.ts +0 -97
  206. package/lib/connectors/slack-listener.ts +0 -97
  207. package/lib/engine/channels/channels.ts +0 -520
  208. package/lib/engine/claude/claude.ts +0 -199
  209. package/lib/engine/claude/gateway-controller.ts +0 -4
  210. package/lib/engine/fs/file-system.ts +0 -23
  211. package/lib/engine/fs/memory-file-system.ts +0 -102
  212. package/lib/engine/fs/node-file-system.ts +0 -68
  213. package/lib/engine/http/http-client.ts +0 -17
  214. package/lib/engine/http/memory-http-client.ts +0 -36
  215. package/lib/engine/http/node-http-client.ts +0 -23
  216. package/lib/engine/id/id-generator.ts +0 -7
  217. package/lib/engine/id/memory-id-generator.ts +0 -20
  218. package/lib/engine/id/node-id-generator.ts +0 -7
  219. package/lib/engine/logger/logger.ts +0 -11
  220. package/lib/engine/logger/memory-logger.ts +0 -28
  221. package/lib/engine/logger/node-logger.ts +0 -49
  222. package/lib/engine/logger/noop-logger.ts +0 -9
  223. package/lib/engine/mcp/channel-server.ts +0 -204
  224. package/lib/engine/mcp/mcp.ts +0 -126
  225. package/lib/engine/process/memory-process-runner.ts +0 -88
  226. package/lib/engine/process/node-process-runner.ts +0 -91
  227. package/lib/engine/process/process-runner.ts +0 -33
  228. package/lib/engine/profiles/profile-channel-checker.ts +0 -7
  229. package/lib/engine/profiles/profiles.ts +0 -126
  230. package/lib/engine/settings/mock-settings-reader.ts +0 -27
  231. package/lib/engine/settings/settings-reader.ts +0 -6
  232. package/lib/engine/settings/settings-schema.ts +0 -46
  233. package/lib/engine/settings/settings-store.ts +0 -110
  234. package/lib/engine/time/clock.ts +0 -15
  235. package/lib/engine/time/memory-clock.ts +0 -26
  236. package/lib/engine/time/node-clock.ts +0 -7
  237. package/lib/funnel.ts +0 -187
  238. package/lib/gateway/auth-middleware.ts +0 -44
  239. package/lib/gateway/broadcaster.ts +0 -319
  240. package/lib/gateway/daemon.ts +0 -47
  241. package/lib/gateway/factory.ts +0 -10
  242. package/lib/gateway/funnel-event-store.ts +0 -155
  243. package/lib/gateway/gateway-server.ts +0 -414
  244. package/lib/gateway/gateway-token.ts +0 -79
  245. package/lib/gateway/gateway.ts +0 -209
  246. package/lib/gateway/kill-competing-slack-gateways.ts +0 -56
  247. package/lib/gateway/listener-supervisor.ts +0 -339
  248. package/lib/gateway/listeners-client.ts +0 -128
  249. package/lib/gateway/resolve-daemon-script.ts +0 -26
  250. package/lib/gateway/routes/channels.connectors.call.ts +0 -39
  251. package/lib/gateway/routes/health.ts +0 -13
  252. package/lib/gateway/routes/index.ts +0 -24
  253. package/lib/gateway/routes/listeners.list.ts +0 -6
  254. package/lib/gateway/routes/listeners.restart.ts +0 -15
  255. package/lib/gateway/routes/listeners.start.ts +0 -15
  256. package/lib/gateway/routes/listeners.stop.ts +0 -15
  257. package/lib/gateway/routes/route-deps.ts +0 -11
  258. package/lib/gateway/routes/status.ts +0 -15
  259. package/lib/gateway/routes/validator.ts +0 -17
  260. package/lib/index.ts +0 -52
  261. package/lib/logger/leuco-human-file-writer.ts +0 -65
  262. package/lib/logger/leuco-human-logger.ts +0 -98
  263. package/lib/logger/leuco-human-record.ts +0 -16
  264. package/lib/logger/leuco-human-stdout-writer.ts +0 -26
  265. package/lib/logger/leuco-human-writer.ts +0 -14
  266. package/lib/logger/leuco-logger-memory-sink.ts +0 -67
  267. package/lib/logger/leuco-logger-record.ts +0 -13
  268. package/lib/logger/leuco-logger-sink.ts +0 -33
  269. package/lib/logger/leuco-logger-sqlite-sink.ts +0 -355
  270. package/lib/logger/leuco-logger.ts +0 -135
  271. package/lib/tui/app.tsx +0 -357
  272. package/lib/tui/components/add-row.tsx +0 -18
  273. package/lib/tui/components/brand.tsx +0 -27
  274. package/lib/tui/components/card.tsx +0 -44
  275. package/lib/tui/components/detail-bar.tsx +0 -46
  276. package/lib/tui/components/editable-field.tsx +0 -33
  277. package/lib/tui/components/empty-state.tsx +0 -11
  278. package/lib/tui/components/gateway-status.tsx +0 -66
  279. package/lib/tui/components/keymap.tsx +0 -29
  280. package/lib/tui/components/menu-item.tsx +0 -73
  281. package/lib/tui/components/menu.tsx +0 -26
  282. package/lib/tui/components/panel-header.tsx +0 -22
  283. package/lib/tui/components/readonly-field.tsx +0 -18
  284. package/lib/tui/components/section-header.tsx +0 -25
  285. package/lib/tui/components/selection-accent.tsx +0 -32
  286. package/lib/tui/components/session-item.tsx +0 -33
  287. package/lib/tui/components/session-list.tsx +0 -33
  288. package/lib/tui/components/ui/hascii/accordion-item.tsx +0 -88
  289. package/lib/tui/components/ui/hascii/accordion.tsx +0 -96
  290. package/lib/tui/components/ui/hascii/alert-dialog.tsx +0 -43
  291. package/lib/tui/components/ui/hascii/badge.tsx +0 -51
  292. package/lib/tui/components/ui/hascii/breadcrumb.tsx +0 -58
  293. package/lib/tui/components/ui/hascii/button.tsx +0 -194
  294. package/lib/tui/components/ui/hascii/card-content.tsx +0 -14
  295. package/lib/tui/components/ui/hascii/card-description.tsx +0 -13
  296. package/lib/tui/components/ui/hascii/card-footer.tsx +0 -14
  297. package/lib/tui/components/ui/hascii/card-header.tsx +0 -14
  298. package/lib/tui/components/ui/hascii/card-title.tsx +0 -13
  299. package/lib/tui/components/ui/hascii/card.tsx +0 -27
  300. package/lib/tui/components/ui/hascii/checkbox.tsx +0 -65
  301. package/lib/tui/components/ui/hascii/command.tsx +0 -159
  302. package/lib/tui/components/ui/hascii/dialog-content.tsx +0 -14
  303. package/lib/tui/components/ui/hascii/dialog-description.tsx +0 -13
  304. package/lib/tui/components/ui/hascii/dialog-footer.tsx +0 -14
  305. package/lib/tui/components/ui/hascii/dialog-header.tsx +0 -14
  306. package/lib/tui/components/ui/hascii/dialog-title.tsx +0 -13
  307. package/lib/tui/components/ui/hascii/dialog.tsx +0 -27
  308. package/lib/tui/components/ui/hascii/file-tree.tsx +0 -142
  309. package/lib/tui/components/ui/hascii/focus-group.tsx +0 -62
  310. package/lib/tui/components/ui/hascii/form-item.tsx +0 -43
  311. package/lib/tui/components/ui/hascii/input-otp.tsx +0 -86
  312. package/lib/tui/components/ui/hascii/input.tsx +0 -130
  313. package/lib/tui/components/ui/hascii/pagination.tsx +0 -105
  314. package/lib/tui/components/ui/hascii/progress.tsx +0 -28
  315. package/lib/tui/components/ui/hascii/select.tsx +0 -131
  316. package/lib/tui/components/ui/hascii/separator.tsx +0 -35
  317. package/lib/tui/components/ui/hascii/sidebar-content.tsx +0 -23
  318. package/lib/tui/components/ui/hascii/sidebar-header.tsx +0 -14
  319. package/lib/tui/components/ui/hascii/sidebar-menu-item.tsx +0 -67
  320. package/lib/tui/components/ui/hascii/sidebar.tsx +0 -24
  321. package/lib/tui/components/ui/hascii/skeleton.tsx +0 -60
  322. package/lib/tui/components/ui/hascii/slider.tsx +0 -91
  323. package/lib/tui/components/ui/hascii/snackbar.tsx +0 -75
  324. package/lib/tui/components/ui/hascii/sparkline.tsx +0 -53
  325. package/lib/tui/components/ui/hascii/spinner.tsx +0 -47
  326. package/lib/tui/components/ui/hascii/stepper.tsx +0 -54
  327. package/lib/tui/components/ui/hascii/switch.tsx +0 -66
  328. package/lib/tui/components/ui/hascii/table.tsx +0 -95
  329. package/lib/tui/components/ui/hascii/tabs.tsx +0 -59
  330. package/lib/tui/components/ui/hascii/toggle-group-item.tsx +0 -45
  331. package/lib/tui/components/ui/hascii/toggle-group.tsx +0 -99
  332. package/lib/tui/components/ui/hascii/tree.tsx +0 -104
  333. package/lib/tui/components/view-shell.tsx +0 -44
  334. package/lib/tui/filter-input.tsx +0 -33
  335. package/lib/tui/hooks/hascii/use-pressable.ts +0 -54
  336. package/lib/tui/parse-comma-list.ts +0 -14
  337. package/lib/tui/profile-launcher.tsx +0 -61
  338. package/lib/tui/scrollbar-options.ts +0 -19
  339. package/lib/tui/sidebar.tsx +0 -50
  340. package/lib/tui/theme.ts +0 -40
  341. package/lib/tui/tui.tsx +0 -20
  342. package/lib/tui/types.ts +0 -38
  343. package/lib/tui/unique-name.ts +0 -18
  344. package/lib/tui/use-event-stream.ts +0 -133
  345. package/lib/tui/use-snapshot.ts +0 -99
  346. package/lib/tui/utils/hascii/form-item-context.tsx +0 -23
  347. package/lib/tui/utils/hascii/input-focus-context.tsx +0 -31
  348. package/lib/tui/utils/hascii/theme-context.tsx +0 -26
  349. package/lib/tui/utils/hascii/theme.ts +0 -176
  350. package/lib/tui/views/channels-view.tsx +0 -108
  351. package/lib/tui/views/connectors-view.tsx +0 -164
  352. package/lib/tui/views/events-view.tsx +0 -160
  353. package/lib/tui/views/listeners-view.tsx +0 -80
  354. package/lib/tui/views/profiles-view.tsx +0 -152
@@ -1,97 +0,0 @@
1
- export type SlackRawEvent = Record<string, unknown>
2
-
3
- export type SlackProcessedSkip = { skip: true }
4
-
5
- export type SlackProcessedEmit = {
6
- skip: false
7
- content: string
8
- meta: Record<string, string>
9
- shouldReact: boolean
10
- channel: string
11
- timestamp: string
12
- }
13
-
14
- export type SlackProcessed = SlackProcessedSkip | SlackProcessedEmit
15
-
16
- const ALLOWED_EVENTS = new Set(["message", "app_mention"])
17
- const ALLOWED_SUBTYPES = new Set<string | undefined>([
18
- undefined,
19
- "thread_broadcast",
20
- "bot_message",
21
- "file_share",
22
- ])
23
-
24
- const DEDUP_WINDOW = 10_000
25
-
26
- type Props = {
27
- ownBotUserId: string
28
- ownBotId: string
29
- now?: () => number
30
- }
31
-
32
- const getString = (event: SlackRawEvent, key: string): string | undefined => {
33
- const value = event[key]
34
-
35
- return typeof value === "string" ? value : undefined
36
- }
37
-
38
- export class FunnelSlackEventProcessor {
39
- private readonly ownBotUserId: string
40
- private readonly ownBotId: string
41
- private readonly now: () => number
42
- private readonly dedup = new Map<string, number>()
43
-
44
- constructor(props: Props) {
45
- this.ownBotUserId = props.ownBotUserId
46
- this.ownBotId = props.ownBotId
47
- this.now = props.now ?? (() => Date.now())
48
- }
49
-
50
- process(event: SlackRawEvent): SlackProcessed {
51
- const eventType = getString(event, "type")
52
-
53
- if (!eventType || !ALLOWED_EVENTS.has(eventType)) return { skip: true }
54
-
55
- const subtype = getString(event, "subtype")
56
-
57
- if (!ALLOWED_SUBTYPES.has(subtype)) return { skip: true }
58
-
59
- const channelId = getString(event, "channel") ?? ""
60
- const eventTs = getString(event, "event_ts") ?? getString(event, "ts") ?? ""
61
- const dedupKey = `${channelId}:${eventTs}`
62
- const now = this.now()
63
-
64
- if (this.dedup.has(dedupKey)) return { skip: true }
65
-
66
- this.dedup.set(dedupKey, now)
67
-
68
- for (const key of this.dedup.keys()) {
69
- if ((this.dedup.get(key) ?? 0) < now - DEDUP_WINDOW) this.dedup.delete(key)
70
- }
71
-
72
- const userId = getString(event, "user")
73
- const botId = getString(event, "bot_id")
74
-
75
- if (userId === this.ownBotUserId) return { skip: true }
76
- if (botId === this.ownBotId) return { skip: true }
77
-
78
- const text = getString(event, "text") ?? ""
79
- const mentioned = text.includes(`<@${this.ownBotUserId}>`)
80
- const threadTs = getString(event, "thread_ts") ?? getString(event, "ts") ?? ""
81
-
82
- return {
83
- skip: false,
84
- content: JSON.stringify(event),
85
- meta: {
86
- event_type: "slack",
87
- channel_id: channelId,
88
- user_id: userId ?? "",
89
- mentioned: String(mentioned),
90
- thread_ts: threadTs,
91
- },
92
- shouldReact: mentioned,
93
- channel: channelId,
94
- timestamp: getString(event, "ts") ?? "",
95
- }
96
- }
97
- }
@@ -1,97 +0,0 @@
1
- import { App, LogLevel } from "@slack/bolt"
2
- import { z } from "zod"
3
- import { FunnelConnectorListener, type NotifyFn } from "@/connectors/connector-listener"
4
- import { FunnelSlackEventProcessor } from "@/connectors/slack-event-processor"
5
- import { FunnelLogger } from "@/engine/logger/logger"
6
- import { NodeFunnelLogger } from "@/engine/logger/node-logger"
7
- import type { SlackConnectorConfig } from "@/connectors/slack-connector-schema"
8
-
9
- const middlewareArgsSchema = z.object({
10
- event: z.record(z.string(), z.unknown()).optional(),
11
- })
12
-
13
- type Deps = {
14
- config: SlackConnectorConfig
15
- logger?: FunnelLogger
16
- }
17
-
18
- const defaultLogger = new NodeFunnelLogger()
19
-
20
- export class FunnelSlackListener extends FunnelConnectorListener {
21
- private readonly config: SlackConnectorConfig
22
- private readonly logger: FunnelLogger
23
- private app: App | null = null
24
-
25
- constructor(deps: Deps) {
26
- super()
27
- this.config = deps.config
28
- this.logger = deps.logger ?? defaultLogger
29
- }
30
-
31
- async start(notify: NotifyFn): Promise<void> {
32
- const app = new App({
33
- token: this.config.botToken,
34
- appToken: this.config.appToken,
35
- socketMode: true,
36
- logLevel: LogLevel.ERROR,
37
- })
38
-
39
- const authResult = await app.client.auth.test({ token: this.config.botToken })
40
- const processor = new FunnelSlackEventProcessor({
41
- ownBotUserId: authResult.user_id ?? "",
42
- ownBotId: authResult.bot_id ?? "",
43
- })
44
-
45
- app.use(async (args) => {
46
- const parsed = middlewareArgsSchema.safeParse(args)
47
-
48
- if (!parsed.success || !parsed.data.event) return
49
-
50
- const result = processor.process(parsed.data.event)
51
-
52
- if (result.skip) return
53
-
54
- if (result.shouldReact) {
55
- try {
56
- await app.client.reactions.add({
57
- token: this.config.botToken,
58
- channel: result.channel,
59
- timestamp: result.timestamp,
60
- name: "eyes",
61
- })
62
- } catch {
63
- // ignore
64
- }
65
- }
66
-
67
- await notify(result.content, result.meta)
68
- })
69
-
70
- app.error(async (error) => {
71
- this.logger.error("Slack error", {
72
- error: error instanceof Error ? error.message : String(error),
73
- })
74
- })
75
-
76
- await app.start()
77
- this.app = app
78
- }
79
-
80
- async stop(): Promise<void> {
81
- if (!this.app) return
82
-
83
- try {
84
- await this.app.stop()
85
- } catch (error) {
86
- this.logger.error("Slack stop error", {
87
- error: error instanceof Error ? error.message : String(error),
88
- })
89
- } finally {
90
- this.app = null
91
- }
92
- }
93
-
94
- override isAlive(): boolean {
95
- return this.app !== null
96
- }
97
- }
@@ -1,520 +0,0 @@
1
- import type { CallInput } from "@/connectors/connector-adapter"
2
- import type { ConnectorConfig } from "@/connectors/connector-config-schema"
3
- import type { FunnelConnectorFactory } from "@/connectors/connector-factory"
4
- import type { FunnelConnectorListener } from "@/connectors/connector-listener"
5
- import type { DiscordConnectorConfig } from "@/connectors/discord-connector-schema"
6
- import type { GhConnectorConfig } from "@/connectors/gh-connector-schema"
7
- import type { ScheduleConnectorConfig, ScheduleEntry } from "@/connectors/schedule-connector-schema"
8
- import type { SlackConnectorConfig } from "@/connectors/slack-connector-schema"
9
- import type { ProfileChannelChecker } from "@/engine/profiles/profile-channel-checker"
10
- import { FunnelClock } from "@/engine/time/clock"
11
- import { NodeFunnelClock } from "@/engine/time/node-clock"
12
- import { FunnelIdGenerator } from "@/engine/id/id-generator"
13
- import { NodeFunnelIdGenerator } from "@/engine/id/node-id-generator"
14
- import { FunnelSettingsReader } from "@/engine/settings/settings-reader"
15
- import type {
16
- ChannelConfig,
17
- ChannelDeliveryMode,
18
- Settings,
19
- } from "@/engine/settings/settings-schema"
20
-
21
- type Deps = {
22
- store: FunnelSettingsReader
23
- factory: FunnelConnectorFactory
24
- profileChecker: ProfileChannelChecker
25
- clock?: FunnelClock
26
- idGenerator?: FunnelIdGenerator
27
- }
28
-
29
- export type ChannelConnectorView = ConnectorConfig & {
30
- channelId: string
31
- channelName: string
32
- }
33
-
34
- type AddConnectorInput =
35
- | { type: "slack"; name: string; botToken: string; appToken: string }
36
- | { type: "gh"; name: string; pollInterval?: number }
37
- | { type: "discord"; name: string; botToken: string }
38
- | { type: "schedule"; name: string; entries?: ScheduleEntry[] }
39
-
40
- const defaultClock = new NodeFunnelClock()
41
- const defaultIdGenerator = new NodeFunnelIdGenerator()
42
-
43
- /**
44
- * Channels own their connectors. Each channel has a stable id (UUID); the
45
- * `name` is the human-facing label used by the CLI. Connectors live nested
46
- * inside `channel.connectors[]`, so add/remove/rename are channel-scoped — no
47
- * global connector namespace exists. Token uniqueness is enforced across all
48
- * channels at add/update time so the same Slack/Discord credentials cannot
49
- * be registered twice.
50
- */
51
- export class FunnelChannels {
52
- private readonly store: FunnelSettingsReader
53
- private readonly factory: FunnelConnectorFactory
54
- private readonly profileChecker: ProfileChannelChecker
55
- private readonly clock: FunnelClock
56
- private readonly idGenerator: FunnelIdGenerator
57
-
58
- constructor(deps: Deps) {
59
- this.store = deps.store
60
- this.factory = deps.factory
61
- this.profileChecker = deps.profileChecker
62
- this.clock = deps.clock ?? defaultClock
63
- this.idGenerator = deps.idGenerator ?? defaultIdGenerator
64
- Object.freeze(this)
65
- }
66
-
67
- list(): ChannelConfig[] {
68
- return this.store.read().channels
69
- }
70
-
71
- get(name: string): ChannelConfig | null {
72
- return this.list().find((c) => c.name === name) ?? null
73
- }
74
-
75
- getById(id: string): ChannelConfig | null {
76
- return this.list().find((c) => c.id === id) ?? null
77
- }
78
-
79
- add(input: { name: string; delivery?: ChannelDeliveryMode }): ChannelConfig {
80
- const settings = this.store.read()
81
-
82
- if (settings.channels.some((c) => c.name === input.name)) {
83
- throw new Error(`channel "${input.name}" already exists`)
84
- }
85
-
86
- const channel: ChannelConfig = {
87
- id: this.idGenerator.generate(),
88
- name: input.name,
89
- delivery: input.delivery ?? "fanout",
90
- connectors: [],
91
- }
92
-
93
- settings.channels.push(channel)
94
- this.store.write(settings)
95
-
96
- return channel
97
- }
98
-
99
- setDelivery(name: string, delivery: ChannelDeliveryMode): void {
100
- const settings = this.store.read()
101
- const channel = this.requireChannel(settings, name)
102
-
103
- channel.delivery = delivery
104
-
105
- this.store.write(settings)
106
- }
107
-
108
- remove(name: string): void {
109
- const settings = this.store.read()
110
- const index = settings.channels.findIndex((c) => c.name === name)
111
-
112
- if (index < 0) throw new Error(`channel "${name}" not found`)
113
-
114
- const channel = settings.channels[index]
115
-
116
- if (channel && this.profileChecker.hasChannelRef(channel.id)) {
117
- throw new Error(`channel "${name}" is referenced by a profile`)
118
- }
119
-
120
- settings.channels.splice(index, 1)
121
- this.store.write(settings)
122
- }
123
-
124
- rename(oldName: string, newName: string): void {
125
- const settings = this.store.read()
126
- const channel = settings.channels.find((c) => c.name === oldName)
127
-
128
- if (!channel) throw new Error(`channel "${oldName}" not found`)
129
- if (settings.channels.some((c) => c.name === newName)) {
130
- throw new Error(`channel "${newName}" already exists`)
131
- }
132
-
133
- channel.name = newName
134
- this.store.write(settings)
135
- }
136
-
137
- listConnectors(channelName: string): ConnectorConfig[] {
138
- return this.requireChannel(this.store.read(), channelName).connectors
139
- }
140
-
141
- getConnector(channelName: string, connectorName: string): ConnectorConfig | null {
142
- const channel = this.get(channelName)
143
-
144
- if (!channel) return null
145
-
146
- return channel.connectors.find((c) => c.name === connectorName) ?? null
147
- }
148
-
149
- listAllConnectors(): ChannelConnectorView[] {
150
- const out: ChannelConnectorView[] = []
151
-
152
- for (const channel of this.list()) {
153
- for (const connector of channel.connectors) {
154
- out.push({ ...connector, channelId: channel.id, channelName: channel.name })
155
- }
156
- }
157
-
158
- return out
159
- }
160
-
161
- addConnector(channelName: string, input: AddConnectorInput): ConnectorConfig {
162
- const settings = this.store.read()
163
- const channel = this.requireChannel(settings, channelName)
164
-
165
- if (channel.connectors.some((c) => c.name === input.name)) {
166
- throw new Error(`connector "${input.name}" already exists in channel "${channelName}"`)
167
- }
168
-
169
- const candidate = this.fromInput(input)
170
-
171
- this.assertNoTokenCollision(settings, candidate)
172
-
173
- channel.connectors.push(candidate)
174
- this.store.write(settings)
175
-
176
- return candidate
177
- }
178
-
179
- private fromInput(input: AddConnectorInput): ConnectorConfig {
180
- const id = this.idGenerator.generate()
181
- const now = this.clock.iso()
182
- const createdAt = now
183
- const updatedAt = now
184
-
185
- if (input.type === "slack") {
186
- return {
187
- id,
188
- type: "slack",
189
- name: input.name,
190
- botToken: input.botToken,
191
- appToken: input.appToken,
192
- createdAt,
193
- updatedAt,
194
- }
195
- }
196
-
197
- if (input.type === "gh") {
198
- return {
199
- id,
200
- type: "gh",
201
- name: input.name,
202
- ...(input.pollInterval !== undefined ? { pollInterval: input.pollInterval } : {}),
203
- createdAt,
204
- updatedAt,
205
- }
206
- }
207
-
208
- if (input.type === "discord") {
209
- return {
210
- id,
211
- type: "discord",
212
- name: input.name,
213
- botToken: input.botToken,
214
- createdAt,
215
- updatedAt,
216
- }
217
- }
218
-
219
- return {
220
- id,
221
- type: "schedule",
222
- name: input.name,
223
- entries: input.entries ?? [],
224
- createdAt,
225
- updatedAt,
226
- }
227
- }
228
-
229
- removeConnector(channelName: string, connectorName: string): void {
230
- const settings = this.store.read()
231
- const channel = this.requireChannel(settings, channelName)
232
- const index = channel.connectors.findIndex((c) => c.name === connectorName)
233
-
234
- if (index < 0) {
235
- throw new Error(`connector "${connectorName}" not found in channel "${channelName}"`)
236
- }
237
-
238
- channel.connectors.splice(index, 1)
239
- this.store.write(settings)
240
- }
241
-
242
- renameConnector(channelName: string, oldName: string, newName: string): void {
243
- const settings = this.store.read()
244
- const channel = this.requireChannel(settings, channelName)
245
- const connector = channel.connectors.find((c) => c.name === oldName)
246
-
247
- if (!connector) {
248
- throw new Error(`connector "${oldName}" not found in channel "${channelName}"`)
249
- }
250
-
251
- if (channel.connectors.some((c) => c.name === newName)) {
252
- throw new Error(`connector "${newName}" already exists in channel "${channelName}"`)
253
- }
254
-
255
- connector.name = newName
256
- connector.updatedAt = this.clock.iso()
257
- this.store.write(settings)
258
- }
259
-
260
- updateSlackConnector(
261
- channelName: string,
262
- connectorName: string,
263
- fields: { botToken?: string; appToken?: string },
264
- ): void {
265
- const settings = this.store.read()
266
- const channel = this.requireChannel(settings, channelName)
267
- const connector = this.requireSlackConnector(channel, connectorName)
268
-
269
- const updated: SlackConnectorConfig = {
270
- ...connector,
271
- botToken: fields.botToken ?? connector.botToken,
272
- appToken: fields.appToken ?? connector.appToken,
273
- updatedAt: this.clock.iso(),
274
- }
275
-
276
- this.assertNoTokenCollision(settings, updated)
277
-
278
- Object.assign(connector, updated)
279
- this.store.write(settings)
280
- }
281
-
282
- updateGhConnector(
283
- channelName: string,
284
- connectorName: string,
285
- fields: { pollInterval?: number },
286
- ): void {
287
- const settings = this.store.read()
288
- const channel = this.requireChannel(settings, channelName)
289
- const connector = this.requireGhConnector(channel, connectorName)
290
-
291
- if (fields.pollInterval !== undefined) connector.pollInterval = fields.pollInterval
292
- connector.updatedAt = this.clock.iso()
293
-
294
- this.store.write(settings)
295
- }
296
-
297
- updateDiscordConnector(
298
- channelName: string,
299
- connectorName: string,
300
- fields: { botToken?: string },
301
- ): void {
302
- const settings = this.store.read()
303
- const channel = this.requireChannel(settings, channelName)
304
- const connector = this.requireDiscordConnector(channel, connectorName)
305
-
306
- const updated: DiscordConnectorConfig = {
307
- ...connector,
308
- botToken: fields.botToken ?? connector.botToken,
309
- updatedAt: this.clock.iso(),
310
- }
311
-
312
- this.assertNoTokenCollision(settings, updated)
313
-
314
- Object.assign(connector, updated)
315
- this.store.write(settings)
316
- }
317
-
318
- listScheduleEntries(channelName: string, connectorName: string): ScheduleEntry[] {
319
- const channel = this.requireChannel(this.store.read(), channelName)
320
- const connector = this.requireScheduleConnector(channel, connectorName)
321
-
322
- return connector.entries
323
- }
324
-
325
- addScheduleEntry(
326
- channelName: string,
327
- connectorName: string,
328
- entry: Pick<ScheduleEntry, "cron" | "prompt"> &
329
- Partial<Pick<ScheduleEntry, "id" | "enabled" | "catchupPolicy">>,
330
- ): ScheduleEntry {
331
- const settings = this.store.read()
332
- const channel = this.requireChannel(settings, channelName)
333
- const connector = this.requireScheduleConnector(channel, connectorName)
334
-
335
- const persisted: ScheduleEntry = {
336
- id: entry.id ?? this.idGenerator.generate(),
337
- cron: entry.cron,
338
- prompt: entry.prompt,
339
- enabled: entry.enabled ?? true,
340
- catchupPolicy: entry.catchupPolicy ?? "latest",
341
- }
342
-
343
- connector.entries.push(persisted)
344
- connector.updatedAt = this.clock.iso()
345
- this.store.write(settings)
346
-
347
- return persisted
348
- }
349
-
350
- removeScheduleEntry(channelName: string, connectorName: string, id: string): void {
351
- const settings = this.store.read()
352
- const channel = this.requireChannel(settings, channelName)
353
- const connector = this.requireScheduleConnector(channel, connectorName)
354
- const index = connector.entries.findIndex((e) => e.id === id)
355
-
356
- if (index < 0) throw new Error(`schedule entry "${id}" not found`)
357
-
358
- connector.entries.splice(index, 1)
359
- connector.updatedAt = this.clock.iso()
360
- this.store.write(settings)
361
- }
362
-
363
- async call(channelName: string, connectorName: string, input: CallInput): Promise<unknown> {
364
- const connector = this.getConnector(channelName, connectorName)
365
-
366
- if (!connector) {
367
- throw new Error(`connector "${connectorName}" not found in channel "${channelName}"`)
368
- }
369
-
370
- const adapter = this.factory.createAdapter(connector)
371
-
372
- if (!adapter) {
373
- throw new Error(`connector type "${connector.type}" does not support outbound calls`)
374
- }
375
-
376
- return await adapter.call(input)
377
- }
378
-
379
- createListener(
380
- channelName: string,
381
- connectorName: string,
382
- ): { config: ConnectorConfig; channelId: string; listener: FunnelConnectorListener } | null {
383
- const channel = this.get(channelName)
384
-
385
- if (!channel) return null
386
-
387
- const connector = channel.connectors.find((c) => c.name === connectorName)
388
-
389
- if (!connector) return null
390
-
391
- return {
392
- config: connector,
393
- channelId: channel.id,
394
- listener: this.factory.createListener(channel.id, connector),
395
- }
396
- }
397
-
398
- createAllListeners(): {
399
- config: ConnectorConfig
400
- channelId: string
401
- channelName: string
402
- listener: FunnelConnectorListener
403
- }[] {
404
- const out: {
405
- config: ConnectorConfig
406
- channelId: string
407
- channelName: string
408
- listener: FunnelConnectorListener
409
- }[] = []
410
-
411
- for (const channel of this.list()) {
412
- for (const connector of channel.connectors) {
413
- out.push({
414
- config: connector,
415
- channelId: channel.id,
416
- channelName: channel.name,
417
- listener: this.factory.createListener(channel.id, connector),
418
- })
419
- }
420
- }
421
-
422
- return out
423
- }
424
-
425
- private requireChannel(settings: Settings, name: string): ChannelConfig {
426
- const channel = settings.channels.find((c) => c.name === name)
427
-
428
- if (!channel) throw new Error(`channel "${name}" not found`)
429
-
430
- return channel
431
- }
432
-
433
- private requireConnector(channel: ChannelConfig, connectorName: string): ConnectorConfig {
434
- const connector = channel.connectors.find((c) => c.name === connectorName)
435
-
436
- if (!connector) {
437
- throw new Error(`connector "${connectorName}" not found in channel "${channel.name}"`)
438
- }
439
-
440
- return connector
441
- }
442
-
443
- private requireSlackConnector(
444
- channel: ChannelConfig,
445
- connectorName: string,
446
- ): SlackConnectorConfig {
447
- const connector = this.requireConnector(channel, connectorName)
448
-
449
- if (connector.type !== "slack") {
450
- throw new Error(`connector "${connectorName}" is type "${connector.type}", not "slack"`)
451
- }
452
-
453
- return connector
454
- }
455
-
456
- private requireGhConnector(channel: ChannelConfig, connectorName: string): GhConnectorConfig {
457
- const connector = this.requireConnector(channel, connectorName)
458
-
459
- if (connector.type !== "gh") {
460
- throw new Error(`connector "${connectorName}" is type "${connector.type}", not "gh"`)
461
- }
462
-
463
- return connector
464
- }
465
-
466
- private requireDiscordConnector(
467
- channel: ChannelConfig,
468
- connectorName: string,
469
- ): DiscordConnectorConfig {
470
- const connector = this.requireConnector(channel, connectorName)
471
-
472
- if (connector.type !== "discord") {
473
- throw new Error(`connector "${connectorName}" is type "${connector.type}", not "discord"`)
474
- }
475
-
476
- return connector
477
- }
478
-
479
- private requireScheduleConnector(
480
- channel: ChannelConfig,
481
- connectorName: string,
482
- ): ScheduleConnectorConfig {
483
- const connector = this.requireConnector(channel, connectorName)
484
-
485
- if (connector.type !== "schedule") {
486
- throw new Error(`connector "${connectorName}" is type "${connector.type}", not "schedule"`)
487
- }
488
-
489
- return connector
490
- }
491
-
492
- private assertNoTokenCollision(settings: Settings, candidate: ConnectorConfig): void {
493
- const tokens = this.tokensOf(candidate)
494
-
495
- if (tokens.length === 0) return
496
-
497
- for (const channel of settings.channels) {
498
- for (const other of channel.connectors) {
499
- if (other.id === candidate.id) continue
500
-
501
- for (const token of this.tokensOf(other)) {
502
- if (tokens.includes(token)) {
503
- throw new Error(
504
- `token already in use by connector "${other.name}" in channel "${channel.name}"`,
505
- )
506
- }
507
- }
508
- }
509
- }
510
- }
511
-
512
- private tokensOf(connector: ConnectorConfig): string[] {
513
- if (connector.type === "slack") return [connector.botToken, connector.appToken]
514
- if (connector.type === "discord") return [connector.botToken]
515
-
516
- return []
517
- }
518
- }
519
-
520
- export type { ScheduleConnectorConfig }