@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,6 +0,0 @@
1
- import type { Settings } from "@/engine/settings/settings-schema"
2
-
3
- export abstract class FunnelSettingsReader {
4
- abstract read(): Settings
5
- abstract write(settings: Settings): void
6
- }
@@ -1,46 +0,0 @@
1
- import { z } from "zod"
2
- import { connectorConfigSchema } from "@/connectors/connector-config-schema"
3
-
4
- /**
5
- * Routing mode when multiple WS clients are subscribed to the same channel.
6
- *
7
- * - `fanout` (default): every connected client receives every event. Right when each
8
- * subscriber has its own job (e.g., TUI mirrors, distinct Claude profiles each running
9
- * their own pipeline against the same source).
10
- * - `exclusive`: each event is delivered to exactly one connected client, picked
11
- * round-robin per channel. Right when subscribers are interchangeable workers and you
12
- * want each event handled once. Tap=all clients (TUI dashboard) always receive,
13
- * regardless of mode, so they can passively observe.
14
- */
15
- export const channelDeliveryModeSchema = z.enum(["fanout", "exclusive"])
16
-
17
- export type ChannelDeliveryMode = z.infer<typeof channelDeliveryModeSchema>
18
-
19
- export const channelConfigSchema = z.object({
20
- id: z.string(),
21
- name: z.string(),
22
- delivery: channelDeliveryModeSchema.default("fanout"),
23
- connectors: z.array(connectorConfigSchema).default([]),
24
- })
25
-
26
- export type ChannelConfig = z.infer<typeof channelConfigSchema>
27
-
28
- export const profileConfigSchema = z.object({
29
- name: z.string(),
30
- path: z.string(),
31
- subAgent: z.string(),
32
- channelId: z.string(),
33
- })
34
-
35
- export type ProfileConfig = z.infer<typeof profileConfigSchema>
36
-
37
- export const SETTINGS_VERSION = 1
38
-
39
- export const settingsSchema = z.object({
40
- /** Schema version. New files always write the current version; older files without one are read as v1. */
41
- version: z.literal(SETTINGS_VERSION).default(SETTINGS_VERSION),
42
- channels: z.array(channelConfigSchema).default([]),
43
- profiles: z.array(profileConfigSchema).default([]),
44
- })
45
-
46
- export type Settings = z.infer<typeof settingsSchema>
@@ -1,110 +0,0 @@
1
- import { homedir } from "node:os"
2
- import { dirname, join } from "node:path"
3
- import { FunnelFileSystem } from "@/engine/fs/file-system"
4
- import { NodeFunnelFileSystem } from "@/engine/fs/node-file-system"
5
- import { FunnelSettingsReader } from "@/engine/settings/settings-reader"
6
- import { SETTINGS_VERSION, settingsSchema } from "@/engine/settings/settings-schema"
7
- import type { Settings } from "@/engine/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
- version: SETTINGS_VERSION,
34
- channels: [],
35
- profiles: [],
36
- }
37
- }
38
-
39
- const content = this.fs.readFileSync(this.path)
40
- const parsed: unknown = JSON.parse(content)
41
-
42
- if (this.looksLikeLegacy(parsed)) {
43
- throw new Error(
44
- `legacy settings.json detected at ${this.path}. The schema changed (channel.connectors are now nested objects with ids; profile fields renamed). Migration is intentionally not provided. Back up and remove the old file:\n mv ${this.path} ${this.path}.bak`,
45
- )
46
- }
47
-
48
- if (
49
- parsed &&
50
- typeof parsed === "object" &&
51
- "version" in parsed &&
52
- parsed.version !== SETTINGS_VERSION
53
- ) {
54
- throw new Error(
55
- `unsupported settings.json version (${this.path}): expected ${SETTINGS_VERSION}, got ${String(parsed.version)}`,
56
- )
57
- }
58
-
59
- const result = settingsSchema.safeParse(parsed)
60
-
61
- if (!result.success) {
62
- throw new Error(
63
- `invalid settings.json (${this.path}): ${result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ")}`,
64
- )
65
- }
66
-
67
- return result.data
68
- }
69
-
70
- private looksLikeLegacy(parsed: unknown): boolean {
71
- if (!parsed || typeof parsed !== "object") return false
72
-
73
- const obj = parsed as Record<string, unknown>
74
-
75
- if (Array.isArray(obj.channels)) {
76
- for (const channel of obj.channels) {
77
- if (!channel || typeof channel !== "object") continue
78
- const ch = channel as Record<string, unknown>
79
-
80
- if (Array.isArray(ch.connectors) && ch.connectors.some((x) => typeof x === "string")) {
81
- return true
82
- }
83
-
84
- if (!("id" in ch) && "name" in ch) return true
85
- }
86
- }
87
-
88
- if (Array.isArray(obj.connectors)) return true
89
- if (Array.isArray(obj.repositories)) return true
90
-
91
- if (Array.isArray(obj.profiles)) {
92
- for (const profile of obj.profiles) {
93
- if (!profile || typeof profile !== "object") continue
94
- const p = profile as Record<string, unknown>
95
-
96
- if ("repository" in p || "envFiles" in p || ("channel" in p && !("channelId" in p))) {
97
- return true
98
- }
99
- }
100
- }
101
-
102
- return false
103
- }
104
-
105
- write(settings: Settings): void {
106
- this.fs.mkdirSync(dirname(this.path), { recursive: true })
107
- const versioned: Settings = { ...settings, version: SETTINGS_VERSION }
108
- this.fs.writeFileSync(this.path, `${JSON.stringify(versioned, null, 2)}\n`)
109
- }
110
- }
@@ -1,15 +0,0 @@
1
- /**
2
- * Time boundary. Default NodeFunnelClock returns `new Date()`; MemoryFunnelClock
3
- * is settable and `advance(ms)`-able for deterministic schedule / timeout tests.
4
- */
5
- export abstract class FunnelClock {
6
- abstract now(): Date
7
-
8
- millis(): number {
9
- return this.now().getTime()
10
- }
11
-
12
- iso(): string {
13
- return this.now().toISOString()
14
- }
15
- }
@@ -1,26 +0,0 @@
1
- import { FunnelClock } from "@/engine/time/clock"
2
-
3
- type Props = {
4
- start?: Date
5
- }
6
-
7
- export class MemoryFunnelClock extends FunnelClock {
8
- private current: Date
9
-
10
- constructor(props: Props = {}) {
11
- super()
12
- this.current = props.start ?? new Date(0)
13
- }
14
-
15
- now(): Date {
16
- return new Date(this.current.getTime())
17
- }
18
-
19
- set(date: Date): void {
20
- this.current = date
21
- }
22
-
23
- advance(ms: number): void {
24
- this.current = new Date(this.current.getTime() + ms)
25
- }
26
- }
@@ -1,7 +0,0 @@
1
- import { FunnelClock } from "@/engine/time/clock"
2
-
3
- export class NodeFunnelClock extends FunnelClock {
4
- now(): Date {
5
- return new Date()
6
- }
7
- }
package/lib/funnel.ts DELETED
@@ -1,187 +0,0 @@
1
- import { join } from "node:path"
2
- import { FunnelConnectorFactory } from "@/connectors/connector-factory"
3
- import { FunnelChannels } from "@/engine/channels/channels"
4
- import { FunnelClaude } from "@/engine/claude/claude"
5
- import type { FunnelFileSystem } from "@/engine/fs/file-system"
6
- import type { FunnelIdGenerator } from "@/engine/id/id-generator"
7
- import { FunnelLogger } from "@/engine/logger/logger"
8
- import { NodeFunnelLogger } from "@/engine/logger/node-logger"
9
- import { FunnelMcp } from "@/engine/mcp/mcp"
10
- import { FunnelProcessRunner } from "@/engine/process/process-runner"
11
- import { NodeFunnelProcessRunner } from "@/engine/process/node-process-runner"
12
- import { FunnelProfiles } from "@/engine/profiles/profiles"
13
- import { FunnelSettingsReader } from "@/engine/settings/settings-reader"
14
- import { FUNNEL_DIR, FunnelSettingsStore } from "@/engine/settings/settings-store"
15
- import type { FunnelClock } from "@/engine/time/clock"
16
- import { FunnelGateway } from "@/gateway/gateway"
17
- import { FunnelGatewayServer } from "@/gateway/gateway-server"
18
- import { FunnelGatewayToken } from "@/gateway/gateway-token"
19
- import { FunnelListenersClient } from "@/gateway/listeners-client"
20
-
21
- type Props = {
22
- /** Settings persistence (channels with nested connectors / profiles). Defaults to a FunnelSettingsStore rooted at `dir`. */
23
- store?: FunnelSettingsReader
24
- /** Filesystem boundary. Replace with MemoryFunnelFileSystem to sandbox all disk I/O. */
25
- fs?: FunnelFileSystem
26
- /** Process runner used by gateway / claude / gh listener. Replace with MemoryFunnelProcessRunner for tests. */
27
- process?: FunnelProcessRunner
28
- /** Logger flowed into every facet. Replace with MemoryFunnelLogger or NoopFunnelLogger to silence/inspect. */
29
- logger?: FunnelLogger
30
- /** Clock used by schedule listener, gh poll watermarks, and gateway timeouts. */
31
- clock?: FunnelClock
32
- /** ID generator for channel and connector ids. Use MemoryFunnelIdGenerator for deterministic tests. */
33
- idGenerator?: FunnelIdGenerator
34
- /** Funnel home directory (settings.json + per-channel/per-connector dirs). Defaults to ~/.funnel. */
35
- dir?: string
36
- /** Temp / runtime directory (gateway logs and PID adjacent files). Defaults to /tmp/funnel. */
37
- tmpDir?: string
38
- }
39
-
40
- /**
41
- * Facade exposing every funnel facet as a getter.
42
- *
43
- * The same `Funnel` is used by the CLI, the TUI, and as a programmable library.
44
- * All side-effecting boundaries (filesystem, process, logger, clock, id, paths) are
45
- * injectable via `Props` — passing memory implementations gives a fully sandboxed
46
- * Funnel that touches no real disk, processes, or wall-clock time.
47
- *
48
- * Connectors live nested inside their owning channel (channels[].connectors[]),
49
- * so connector CRUD is reached via `funnel.channels.addConnector(...)` etc.
50
- *
51
- * @example
52
- * ```ts
53
- * const funnel = new Funnel({})
54
- * const channel = funnel.channels.add({ name: "inbox" })
55
- * funnel.channels.addConnector("inbox", { type: "slack", name: "ops", botToken, appToken })
56
- * await funnel.gatewayServer({ port: 9742 }).start()
57
- * ```
58
- */
59
- export class Funnel {
60
- constructor(private readonly props: Props = {}) {
61
- Object.freeze(this)
62
- }
63
-
64
- /** Settings reader. If not injected, a FunnelSettingsStore rooted at `dir` is created. */
65
- get store(): FunnelSettingsReader {
66
- return (
67
- this.props.store ??
68
- new FunnelSettingsStore({
69
- path: join(this.props.dir ?? FUNNEL_DIR, "settings.json"),
70
- fs: this.props.fs,
71
- })
72
- )
73
- }
74
-
75
- /** Process runner boundary. Defaults to NodeFunnelProcessRunner. */
76
- get process(): FunnelProcessRunner {
77
- return this.props.process ?? new NodeFunnelProcessRunner()
78
- }
79
-
80
- /** Logger boundary. Defaults to NodeFunnelLogger. */
81
- get logger(): FunnelLogger {
82
- return this.props.logger ?? new NodeFunnelLogger()
83
- }
84
-
85
- /** Pure factory that constructs per-type listeners and adapters from connector configs. */
86
- get factory(): FunnelConnectorFactory {
87
- return new FunnelConnectorFactory({
88
- fs: this.props.fs,
89
- process: this.props.process,
90
- logger: this.props.logger,
91
- dir: this.props.dir,
92
- })
93
- }
94
-
95
- /** Channel CRUD + nested connector CRUD + schedule entries + listener/adapter dispatch. */
96
- get channels(): FunnelChannels {
97
- return new FunnelChannels({
98
- store: this.store,
99
- factory: this.factory,
100
- profileChecker: this.profiles,
101
- clock: this.props.clock,
102
- idGenerator: this.props.idGenerator,
103
- })
104
- }
105
-
106
- /** Launch profiles (named presets for `fnl claude`: path + sub-agent + channel id). */
107
- get profiles(): FunnelProfiles {
108
- return new FunnelProfiles({ store: this.store })
109
- }
110
-
111
- /** funnel MCP installer (writes/removes `.mcp.json` entries in target repos). */
112
- get mcp(): FunnelMcp {
113
- return new FunnelMcp({ fs: this.props.fs })
114
- }
115
-
116
- /** Launch Claude Code with a channel injected via env, MCP installed, gateway ensured. */
117
- get claude(): FunnelClaude {
118
- return new FunnelClaude({
119
- channels: this.channels,
120
- mcp: this.mcp,
121
- gateway: this.gateway,
122
- fs: this.props.fs,
123
- process: this.props.process,
124
- logger: this.props.logger,
125
- dir: this.props.dir,
126
- })
127
- }
128
-
129
- /** Gateway daemon controller (PID-file, start/stop the separate `bun daemon.ts` process). */
130
- get gateway(): FunnelGateway {
131
- return new FunnelGateway({
132
- fs: this.props.fs,
133
- process: this.props.process,
134
- clock: this.props.clock,
135
- dir: this.props.dir,
136
- tmpDir: this.props.tmpDir,
137
- })
138
- }
139
-
140
- /** Read / generate the daemon's gateway token (mode 0600 file under `dir`). */
141
- get gatewayToken(): FunnelGatewayToken {
142
- return new FunnelGatewayToken({ fs: this.props.fs, dir: this.props.dir })
143
- }
144
-
145
- /**
146
- * HTTP client for listener operations on the running gateway daemon.
147
- * Returns `{ state: "offline" }` when the daemon is offline so hot-reload
148
- * paths stay write-only without parsing strings.
149
- */
150
- get listeners(): FunnelListenersClient {
151
- const gateway = this.gateway
152
- const token = this.gatewayToken
153
-
154
- return new FunnelListenersClient({
155
- port: gateway.getPort(),
156
- isDaemonRunning: () => gateway.isRunning(),
157
- getToken: () => token.read(),
158
- })
159
- }
160
-
161
- /**
162
- * In-process gateway server. Unlike `gateway.start()` (which spawns a daemon),
163
- * this returns a class that runs `Bun.serve` + listeners inside the current process —
164
- * useful for tests, embedding, or custom hosts.
165
- */
166
- gatewayServer(
167
- options: {
168
- port?: number
169
- logDir?: string
170
- killCompetingSlack?: boolean
171
- /** Override the auth token. Defaults to the persisted gateway.token. Pass "" to disable auth (tests). */
172
- token?: string
173
- } = {},
174
- ): FunnelGatewayServer {
175
- return new FunnelGatewayServer({
176
- channels: this.channels,
177
- settings: this.store,
178
- port: options.port,
179
- logDir: options.logDir,
180
- process: this.props.process,
181
- clock: this.props.clock,
182
- logger: this.props.logger,
183
- killCompetingSlack: options.killCompetingSlack,
184
- token: options.token ?? this.gatewayToken.ensure(),
185
- })
186
- }
187
- }
@@ -1,44 +0,0 @@
1
- import { timingSafeEqual } from "node:crypto"
2
- import type { MiddlewareHandler } from "hono"
3
- import type { Env } from "@/gateway/factory"
4
-
5
- type Deps = {
6
- expected: string
7
- }
8
-
9
- /**
10
- * Verifies `Authorization: Bearer <token>` against the daemon's gateway token.
11
- * Mounted on the routes that mutate listener state or expose detailed status.
12
- * `/health` is intentionally left unauthenticated so the daemon manager can
13
- * probe liveness without needing the token.
14
- */
15
- export const requireBearerToken = (deps: Deps): MiddlewareHandler<Env> => {
16
- return async (c, next) => {
17
- const header = c.req.header("authorization") ?? ""
18
- const match = header.match(/^Bearer\s+(.+)$/i)
19
- const presented = match?.[1] ?? ""
20
-
21
- if (!constantTimeEqual(presented, deps.expected)) {
22
- return c.text("unauthorized", 401)
23
- }
24
-
25
- return await next()
26
- }
27
- }
28
-
29
- export const constantTimeEqual = (a: string, b: string): boolean => {
30
- const bufA = Buffer.from(a, "utf-8")
31
- const bufB = Buffer.from(b, "utf-8")
32
- const maxLen = Math.max(bufA.length, bufB.length, 1)
33
- const padA = Buffer.alloc(maxLen)
34
- const padB = Buffer.alloc(maxLen)
35
-
36
- bufA.copy(padA)
37
- bufB.copy(padB)
38
-
39
- // timingSafeEqual on equal-length padded buffers, then AND with length match
40
- // so a length-only probe still requires the full comparison time.
41
- const equal = timingSafeEqual(padA, padB)
42
-
43
- return equal && bufA.length === bufB.length
44
- }