@interactive-inc/claude-funnel 0.7.1 → 0.8.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 (472) hide show
  1. package/README.md +155 -133
  2. package/dist/bin.js +1344 -0
  3. package/dist/cli/factory.d.ts +7 -0
  4. package/dist/cli/router/query-to-cli-args.d.ts +1 -0
  5. package/dist/cli/router/to-request.d.ts +5 -0
  6. package/dist/cli/router/validator.d.ts +5 -0
  7. package/dist/cli/routes/channels.$channel.connectors.$connector.d.ts +42 -0
  8. package/dist/cli/routes/channels.$channel.connectors.$connector.rename.$newName.d.ts +46 -0
  9. package/dist/cli/routes/channels.$channel.connectors.$connector.request.d.ts +54 -0
  10. package/dist/cli/routes/channels.$channel.connectors.$connector.schedules.add.$id.d.ts +66 -0
  11. package/dist/cli/routes/channels.$channel.connectors.$connector.schedules.d.ts +42 -0
  12. package/dist/cli/routes/channels.$channel.connectors.$connector.schedules.remove.$id.d.ts +46 -0
  13. package/dist/cli/routes/channels.$channel.connectors.add.$connector.d.ts +90 -0
  14. package/dist/cli/routes/channels.$channel.connectors.d.ts +38 -0
  15. package/dist/cli/routes/channels.$channel.connectors.remove.$connector.d.ts +42 -0
  16. package/dist/cli/routes/channels.$channel.connectors.set.$connector.d.ts +62 -0
  17. package/dist/cli/routes/channels.$channel.d.ts +38 -0
  18. package/dist/cli/routes/channels.$channel.rename.$newName.d.ts +42 -0
  19. package/dist/cli/routes/channels.$channel.set.delivery.$mode.d.ts +28 -0
  20. package/dist/cli/routes/channels.add.$channel.d.ts +46 -0
  21. package/dist/cli/routes/channels.d.ts +16 -0
  22. package/dist/cli/routes/channels.remove.$channel.d.ts +38 -0
  23. package/dist/cli/routes/claude.d.ts +32 -0
  24. package/dist/cli/routes/gateway.d.ts +20 -0
  25. package/dist/cli/routes/gateway.listeners.d.ts +17 -0
  26. package/dist/cli/routes/gateway.logs.d.ts +24 -0
  27. package/dist/cli/routes/gateway.restart.d.ts +24 -0
  28. package/dist/cli/routes/gateway.run.d.ts +24 -0
  29. package/dist/cli/routes/gateway.start.d.ts +24 -0
  30. package/dist/cli/routes/gateway.status.d.ts +13 -0
  31. package/dist/cli/routes/gateway.stop.d.ts +16 -0
  32. package/dist/cli/routes/index.d.ts +1222 -0
  33. package/dist/cli/routes/profiles.$profile.as-default.d.ts +38 -0
  34. package/dist/cli/routes/profiles.$profile.rename.$newName.d.ts +42 -0
  35. package/dist/cli/routes/profiles.$profile.run.d.ts +46 -0
  36. package/dist/cli/routes/profiles.add.$profile.d.ts +54 -0
  37. package/dist/cli/routes/profiles.d.ts +16 -0
  38. package/dist/cli/routes/profiles.remove.$profile.d.ts +38 -0
  39. package/dist/cli/routes/profiles.set.$profile.d.ts +54 -0
  40. package/dist/cli/routes/status.d.ts +16 -0
  41. package/dist/cli/routes/update.d.ts +16 -0
  42. package/dist/connectors/connector-adapter.d.ts +8 -0
  43. package/dist/connectors/connector-config-schema.d.ts +43 -0
  44. package/dist/connectors/connector-factory.d.ts +32 -0
  45. package/dist/connectors/connector-listener.d.ts +17 -0
  46. package/dist/connectors/discord-adapter.d.ts +14 -0
  47. package/dist/connectors/discord-connector-schema.d.ts +10 -0
  48. package/dist/connectors/discord-event-processor.d.ts +26 -0
  49. package/dist/connectors/discord-listener.d.ts +17 -0
  50. package/dist/connectors/gh-adapter.d.ts +11 -0
  51. package/dist/connectors/gh-connector-schema.d.ts +10 -0
  52. package/dist/connectors/gh-listener.d.ts +26 -0
  53. package/dist/connectors/match-cron.d.ts +1 -0
  54. package/dist/connectors/schedule-connector-schema.d.ts +45 -0
  55. package/dist/connectors/schedule-listener.d.ts +30 -0
  56. package/dist/connectors/schedule-state-store.d.ts +19 -0
  57. package/dist/connectors/slack-adapter.d.ts +15 -0
  58. package/dist/connectors/slack-connector-schema.d.ts +11 -0
  59. package/dist/connectors/slack-event-processor.d.ts +27 -0
  60. package/dist/connectors/slack-listener.d.ts +17 -0
  61. package/dist/engine/channels/channels.d.ts +106 -0
  62. package/dist/engine/claude/claude.d.ts +49 -0
  63. package/dist/engine/claude/gateway-controller.d.ts +6 -0
  64. package/dist/engine/fs/file-system.d.ts +24 -0
  65. package/dist/engine/fs/memory-file-system.d.ts +31 -0
  66. package/dist/engine/fs/node-file-system.d.ts +15 -0
  67. package/dist/engine/http/http-client.d.ts +15 -0
  68. package/dist/engine/http/memory-http-client.d.ts +12 -0
  69. package/dist/engine/http/node-http-client.d.ts +5 -0
  70. package/dist/engine/id/id-generator.d.ts +7 -0
  71. package/dist/engine/id/memory-id-generator.d.ts +11 -0
  72. package/dist/engine/id/node-id-generator.d.ts +4 -0
  73. package/dist/engine/logger/logger.d.ts +11 -0
  74. package/dist/engine/logger/memory-logger.d.ts +14 -0
  75. package/dist/engine/logger/node-logger.d.ts +15 -0
  76. package/dist/engine/logger/noop-logger.d.ts +7 -0
  77. package/dist/engine/mcp/channel-server.d.ts +1 -0
  78. package/dist/engine/mcp/mcp.d.ts +22 -0
  79. package/dist/engine/process/memory-process-runner.d.ts +43 -0
  80. package/dist/engine/process/node-process-runner.d.ts +9 -0
  81. package/dist/engine/process/process-runner.d.ts +29 -0
  82. package/dist/engine/profiles/profile-channel-checker.d.ts +7 -0
  83. package/dist/engine/profiles/profiles.d.ts +31 -0
  84. package/dist/engine/settings/mock-settings-reader.d.ts +9 -0
  85. package/dist/engine/settings/settings-reader.d.ts +5 -0
  86. package/dist/engine/settings/settings-schema.d.ts +132 -0
  87. package/dist/engine/settings/settings-store.d.ts +18 -0
  88. package/dist/engine/time/clock.d.ts +9 -0
  89. package/dist/engine/time/memory-clock.d.ts +12 -0
  90. package/dist/engine/time/node-clock.d.ts +4 -0
  91. package/dist/funnel.d.ts +95 -0
  92. package/dist/gateway/auth-middleware.d.ts +14 -0
  93. package/dist/gateway/broadcaster.d.ts +122 -0
  94. package/dist/gateway/daemon.d.ts +2 -0
  95. package/dist/gateway/daemon.js +485 -0
  96. package/dist/gateway/factory.d.ts +7 -0
  97. package/dist/gateway/funnel-event-store.d.ts +81 -0
  98. package/dist/gateway/gateway-server.d.ts +94 -0
  99. package/dist/gateway/gateway-token.d.ts +33 -0
  100. package/dist/gateway/gateway.d.ts +58 -0
  101. package/dist/gateway/kill-competing-slack-gateways.d.ts +9 -0
  102. package/dist/gateway/listener-supervisor.d.ts +85 -0
  103. package/dist/gateway/listeners-client.d.ts +53 -0
  104. package/dist/gateway/resolve-daemon-script.d.ts +11 -0
  105. package/dist/gateway/routes/channels.connectors.call.d.ts +41 -0
  106. package/dist/gateway/routes/health.d.ts +17 -0
  107. package/dist/gateway/routes/index.d.ts +209 -0
  108. package/dist/gateway/routes/listeners.list.d.ts +14 -0
  109. package/dist/gateway/routes/listeners.restart.d.ts +34 -0
  110. package/dist/gateway/routes/listeners.start.d.ts +34 -0
  111. package/dist/gateway/routes/listeners.stop.d.ts +34 -0
  112. package/dist/gateway/routes/route-deps.d.ts +10 -0
  113. package/dist/gateway/routes/status.d.ts +30 -0
  114. package/dist/gateway/routes/validator.d.ts +19 -0
  115. package/dist/highlights-eq9cgrbb.scm +604 -0
  116. package/dist/highlights-ghv9g403.scm +205 -0
  117. package/dist/highlights-hk7bwhj4.scm +284 -0
  118. package/dist/highlights-r812a2qc.scm +150 -0
  119. package/dist/highlights-x6tmsnaa.scm +115 -0
  120. package/dist/index.d.ts +36 -0
  121. package/dist/index.js +3575 -0
  122. package/dist/injections-73j83es3.scm +27 -0
  123. package/dist/logger/leuco-human-file-writer.d.ts +33 -0
  124. package/dist/logger/leuco-human-logger.d.ts +46 -0
  125. package/dist/logger/leuco-human-record.d.ts +15 -0
  126. package/dist/logger/leuco-human-stdout-writer.d.ts +20 -0
  127. package/dist/logger/leuco-human-writer.d.ts +13 -0
  128. package/dist/logger/leuco-logger-memory-sink.d.ts +33 -0
  129. package/dist/logger/leuco-logger-record.d.ts +13 -0
  130. package/dist/logger/leuco-logger-sink.d.ts +34 -0
  131. package/dist/logger/leuco-logger-sqlite-sink.d.ts +102 -0
  132. package/dist/logger/leuco-logger.d.ts +56 -0
  133. package/dist/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
  134. package/dist/tree-sitter-markdown-411r6y9b.wasm +0 -0
  135. package/dist/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
  136. package/dist/tree-sitter-typescript-zxjzwt75.wasm +0 -0
  137. package/dist/tree-sitter-zig-e78zbjpm.wasm +0 -0
  138. package/lib/bin.ts +78 -0
  139. package/lib/{modules → cli}/router/to-request.ts +13 -20
  140. package/lib/cli/routes/channels.$channel.connectors.$connector.rename.$newName.ts +27 -0
  141. package/lib/cli/routes/channels.$channel.connectors.$connector.request.ts +40 -0
  142. package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.add.$id.ts +41 -0
  143. package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.remove.$id.ts +22 -0
  144. package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.ts +23 -0
  145. package/lib/cli/routes/channels.$channel.connectors.$connector.ts +26 -0
  146. package/lib/cli/routes/channels.$channel.connectors.add.$connector.ts +92 -0
  147. package/lib/cli/routes/channels.$channel.connectors.remove.$connector.ts +22 -0
  148. package/lib/cli/routes/channels.$channel.connectors.set.$connector.ts +63 -0
  149. package/lib/cli/routes/channels.$channel.connectors.ts +26 -0
  150. package/lib/cli/routes/channels.$channel.rename.$newName.ts +22 -0
  151. package/lib/cli/routes/channels.$channel.set.delivery.$mode.ts +34 -0
  152. package/lib/cli/routes/channels.$channel.ts +34 -0
  153. package/lib/cli/routes/channels.add.$channel.ts +33 -0
  154. package/lib/cli/routes/channels.remove.$channel.ts +20 -0
  155. package/lib/cli/routes/channels.ts +39 -0
  156. package/lib/cli/routes/claude.ts +69 -0
  157. package/lib/cli/routes/gateway.listeners.ts +41 -0
  158. package/lib/cli/routes/gateway.logs.ts +123 -0
  159. package/lib/{routes/gateway/restart.ts → cli/routes/gateway.restart.ts} +20 -5
  160. package/lib/cli/routes/gateway.run.ts +41 -0
  161. package/lib/cli/routes/gateway.start.ts +50 -0
  162. package/lib/cli/routes/gateway.status.ts +19 -0
  163. package/lib/cli/routes/gateway.stop.ts +32 -0
  164. package/lib/cli/routes/gateway.ts +55 -0
  165. package/lib/cli/routes/index.ts +202 -0
  166. package/lib/cli/routes/profiles.$profile.as-default.ts +22 -0
  167. package/lib/cli/routes/profiles.$profile.rename.$newName.ts +22 -0
  168. package/lib/cli/routes/profiles.$profile.run.ts +36 -0
  169. package/lib/cli/routes/profiles.add.$profile.ts +46 -0
  170. package/lib/cli/routes/profiles.remove.$profile.ts +20 -0
  171. package/lib/cli/routes/profiles.set.$profile.ts +46 -0
  172. package/lib/cli/routes/profiles.ts +40 -0
  173. package/lib/cli/routes/status.ts +93 -0
  174. package/lib/cli/routes/update.ts +27 -0
  175. package/lib/connectors/connector-config-schema.ts +16 -0
  176. package/lib/connectors/connector-factory.ts +94 -0
  177. package/lib/connectors/connector-listener.ts +20 -0
  178. package/lib/{modules/connectors/funnel-discord-adapter.ts → connectors/discord-adapter.ts} +6 -11
  179. package/lib/{modules/connectors → connectors}/discord-connector-schema.ts +4 -1
  180. package/lib/connectors/discord-listener.ts +111 -0
  181. package/lib/{modules/connectors/funnel-gh-adapter.ts → connectors/gh-adapter.ts} +3 -6
  182. package/lib/{modules/connectors → connectors}/gh-connector-schema.ts +4 -1
  183. package/lib/{modules/connectors/funnel-gh-listener.ts → connectors/gh-listener.ts} +45 -19
  184. package/lib/{modules/connectors → connectors}/match-cron.ts +10 -4
  185. package/lib/connectors/schedule-connector-schema.ts +33 -0
  186. package/lib/connectors/schedule-listener.ts +207 -0
  187. package/lib/connectors/schedule-state-store.ts +54 -0
  188. package/lib/connectors/slack-adapter.ts +36 -0
  189. package/lib/{modules/connectors → connectors}/slack-connector-schema.ts +4 -1
  190. package/lib/{modules/connectors/funnel-slack-event-processor.ts → connectors/slack-event-processor.ts} +15 -9
  191. package/lib/{modules/connectors/funnel-slack-listener.ts → connectors/slack-listener.ts} +33 -14
  192. package/lib/engine/channels/channels.ts +520 -0
  193. package/lib/{modules/claude/funnel-claude.ts → engine/claude/claude.ts} +28 -55
  194. package/lib/engine/claude/gateway-controller.ts +4 -0
  195. package/lib/{modules/fs/funnel-file-system.ts → engine/fs/file-system.ts} +4 -0
  196. package/lib/{modules/fs/memory-funnel-file-system.ts → engine/fs/memory-file-system.ts} +20 -3
  197. package/lib/{modules/fs/node-funnel-file-system.ts → engine/fs/node-file-system.ts} +14 -2
  198. package/lib/{modules/http/memory-funnel-http-client.ts → engine/http/memory-http-client.ts} +1 -5
  199. package/lib/{modules/http/node-funnel-http-client.ts → engine/http/node-http-client.ts} +1 -5
  200. package/lib/{modules/id/memory-funnel-id-generator.ts → engine/id/memory-id-generator.ts} +1 -1
  201. package/lib/{modules/id/node-funnel-id-generator.ts → engine/id/node-id-generator.ts} +1 -1
  202. package/lib/{modules/logger/memory-funnel-logger.ts → engine/logger/memory-logger.ts} +1 -1
  203. package/lib/{modules/logger/node-funnel-logger.ts → engine/logger/node-logger.ts} +1 -1
  204. package/lib/{modules/logger/noop-funnel-logger.ts → engine/logger/noop-logger.ts} +1 -1
  205. package/lib/engine/mcp/channel-server.ts +204 -0
  206. package/lib/{modules/mcp/funnel-mcp.ts → engine/mcp/mcp.ts} +24 -10
  207. package/lib/{modules/process/memory-funnel-process-runner.ts → engine/process/memory-process-runner.ts} +1 -1
  208. package/lib/{modules/process/node-funnel-process-runner.ts → engine/process/node-process-runner.ts} +12 -21
  209. package/lib/engine/profiles/profile-channel-checker.ts +7 -0
  210. package/lib/{modules/profiles/funnel-profiles.ts → engine/profiles/profiles.ts} +41 -43
  211. package/lib/{modules/settings/mock-funnel-settings-reader.ts → engine/settings/mock-settings-reader.ts} +4 -3
  212. package/lib/{modules/settings/funnel-settings-reader.ts → engine/settings/settings-reader.ts} +1 -1
  213. package/lib/engine/settings/settings-schema.ts +46 -0
  214. package/lib/engine/settings/settings-store.ts +110 -0
  215. package/lib/{modules/time/memory-funnel-clock.ts → engine/time/memory-clock.ts} +1 -1
  216. package/lib/{modules/time/node-funnel-clock.ts → engine/time/node-clock.ts} +1 -1
  217. package/lib/funnel.ts +83 -78
  218. package/lib/gateway/auth-middleware.ts +44 -0
  219. package/lib/gateway/broadcaster.ts +319 -0
  220. package/lib/gateway/daemon.ts +47 -0
  221. package/lib/gateway/factory.ts +10 -0
  222. package/lib/gateway/funnel-event-store.ts +155 -0
  223. package/lib/gateway/gateway-server.ts +414 -0
  224. package/lib/gateway/gateway-token.ts +79 -0
  225. package/lib/{modules/gateway/funnel-gateway.ts → gateway/gateway.ts} +27 -13
  226. package/lib/{modules/gateway → gateway}/kill-competing-slack-gateways.ts +4 -4
  227. package/lib/gateway/listener-supervisor.ts +339 -0
  228. package/lib/gateway/listeners-client.ts +128 -0
  229. package/lib/gateway/resolve-daemon-script.ts +26 -0
  230. package/lib/gateway/routes/channels.connectors.call.ts +39 -0
  231. package/lib/gateway/routes/health.ts +13 -0
  232. package/lib/gateway/routes/index.ts +24 -0
  233. package/lib/gateway/routes/listeners.list.ts +6 -0
  234. package/lib/gateway/routes/listeners.restart.ts +15 -0
  235. package/lib/gateway/routes/listeners.start.ts +15 -0
  236. package/lib/gateway/routes/listeners.stop.ts +15 -0
  237. package/lib/gateway/routes/route-deps.ts +11 -0
  238. package/lib/gateway/routes/status.ts +15 -0
  239. package/lib/gateway/routes/validator.ts +17 -0
  240. package/lib/index.ts +52 -92
  241. package/lib/logger/leuco-human-file-writer.ts +65 -0
  242. package/lib/logger/leuco-human-logger.ts +98 -0
  243. package/lib/logger/leuco-human-record.ts +16 -0
  244. package/lib/logger/leuco-human-stdout-writer.ts +26 -0
  245. package/lib/logger/leuco-human-writer.ts +14 -0
  246. package/lib/logger/leuco-logger-memory-sink.ts +67 -0
  247. package/lib/logger/leuco-logger-record.ts +13 -0
  248. package/lib/logger/leuco-logger-sink.ts +33 -0
  249. package/lib/logger/leuco-logger-sqlite-sink.ts +355 -0
  250. package/lib/logger/leuco-logger.ts +135 -0
  251. package/lib/tui/app.tsx +357 -0
  252. package/lib/tui/components/add-row.tsx +18 -0
  253. package/lib/tui/components/brand.tsx +27 -0
  254. package/lib/tui/components/card.tsx +44 -0
  255. package/lib/tui/components/detail-bar.tsx +46 -0
  256. package/lib/tui/components/editable-field.tsx +33 -0
  257. package/lib/tui/components/empty-state.tsx +11 -0
  258. package/lib/tui/components/gateway-status.tsx +66 -0
  259. package/lib/tui/components/keymap.tsx +29 -0
  260. package/lib/tui/components/menu-item.tsx +73 -0
  261. package/lib/tui/components/menu.tsx +26 -0
  262. package/lib/tui/components/panel-header.tsx +22 -0
  263. package/lib/tui/components/readonly-field.tsx +18 -0
  264. package/lib/tui/components/section-header.tsx +25 -0
  265. package/lib/tui/components/selection-accent.tsx +32 -0
  266. package/lib/tui/components/session-item.tsx +33 -0
  267. package/lib/tui/components/session-list.tsx +33 -0
  268. package/lib/tui/components/ui/hascii/accordion-item.tsx +88 -0
  269. package/lib/tui/components/ui/hascii/accordion.tsx +96 -0
  270. package/lib/tui/components/ui/hascii/alert-dialog.tsx +43 -0
  271. package/lib/tui/components/ui/hascii/badge.tsx +51 -0
  272. package/lib/tui/components/ui/hascii/breadcrumb.tsx +58 -0
  273. package/lib/tui/components/ui/hascii/button.tsx +194 -0
  274. package/lib/tui/components/ui/hascii/card-content.tsx +14 -0
  275. package/lib/tui/components/ui/hascii/card-description.tsx +13 -0
  276. package/lib/tui/components/ui/hascii/card-footer.tsx +14 -0
  277. package/lib/tui/components/ui/hascii/card-header.tsx +14 -0
  278. package/lib/tui/components/ui/hascii/card-title.tsx +13 -0
  279. package/lib/tui/components/ui/hascii/card.tsx +27 -0
  280. package/lib/tui/components/ui/hascii/checkbox.tsx +65 -0
  281. package/lib/tui/components/ui/hascii/command.tsx +159 -0
  282. package/lib/tui/components/ui/hascii/dialog-content.tsx +14 -0
  283. package/lib/tui/components/ui/hascii/dialog-description.tsx +13 -0
  284. package/lib/tui/components/ui/hascii/dialog-footer.tsx +14 -0
  285. package/lib/tui/components/ui/hascii/dialog-header.tsx +14 -0
  286. package/lib/tui/components/ui/hascii/dialog-title.tsx +13 -0
  287. package/lib/tui/components/ui/hascii/dialog.tsx +27 -0
  288. package/lib/tui/components/ui/hascii/file-tree.tsx +142 -0
  289. package/lib/tui/components/ui/hascii/focus-group.tsx +62 -0
  290. package/lib/tui/components/ui/hascii/form-item.tsx +43 -0
  291. package/lib/tui/components/ui/hascii/input-otp.tsx +86 -0
  292. package/lib/tui/components/ui/hascii/input.tsx +130 -0
  293. package/lib/tui/components/ui/hascii/pagination.tsx +105 -0
  294. package/lib/tui/components/ui/hascii/progress.tsx +28 -0
  295. package/lib/tui/components/ui/hascii/select.tsx +131 -0
  296. package/lib/tui/components/ui/hascii/separator.tsx +35 -0
  297. package/lib/tui/components/ui/hascii/sidebar-content.tsx +23 -0
  298. package/lib/tui/components/ui/hascii/sidebar-header.tsx +14 -0
  299. package/lib/tui/components/ui/hascii/sidebar-menu-item.tsx +67 -0
  300. package/lib/tui/components/ui/hascii/sidebar.tsx +24 -0
  301. package/lib/tui/components/ui/hascii/skeleton.tsx +60 -0
  302. package/lib/tui/components/ui/hascii/slider.tsx +91 -0
  303. package/lib/tui/components/ui/hascii/snackbar.tsx +75 -0
  304. package/lib/tui/components/ui/hascii/sparkline.tsx +53 -0
  305. package/lib/tui/components/ui/hascii/spinner.tsx +47 -0
  306. package/lib/tui/components/ui/hascii/stepper.tsx +54 -0
  307. package/lib/tui/components/ui/hascii/switch.tsx +66 -0
  308. package/lib/tui/components/ui/hascii/table.tsx +95 -0
  309. package/lib/tui/components/ui/hascii/tabs.tsx +59 -0
  310. package/lib/tui/components/ui/hascii/toggle-group-item.tsx +45 -0
  311. package/lib/tui/components/ui/hascii/toggle-group.tsx +99 -0
  312. package/lib/tui/components/ui/hascii/tree.tsx +104 -0
  313. package/lib/tui/components/view-shell.tsx +44 -0
  314. package/lib/tui/filter-input.tsx +33 -0
  315. package/lib/tui/hooks/hascii/use-pressable.ts +54 -0
  316. package/lib/tui/parse-comma-list.ts +14 -0
  317. package/lib/tui/profile-launcher.tsx +61 -0
  318. package/lib/tui/scrollbar-options.ts +19 -0
  319. package/lib/tui/sidebar.tsx +50 -0
  320. package/lib/tui/theme.ts +40 -0
  321. package/lib/tui/tui.tsx +20 -0
  322. package/lib/tui/types.ts +38 -0
  323. package/lib/tui/unique-name.ts +18 -0
  324. package/lib/tui/use-event-stream.ts +133 -0
  325. package/lib/tui/use-snapshot.ts +99 -0
  326. package/lib/tui/utils/hascii/form-item-context.tsx +23 -0
  327. package/lib/tui/utils/hascii/input-focus-context.tsx +31 -0
  328. package/lib/tui/utils/hascii/theme-context.tsx +26 -0
  329. package/lib/tui/utils/hascii/theme.ts +176 -0
  330. package/lib/tui/views/channels-view.tsx +108 -0
  331. package/lib/tui/views/connectors-view.tsx +164 -0
  332. package/lib/tui/views/events-view.tsx +160 -0
  333. package/lib/tui/views/listeners-view.tsx +80 -0
  334. package/lib/tui/views/profiles-view.tsx +152 -0
  335. package/package.json +55 -44
  336. package/lib/api.ts +0 -54
  337. package/lib/modules/channels/channel-connector-ref-updater.ts +0 -4
  338. package/lib/modules/channels/funnel-channels.ts +0 -160
  339. package/lib/modules/connectors/connector-config-schema.ts +0 -16
  340. package/lib/modules/connectors/connector-existence-checker.ts +0 -3
  341. package/lib/modules/connectors/funnel-callable-connector-store.ts +0 -9
  342. package/lib/modules/connectors/funnel-connector-listener.ts +0 -5
  343. package/lib/modules/connectors/funnel-connector-stores.ts +0 -52
  344. package/lib/modules/connectors/funnel-connector-type-store.ts +0 -24
  345. package/lib/modules/connectors/funnel-connectors.ts +0 -151
  346. package/lib/modules/connectors/funnel-discord-listener.ts +0 -71
  347. package/lib/modules/connectors/funnel-discord-store.ts +0 -88
  348. package/lib/modules/connectors/funnel-gh-store.ts +0 -101
  349. package/lib/modules/connectors/funnel-json-connector-store.ts +0 -100
  350. package/lib/modules/connectors/funnel-schedule-listener.ts +0 -130
  351. package/lib/modules/connectors/funnel-schedule-store.ts +0 -195
  352. package/lib/modules/connectors/funnel-slack-adapter.ts +0 -31
  353. package/lib/modules/connectors/funnel-slack-store.ts +0 -90
  354. package/lib/modules/connectors/migrate-legacy-connectors.ts +0 -81
  355. package/lib/modules/connectors/schedule-connector-schema.ts +0 -18
  356. package/lib/modules/connectors/schedule-last-fired-store.ts +0 -48
  357. package/lib/modules/gateway/daemon.ts +0 -74
  358. package/lib/modules/gateway/funnel-broadcaster.ts +0 -37
  359. package/lib/modules/gateway/funnel-event-logger.ts +0 -59
  360. package/lib/modules/gateway/funnel-gateway-server.ts +0 -241
  361. package/lib/modules/mcp/channel-server.ts +0 -76
  362. package/lib/modules/profiles/profile-channel-checker.ts +0 -3
  363. package/lib/modules/profiles/profile-channel-ref-updater.ts +0 -3
  364. package/lib/modules/repos/funnel-repositories.ts +0 -112
  365. package/lib/modules/schedule/funnel-schedule.ts +0 -39
  366. package/lib/modules/settings/funnel-settings-store.ts +0 -56
  367. package/lib/modules/settings/settings-schema.ts +0 -33
  368. package/lib/modules/tui/app.tsx +0 -44
  369. package/lib/modules/tui/tui.tsx +0 -13
  370. package/lib/routes/channels/add.help.ts +0 -3
  371. package/lib/routes/channels/add.ts +0 -21
  372. package/lib/routes/channels/connectors-attach.help.ts +0 -3
  373. package/lib/routes/channels/connectors-attach.ts +0 -17
  374. package/lib/routes/channels/connectors-detach.help.ts +0 -3
  375. package/lib/routes/channels/connectors-detach.ts +0 -17
  376. package/lib/routes/channels/group.help.ts +0 -16
  377. package/lib/routes/channels/group.ts +0 -22
  378. package/lib/routes/channels/remove.help.ts +0 -3
  379. package/lib/routes/channels/remove.ts +0 -17
  380. package/lib/routes/channels/rename.help.ts +0 -5
  381. package/lib/routes/channels/rename.ts +0 -17
  382. package/lib/routes/channels/routes.ts +0 -19
  383. package/lib/routes/channels/show.help.ts +0 -1
  384. package/lib/routes/channels/show.ts +0 -26
  385. package/lib/routes/claude/claude.help.ts +0 -16
  386. package/lib/routes/claude/claude.ts +0 -76
  387. package/lib/routes/claude/routes.ts +0 -4
  388. package/lib/routes/connectors/add.help.ts +0 -28
  389. package/lib/routes/connectors/add.ts +0 -64
  390. package/lib/routes/connectors/group.help.ts +0 -14
  391. package/lib/routes/connectors/group.ts +0 -18
  392. package/lib/routes/connectors/remove.help.ts +0 -3
  393. package/lib/routes/connectors/remove.ts +0 -17
  394. package/lib/routes/connectors/rename.help.ts +0 -5
  395. package/lib/routes/connectors/rename.ts +0 -17
  396. package/lib/routes/connectors/routes.ts +0 -23
  397. package/lib/routes/connectors/schedules-add.help.ts +0 -11
  398. package/lib/routes/connectors/schedules-add.ts +0 -33
  399. package/lib/routes/connectors/schedules-group.help.ts +0 -1
  400. package/lib/routes/connectors/schedules-group.ts +0 -38
  401. package/lib/routes/connectors/schedules-remove.help.ts +0 -3
  402. package/lib/routes/connectors/schedules-remove.ts +0 -17
  403. package/lib/routes/connectors/set.help.ts +0 -8
  404. package/lib/routes/connectors/set.ts +0 -72
  405. package/lib/routes/connectors/show.help.ts +0 -1
  406. package/lib/routes/connectors/show.ts +0 -41
  407. package/lib/routes/gateway/group.help.ts +0 -15
  408. package/lib/routes/gateway/group.ts +0 -28
  409. package/lib/routes/gateway/logs.help.ts +0 -13
  410. package/lib/routes/gateway/logs.ts +0 -102
  411. package/lib/routes/gateway/restart.help.ts +0 -10
  412. package/lib/routes/gateway/routes.ts +0 -18
  413. package/lib/routes/gateway/run.help.ts +0 -12
  414. package/lib/routes/gateway/run.ts +0 -35
  415. package/lib/routes/gateway/start.help.ts +0 -15
  416. package/lib/routes/gateway/start.ts +0 -32
  417. package/lib/routes/gateway/status.help.ts +0 -9
  418. package/lib/routes/gateway/status.ts +0 -28
  419. package/lib/routes/gateway/stop.help.ts +0 -8
  420. package/lib/routes/gateway/stop.ts +0 -21
  421. package/lib/routes/profiles/add.help.ts +0 -3
  422. package/lib/routes/profiles/add.ts +0 -33
  423. package/lib/routes/profiles/group.help.ts +0 -16
  424. package/lib/routes/profiles/group.ts +0 -25
  425. package/lib/routes/profiles/launch.help.ts +0 -4
  426. package/lib/routes/profiles/launch.ts +0 -36
  427. package/lib/routes/profiles/remove.help.ts +0 -3
  428. package/lib/routes/profiles/remove.ts +0 -17
  429. package/lib/routes/profiles/rename.help.ts +0 -5
  430. package/lib/routes/profiles/rename.ts +0 -17
  431. package/lib/routes/profiles/routes.ts +0 -18
  432. package/lib/routes/profiles/set.help.ts +0 -5
  433. package/lib/routes/profiles/set.ts +0 -32
  434. package/lib/routes/repos/add.help.ts +0 -6
  435. package/lib/routes/repos/add.ts +0 -20
  436. package/lib/routes/repos/group.help.ts +0 -11
  437. package/lib/routes/repos/group.ts +0 -18
  438. package/lib/routes/repos/remove.help.ts +0 -3
  439. package/lib/routes/repos/remove.ts +0 -17
  440. package/lib/routes/repos/rename.help.ts +0 -5
  441. package/lib/routes/repos/rename.ts +0 -17
  442. package/lib/routes/repos/routes.ts +0 -17
  443. package/lib/routes/repos/set.help.ts +0 -5
  444. package/lib/routes/repos/set.ts +0 -21
  445. package/lib/routes/repos/show.help.ts +0 -1
  446. package/lib/routes/repos/show.ts +0 -19
  447. package/lib/routes/request/discord-help.ts +0 -9
  448. package/lib/routes/request/discord.help.ts +0 -19
  449. package/lib/routes/request/discord.ts +0 -65
  450. package/lib/routes/request/group.help.ts +0 -15
  451. package/lib/routes/request/group.ts +0 -9
  452. package/lib/routes/request/routes.ts +0 -14
  453. package/lib/routes/request/slack-help.ts +0 -9
  454. package/lib/routes/request/slack.help.ts +0 -19
  455. package/lib/routes/request/slack.ts +0 -61
  456. package/lib/routes/status/routes.ts +0 -4
  457. package/lib/routes/status/status.help.ts +0 -6
  458. package/lib/routes/status/status.ts +0 -77
  459. package/lib/routes/update/routes.ts +0 -4
  460. package/lib/routes/update/update.help.ts +0 -5
  461. package/lib/routes/update/update.ts +0 -21
  462. package/lib/routes.ts +0 -40
  463. /package/lib/{factory.ts → cli/factory.ts} +0 -0
  464. /package/lib/{modules → cli}/router/query-to-cli-args.ts +0 -0
  465. /package/lib/{modules → cli}/router/validator.ts +0 -0
  466. /package/lib/{modules/connectors/funnel-connector-adapter.ts → connectors/connector-adapter.ts} +0 -0
  467. /package/lib/{modules/connectors/funnel-discord-event-processor.ts → connectors/discord-event-processor.ts} +0 -0
  468. /package/lib/{modules/http/funnel-http-client.ts → engine/http/http-client.ts} +0 -0
  469. /package/lib/{modules/id/funnel-id-generator.ts → engine/id/id-generator.ts} +0 -0
  470. /package/lib/{modules/logger/funnel-logger.ts → engine/logger/logger.ts} +0 -0
  471. /package/lib/{modules/process/funnel-process-runner.ts → engine/process/process-runner.ts} +0 -0
  472. /package/lib/{modules/time/funnel-clock.ts → engine/time/clock.ts} +0 -0
@@ -1,76 +0,0 @@
1
- import { Server } from "@modelcontextprotocol/sdk/server/index.js"
2
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
3
- import { FUNNEL_MCP_NAME } from "@/modules/mcp/funnel-mcp"
4
-
5
- const GATEWAY_WS_URL = process.env.FUNNEL_GATEWAY_URL ?? "ws://localhost:9742/ws"
6
- const RECONNECT_DELAY = 1000
7
- const MAX_RECONNECT_DELAY = 10000
8
-
9
- export const startChannelServer = async (): Promise<void> => {
10
- const server = new Server(
11
- { name: FUNNEL_MCP_NAME, version: "1.0.0" },
12
- {
13
- capabilities: {
14
- experimental: { "claude/channel": {} },
15
- },
16
- instructions: [
17
- `Events arrive inside <channel source="${FUNNEL_MCP_NAME}"> tags. Use meta.event_type to discriminate.`,
18
- "",
19
- "To reply or act on an event, run `funnel request <platform> --help` via the Bash tool (e.g. `funnel request slack --help`). For general CLI usage, run `funnel --help`.",
20
- ].join("\n"),
21
- },
22
- )
23
-
24
- const transport = new StdioServerTransport()
25
-
26
- await server.connect(transport)
27
-
28
- const channelId = process.env.FUNNEL_CHANNEL_ID
29
-
30
- if (!channelId) return
31
-
32
- const wsUrl = `${GATEWAY_WS_URL}?channel=${encodeURIComponent(channelId)}`
33
- let reconnectDelay = RECONNECT_DELAY
34
-
35
- const connect = () => {
36
- const ws = new WebSocket(wsUrl)
37
-
38
- ws.addEventListener("open", () => {
39
- reconnectDelay = RECONNECT_DELAY
40
- process.stderr.write(`funnel: connected (${wsUrl})\n`)
41
- })
42
-
43
- ws.addEventListener("message", async (event) => {
44
- try {
45
- const payload = JSON.parse(String(event.data))
46
- const eventType = payload.meta?.event_type ?? "unknown"
47
-
48
- process.stderr.write(`funnel: received event (${eventType})\n`)
49
-
50
- await server.notification({
51
- method: "notifications/claude/channel",
52
- params: {
53
- content: payload.content,
54
- meta: payload.meta,
55
- },
56
- })
57
- } catch (error) {
58
- process.stderr.write(
59
- `funnel: error: ${error instanceof Error ? error.message : String(error)}\n`,
60
- )
61
- }
62
- })
63
-
64
- ws.addEventListener("close", () => {
65
- process.stderr.write(`funnel: disconnected, reconnecting in ${reconnectDelay}ms\n`)
66
- setTimeout(connect, reconnectDelay)
67
- reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY)
68
- })
69
-
70
- ws.addEventListener("error", () => {
71
- // close handler will reconnect
72
- })
73
- }
74
-
75
- connect()
76
- }
@@ -1,3 +0,0 @@
1
- export type ProfileChannelChecker = {
2
- hasChannelRef(channelName: string): boolean
3
- }
@@ -1,3 +0,0 @@
1
- export type ProfileChannelRefUpdater = {
2
- renameChannelRef(oldName: string, newName: string): void
3
- }
@@ -1,112 +0,0 @@
1
- import type { FunnelMcp } from "@/modules/mcp/funnel-mcp"
2
- import { FunnelSettingsReader } from "@/modules/settings/funnel-settings-reader"
3
- import type { RepositoryConfig } from "@/modules/settings/settings-schema"
4
-
5
- type Deps = {
6
- store: FunnelSettingsReader
7
- mcp: FunnelMcp
8
- }
9
-
10
- /**
11
- * Repository registry. Each entry has a name + filesystem path; add/remove
12
- * also writes/removes the funnel MCP entry in `<path>/.mcp.json` so Claude Code
13
- * picks it up automatically when launched in that directory.
14
- */
15
- export class FunnelRepositories {
16
- private readonly store: FunnelSettingsReader
17
- private readonly mcp: FunnelMcp
18
-
19
- constructor(deps: Deps) {
20
- this.store = deps.store
21
- this.mcp = deps.mcp
22
- Object.freeze(this)
23
- }
24
-
25
- list(): RepositoryConfig[] {
26
- return this.store.read().repositories
27
- }
28
-
29
- get(name: string): RepositoryConfig | null {
30
- return this.list().find((r) => r.name === name) ?? null
31
- }
32
-
33
- add(config: RepositoryConfig): void {
34
- const settings = this.store.read()
35
-
36
- if (settings.repositories.some((r) => r.name === config.name)) {
37
- throw new Error(`repo "${config.name}" already exists`)
38
- }
39
-
40
- this.mcp.install(config.path)
41
-
42
- settings.repositories.push(config)
43
-
44
- this.store.write(settings)
45
- }
46
-
47
- remove(name: string): void {
48
- const settings = this.store.read()
49
-
50
- const index = settings.repositories.findIndex((r) => r.name === name)
51
-
52
- if (index < 0) throw new Error(`repo "${name}" not found`)
53
-
54
- if (settings.profiles.some((p) => p.repo === name)) {
55
- throw new Error(`repo "${name}" is referenced by a profile`)
56
- }
57
-
58
- const repo = settings.repositories[index]!
59
-
60
- this.mcp.uninstall(repo.path)
61
-
62
- settings.repositories.splice(index, 1)
63
-
64
- this.store.write(settings)
65
- }
66
-
67
- rename(oldName: string, newName: string): void {
68
- const settings = this.store.read()
69
-
70
- const repo = settings.repositories.find((r) => r.name === oldName)
71
-
72
- if (!repo) throw new Error(`repo "${oldName}" not found`)
73
-
74
- if (settings.repositories.some((r) => r.name === newName)) {
75
- throw new Error(`repo "${newName}" already exists`)
76
- }
77
-
78
- repo.name = newName
79
-
80
- for (const profile of settings.profiles) {
81
- if (profile.repo === oldName) profile.repo = newName
82
- }
83
-
84
- this.store.write(settings)
85
- }
86
-
87
- update(name: string, fields: Partial<Pick<RepositoryConfig, "path">>): void {
88
- const settings = this.store.read()
89
-
90
- const repo = settings.repositories.find((r) => r.name === name)
91
-
92
- if (!repo) throw new Error(`repo "${name}" not found`)
93
-
94
- if (fields.path !== undefined && fields.path !== repo.path) {
95
- this.mcp.uninstall(repo.path)
96
-
97
- this.mcp.install(fields.path)
98
-
99
- repo.path = fields.path
100
- }
101
-
102
- this.store.write(settings)
103
- }
104
-
105
- resolvePath(name: string): string {
106
- const repo = this.get(name)
107
-
108
- if (!repo) throw new Error(`repo "${name}" not found`)
109
-
110
- return repo.path
111
- }
112
- }
@@ -1,39 +0,0 @@
1
- import type { FunnelScheduleStore } from "@/modules/connectors/funnel-schedule-store"
2
- import type { ScheduleEntry } from "@/modules/connectors/schedule-connector-schema"
3
-
4
- type Deps = {
5
- store: FunnelScheduleStore
6
- }
7
-
8
- /**
9
- * Cron entry CRUD for a schedule connector. The schedule connector itself
10
- * is created via `connectors.add({ type: "schedule", ... })`; this class
11
- * manages the JSONL entries inside it.
12
- */
13
- export class FunnelSchedule {
14
- private readonly store: FunnelScheduleStore
15
-
16
- constructor(deps: Deps) {
17
- this.store = deps.store
18
- Object.freeze(this)
19
- }
20
-
21
- listEntries(connector: string): ScheduleEntry[] {
22
- const config = this.store.get(connector)
23
-
24
- if (!config) throw new Error(`connector "${connector}" not found`)
25
-
26
- return config.entries
27
- }
28
-
29
- addEntry(
30
- connector: string,
31
- entry: Omit<ScheduleEntry, "id"> & { id?: string },
32
- ): ScheduleEntry {
33
- return this.store.addEntry(connector, entry)
34
- }
35
-
36
- removeEntry(connector: string, id: string): void {
37
- this.store.removeEntry(connector, id)
38
- }
39
- }
@@ -1,56 +0,0 @@
1
- import { homedir } from "node:os"
2
- import { dirname, join } from "node:path"
3
- import { FunnelFileSystem } from "@/modules/fs/funnel-file-system"
4
- import { NodeFunnelFileSystem } from "@/modules/fs/node-funnel-file-system"
5
- import { FunnelSettingsReader } from "@/modules/settings/funnel-settings-reader"
6
- import { settingsSchema } from "@/modules/settings/settings-schema"
7
- import type { Settings } from "@/modules/settings/settings-schema"
8
-
9
- export const FUNNEL_DIR = join(homedir(), ".funnel")
10
- export const SETTINGS_PATH = join(FUNNEL_DIR, "settings.json")
11
-
12
- type Deps = {
13
- path?: string
14
- fs?: FunnelFileSystem
15
- }
16
-
17
- const defaultFs = new NodeFunnelFileSystem()
18
-
19
- export class FunnelSettingsStore extends FunnelSettingsReader {
20
- private readonly path: string
21
- private readonly fs: FunnelFileSystem
22
-
23
- constructor(deps: Deps = {}) {
24
- super()
25
- this.path = deps.path ?? SETTINGS_PATH
26
- this.fs = deps.fs ?? defaultFs
27
- Object.freeze(this)
28
- }
29
-
30
- read(): Settings {
31
- if (!this.fs.existsSync(this.path)) {
32
- return {
33
- channels: [],
34
- repositories: [],
35
- profiles: [],
36
- }
37
- }
38
-
39
- const content = this.fs.readFileSync(this.path)
40
- const parsed = JSON.parse(content)
41
- const result = settingsSchema.safeParse(parsed)
42
-
43
- if (!result.success) {
44
- throw new Error(
45
- `invalid settings.json (${this.path}): ${result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ")}`,
46
- )
47
- }
48
-
49
- return result.data
50
- }
51
-
52
- write(settings: Settings): void {
53
- this.fs.mkdirSync(dirname(this.path), { recursive: true })
54
- this.fs.writeFileSync(this.path, `${JSON.stringify(settings, null, 2)}\n`)
55
- }
56
- }
@@ -1,33 +0,0 @@
1
- import { z } from "zod"
2
-
3
- export const channelConfigSchema = z.object({
4
- name: z.string(),
5
- connectors: z.array(z.string()).default([]),
6
- })
7
-
8
- export type ChannelConfig = z.infer<typeof channelConfigSchema>
9
-
10
- export const repositoryConfigSchema = z.object({
11
- name: z.string(),
12
- path: z.string(),
13
- })
14
-
15
- export type RepositoryConfig = z.infer<typeof repositoryConfigSchema>
16
-
17
- export const profileConfigSchema = z.object({
18
- name: z.string(),
19
- channel: z.string(),
20
- repo: z.string().optional(),
21
- subAgent: z.string().optional(),
22
- envFiles: z.array(z.string()).optional(),
23
- })
24
-
25
- export type ProfileConfig = z.infer<typeof profileConfigSchema>
26
-
27
- export const settingsSchema = z.object({
28
- channels: z.array(channelConfigSchema).default([]),
29
- repositories: z.array(repositoryConfigSchema).default([]),
30
- profiles: z.array(profileConfigSchema).default([]),
31
- })
32
-
33
- export type Settings = z.infer<typeof settingsSchema>
@@ -1,44 +0,0 @@
1
- import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/react"
2
-
3
- const zinc = {
4
- 50: "#fafafa",
5
- 600: "#52525b",
6
- 950: "#09090b",
7
- } as const
8
-
9
- const LABEL = "funnel"
10
-
11
- export function App() {
12
- const renderer = useRenderer()
13
-
14
- const dimensions = useTerminalDimensions()
15
-
16
- useKeyboard((key) => {
17
- if (key.name === "q" || key.name === "escape" || (key.ctrl && key.name === "c")) {
18
- renderer.destroy()
19
- }
20
- })
21
-
22
- const marginLeft = Math.max(0, Math.floor((dimensions.width - LABEL.length) / 2))
23
-
24
- const marginTop = Math.max(0, Math.floor(dimensions.height / 2) - 1)
25
-
26
- return (
27
- <box
28
- style={{
29
- width: "100%",
30
- height: "100%",
31
- flexDirection: "column",
32
- backgroundColor: zinc[950],
33
- }}
34
- >
35
- <box style={{ height: marginTop, backgroundColor: zinc[950] }} />
36
- <text fg={zinc[50]} bg={zinc[950]} style={{ marginLeft }}>
37
- {LABEL}
38
- </text>
39
- <text fg={zinc[600]} bg={zinc[950]} position="absolute" bottom={0}>
40
- press q to quit
41
- </text>
42
- </box>
43
- )
44
- }
@@ -1,13 +0,0 @@
1
- import { createCliRenderer } from "@opentui/core"
2
- import { createRoot } from "@opentui/react"
3
- import { App } from "@/modules/tui/app"
4
-
5
- export async function launchTui(): Promise<void> {
6
- const renderer = await createCliRenderer()
7
-
8
- createRoot(renderer).render(<App />)
9
-
10
- await new Promise<void>((resolve) => {
11
- renderer.once("destroy", () => resolve())
12
- })
13
- }
@@ -1,3 +0,0 @@
1
- export const help = `funnel channels add — add a channel
2
-
3
- usage: funnel channels add <name> [--connector <c>]...`
@@ -1,21 +0,0 @@
1
- import { z } from "zod"
2
- import { factory } from "@/factory"
3
- import { zValidator } from "@/modules/router/validator"
4
- import { help } from "@/routes/channels/add.help"
5
-
6
- export const channelsAddHandler = factory.createHandlers(
7
- zValidator("param", z.object({ name: z.string() })),
8
- zValidator("query", z.object({ connector: z.string().optional() }), help),
9
- (c) => {
10
- const param = c.req.valid("param")
11
- const query = c.req.valid("query")
12
- const funnel = c.var.funnel
13
-
14
- funnel.channels.add({
15
- name: param.name,
16
- connectors: query.connector ? [query.connector] : [],
17
- })
18
-
19
- return c.text(`added channel "${param.name}"`)
20
- },
21
- )
@@ -1,3 +0,0 @@
1
- export const help = `funnel channels <name> connectors attach — subscribe to a connector
2
-
3
- usage: funnel channels <name> connectors attach <connector>`
@@ -1,17 +0,0 @@
1
- import { z } from "zod"
2
- import { factory } from "@/factory"
3
- import { zValidator } from "@/modules/router/validator"
4
- import { help } from "@/routes/channels/connectors-attach.help"
5
-
6
- export const channelsConnectorsAttachHandler = factory.createHandlers(
7
- zValidator("param", z.object({ name: z.string(), connector: z.string() })),
8
- zValidator("query", z.object({}), help),
9
- (c) => {
10
- const param = c.req.valid("param")
11
- const funnel = c.var.funnel
12
-
13
- funnel.channels.attachConnector(param.name, param.connector)
14
-
15
- return c.text(`attached connector "${param.connector}" to channel "${param.name}"`)
16
- },
17
- )
@@ -1,3 +0,0 @@
1
- export const help = `funnel channels <name> connectors detach — unsubscribe from a connector
2
-
3
- usage: funnel channels <name> connectors detach <connector>`
@@ -1,17 +0,0 @@
1
- import { z } from "zod"
2
- import { factory } from "@/factory"
3
- import { zValidator } from "@/modules/router/validator"
4
- import { help } from "@/routes/channels/connectors-detach.help"
5
-
6
- export const channelsConnectorsDetachHandler = factory.createHandlers(
7
- zValidator("param", z.object({ name: z.string(), connector: z.string() })),
8
- zValidator("query", z.object({}), help),
9
- (c) => {
10
- const param = c.req.valid("param")
11
- const funnel = c.var.funnel
12
-
13
- funnel.channels.detachConnector(param.name, param.connector)
14
-
15
- return c.text(`detached connector "${param.connector}" from channel "${param.name}"`)
16
- },
17
- )
@@ -1,16 +0,0 @@
1
- export const help = `funnel channels — manage subscription boxes
2
-
3
- usage: funnel channels [subcommand]
4
-
5
- subcommands:
6
- (none) list
7
- add <name> add
8
- remove <name> remove
9
- <name> show details
10
- <name> connectors attach <c> subscribe to a connector
11
- <name> connectors detach <c> unsubscribe from a connector
12
-
13
- examples:
14
- funnel channels add prod-inbox
15
- funnel channels prod-inbox connectors attach prod-slack
16
- funnel channels prod-inbox`
@@ -1,22 +0,0 @@
1
- import { z } from "zod"
2
- import { factory } from "@/factory"
3
- import { zValidator } from "@/modules/router/validator"
4
- import { help } from "@/routes/channels/group.help"
5
-
6
- export const channelsGroupHandler = factory.createHandlers(
7
- zValidator("query", z.object({}), help),
8
- (c) => {
9
- const funnel = c.var.funnel
10
- const channels = funnel.channels.list()
11
-
12
- if (channels.length === 0) return c.text("no channels")
13
-
14
- const lines = channels.map((ch) => {
15
- const connectors = ch.connectors.length > 0 ? ch.connectors.join(", ") : "(none)"
16
-
17
- return `${ch.name} [${connectors}]`
18
- })
19
-
20
- return c.text(lines.join("\n"))
21
- },
22
- )
@@ -1,3 +0,0 @@
1
- export const help = `funnel channels remove — remove a channel
2
-
3
- usage: funnel channels remove <name>`
@@ -1,17 +0,0 @@
1
- import { z } from "zod"
2
- import { factory } from "@/factory"
3
- import { zValidator } from "@/modules/router/validator"
4
- import { help } from "@/routes/channels/remove.help"
5
-
6
- export const channelsRemoveHandler = factory.createHandlers(
7
- zValidator("param", z.object({ name: z.string() })),
8
- zValidator("query", z.object({}), help),
9
- (c) => {
10
- const param = c.req.valid("param")
11
- const funnel = c.var.funnel
12
-
13
- funnel.channels.remove(param.name)
14
-
15
- return c.text(`removed channel "${param.name}"`)
16
- },
17
- )
@@ -1,5 +0,0 @@
1
- export const help = `funnel channels rename — rename a channel
2
-
3
- usage:
4
- funnel channels rename <old> <new>
5
- funnel channels <old> rename <new>`
@@ -1,17 +0,0 @@
1
- import { z } from "zod"
2
- import { factory } from "@/factory"
3
- import { zValidator } from "@/modules/router/validator"
4
- import { help } from "@/routes/channels/rename.help"
5
-
6
- export const channelsRenameHandler = factory.createHandlers(
7
- zValidator("param", z.object({ name: z.string(), newName: z.string() })),
8
- zValidator("query", z.object({}), help),
9
- (c) => {
10
- const param = c.req.valid("param")
11
- const funnel = c.var.funnel
12
-
13
- funnel.channels.rename(param.name, param["newName"])
14
-
15
- return c.text(`renamed channel "${param.name}" to "${param["newName"]}"`)
16
- },
17
- )
@@ -1,19 +0,0 @@
1
- import { factory } from "@/factory"
2
- import { channelsAddHandler } from "@/routes/channels/add"
3
- import { channelsConnectorsAttachHandler } from "@/routes/channels/connectors-attach"
4
- import { channelsConnectorsDetachHandler } from "@/routes/channels/connectors-detach"
5
- import { channelsGroupHandler } from "@/routes/channels/group"
6
- import { channelsRemoveHandler } from "@/routes/channels/remove"
7
- import { channelsRenameHandler } from "@/routes/channels/rename"
8
- import { channelsShowHandler } from "@/routes/channels/show"
9
-
10
- export const channelsRoutes = factory
11
- .createApp()
12
- .get("/", ...channelsGroupHandler)
13
- .put("/:name/rename/:newName", ...channelsRenameHandler)
14
- .put("/rename/:name/:newName", ...channelsRenameHandler)
15
- .put("/:name/connectors/attach/:connector", ...channelsConnectorsAttachHandler)
16
- .delete("/:name/connectors/detach/:connector", ...channelsConnectorsDetachHandler)
17
- .post("/:name", ...channelsAddHandler)
18
- .delete("/:name", ...channelsRemoveHandler)
19
- .get("/:name", ...channelsShowHandler)
@@ -1 +0,0 @@
1
- export const help = `funnel channels <name> — show channel details`
@@ -1,26 +0,0 @@
1
- import { HTTPException } from "hono/http-exception"
2
- import { z } from "zod"
3
- import { factory } from "@/factory"
4
- import { zValidator } from "@/modules/router/validator"
5
- import { help } from "@/routes/channels/show.help"
6
-
7
- export const channelsShowHandler = factory.createHandlers(
8
- zValidator("param", z.object({ name: z.string() })),
9
- zValidator("query", z.object({}), help),
10
- (c) => {
11
- const param = c.req.valid("param")
12
- const funnel = c.var.funnel
13
- const channel = funnel.channels.get(param.name)
14
-
15
- if (!channel) {
16
- throw new HTTPException(404, { message: `channel "${param.name}" not found` })
17
- }
18
-
19
- const lines = [
20
- `name: ${channel.name}`,
21
- `connectors: ${channel.connectors.length > 0 ? channel.connectors.join(", ") : "(none)"}`,
22
- ]
23
-
24
- return c.text(lines.join("\n"))
25
- },
26
- )
@@ -1,16 +0,0 @@
1
- export const help = `funnel claude — launch Claude Code
2
-
3
- usage:
4
- funnel claude launch "default" profile (or the first profile)
5
- funnel claude --profile <name> launch a named profile
6
- funnel claude --channel <name> [opts] raw launch (no profile)
7
-
8
- options (override profile / raw):
9
- --profile profile name to launch
10
- --channel channel name to subscribe to
11
- --repo switch working directory to the named repo
12
- --sub-agent sub-agent name (passed to claude --agent)
13
- --env-file additional env file to load (relative path)
14
-
15
- Any other arguments are forwarded to the claude CLI.
16
- On launch the FUNNEL_CHANNEL_ID env var is set and MCP connects to the gateway.`