@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
package/lib/tui/app.tsx DELETED
@@ -1,357 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import { useKeyboard, useRenderer } from "@opentui/react"
3
- import { useState } from "react"
4
- import { FilterInput } from "@/tui/filter-input"
5
- import { ProfileLauncher } from "@/tui/profile-launcher"
6
- import { Sidebar } from "@/tui/sidebar"
7
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
8
- import type { MenuItem, Mode, View } from "@/tui/types"
9
- import { useEventStream } from "@/tui/use-event-stream"
10
- import { useSnapshot } from "@/tui/use-snapshot"
11
- import { ChannelsView } from "@/tui/views/channels-view"
12
- import { ConnectorsView } from "@/tui/views/connectors-view"
13
- import { EventsView } from "@/tui/views/events-view"
14
- import { ListenersView } from "@/tui/views/listeners-view"
15
- import { ProfilesView } from "@/tui/views/profiles-view"
16
- import type { Funnel } from "@/funnel"
17
-
18
- type Props = {
19
- funnel: Funnel
20
- }
21
-
22
- const VIEW_KEYS: View[] = ["events", "connectors", "channels", "profiles", "listeners"]
23
-
24
- const clamp = (value: number, length: number): number => {
25
- if (length === 0) return 0
26
- if (value < 0) return 0
27
- if (value >= length) return length - 1
28
-
29
- return value
30
- }
31
-
32
- const matchesEventFilter = (
33
- event: { content: string; meta: Record<string, string> },
34
- filter: string,
35
- ): boolean => {
36
- if (!filter) return true
37
-
38
- const needle = filter.toLowerCase()
39
- const haystack = [
40
- event.content,
41
- event.meta.connector ?? "",
42
- event.meta.event_type ?? "",
43
- event.meta.channel ?? "",
44
- ]
45
- .join(" ")
46
- .toLowerCase()
47
-
48
- return haystack.includes(needle)
49
- }
50
-
51
- /**
52
- * Funnel TUI: side-rail navigation + main content panel.
53
- *
54
- * Default landing view is the live `events` log. The sidebar shows the
55
- * gateway state, currently connected sessions, and a navigation menu
56
- * where each row carries the live count of its underlying entity.
57
- */
58
- export function App(props: Props) {
59
- const theme = useHasciiTheme()
60
- const renderer = useRenderer()
61
- const { snapshot, refresh } = useSnapshot(props.funnel)
62
- const { events, status: streamStatus } = useEventStream(
63
- snapshot.gateway.port,
64
- snapshot.daemonReachable,
65
- props.funnel.gatewayToken.read(),
66
- )
67
-
68
- const [view, setViewState] = useState<View>("events")
69
- const [mode, setMode] = useState<Mode>("browse")
70
- const [listenerCursor, setListenerCursor] = useState(0)
71
- const [profileCursor, setProfileCursor] = useState(0)
72
- const [eventCursor, setEventCursor] = useState(0)
73
- const [filter, setFilter] = useState("")
74
- const [filterDraft, setFilterDraft] = useState("")
75
- const [busy, setBusy] = useState(false)
76
- const [editFocus, setEditFocus] = useState<string | null>(null)
77
-
78
- const isEditing = editFocus !== null
79
-
80
- const setView = (next: View) => {
81
- setViewState(next)
82
- setEditFocus(null)
83
- }
84
-
85
- const visibleEventCount = events.filter((event) => matchesEventFilter(event, filter)).length
86
-
87
- const menuItems: MenuItem[] = [
88
- { view: "events", label: "events", count: events.length },
89
- { view: "connectors", label: "connectors", count: snapshot.connectors.length },
90
- { view: "channels", label: "channels", count: snapshot.channels.length },
91
- { view: "profiles", label: "profiles", count: snapshot.profiles.length },
92
- { view: "listeners", label: "listeners", count: snapshot.listeners.length },
93
- ]
94
-
95
- const moveCursor = (delta: number) => {
96
- if (view === "listeners") {
97
- setListenerCursor((prev) => clamp(prev + delta, snapshot.listeners.length))
98
- } else if (view === "profiles") {
99
- setProfileCursor((prev) => clamp(prev + delta, snapshot.profiles.length))
100
- } else if (view === "events") {
101
- setEventCursor((prev) => clamp(prev + delta, visibleEventCount))
102
- }
103
- }
104
-
105
- const runListenerAction = async (action: "start" | "stop" | "restart") => {
106
- const entry = snapshot.listeners[listenerCursor]
107
-
108
- if (!entry || busy) return
109
-
110
- setBusy(true)
111
-
112
- if (action === "start") await props.funnel.listeners.start(entry.channelName, entry.name)
113
- if (action === "stop") await props.funnel.listeners.stop(entry.channelName, entry.name)
114
- if (action === "restart") await props.funnel.listeners.restart(entry.channelName, entry.name)
115
-
116
- setBusy(false)
117
- refresh()
118
- }
119
-
120
- const launchProfile = async () => {
121
- const profile = snapshot.profiles[profileCursor]
122
-
123
- if (!profile) return
124
-
125
- renderer.destroy()
126
-
127
- try {
128
- await props.funnel.claude.launch({
129
- channel: profile.channelId,
130
- cwd: profile.path,
131
- subAgent: profile.subAgent,
132
- profileName: profile.name,
133
- })
134
- } catch (error) {
135
- process.stderr.write(`error: ${error instanceof Error ? error.message : String(error)}\n`)
136
- process.exit(1)
137
- }
138
-
139
- process.exit(0)
140
- }
141
-
142
- const toggleGateway = async () => {
143
- if (busy) return
144
-
145
- setBusy(true)
146
-
147
- if (snapshot.gateway.running) {
148
- await props.funnel.gateway.stop()
149
- } else {
150
- await props.funnel.gateway.start()
151
- }
152
-
153
- setBusy(false)
154
- refresh()
155
- }
156
-
157
- useKeyboard((key) => {
158
- if (isEditing) {
159
- if (key.name === "escape") setEditFocus(null)
160
- return
161
- }
162
-
163
- if (mode === "filter") {
164
- if (key.name === "return") {
165
- setFilter(filterDraft)
166
- setEventCursor(0)
167
- setMode("browse")
168
- return
169
- }
170
-
171
- if (key.name === "escape") {
172
- setFilterDraft(filter)
173
- setMode("browse")
174
- return
175
- }
176
-
177
- if (key.name === "backspace") {
178
- setFilterDraft((prev) => prev.slice(0, -1))
179
- return
180
- }
181
-
182
- if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta) {
183
- const ch = key.sequence
184
-
185
- if (ch >= " " && ch <= "~") {
186
- setFilterDraft((prev) => prev + ch)
187
- }
188
- }
189
-
190
- return
191
- }
192
-
193
- if (mode === "profile-launcher") {
194
- if (key.name === "escape" || (key.ctrl && key.name === "c")) {
195
- setMode("browse")
196
- return
197
- }
198
-
199
- if (key.name === "up" || key.name === "k") {
200
- setProfileCursor((prev) => clamp(prev - 1, snapshot.profiles.length))
201
- return
202
- }
203
-
204
- if (key.name === "down" || key.name === "j") {
205
- setProfileCursor((prev) => clamp(prev + 1, snapshot.profiles.length))
206
- return
207
- }
208
-
209
- if (key.name === "return") {
210
- void launchProfile()
211
- }
212
-
213
- return
214
- }
215
-
216
- if (key.name === "q" || key.name === "escape" || (key.ctrl && key.name === "c")) {
217
- renderer.destroy()
218
- return
219
- }
220
-
221
- const numericIndex = Number.parseInt(key.name ?? "", 10)
222
- const target = Number.isFinite(numericIndex) ? VIEW_KEYS[numericIndex - 1] : undefined
223
-
224
- if (target) {
225
- setView(target)
226
- return
227
- }
228
-
229
- if (key.name === "j" || key.name === "down") {
230
- moveCursor(1)
231
- return
232
- }
233
-
234
- if (key.name === "k" || key.name === "up") {
235
- moveCursor(-1)
236
- return
237
- }
238
-
239
- if (key.name === "r") {
240
- refresh()
241
- return
242
- }
243
-
244
- if (key.name === "/" && view === "events") {
245
- setFilterDraft(filter)
246
- setMode("filter")
247
- return
248
- }
249
-
250
- if (key.name === "c") {
251
- if (snapshot.profiles.length === 0) return
252
-
253
- setProfileCursor((prev) => Math.min(prev, Math.max(0, snapshot.profiles.length - 1)))
254
- setMode("profile-launcher")
255
- return
256
- }
257
-
258
- if (view === "listeners") {
259
- if (key.name === "s") {
260
- void runListenerAction("start")
261
- return
262
- }
263
-
264
- if (key.name === "x") {
265
- void runListenerAction("stop")
266
- return
267
- }
268
-
269
- if (key.name === "R" || (key.shift && key.name === "r")) {
270
- void runListenerAction("restart")
271
- return
272
- }
273
- }
274
-
275
- if (key.name === "G" || (key.shift && key.name === "g")) {
276
- void toggleGateway()
277
- }
278
- })
279
-
280
- return (
281
- <box
282
- style={{
283
- width: "100%",
284
- height: "100%",
285
- backgroundColor: theme.color.background,
286
- flexDirection: "column",
287
- }}
288
- >
289
- <box style={{ flexDirection: "row", flexGrow: 1 }}>
290
- <Sidebar
291
- snapshot={snapshot}
292
- menuItems={menuItems}
293
- view={view}
294
- onSelect={setView}
295
- busy={busy}
296
- onToggleGateway={() => void toggleGateway()}
297
- />
298
-
299
- <box
300
- style={{
301
- flexDirection: "column",
302
- flexGrow: 1,
303
- backgroundColor: theme.color.background,
304
- }}
305
- >
306
- {view === "events" ? (
307
- <EventsView
308
- events={events}
309
- filter={filter}
310
- selectedIndex={eventCursor}
311
- streamStatus={streamStatus}
312
- />
313
- ) : view === "connectors" ? (
314
- <ConnectorsView
315
- snapshot={snapshot}
316
- funnel={props.funnel}
317
- refresh={refresh}
318
- focusedKey={editFocus}
319
- setFocusedKey={setEditFocus}
320
- />
321
- ) : view === "channels" ? (
322
- <ChannelsView
323
- snapshot={snapshot}
324
- funnel={props.funnel}
325
- refresh={refresh}
326
- focusedKey={editFocus}
327
- setFocusedKey={setEditFocus}
328
- />
329
- ) : view === "profiles" ? (
330
- <ProfilesView
331
- snapshot={snapshot}
332
- selectedIndex={profileCursor}
333
- funnel={props.funnel}
334
- refresh={refresh}
335
- focusedKey={editFocus}
336
- setFocusedKey={setEditFocus}
337
- />
338
- ) : (
339
- <ListenersView
340
- snapshot={snapshot}
341
- events={events}
342
- selectedIndex={listenerCursor}
343
- busy={busy}
344
- />
345
- )}
346
- </box>
347
- </box>
348
-
349
- <FilterInput value={filterDraft} active={mode === "filter"} />
350
- <ProfileLauncher
351
- active={mode === "profile-launcher"}
352
- profiles={snapshot.profiles}
353
- selectedIndex={profileCursor}
354
- />
355
- </box>
356
- )
357
- }
@@ -1,18 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import { HasciiButton } from "@/tui/components/ui/hascii/button"
3
-
4
- type Props = {
5
- label: string
6
- onClick: () => void
7
- }
8
-
9
- /**
10
- * "+ add …" row used at the foot of an entity list.
11
- *
12
- * Bound to hascii's primary `HasciiButton` so AddRows match the gateway's
13
- * start / stop affordance — same neutral-white CTA chip with darken-
14
- * on-hover feel.
15
- */
16
- export function AddRow(props: Props) {
17
- return <HasciiButton onPress={props.onClick}>{`+ ${props.label}`}</HasciiButton>
18
- }
@@ -1,27 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import { TextAttributes } from "@opentui/core"
3
- import { funnel } from "@/tui/theme"
4
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
5
-
6
- /**
7
- * Brand mark rendered at the top of the sidebar. Carries its own paddingX
8
- * so it aligns with menu items (which need paddingX-less parents so their
9
- * active highlight spans edge-to-edge).
10
- */
11
- export function Brand() {
12
- const theme = useHasciiTheme()
13
-
14
- return (
15
- <box
16
- style={{
17
- flexDirection: "row",
18
- paddingLeft: funnel.paddingX,
19
- paddingRight: funnel.paddingX,
20
- }}
21
- >
22
- <text fg={theme.color.foreground} attributes={TextAttributes.BOLD}>
23
- funnel
24
- </text>
25
- </box>
26
- )
27
- }
@@ -1,44 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import type { ReactNode } from "react"
3
- import { HasciiButton } from "@/tui/components/ui/hascii/button"
4
- import { HasciiCard } from "@/tui/components/ui/hascii/card"
5
- import { HasciiCardFooter } from "@/tui/components/ui/hascii/card-footer"
6
- import { HasciiCardHeader } from "@/tui/components/ui/hascii/card-header"
7
- import { HasciiCardTitle } from "@/tui/components/ui/hascii/card-title"
8
- import { SelectionAccent } from "@/tui/components/selection-accent"
9
-
10
- type Props = {
11
- /** Entity identifier shown at the top so each Card reads as one item. */
12
- title: string
13
- children: ReactNode
14
- /** When provided, a destructive "delete" Button is rendered bottom-right. */
15
- onDelete?: () => void
16
- selected?: boolean
17
- }
18
-
19
- /**
20
- * Per-entity form wrapper used inside the connectors / channels /
21
- * profiles / listeners views.
22
- *
23
- * Composed from hascii's `HasciiCard` family — header + body + footer.
24
- * `selected` overlays a `SelectionAccent` (▏ primary rule) at the left
25
- * edge for cursor-driven views.
26
- */
27
- export function Card(props: Props) {
28
- return (
29
- <HasciiCard>
30
- {props.selected ? <SelectionAccent /> : null}
31
- <HasciiCardHeader>
32
- <HasciiCardTitle>{props.title}</HasciiCardTitle>
33
- </HasciiCardHeader>
34
- {props.children}
35
- {props.onDelete ? (
36
- <HasciiCardFooter>
37
- <HasciiButton variant="destructive" size="sm" onPress={props.onDelete}>
38
- delete
39
- </HasciiButton>
40
- </HasciiCardFooter>
41
- ) : null}
42
- </HasciiCard>
43
- )
44
- }
@@ -1,46 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import type { ReactNode } from "react"
3
- import { verticalScrollbarOptions } from "@/tui/scrollbar-options"
4
- import { funnel } from "@/tui/theme"
5
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
6
-
7
- type Props = {
8
- children: ReactNode
9
- }
10
-
11
- /**
12
- * Bottom inspector strip rendered at the foot of a view.
13
- *
14
- * Sits as a sibling of `ViewShell` (not inside it) so its background
15
- * stretches edge-to-edge across the main column and butts against the
16
- * sidebar with no horizontal gap. Background tier is `elevated` —
17
- * one step brighter than the sidebar — to read as a separate stratum
18
- * without needing a border.
19
- *
20
- * The strip is itself a `<scrollbox>` so long content (e.g., JSON for
21
- * the selected event) scrolls within the fixed `funnel.detailPanelHeight`
22
- * frame instead of pushing other UI off-screen.
23
- */
24
- export function DetailBar(props: Props) {
25
- const theme = useHasciiTheme()
26
-
27
- return (
28
- <scrollbox
29
- style={{
30
- height: funnel.detailPanelHeight,
31
- backgroundColor: theme.color.muted,
32
- }}
33
- contentOptions={{
34
- flexDirection: "column",
35
- paddingLeft: funnel.paddingX,
36
- paddingRight: funnel.paddingX,
37
- paddingTop: funnel.paddingY,
38
- paddingBottom: funnel.paddingY,
39
- gap: funnel.gap,
40
- }}
41
- verticalScrollbarOptions={verticalScrollbarOptions(theme)}
42
- >
43
- {props.children}
44
- </scrollbox>
45
- )
46
- }
@@ -1,33 +0,0 @@
1
- import { HasciiFormItem } from "@/tui/components/ui/hascii/form-item"
2
- import { HasciiInput } from "@/tui/components/ui/hascii/input"
3
-
4
- type Props = {
5
- label: string
6
- initialValue: string
7
- focused: boolean
8
- onFocus: () => void
9
- onCommit: (value: string) => void
10
- placeholder?: string
11
- }
12
-
13
- /**
14
- * Inline label + input row built on hascii primitives. The hascii Input fires
15
- * `onChange` on every keystroke; we forward that to `onCommit` so callers
16
- * persist live (re-keying by `focused` still forces a remount on blur so the
17
- * input snaps back when the user clicks away without typing).
18
- */
19
- export function EditableField(props: Props) {
20
- return (
21
- <box style={{ flexDirection: "row" }} onMouseDown={props.onFocus}>
22
- <HasciiFormItem label={props.label} labelWidth={12}>
23
- <HasciiInput
24
- key={props.focused ? "focused" : "blurred"}
25
- value={props.initialValue}
26
- placeholder={props.placeholder}
27
- defaultFocused={props.focused}
28
- onChange={props.onCommit}
29
- />
30
- </HasciiFormItem>
31
- </box>
32
- )
33
- }
@@ -1,11 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import { funnel } from "@/tui/theme"
3
-
4
- type Props = {
5
- message: string
6
- }
7
-
8
- /** Faint placeholder shown when a list has no items. */
9
- export function EmptyState(props: Props) {
10
- return <text fg={funnel.faint}>{props.message}</text>
11
- }
@@ -1,66 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import { HasciiButton } from "@/tui/components/ui/hascii/button"
3
- import { funnel } from "@/tui/theme"
4
- import type { Snapshot } from "@/tui/types"
5
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
6
-
7
- type Props = {
8
- gateway: Snapshot["gateway"]
9
- busy: boolean
10
- onToggle: () => void
11
- }
12
-
13
- /**
14
- * Compact running/stopped indicator with pid and port for the sidebar.
15
- *
16
- * The "gateway" label lives inside the same elevated block as the status
17
- * so the heading reads as part of the card, not a floating sidebar
18
- * separator on the surrounding surface tier.
19
- *
20
- * The toggle is rendered as a neutral-white `Button` with the same
21
- * paddingX=2 / paddingY=1 as the rest of the form chrome — no leading
22
- * glyph, just the verb. `busy` disables the button while a toggle is
23
- * in flight so rapid clicks don't stack daemon spawns.
24
- */
25
- export function GatewayStatus(props: Props) {
26
- const theme = useHasciiTheme()
27
-
28
- return (
29
- <box
30
- style={{
31
- flexDirection: "column",
32
- backgroundColor: theme.color.muted,
33
- paddingLeft: funnel.paddingX,
34
- paddingRight: funnel.paddingX,
35
- paddingTop: funnel.paddingY,
36
- paddingBottom: funnel.paddingY,
37
- gap: funnel.gap,
38
- }}
39
- >
40
- <text fg={funnel.faint}>gateway</text>
41
-
42
- {props.gateway.running ? (
43
- <>
44
- <text>
45
- <span fg={funnel.alive}>●</span>
46
- <span fg={theme.color.foreground}>{` running`}</span>
47
- </text>
48
- <text fg={funnel.faint}>{`pid ${props.gateway.pid} · :${props.gateway.port}`}</text>
49
- <HasciiButton onPress={props.onToggle} isDisabled={props.busy}>
50
- {props.busy ? "stopping…" : "stop"}
51
- </HasciiButton>
52
- </>
53
- ) : (
54
- <>
55
- <text>
56
- <span fg={theme.color.mutedForeground}>○</span>
57
- <span fg={theme.color.mutedForeground}>{` stopped`}</span>
58
- </text>
59
- <HasciiButton onPress={props.onToggle} isDisabled={props.busy}>
60
- {props.busy ? "starting…" : "start"}
61
- </HasciiButton>
62
- </>
63
- )}
64
- </box>
65
- )
66
- }
@@ -1,29 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import { funnel } from "@/tui/theme"
3
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
4
-
5
- type Hint = {
6
- key: string
7
- label: string
8
- }
9
-
10
- type Props = {
11
- hints: Hint[]
12
- }
13
-
14
- /** Inline keymap row — used at the bottom of each interactive view. */
15
- export function Keymap(props: Props) {
16
- const theme = useHasciiTheme()
17
-
18
- return (
19
- <text fg={theme.color.mutedForeground}>
20
- {props.hints.map((hint, index) => (
21
- <span key={hint.key}>
22
- {index > 0 ? <span fg={funnel.faint}>{" · "}</span> : null}
23
- <span fg={funnel.faint}>{hint.key} </span>
24
- {hint.label}
25
- </span>
26
- ))}
27
- </text>
28
- )
29
- }