@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,66 +0,0 @@
1
- import { useState } from "react"
2
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
3
- import { usePressable } from "@/tui/hooks/hascii/use-pressable"
4
-
5
- export type Props = {
6
- isChecked?: boolean
7
- defaultChecked?: boolean
8
- isDisabled?: boolean
9
- onChange?: (next: boolean) => void
10
- }
11
-
12
- /** Two-cell on/off switch. The thumb sits at the left or right edge of a 3-cell track. */
13
- export function HasciiSwitch(props: Props) {
14
- const isDisabled = props.isDisabled ?? false
15
- const theme = useHasciiTheme()
16
-
17
- const internalState = useState(props.defaultChecked ?? false)
18
- const internal = internalState[0]
19
- const setInternal = internalState[1]
20
-
21
- const isChecked = props.isChecked ?? internal
22
-
23
- const toggle = () => {
24
- const next = !isChecked
25
-
26
- if (props.isChecked === undefined) setInternal(next)
27
- props.onChange?.(next)
28
- }
29
-
30
- const press = usePressable({ isDisabled, onPress: toggle })
31
-
32
- const trackBg = isDisabled
33
- ? theme.color.muted
34
- : isChecked
35
- ? press.isPressed
36
- ? theme.color.primaryActive
37
- : press.isHovered
38
- ? theme.color.primaryHover
39
- : theme.color.primary
40
- : press.isPressed
41
- ? theme.color.secondaryActive
42
- : press.isHovered
43
- ? theme.color.secondaryActive
44
- : theme.color.popover
45
-
46
- const thumbFg = isDisabled
47
- ? theme.color.mutedForeground
48
- : isChecked
49
- ? theme.color.primaryForeground
50
- : theme.color.foreground
51
-
52
- return (
53
- <box
54
- width={3}
55
- height={1}
56
- backgroundColor={trackBg}
57
- flexDirection="row"
58
- alignItems="center"
59
- justifyContent={isChecked ? "flex-end" : "flex-start"}
60
- paddingRight={isChecked ? 1 : 0}
61
- {...press.bind}
62
- >
63
- <text fg={thumbFg}>▮</text>
64
- </box>
65
- )
66
- }
@@ -1,95 +0,0 @@
1
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
2
-
3
- export type TableColumn = {
4
- key: string
5
- label: string
6
- width?: number
7
- align?: "left" | "right"
8
- }
9
-
10
- export type TableRow = Record<string, string | number>
11
-
12
- export type Props = {
13
- columns: TableColumn[]
14
- rows: TableRow[]
15
- selectedIndex?: number
16
- onSelect?: (index: number) => void
17
- }
18
-
19
- const padCell = (text: string, width: number, align: "left" | "right"): string => {
20
- const truncated = text.length > width ? `${text.slice(0, Math.max(0, width - 1))}…` : text
21
- const pad = " ".repeat(Math.max(0, width - truncated.length))
22
- return align === "right" ? `${pad}${truncated}` : `${truncated}${pad}`
23
- }
24
-
25
- const resolveColumnWidth = (column: TableColumn, rows: TableRow[]): number => {
26
- if (column.width !== undefined) return column.width
27
-
28
- let width = column.label.length
29
-
30
- for (const row of rows) {
31
- const value = String(row[column.key] ?? "")
32
- if (value.length > width) width = value.length
33
- }
34
-
35
- return width
36
- }
37
-
38
- /** Static row/column table. Cell text is padded to the column width; rows are clickable when onSelect is provided. */
39
- export function HasciiTable(props: Props) {
40
- const theme = useHasciiTheme()
41
-
42
- const widths = props.columns.map((column) => resolveColumnWidth(column, props.rows))
43
-
44
- return (
45
- <box flexDirection="column">
46
- <box flexDirection="row" gap={2} paddingLeft={1} paddingRight={1} height={1}>
47
- {props.columns.map((column, columnIndex) => (
48
- <text key={column.key} fg={theme.color.mutedForeground}>
49
- {padCell(
50
- column.label,
51
- widths[columnIndex] ?? column.label.length,
52
- column.align ?? "left",
53
- )}
54
- </text>
55
- ))}
56
- </box>
57
- <box flexDirection="row" paddingLeft={1} paddingRight={1} height={1}>
58
- <text fg={theme.color.border}>
59
- {"─".repeat(
60
- widths.reduce((sum, width) => sum + width, 0) +
61
- Math.max(0, props.columns.length - 1) * 2,
62
- )}
63
- </text>
64
- </box>
65
- {props.rows.map((row, rowIndex) => {
66
- const isSelected = props.selectedIndex === rowIndex
67
- const rowBg = isSelected ? theme.color.secondaryActive : undefined
68
- const rowFg = isSelected ? theme.color.foreground : theme.color.foreground
69
-
70
- return (
71
- <box
72
- key={`row-${rowIndex}`}
73
- flexDirection="row"
74
- gap={2}
75
- paddingLeft={1}
76
- paddingRight={1}
77
- height={1}
78
- backgroundColor={rowBg}
79
- onMouseUp={props.onSelect !== undefined ? () => props.onSelect?.(rowIndex) : undefined}
80
- >
81
- {props.columns.map((column, columnIndex) => (
82
- <text key={column.key} fg={rowFg}>
83
- {padCell(
84
- String(row[column.key] ?? ""),
85
- widths[columnIndex] ?? 0,
86
- column.align ?? "left",
87
- )}
88
- </text>
89
- ))}
90
- </box>
91
- )
92
- })}
93
- </box>
94
- )
95
- }
@@ -1,59 +0,0 @@
1
- import { useState } from "react"
2
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
3
-
4
- export type TabItem = {
5
- value: string
6
- label: string
7
- }
8
-
9
- export type Props = {
10
- items: TabItem[]
11
- value?: string
12
- defaultValue?: string
13
- onChange?: (value: string) => void
14
- }
15
-
16
- /** Single-row segmented tabs. Uncontrolled by default; pass value + onChange to control externally. */
17
- export function HasciiTabs(props: Props) {
18
- const theme = useHasciiTheme()
19
-
20
- const initial = props.defaultValue ?? props.value ?? props.items[0]?.value ?? ""
21
-
22
- const internalState = useState(initial)
23
- const internal = internalState[0]
24
- const setInternal = internalState[1]
25
-
26
- const current = props.value ?? internal
27
-
28
- const onSelect = (next: string) => {
29
- if (props.value === undefined) setInternal(next)
30
- props.onChange?.(next)
31
- }
32
-
33
- return (
34
- <box flexDirection="row" gap={0} height={2}>
35
- {props.items.map((item) => {
36
- const isActive = item.value === current
37
- const fg = isActive ? theme.color.foreground : theme.color.mutedForeground
38
- const itemWidth = item.label.length + 4
39
-
40
- return (
41
- <box
42
- key={item.value}
43
- height={2}
44
- paddingLeft={2}
45
- paddingRight={2}
46
- onMouseUp={() => onSelect(item.value)}
47
- >
48
- <text fg={fg}>{item.label}</text>
49
- {isActive ? (
50
- <box position="absolute" bottom={0} left={0} right={0}>
51
- <text fg={theme.color.primary}>{"▁".repeat(itemWidth)}</text>
52
- </box>
53
- ) : null}
54
- </box>
55
- )
56
- })}
57
- </box>
58
- )
59
- }
@@ -1,45 +0,0 @@
1
- import type { ReactNode } from "react"
2
- import { useHasciiToggleGroup } from "@/tui/components/ui/hascii/toggle-group"
3
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
4
- import { usePressable } from "@/tui/hooks/hascii/use-pressable"
5
-
6
- export type Props = {
7
- value: string
8
- children?: ReactNode
9
- }
10
-
11
- /** Pressable cell inside HasciiToggleGroup. Pressed state is controlled by the surrounding group. */
12
- export function HasciiToggleGroupItem(props: Props) {
13
- const theme = useHasciiTheme()
14
- const ctx = useHasciiToggleGroup()
15
-
16
- const isSelected = ctx?.isPressed(props.value) ?? false
17
-
18
- const press = usePressable({
19
- onPress: () => ctx?.toggle(props.value),
20
- })
21
-
22
- const bg = isSelected
23
- ? press.isPressed
24
- ? theme.color.primaryActive
25
- : press.isHovered
26
- ? theme.color.primaryHover
27
- : theme.color.primary
28
- : press.isPressed
29
- ? theme.color.secondaryActive
30
- : press.isHovered
31
- ? theme.color.secondaryHover
32
- : theme.color.popover
33
-
34
- const fg = isSelected
35
- ? theme.color.primaryForeground
36
- : press.isHovered
37
- ? theme.color.foreground
38
- : theme.color.mutedForeground
39
-
40
- return (
41
- <box height={1} paddingLeft={2} paddingRight={2} backgroundColor={bg} {...press.bind}>
42
- <text fg={fg}>{props.children}</text>
43
- </box>
44
- )
45
- }
@@ -1,99 +0,0 @@
1
- import { createContext, useContext, useState } from "react"
2
- import type { ReactNode } from "react"
3
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
4
-
5
- type SelectionMode = "single" | "multiple"
6
-
7
- type SingleProps = {
8
- type?: "single"
9
- value?: string
10
- defaultValue?: string
11
- onChange?: (value: string) => void
12
- }
13
-
14
- type MultipleProps = {
15
- type: "multiple"
16
- value?: string[]
17
- defaultValue?: string[]
18
- onChange?: (value: string[]) => void
19
- }
20
-
21
- export type Props = (SingleProps | MultipleProps) & {
22
- children?: ReactNode
23
- }
24
-
25
- type ContextValue = {
26
- mode: SelectionMode
27
- isPressed: (value: string) => boolean
28
- toggle: (value: string) => void
29
- }
30
-
31
- const ToggleGroupContext = createContext<ContextValue | null>(null)
32
-
33
- /** Read the current ToggleGroup context. Returns null when called outside a HasciiToggleGroup. */
34
- export function useHasciiToggleGroup(): ContextValue | null {
35
- return useContext(ToggleGroupContext)
36
- }
37
-
38
- const isSingle = (props: Props): props is SingleProps & { children?: ReactNode } =>
39
- props.type !== "multiple"
40
-
41
- /** Segmented row of HasciiToggleGroupItem. type="single" is mutually exclusive; type="multiple" allows any subset. */
42
- export function HasciiToggleGroup(props: Props) {
43
- const theme = useHasciiTheme()
44
- const internalSingleState = useState<string>(isSingle(props) ? (props.defaultValue ?? "") : "")
45
- const internalMultipleState = useState<string[]>(
46
- !isSingle(props) ? (props.defaultValue ?? []) : [],
47
- )
48
-
49
- if (isSingle(props)) {
50
- const internal = internalSingleState[0]
51
- const setInternal = internalSingleState[1]
52
- const current = props.value ?? internal
53
-
54
- const toggle = (value: string) => {
55
- if (props.value === undefined) setInternal(value)
56
- props.onChange?.(value)
57
- }
58
-
59
- const ctx: ContextValue = {
60
- mode: "single",
61
- isPressed: (value) => value === current,
62
- toggle,
63
- }
64
-
65
- return (
66
- <ToggleGroupContext.Provider value={ctx}>
67
- <box flexDirection="row" gap={0} height={1} backgroundColor={theme.color.popover}>
68
- {props.children}
69
- </box>
70
- </ToggleGroupContext.Provider>
71
- )
72
- }
73
-
74
- const internal = internalMultipleState[0]
75
- const setInternal = internalMultipleState[1]
76
- const current = props.value ?? internal
77
-
78
- const toggle = (value: string) => {
79
- const next = current.includes(value)
80
- ? current.filter((entry) => entry !== value)
81
- : [...current, value]
82
- if (props.value === undefined) setInternal(next)
83
- props.onChange?.(next)
84
- }
85
-
86
- const ctx: ContextValue = {
87
- mode: "multiple",
88
- isPressed: (value) => current.includes(value),
89
- toggle,
90
- }
91
-
92
- return (
93
- <ToggleGroupContext.Provider value={ctx}>
94
- <box flexDirection="row" gap={0} height={1}>
95
- {props.children}
96
- </box>
97
- </ToggleGroupContext.Provider>
98
- )
99
- }
@@ -1,104 +0,0 @@
1
- import { useState } from "react"
2
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
3
-
4
- export type TreeNode = {
5
- id: string
6
- label: string
7
- children?: TreeNode[]
8
- }
9
-
10
- export type Props = {
11
- nodes: TreeNode[]
12
- indent?: number
13
- }
14
-
15
- type Row = {
16
- node: TreeNode
17
- prefix: string
18
- }
19
-
20
- type RowProps = {
21
- row: Row
22
- }
23
-
24
- /** Internal row used by HasciiTree. Hover-only background; no click handler. */
25
- function HasciiTreeRow(props: RowProps) {
26
- const theme = useHasciiTheme()
27
-
28
- const hoveredState = useState(false)
29
- const isHovered = hoveredState[0]
30
- const setHovered = hoveredState[1]
31
-
32
- const bg = isHovered ? theme.color.secondaryHover : undefined
33
-
34
- return (
35
- <box
36
- flexDirection="row"
37
- alignItems="center"
38
- paddingLeft={1}
39
- paddingRight={1}
40
- height={1}
41
- backgroundColor={bg}
42
- onMouseOver={() => setHovered(true)}
43
- onMouseOut={() => setHovered(false)}
44
- >
45
- <text fg={theme.color.mutedForeground}>{props.row.prefix}</text>
46
- <text fg={theme.color.foreground}>{props.row.node.label}</text>
47
- </box>
48
- )
49
- }
50
-
51
- const buildSegment = (
52
- kind: "ancestor-bar" | "ancestor-blank" | "tee" | "elbow",
53
- indent: number,
54
- ): string => {
55
- const head =
56
- kind === "ancestor-bar" ? "│" : kind === "ancestor-blank" ? " " : kind === "tee" ? "├" : "└"
57
- const tail =
58
- kind === "tee" || kind === "elbow"
59
- ? "─".repeat(Math.max(0, indent - 1))
60
- : " ".repeat(Math.max(0, indent - 1))
61
- return `${head}${tail}`
62
- }
63
-
64
- const flatten = (nodes: TreeNode[], ancestorsAreLast: boolean[], indent: number): Row[] => {
65
- const rows: Row[] = []
66
-
67
- for (let index = 0; index < nodes.length; index++) {
68
- const node = nodes[index]
69
- if (node === undefined) continue
70
-
71
- const isLast = index === nodes.length - 1
72
-
73
- let prefix = ""
74
- for (const isAncestorLast of ancestorsAreLast) {
75
- prefix += buildSegment(isAncestorLast ? "ancestor-blank" : "ancestor-bar", indent)
76
- }
77
- prefix += buildSegment(isLast ? "elbow" : "tee", indent)
78
- prefix += " "
79
-
80
- rows.push({ node, prefix })
81
-
82
- if (node.children && node.children.length > 0) {
83
- const childRows = flatten(node.children, [...ancestorsAreLast, isLast], indent)
84
- for (const childRow of childRows) rows.push(childRow)
85
- }
86
- }
87
-
88
- return rows
89
- }
90
-
91
- /** Static read-only file-tree drawn with ├/└/│ box-drawing characters. Hover highlights a row but rows are not clickable. */
92
- export function HasciiTree(props: Props) {
93
- const indent = props.indent ?? 2
94
-
95
- const rows = flatten(props.nodes, [], indent)
96
-
97
- return (
98
- <box flexDirection="column">
99
- {rows.map((row) => (
100
- <HasciiTreeRow key={row.node.id} row={row} />
101
- ))}
102
- </box>
103
- )
104
- }
@@ -1,44 +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
- * Outer wrapper every view renders into.
13
- *
14
- * Renders a vertical `<scrollbox>` so content that overflows the visible
15
- * area scrolls instead of clipping the layout. Padding follows the
16
- * uniform `funnel.paddingX/Y` rule and lives on the inner content
17
- * container (via `contentOptions`); the outer scrollbox itself is
18
- * transparent so multi-block views (`events` events list + DetailBar
19
- * sibling) still stack cleanly.
20
- *
21
- * The vertical scrollbar's track and thumb pull from the theme so the
22
- * widget reads as part of the surface palette instead of OpenTUI's
23
- * default electric blue.
24
- */
25
- export function ViewShell(props: Props) {
26
- const theme = useHasciiTheme()
27
-
28
- return (
29
- <scrollbox
30
- style={{ flexGrow: 1 }}
31
- contentOptions={{
32
- flexDirection: "column",
33
- paddingLeft: funnel.paddingX,
34
- paddingRight: funnel.paddingX,
35
- paddingTop: funnel.paddingY,
36
- paddingBottom: funnel.paddingY,
37
- gap: funnel.gap,
38
- }}
39
- verticalScrollbarOptions={verticalScrollbarOptions(theme)}
40
- >
41
- {props.children}
42
- </scrollbox>
43
- )
44
- }
@@ -1,33 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import { funnel } from "@/tui/theme"
3
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
4
-
5
- type Props = {
6
- value: string
7
- active: boolean
8
- }
9
-
10
- /** Inline filter overlay shown when the user presses `/`. */
11
- export function FilterInput(props: Props) {
12
- const theme = useHasciiTheme()
13
-
14
- if (!props.active) return null
15
-
16
- return (
17
- <box
18
- style={{
19
- height: funnel.barHeight,
20
- backgroundColor: theme.color.muted,
21
- paddingLeft: funnel.paddingX,
22
- paddingRight: funnel.paddingX,
23
- }}
24
- >
25
- <text>
26
- <span fg={theme.color.foreground}>/</span>
27
- <span fg={theme.color.foreground}>{props.value}</span>
28
- <span fg={theme.color.foreground}>█</span>
29
- <span fg={theme.color.mutedForeground}>{" · Enter to apply · Esc to cancel"}</span>
30
- </text>
31
- </box>
32
- )
33
- }
@@ -1,54 +0,0 @@
1
- import { useState } from "react"
2
-
3
- export type Bindings = {
4
- onMouseOver: () => void
5
- onMouseOut: () => void
6
- onMouseDown: () => void
7
- onMouseUp: () => void
8
- }
9
-
10
- export type PressableState = {
11
- isHovered: boolean
12
- isPressed: boolean
13
- bind: Bindings
14
- }
15
-
16
- export type Options = {
17
- isDisabled?: boolean
18
- onPress?: () => void
19
- }
20
-
21
- /** Tracks hover and press state for a focusable element and exposes mouse handlers ready for spread. */
22
- export function usePressable(options?: Options): PressableState {
23
- const isDisabled = options?.isDisabled ?? false
24
- const onPress = options?.onPress
25
-
26
- const hoveredState = useState(false)
27
- const isHovered = hoveredState[0]
28
- const setHovered = hoveredState[1]
29
-
30
- const pressedState = useState(false)
31
- const isPressed = pressedState[0]
32
- const setPressed = pressedState[1]
33
-
34
- const bind: Bindings = {
35
- onMouseOver: () => {
36
- if (!isDisabled) setHovered(true)
37
- },
38
- onMouseOut: () => {
39
- setHovered(false)
40
- setPressed(false)
41
- },
42
- onMouseDown: () => {
43
- if (!isDisabled) setPressed(true)
44
- },
45
- onMouseUp: () => {
46
- if (isDisabled) return
47
-
48
- if (isPressed) onPress?.()
49
- setPressed(false)
50
- },
51
- }
52
-
53
- return { isHovered, isPressed, bind }
54
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * Parse a comma-separated text input into a clean string array.
3
- *
4
- * Used by the editable channels (connector list) and profiles (env-files)
5
- * views to turn the user's free-form input ("a, b , c,") into the
6
- * actual list ["a", "b", "c"]. Empty entries and surrounding whitespace
7
- * are dropped so trailing commas and stray spaces don't matter.
8
- */
9
- export function parseCommaList(raw: string): string[] {
10
- return raw
11
- .split(",")
12
- .map((part) => part.trim())
13
- .filter((part) => part.length > 0)
14
- }
@@ -1,61 +0,0 @@
1
- /** @jsxImportSource @opentui/react */
2
- import { HasciiSeparator } from "@/tui/components/ui/hascii/separator"
3
- import { EmptyState } from "@/tui/components/empty-state"
4
- import { funnel } from "@/tui/theme"
5
- import { useHasciiTheme } from "@/tui/utils/hascii/theme-context"
6
- import type { ProfileConfig } from "@/engine/settings/settings-schema"
7
-
8
- type Props = {
9
- active: boolean
10
- profiles: ProfileConfig[]
11
- selectedIndex: number
12
- }
13
-
14
- /**
15
- * Modal-style overlay: pick a profile and launch Claude Code via the same
16
- * code path as `fnl claude --profile`. The launcher exits the TUI before
17
- * exec'ing so Claude takes over the terminal.
18
- */
19
- export function ProfileLauncher(props: Props) {
20
- const theme = useHasciiTheme()
21
-
22
- if (!props.active) return null
23
-
24
- return (
25
- <box
26
- style={{
27
- flexDirection: "column",
28
- backgroundColor: funnel.surface,
29
- paddingLeft: funnel.paddingX,
30
- paddingRight: funnel.paddingX,
31
- paddingTop: funnel.paddingY,
32
- paddingBottom: funnel.paddingY,
33
- gap: funnel.gap,
34
- position: "absolute",
35
- top: funnel.modalTop,
36
- left: funnel.modalInset,
37
- right: funnel.modalInset,
38
- }}
39
- >
40
- <text fg={theme.color.foreground}>launch claude with profile</text>
41
- <HasciiSeparator />
42
-
43
- {props.profiles.length === 0 ? (
44
- <EmptyState message="(no profiles — `fnl profiles add` first)" />
45
- ) : (
46
- props.profiles.map((profile, index) => {
47
- const selected = index === props.selectedIndex
48
-
49
- return (
50
- <text key={profile.name} bg={selected ? theme.color.muted : undefined}>
51
- <span fg={theme.color.foreground}>{profile.name}</span>
52
- <span fg={funnel.faint}>
53
- {` → channel ${profile.channelId} · path ${profile.path} · sub-agent ${profile.subAgent}`}
54
- </span>
55
- </text>
56
- )
57
- })
58
- )}
59
- </box>
60
- )
61
- }