@interactive-inc/claude-funnel 0.7.1 → 0.8.0
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.
- package/README.md +155 -133
- package/dist/bin.js +1417 -0
- package/dist/gateway/daemon.js +513 -0
- package/dist/highlights-eq9cgrbb.scm +604 -0
- package/dist/highlights-ghv9g403.scm +205 -0
- package/dist/highlights-hk7bwhj4.scm +284 -0
- package/dist/highlights-r812a2qc.scm +150 -0
- package/dist/highlights-x6tmsnaa.scm +115 -0
- package/dist/injections-73j83es3.scm +27 -0
- package/dist/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
- package/dist/tree-sitter-markdown-411r6y9b.wasm +0 -0
- package/dist/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
- package/dist/tree-sitter-typescript-zxjzwt75.wasm +0 -0
- package/dist/tree-sitter-zig-e78zbjpm.wasm +0 -0
- package/lib/bin.ts +78 -0
- package/lib/{modules → cli}/router/to-request.ts +13 -20
- package/lib/cli/routes/channels.$channel.connectors.$connector.rename.$newName.ts +27 -0
- package/lib/cli/routes/channels.$channel.connectors.$connector.request.ts +40 -0
- package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.add.$id.ts +41 -0
- package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.remove.$id.ts +22 -0
- package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.ts +23 -0
- package/lib/cli/routes/channels.$channel.connectors.$connector.ts +26 -0
- package/lib/cli/routes/channels.$channel.connectors.add.$connector.ts +92 -0
- package/lib/cli/routes/channels.$channel.connectors.remove.$connector.ts +22 -0
- package/lib/cli/routes/channels.$channel.connectors.set.$connector.ts +63 -0
- package/lib/cli/routes/channels.$channel.connectors.ts +26 -0
- package/lib/cli/routes/channels.$channel.rename.$newName.ts +22 -0
- package/lib/cli/routes/channels.$channel.set.delivery.$mode.ts +34 -0
- package/lib/cli/routes/channels.$channel.ts +34 -0
- package/lib/cli/routes/channels.add.$channel.ts +33 -0
- package/lib/cli/routes/channels.remove.$channel.ts +20 -0
- package/lib/cli/routes/channels.ts +39 -0
- package/lib/cli/routes/claude.ts +69 -0
- package/lib/cli/routes/gateway.listeners.ts +41 -0
- package/lib/cli/routes/gateway.logs.ts +123 -0
- package/lib/{routes/gateway/restart.ts → cli/routes/gateway.restart.ts} +20 -5
- package/lib/cli/routes/gateway.run.ts +41 -0
- package/lib/cli/routes/gateway.start.ts +50 -0
- package/lib/cli/routes/gateway.status.ts +19 -0
- package/lib/cli/routes/gateway.stop.ts +32 -0
- package/lib/cli/routes/gateway.ts +55 -0
- package/lib/cli/routes/index.ts +202 -0
- package/lib/cli/routes/profiles.$profile.as-default.ts +22 -0
- package/lib/cli/routes/profiles.$profile.rename.$newName.ts +22 -0
- package/lib/cli/routes/profiles.$profile.run.ts +36 -0
- package/lib/cli/routes/profiles.add.$profile.ts +46 -0
- package/lib/cli/routes/profiles.remove.$profile.ts +20 -0
- package/lib/cli/routes/profiles.set.$profile.ts +46 -0
- package/lib/cli/routes/profiles.ts +40 -0
- package/lib/cli/routes/status.ts +93 -0
- package/lib/cli/routes/update.ts +27 -0
- package/lib/connectors/connector-config-schema.ts +16 -0
- package/lib/connectors/connector-factory.ts +94 -0
- package/lib/connectors/connector-listener.ts +20 -0
- package/lib/{modules/connectors/funnel-discord-adapter.ts → connectors/discord-adapter.ts} +6 -11
- package/lib/{modules/connectors → connectors}/discord-connector-schema.ts +4 -1
- package/lib/connectors/discord-listener.ts +111 -0
- package/lib/{modules/connectors/funnel-gh-adapter.ts → connectors/gh-adapter.ts} +3 -6
- package/lib/{modules/connectors → connectors}/gh-connector-schema.ts +4 -1
- package/lib/{modules/connectors/funnel-gh-listener.ts → connectors/gh-listener.ts} +45 -19
- package/lib/{modules/connectors → connectors}/match-cron.ts +10 -4
- package/lib/connectors/schedule-connector-schema.ts +33 -0
- package/lib/connectors/schedule-listener.ts +207 -0
- package/lib/connectors/schedule-state-store.ts +54 -0
- package/lib/connectors/slack-adapter.ts +36 -0
- package/lib/{modules/connectors → connectors}/slack-connector-schema.ts +4 -1
- package/lib/{modules/connectors/funnel-slack-event-processor.ts → connectors/slack-event-processor.ts} +15 -9
- package/lib/{modules/connectors/funnel-slack-listener.ts → connectors/slack-listener.ts} +33 -14
- package/lib/engine/channels/channels.ts +520 -0
- package/lib/{modules/claude/funnel-claude.ts → engine/claude/claude.ts} +28 -55
- package/lib/engine/claude/gateway-controller.ts +4 -0
- package/lib/{modules/fs/funnel-file-system.ts → engine/fs/file-system.ts} +4 -0
- package/lib/{modules/fs/memory-funnel-file-system.ts → engine/fs/memory-file-system.ts} +20 -3
- package/lib/{modules/fs/node-funnel-file-system.ts → engine/fs/node-file-system.ts} +14 -2
- package/lib/{modules/http/memory-funnel-http-client.ts → engine/http/memory-http-client.ts} +1 -5
- package/lib/{modules/http/node-funnel-http-client.ts → engine/http/node-http-client.ts} +1 -5
- package/lib/{modules/id/memory-funnel-id-generator.ts → engine/id/memory-id-generator.ts} +1 -1
- package/lib/{modules/id/node-funnel-id-generator.ts → engine/id/node-id-generator.ts} +1 -1
- package/lib/{modules/logger/memory-funnel-logger.ts → engine/logger/memory-logger.ts} +1 -1
- package/lib/{modules/logger/node-funnel-logger.ts → engine/logger/node-logger.ts} +1 -1
- package/lib/{modules/logger/noop-funnel-logger.ts → engine/logger/noop-logger.ts} +1 -1
- package/lib/engine/mcp/channel-server.ts +204 -0
- package/lib/{modules/mcp/funnel-mcp.ts → engine/mcp/mcp.ts} +24 -10
- package/lib/{modules/process/memory-funnel-process-runner.ts → engine/process/memory-process-runner.ts} +1 -1
- package/lib/{modules/process/node-funnel-process-runner.ts → engine/process/node-process-runner.ts} +12 -21
- package/lib/engine/profiles/profile-channel-checker.ts +7 -0
- package/lib/{modules/profiles/funnel-profiles.ts → engine/profiles/profiles.ts} +41 -43
- package/lib/{modules/settings/mock-funnel-settings-reader.ts → engine/settings/mock-settings-reader.ts} +4 -3
- package/lib/{modules/settings/funnel-settings-reader.ts → engine/settings/settings-reader.ts} +1 -1
- package/lib/engine/settings/settings-schema.ts +46 -0
- package/lib/engine/settings/settings-store.ts +110 -0
- package/lib/{modules/time/memory-funnel-clock.ts → engine/time/memory-clock.ts} +1 -1
- package/lib/{modules/time/node-funnel-clock.ts → engine/time/node-clock.ts} +1 -1
- package/lib/funnel.ts +83 -78
- package/lib/gateway/auth-middleware.ts +44 -0
- package/lib/gateway/broadcaster.ts +319 -0
- package/lib/gateway/daemon.ts +47 -0
- package/lib/gateway/factory.ts +10 -0
- package/lib/gateway/funnel-event-store.ts +155 -0
- package/lib/gateway/gateway-server.ts +414 -0
- package/lib/gateway/gateway-token.ts +79 -0
- package/lib/{modules/gateway/funnel-gateway.ts → gateway/gateway.ts} +27 -13
- package/lib/{modules/gateway → gateway}/kill-competing-slack-gateways.ts +4 -4
- package/lib/gateway/listener-supervisor.ts +339 -0
- package/lib/gateway/listeners-client.ts +128 -0
- package/lib/gateway/resolve-daemon-script.ts +26 -0
- package/lib/gateway/routes/channels.connectors.call.ts +39 -0
- package/lib/gateway/routes/health.ts +13 -0
- package/lib/gateway/routes/index.ts +24 -0
- package/lib/gateway/routes/listeners.list.ts +6 -0
- package/lib/gateway/routes/listeners.restart.ts +15 -0
- package/lib/gateway/routes/listeners.start.ts +15 -0
- package/lib/gateway/routes/listeners.stop.ts +15 -0
- package/lib/gateway/routes/route-deps.ts +11 -0
- package/lib/gateway/routes/status.ts +15 -0
- package/lib/gateway/routes/validator.ts +17 -0
- package/lib/index.ts +50 -92
- package/lib/logger/leuco-human-file-writer.ts +65 -0
- package/lib/logger/leuco-human-logger.ts +98 -0
- package/lib/logger/leuco-human-record.ts +16 -0
- package/lib/logger/leuco-human-stdout-writer.ts +26 -0
- package/lib/logger/leuco-human-writer.ts +14 -0
- package/lib/logger/leuco-logger-memory-sink.ts +67 -0
- package/lib/logger/leuco-logger-record.ts +13 -0
- package/lib/logger/leuco-logger-sink.ts +33 -0
- package/lib/logger/leuco-logger-sqlite-sink.ts +355 -0
- package/lib/logger/leuco-logger.ts +135 -0
- package/lib/tui/app.tsx +357 -0
- package/lib/tui/components/add-row.tsx +18 -0
- package/lib/tui/components/brand.tsx +27 -0
- package/lib/tui/components/card.tsx +44 -0
- package/lib/tui/components/detail-bar.tsx +46 -0
- package/lib/tui/components/editable-field.tsx +33 -0
- package/lib/tui/components/empty-state.tsx +11 -0
- package/lib/tui/components/gateway-status.tsx +66 -0
- package/lib/tui/components/keymap.tsx +29 -0
- package/lib/tui/components/menu-item.tsx +73 -0
- package/lib/tui/components/menu.tsx +26 -0
- package/lib/tui/components/panel-header.tsx +22 -0
- package/lib/tui/components/readonly-field.tsx +18 -0
- package/lib/tui/components/section-header.tsx +25 -0
- package/lib/tui/components/selection-accent.tsx +32 -0
- package/lib/tui/components/session-item.tsx +33 -0
- package/lib/tui/components/session-list.tsx +33 -0
- package/lib/tui/components/ui/hascii/accordion-item.tsx +88 -0
- package/lib/tui/components/ui/hascii/accordion.tsx +96 -0
- package/lib/tui/components/ui/hascii/alert-dialog.tsx +43 -0
- package/lib/tui/components/ui/hascii/badge.tsx +51 -0
- package/lib/tui/components/ui/hascii/breadcrumb.tsx +58 -0
- package/lib/tui/components/ui/hascii/button.tsx +194 -0
- package/lib/tui/components/ui/hascii/card-content.tsx +14 -0
- package/lib/tui/components/ui/hascii/card-description.tsx +13 -0
- package/lib/tui/components/ui/hascii/card-footer.tsx +14 -0
- package/lib/tui/components/ui/hascii/card-header.tsx +14 -0
- package/lib/tui/components/ui/hascii/card-title.tsx +13 -0
- package/lib/tui/components/ui/hascii/card.tsx +27 -0
- package/lib/tui/components/ui/hascii/checkbox.tsx +65 -0
- package/lib/tui/components/ui/hascii/command.tsx +159 -0
- package/lib/tui/components/ui/hascii/dialog-content.tsx +14 -0
- package/lib/tui/components/ui/hascii/dialog-description.tsx +13 -0
- package/lib/tui/components/ui/hascii/dialog-footer.tsx +14 -0
- package/lib/tui/components/ui/hascii/dialog-header.tsx +14 -0
- package/lib/tui/components/ui/hascii/dialog-title.tsx +13 -0
- package/lib/tui/components/ui/hascii/dialog.tsx +27 -0
- package/lib/tui/components/ui/hascii/file-tree.tsx +142 -0
- package/lib/tui/components/ui/hascii/focus-group.tsx +62 -0
- package/lib/tui/components/ui/hascii/form-item.tsx +43 -0
- package/lib/tui/components/ui/hascii/input-otp.tsx +86 -0
- package/lib/tui/components/ui/hascii/input.tsx +130 -0
- package/lib/tui/components/ui/hascii/pagination.tsx +105 -0
- package/lib/tui/components/ui/hascii/progress.tsx +28 -0
- package/lib/tui/components/ui/hascii/select.tsx +131 -0
- package/lib/tui/components/ui/hascii/separator.tsx +35 -0
- package/lib/tui/components/ui/hascii/sidebar-content.tsx +23 -0
- package/lib/tui/components/ui/hascii/sidebar-header.tsx +14 -0
- package/lib/tui/components/ui/hascii/sidebar-menu-item.tsx +67 -0
- package/lib/tui/components/ui/hascii/sidebar.tsx +24 -0
- package/lib/tui/components/ui/hascii/skeleton.tsx +60 -0
- package/lib/tui/components/ui/hascii/slider.tsx +91 -0
- package/lib/tui/components/ui/hascii/snackbar.tsx +75 -0
- package/lib/tui/components/ui/hascii/sparkline.tsx +53 -0
- package/lib/tui/components/ui/hascii/spinner.tsx +47 -0
- package/lib/tui/components/ui/hascii/stepper.tsx +54 -0
- package/lib/tui/components/ui/hascii/switch.tsx +66 -0
- package/lib/tui/components/ui/hascii/table.tsx +95 -0
- package/lib/tui/components/ui/hascii/tabs.tsx +59 -0
- package/lib/tui/components/ui/hascii/toggle-group-item.tsx +45 -0
- package/lib/tui/components/ui/hascii/toggle-group.tsx +99 -0
- package/lib/tui/components/ui/hascii/tree.tsx +104 -0
- package/lib/tui/components/view-shell.tsx +44 -0
- package/lib/tui/filter-input.tsx +33 -0
- package/lib/tui/hooks/hascii/use-pressable.ts +54 -0
- package/lib/tui/parse-comma-list.ts +14 -0
- package/lib/tui/profile-launcher.tsx +61 -0
- package/lib/tui/scrollbar-options.ts +19 -0
- package/lib/tui/sidebar.tsx +50 -0
- package/lib/tui/theme.ts +40 -0
- package/lib/tui/tui.tsx +20 -0
- package/lib/tui/types.ts +38 -0
- package/lib/tui/unique-name.ts +18 -0
- package/lib/tui/use-event-stream.ts +133 -0
- package/lib/tui/use-snapshot.ts +99 -0
- package/lib/tui/utils/hascii/form-item-context.tsx +23 -0
- package/lib/tui/utils/hascii/input-focus-context.tsx +31 -0
- package/lib/tui/utils/hascii/theme-context.tsx +26 -0
- package/lib/tui/utils/hascii/theme.ts +176 -0
- package/lib/tui/views/channels-view.tsx +108 -0
- package/lib/tui/views/connectors-view.tsx +164 -0
- package/lib/tui/views/events-view.tsx +160 -0
- package/lib/tui/views/listeners-view.tsx +80 -0
- package/lib/tui/views/profiles-view.tsx +152 -0
- package/package.json +50 -44
- package/lib/api.ts +0 -54
- package/lib/modules/channels/channel-connector-ref-updater.ts +0 -4
- package/lib/modules/channels/funnel-channels.ts +0 -160
- package/lib/modules/connectors/connector-config-schema.ts +0 -16
- package/lib/modules/connectors/connector-existence-checker.ts +0 -3
- package/lib/modules/connectors/funnel-callable-connector-store.ts +0 -9
- package/lib/modules/connectors/funnel-connector-listener.ts +0 -5
- package/lib/modules/connectors/funnel-connector-stores.ts +0 -52
- package/lib/modules/connectors/funnel-connector-type-store.ts +0 -24
- package/lib/modules/connectors/funnel-connectors.ts +0 -151
- package/lib/modules/connectors/funnel-discord-listener.ts +0 -71
- package/lib/modules/connectors/funnel-discord-store.ts +0 -88
- package/lib/modules/connectors/funnel-gh-store.ts +0 -101
- package/lib/modules/connectors/funnel-json-connector-store.ts +0 -100
- package/lib/modules/connectors/funnel-schedule-listener.ts +0 -130
- package/lib/modules/connectors/funnel-schedule-store.ts +0 -195
- package/lib/modules/connectors/funnel-slack-adapter.ts +0 -31
- package/lib/modules/connectors/funnel-slack-store.ts +0 -90
- package/lib/modules/connectors/migrate-legacy-connectors.ts +0 -81
- package/lib/modules/connectors/schedule-connector-schema.ts +0 -18
- package/lib/modules/connectors/schedule-last-fired-store.ts +0 -48
- package/lib/modules/gateway/daemon.ts +0 -74
- package/lib/modules/gateway/funnel-broadcaster.ts +0 -37
- package/lib/modules/gateway/funnel-event-logger.ts +0 -59
- package/lib/modules/gateway/funnel-gateway-server.ts +0 -241
- package/lib/modules/mcp/channel-server.ts +0 -76
- package/lib/modules/profiles/profile-channel-checker.ts +0 -3
- package/lib/modules/profiles/profile-channel-ref-updater.ts +0 -3
- package/lib/modules/repos/funnel-repositories.ts +0 -112
- package/lib/modules/schedule/funnel-schedule.ts +0 -39
- package/lib/modules/settings/funnel-settings-store.ts +0 -56
- package/lib/modules/settings/settings-schema.ts +0 -33
- package/lib/modules/tui/app.tsx +0 -44
- package/lib/modules/tui/tui.tsx +0 -13
- package/lib/routes/channels/add.help.ts +0 -3
- package/lib/routes/channels/add.ts +0 -21
- package/lib/routes/channels/connectors-attach.help.ts +0 -3
- package/lib/routes/channels/connectors-attach.ts +0 -17
- package/lib/routes/channels/connectors-detach.help.ts +0 -3
- package/lib/routes/channels/connectors-detach.ts +0 -17
- package/lib/routes/channels/group.help.ts +0 -16
- package/lib/routes/channels/group.ts +0 -22
- package/lib/routes/channels/remove.help.ts +0 -3
- package/lib/routes/channels/remove.ts +0 -17
- package/lib/routes/channels/rename.help.ts +0 -5
- package/lib/routes/channels/rename.ts +0 -17
- package/lib/routes/channels/routes.ts +0 -19
- package/lib/routes/channels/show.help.ts +0 -1
- package/lib/routes/channels/show.ts +0 -26
- package/lib/routes/claude/claude.help.ts +0 -16
- package/lib/routes/claude/claude.ts +0 -76
- package/lib/routes/claude/routes.ts +0 -4
- package/lib/routes/connectors/add.help.ts +0 -28
- package/lib/routes/connectors/add.ts +0 -64
- package/lib/routes/connectors/group.help.ts +0 -14
- package/lib/routes/connectors/group.ts +0 -18
- package/lib/routes/connectors/remove.help.ts +0 -3
- package/lib/routes/connectors/remove.ts +0 -17
- package/lib/routes/connectors/rename.help.ts +0 -5
- package/lib/routes/connectors/rename.ts +0 -17
- package/lib/routes/connectors/routes.ts +0 -23
- package/lib/routes/connectors/schedules-add.help.ts +0 -11
- package/lib/routes/connectors/schedules-add.ts +0 -33
- package/lib/routes/connectors/schedules-group.help.ts +0 -1
- package/lib/routes/connectors/schedules-group.ts +0 -38
- package/lib/routes/connectors/schedules-remove.help.ts +0 -3
- package/lib/routes/connectors/schedules-remove.ts +0 -17
- package/lib/routes/connectors/set.help.ts +0 -8
- package/lib/routes/connectors/set.ts +0 -72
- package/lib/routes/connectors/show.help.ts +0 -1
- package/lib/routes/connectors/show.ts +0 -41
- package/lib/routes/gateway/group.help.ts +0 -15
- package/lib/routes/gateway/group.ts +0 -28
- package/lib/routes/gateway/logs.help.ts +0 -13
- package/lib/routes/gateway/logs.ts +0 -102
- package/lib/routes/gateway/restart.help.ts +0 -10
- package/lib/routes/gateway/routes.ts +0 -18
- package/lib/routes/gateway/run.help.ts +0 -12
- package/lib/routes/gateway/run.ts +0 -35
- package/lib/routes/gateway/start.help.ts +0 -15
- package/lib/routes/gateway/start.ts +0 -32
- package/lib/routes/gateway/status.help.ts +0 -9
- package/lib/routes/gateway/status.ts +0 -28
- package/lib/routes/gateway/stop.help.ts +0 -8
- package/lib/routes/gateway/stop.ts +0 -21
- package/lib/routes/profiles/add.help.ts +0 -3
- package/lib/routes/profiles/add.ts +0 -33
- package/lib/routes/profiles/group.help.ts +0 -16
- package/lib/routes/profiles/group.ts +0 -25
- package/lib/routes/profiles/launch.help.ts +0 -4
- package/lib/routes/profiles/launch.ts +0 -36
- package/lib/routes/profiles/remove.help.ts +0 -3
- package/lib/routes/profiles/remove.ts +0 -17
- package/lib/routes/profiles/rename.help.ts +0 -5
- package/lib/routes/profiles/rename.ts +0 -17
- package/lib/routes/profiles/routes.ts +0 -18
- package/lib/routes/profiles/set.help.ts +0 -5
- package/lib/routes/profiles/set.ts +0 -32
- package/lib/routes/repos/add.help.ts +0 -6
- package/lib/routes/repos/add.ts +0 -20
- package/lib/routes/repos/group.help.ts +0 -11
- package/lib/routes/repos/group.ts +0 -18
- package/lib/routes/repos/remove.help.ts +0 -3
- package/lib/routes/repos/remove.ts +0 -17
- package/lib/routes/repos/rename.help.ts +0 -5
- package/lib/routes/repos/rename.ts +0 -17
- package/lib/routes/repos/routes.ts +0 -17
- package/lib/routes/repos/set.help.ts +0 -5
- package/lib/routes/repos/set.ts +0 -21
- package/lib/routes/repos/show.help.ts +0 -1
- package/lib/routes/repos/show.ts +0 -19
- package/lib/routes/request/discord-help.ts +0 -9
- package/lib/routes/request/discord.help.ts +0 -19
- package/lib/routes/request/discord.ts +0 -65
- package/lib/routes/request/group.help.ts +0 -15
- package/lib/routes/request/group.ts +0 -9
- package/lib/routes/request/routes.ts +0 -14
- package/lib/routes/request/slack-help.ts +0 -9
- package/lib/routes/request/slack.help.ts +0 -19
- package/lib/routes/request/slack.ts +0 -61
- package/lib/routes/status/routes.ts +0 -4
- package/lib/routes/status/status.help.ts +0 -6
- package/lib/routes/status/status.ts +0 -77
- package/lib/routes/update/routes.ts +0 -4
- package/lib/routes/update/update.help.ts +0 -5
- package/lib/routes/update/update.ts +0 -21
- package/lib/routes.ts +0 -40
- /package/lib/{factory.ts → cli/factory.ts} +0 -0
- /package/lib/{modules → cli}/router/query-to-cli-args.ts +0 -0
- /package/lib/{modules → cli}/router/validator.ts +0 -0
- /package/lib/{modules/connectors/funnel-connector-adapter.ts → connectors/connector-adapter.ts} +0 -0
- /package/lib/{modules/connectors/funnel-discord-event-processor.ts → connectors/discord-event-processor.ts} +0 -0
- /package/lib/{modules/http/funnel-http-client.ts → engine/http/http-client.ts} +0 -0
- /package/lib/{modules/id/funnel-id-generator.ts → engine/id/id-generator.ts} +0 -0
- /package/lib/{modules/logger/funnel-logger.ts → engine/logger/logger.ts} +0 -0
- /package/lib/{modules/process/funnel-process-runner.ts → engine/process/process-runner.ts} +0 -0
- /package/lib/{modules/time/funnel-clock.ts → engine/time/clock.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,39 +1,33 @@
|
|
|
1
|
-
# @interactive-inc/claude-funnel
|
|
2
|
-
|
|
3
1
|
[](https://www.npmjs.com/package/@interactive-inc/claude-funnel)
|
|
4
2
|
[](./LICENSE)
|
|
5
3
|
|
|
6
|
-
A hub CLI that connects multiple Claude Code agents to external services (Slack / GitHub / Discord) and time-based triggers (cron). External events flow through subscription "channels" into Claude Code sessions, and outbound API calls from Claude are funneled through the same connectors.
|
|
4
|
+
A hub CLI that connects multiple Claude Code agents to external services (Slack / GitHub / Discord) and time-based triggers (cron). External events flow through subscription "channels" into Claude Code sessions, and outbound API calls from Claude are funneled through the same connectors as MCP tools.
|
|
7
5
|
|
|
8
6
|
The command is `funnel` or its shorthand `fnl`.
|
|
9
7
|
|
|
10
8
|
## Overview
|
|
11
9
|
|
|
12
10
|
```
|
|
13
|
-
External sources
|
|
14
|
-
(Slack / GitHub / Discord / cron)
|
|
15
|
-
│
|
|
16
|
-
▼
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
Claude Code
|
|
29
|
-
(events surfaced as <channel> tags;
|
|
30
|
-
outbound calls go back through the
|
|
31
|
-
same connectors via funnel MCP)
|
|
11
|
+
External sources Outbound calls
|
|
12
|
+
(Slack / GitHub / Discord / cron) (Claude → MCP tools per connector)
|
|
13
|
+
│ ▲
|
|
14
|
+
▼ │
|
|
15
|
+
Channels (with nested per-type connectors)
|
|
16
|
+
│
|
|
17
|
+
▼ WebSocket
|
|
18
|
+
Gateway daemon
|
|
19
|
+
(port 9742: WS /ws + listener supervisor + reply API)
|
|
20
|
+
│
|
|
21
|
+
▼ MCP (stdio)
|
|
22
|
+
Claude Code
|
|
23
|
+
(events arrive as <channel> notifications;
|
|
24
|
+
one MCP tool is exposed per configured connector
|
|
25
|
+
so Claude can reply / send / call APIs without bash)
|
|
32
26
|
```
|
|
33
27
|
|
|
34
28
|
## Requirements
|
|
35
29
|
|
|
36
|
-
- [Bun](https://bun.sh) 1.3 or later (runtime)
|
|
30
|
+
- [Bun](https://bun.sh) 1.3 or later (runtime — used at install time to build the CLI bundle and at runtime to execute it)
|
|
37
31
|
- [Claude Code](https://docs.claude.com/en/docs/claude-code) CLI
|
|
38
32
|
- A Slack / GitHub / Discord token or CLI, depending on which connectors you use
|
|
39
33
|
|
|
@@ -43,166 +37,191 @@ External sources
|
|
|
43
37
|
bun add -g @interactive-inc/claude-funnel
|
|
44
38
|
```
|
|
45
39
|
|
|
46
|
-
After install, `funnel` and `fnl` are available globally.
|
|
40
|
+
`postinstall` runs `bun run build` to produce a single bundled CLI at `dist/bin.js`. After install, `funnel` and `fnl` are available globally.
|
|
47
41
|
|
|
48
42
|
## Quick start
|
|
49
43
|
|
|
50
44
|
```bash
|
|
51
|
-
#
|
|
52
|
-
fnl
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
fnl channels add my-inbox
|
|
56
|
-
fnl channels my-inbox connectors attach my-slack
|
|
45
|
+
# Create a subscription box (channel) and attach a connector
|
|
46
|
+
fnl channels add ops
|
|
47
|
+
fnl channels ops connectors add my-slack --type=slack \
|
|
48
|
+
--bot-token=xoxb-... --app-token=xapp-...
|
|
57
49
|
|
|
58
|
-
# Start the gateway (connects to Slack Socket Mode)
|
|
50
|
+
# Start the gateway (connects to Slack Socket Mode and surfaces events)
|
|
59
51
|
fnl gateway start
|
|
60
52
|
|
|
61
|
-
# Launch Claude
|
|
62
|
-
fnl claude --channel
|
|
53
|
+
# Launch Claude with a raw channel binding (no profile required)
|
|
54
|
+
fnl claude --channel ops
|
|
55
|
+
|
|
56
|
+
# Or save it as a profile and launch by name
|
|
57
|
+
fnl profiles add cto --path=/repo/myapp --sub-agent=cto --channel=ops
|
|
58
|
+
fnl claude --profile cto
|
|
63
59
|
```
|
|
64
60
|
|
|
65
61
|
Schedule (cron) trigger:
|
|
66
62
|
|
|
67
63
|
```bash
|
|
68
|
-
#
|
|
69
|
-
fnl connectors add daily --type
|
|
70
|
-
fnl connectors daily schedules add
|
|
71
|
-
|
|
72
|
-
# Attach it to a channel just like any other connector
|
|
73
|
-
fnl channels my-inbox connectors attach daily
|
|
64
|
+
# A schedule connector contains many cron entries
|
|
65
|
+
fnl channels ops connectors add daily --type=schedule
|
|
66
|
+
fnl channels ops connectors daily schedules add morning \
|
|
67
|
+
--cron="0 9 * * *" --prompt="morning standup"
|
|
74
68
|
```
|
|
75
69
|
|
|
76
|
-
##
|
|
70
|
+
## CLI surface
|
|
77
71
|
|
|
78
|
-
|
|
79
|
-
fnl connectors list
|
|
80
|
-
fnl connectors add <name> --type slack --bot-token xoxb-... --app-token xapp-...
|
|
81
|
-
fnl connectors add <name> --type gh [--poll-interval <sec>]
|
|
82
|
-
fnl connectors add <name> --type discord --bot-token <token>
|
|
83
|
-
fnl connectors add <name> --type schedule
|
|
84
|
-
fnl connectors <name> show details
|
|
85
|
-
fnl connectors <name> set [--bot-token ...] [--app-token ...] [--poll-interval ...]
|
|
86
|
-
fnl connectors rename <old> <new>
|
|
87
|
-
fnl connectors remove <name>
|
|
88
|
-
|
|
89
|
-
fnl connectors <name> schedules list cron entries
|
|
90
|
-
fnl connectors <name> schedules add --cron "<expr>" --prompt "<text>" [--disabled]
|
|
91
|
-
fnl connectors <name> schedules remove <id>
|
|
92
|
-
|
|
93
|
-
fnl request slack post <path> [body] --connector <name> call Slack Web API
|
|
94
|
-
fnl request discord <method> <path> [body] --connector <name> call Discord REST API
|
|
95
|
-
|
|
96
|
-
fnl channels list
|
|
97
|
-
fnl channels add <name>
|
|
98
|
-
fnl channels <name> show details
|
|
99
|
-
fnl channels <name> connectors attach <connector>
|
|
100
|
-
fnl channels <name> connectors detach <connector>
|
|
101
|
-
fnl channels rename <old> <new>
|
|
102
|
-
fnl channels remove <name>
|
|
72
|
+
Connectors live nested inside their owning channel. Every CLI verb (`add` / `set` / `remove` / `rename` / `as-default` / `request`) maps to `POST` plus the verb in the URL — there is no method-stripping, so the same word stays visible in both shell and HTTP form. Read paths (no verb) stay `GET`.
|
|
103
73
|
|
|
104
|
-
|
|
105
|
-
fnl
|
|
106
|
-
fnl
|
|
107
|
-
fnl
|
|
108
|
-
fnl
|
|
74
|
+
```text
|
|
75
|
+
fnl channels list
|
|
76
|
+
fnl channels add <name> [--delivery=fanout|exclusive]
|
|
77
|
+
fnl channels <name> show details
|
|
78
|
+
fnl channels remove <name>
|
|
79
|
+
fnl channels rename <old> <new> (also `fnl channels <old> rename <new>`)
|
|
80
|
+
fnl channels <name> set delivery <mode>
|
|
81
|
+
|
|
82
|
+
fnl channels <ch> connectors list
|
|
83
|
+
fnl channels <ch> connectors add <c> --type=slack --bot-token=xoxb-... --app-token=xapp-...
|
|
84
|
+
fnl channels <ch> connectors add <c> --type=gh [--poll-interval=<sec>]
|
|
85
|
+
fnl channels <ch> connectors add <c> --type=discord --bot-token=<token>
|
|
86
|
+
fnl channels <ch> connectors add <c> --type=schedule
|
|
87
|
+
fnl channels <ch> connectors <c> show config
|
|
88
|
+
fnl channels <ch> connectors set <c> [--bot-token=...] [--app-token=...] [--poll-interval=...]
|
|
89
|
+
fnl channels <ch> connectors remove <c>
|
|
90
|
+
fnl channels <ch> connectors rename <c> <new>
|
|
91
|
+
fnl channels <ch> connectors <c> request --method=<api.method> [--key=value ...]
|
|
92
|
+
|
|
93
|
+
fnl channels <ch> connectors <c> schedules list cron entries
|
|
94
|
+
fnl channels <ch> connectors <c> schedules add <id> --cron="<expr>" --prompt="<text>" \
|
|
95
|
+
[--enabled=true] [--catchup-policy=latest|all|skip]
|
|
96
|
+
fnl channels <ch> connectors <c> schedules remove <id>
|
|
97
|
+
|
|
98
|
+
fnl profiles list (first entry is the default)
|
|
99
|
+
fnl profiles add <name> --path=<dir> --sub-agent=<agent> --channel=<channel-name>
|
|
100
|
+
fnl profiles <name> launch (alias for `<name> run`)
|
|
101
|
+
fnl profiles <name> run launch (sugar for `fnl claude --profile <name>`)
|
|
102
|
+
fnl profiles <name> set [--path=...] [--sub-agent=...] [--channel=...]
|
|
103
|
+
fnl profiles <name> as-default move to the front of the list
|
|
109
104
|
fnl profiles rename <old> <new>
|
|
110
105
|
fnl profiles remove <name>
|
|
111
106
|
|
|
112
|
-
fnl
|
|
113
|
-
fnl
|
|
114
|
-
fnl
|
|
115
|
-
fnl
|
|
116
|
-
fnl repos rename <old> <new>
|
|
117
|
-
fnl repos remove <name>
|
|
107
|
+
fnl claude launch the default profile
|
|
108
|
+
fnl claude --profile <name> launch a named profile
|
|
109
|
+
fnl claude --channel <name> raw launch (no profile, cwd = current dir)
|
|
110
|
+
fnl mcp run as an MCP server (invoked from .mcp.json)
|
|
118
111
|
|
|
119
|
-
fnl
|
|
120
|
-
fnl
|
|
121
|
-
fnl
|
|
122
|
-
|
|
123
|
-
fnl
|
|
112
|
+
fnl gateway status (default subcommand)
|
|
113
|
+
fnl gateway {start|stop|restart} daemon lifecycle
|
|
114
|
+
fnl gateway run foreground daemon (developer mode)
|
|
115
|
+
fnl gateway logs [-n <N>] tail diagnostic log
|
|
116
|
+
fnl gateway listeners live registry (alive / dead)
|
|
124
117
|
|
|
125
|
-
fnl gateway
|
|
126
|
-
fnl
|
|
127
|
-
fnl
|
|
128
|
-
fnl status overall status (connectors / channels / profiles / repos / gateway)
|
|
118
|
+
fnl status overall status (channels / profiles / gateway / clients)
|
|
119
|
+
fnl update `bun i -g @interactive-inc/claude-funnel`
|
|
120
|
+
fnl (no args) launch the OpenTUI dashboard
|
|
129
121
|
|
|
130
122
|
fnl --version
|
|
131
|
-
fnl --help
|
|
123
|
+
fnl --help every subcommand has --help; verb-without-arg also returns help
|
|
132
124
|
```
|
|
133
125
|
|
|
126
|
+
`--channel` accepts the channel **name** (not the uuid). The CLI resolves it to a channel id before calling the engine.
|
|
127
|
+
|
|
128
|
+
## Reply path: MCP tools per connector
|
|
129
|
+
|
|
130
|
+
When `fnl claude` launches Claude Code, the funnel MCP server connects to the gateway and reads the channel's connectors from `~/.funnel/settings.json`. For every callable connector (`slack` / `discord` / `gh`; `schedule` is one-way and skipped), the MCP advertises one tool with the connector's name. Claude can call them like:
|
|
131
|
+
|
|
132
|
+
```jsonc
|
|
133
|
+
// MCP: tools/list returns
|
|
134
|
+
{ "name": "discord", "inputSchema": { ... { method, path, body } ... } }
|
|
135
|
+
{ "name": "ops-slack", "inputSchema": { ... } }
|
|
136
|
+
{ "name": "gh-main", "inputSchema": { ... } }
|
|
137
|
+
|
|
138
|
+
// Claude calls
|
|
139
|
+
tools/call name="discord" arguments={
|
|
140
|
+
"method": "POST",
|
|
141
|
+
"path": "/channels/123/messages",
|
|
142
|
+
"body": { "content": "got it" }
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The MCP forwards via HTTP `POST /channels/<channel>/connectors/<connector>/call` to the gateway daemon, which dispatches through the existing `FunnelChannels.call()` adapter. No bash subshell, no CLI cold start — replies are essentially synchronous.
|
|
147
|
+
|
|
148
|
+
If you need to invoke a connector from outside Claude, the same path is reachable as `fnl channels <ch> connectors <c> request --method=<...> [--key=value ...]`.
|
|
149
|
+
|
|
134
150
|
## Data model
|
|
135
151
|
|
|
136
152
|
```
|
|
137
|
-
|
|
153
|
+
Channel = { id, name, delivery, connectors[] }
|
|
154
|
+
subscription box; `delivery` is `fanout` (default; every WS client sees every event)
|
|
155
|
+
or `exclusive` (round-robin one client per event)
|
|
156
|
+
|
|
157
|
+
Connector =
|
|
138
158
|
| { type: "slack", name, botToken, appToken }
|
|
139
159
|
Slack Socket Mode
|
|
140
160
|
| { type: "gh", name, pollInterval? }
|
|
141
|
-
GitHub (gh CLI)
|
|
161
|
+
GitHub (gh CLI, poll-based)
|
|
142
162
|
| { type: "discord", name, botToken }
|
|
143
163
|
Discord Gateway
|
|
144
164
|
| { type: "schedule", name, entries[] }
|
|
145
|
-
cron-driven
|
|
146
|
-
|
|
147
|
-
Channel = { name, connectors[] }
|
|
148
|
-
subscription box
|
|
165
|
+
cron-driven; entries = { id, cron, prompt, enabled?, catchupPolicy? }
|
|
149
166
|
|
|
150
|
-
|
|
151
|
-
|
|
167
|
+
Profile = { name, path, subAgent, channelId }
|
|
168
|
+
named launch preset; the first profile in the list is the default
|
|
152
169
|
|
|
153
|
-
|
|
154
|
-
launch profile
|
|
155
|
-
|
|
156
|
-
Settings = { channels[], repositories[], profiles[] }
|
|
170
|
+
Settings = { channels[], profiles[] }
|
|
157
171
|
→ ~/.funnel/settings.json
|
|
158
|
-
|
|
159
|
-
Connectors are stored per type, one file per connector:
|
|
160
|
-
→ ~/.funnel/connectors/<type>/<name>.(json|jsonl)
|
|
161
172
|
```
|
|
162
173
|
|
|
174
|
+
Connectors are stored per type, one file per connector, under `~/.funnel/connectors/<type>/<name>.(json|jsonl)` so adding or retiring a type is contained to its own subdirectory.
|
|
175
|
+
|
|
163
176
|
## Programmable API (Bun)
|
|
164
177
|
|
|
165
178
|
`funnel` is also usable as a library — the same `Funnel` facade the CLI uses is exported from the package root, with no CLI side effects.
|
|
166
179
|
|
|
167
180
|
```ts
|
|
168
|
-
import {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
} from "@interactive-inc/claude-funnel"
|
|
181
|
+
import { Funnel } from "@interactive-inc/claude-funnel"
|
|
182
|
+
|
|
183
|
+
const funnel = new Funnel() // defaults to ~/.funnel + the local filesystem
|
|
172
184
|
|
|
173
|
-
const
|
|
185
|
+
const channel = funnel.channels.add({ name: "inbox" })
|
|
174
186
|
|
|
175
|
-
funnel.
|
|
187
|
+
funnel.channels.addConnector("inbox", {
|
|
176
188
|
type: "slack",
|
|
177
189
|
name: "my-slack",
|
|
178
190
|
botToken: "xoxb-...",
|
|
179
191
|
appToken: "xapp-...",
|
|
180
192
|
})
|
|
181
193
|
|
|
182
|
-
funnel.channels.
|
|
183
|
-
|
|
184
|
-
for (const c of funnel.connectors.list()) console.log(c.type, c.name)
|
|
194
|
+
for (const c of funnel.channels.list()) console.log(c.name, c.connectors.length)
|
|
185
195
|
```
|
|
186
196
|
|
|
187
|
-
|
|
197
|
+
Every facet — `channels` / `profiles` / `gateway` / `gatewayServer` / `gatewayToken` / `listeners` / `mcp` / `claude` / `factory` / `store` / `process` / `logger` — is reachable from the same instance:
|
|
188
198
|
|
|
189
199
|
```ts
|
|
190
|
-
funnel.gateway.getStatus()
|
|
191
|
-
await funnel.gateway.start()
|
|
200
|
+
funnel.gateway.getStatus() // { running, pid, port }
|
|
201
|
+
await funnel.gateway.start() // spawns the daemon as a separate process
|
|
202
|
+
|
|
203
|
+
await funnel.listeners.list() // talks to the running daemon over HTTP
|
|
204
|
+
await funnel.listeners.start("inbox", "my-slack")
|
|
205
|
+
await funnel.listeners.restart("inbox", "my-slack")
|
|
206
|
+
|
|
192
207
|
await funnel.claude.launch({ channel: "inbox" })
|
|
193
|
-
funnel.mcp.install("/path/to/repo")
|
|
208
|
+
funnel.mcp.install("/path/to/repo") // writes .mcp.json
|
|
194
209
|
```
|
|
195
210
|
|
|
196
|
-
|
|
211
|
+
Run the gateway in-process (no daemon spawn — useful for tests or embedding):
|
|
197
212
|
|
|
198
213
|
```ts
|
|
199
214
|
const server = funnel.gatewayServer({ port: 9742 })
|
|
200
|
-
await server.start()
|
|
201
|
-
server.
|
|
202
|
-
|
|
203
|
-
|
|
215
|
+
await server.start() // Bun.serve (HTTP + WS) + listener supervisor
|
|
216
|
+
const unsubscribe = server.getBroadcaster().subscribe(({ content, meta }) => {
|
|
217
|
+
console.log(meta?.connector, content)
|
|
218
|
+
})
|
|
219
|
+
await server.stop()
|
|
220
|
+
unsubscribe()
|
|
204
221
|
```
|
|
205
222
|
|
|
223
|
+
The gateway daemon exposes `/health`, `/status`, `/listeners*`, `/channels/:channel/connectors/:connector/call`, plus the `/ws?channel=<name>` WebSocket. There is no SPA; for a visual operator view, run `fnl` with no arguments to launch the OpenTUI dashboard.
|
|
224
|
+
|
|
206
225
|
Every side-effecting boundary is a DI seam. For tests / sandbox use, swap them all with the in-memory implementations and Funnel will not touch real disk, real processes, real time, or real UUIDs:
|
|
207
226
|
|
|
208
227
|
```ts
|
|
@@ -230,7 +249,7 @@ const funnel = new Funnel({
|
|
|
230
249
|
|
|
231
250
|
Available abstractions (each has `Funnel*` interface, `Node*` default, and `Memory*` for tests): `FunnelFileSystem`, `FunnelProcessRunner`, `FunnelLogger`, `FunnelClock`, `FunnelIdGenerator`. Plus `NoopFunnelLogger` for silent operation.
|
|
232
251
|
|
|
233
|
-
The package ships TypeScript sources
|
|
252
|
+
The published package ships both TypeScript sources (under `lib/`) for library consumers and a single bundled CLI (`dist/bin.js`) which is what the `fnl` / `funnel` bin entries point to. Importing `@interactive-inc/claude-funnel/bin` resolves to the bundled CLI entry — only do this if you're embedding the CLI rather than the library.
|
|
234
253
|
|
|
235
254
|
## Claude Code skill
|
|
236
255
|
|
|
@@ -268,39 +287,42 @@ After this, Claude Code will load the skill in any session.
|
|
|
268
287
|
|
|
269
288
|
## Environment variables
|
|
270
289
|
|
|
271
|
-
| Variable
|
|
272
|
-
|
|
|
273
|
-
| `FUNNEL_CHANNEL_ID`
|
|
274
|
-
| `FUNNEL_PORT`
|
|
275
|
-
| `FUNNEL_GATEWAY_URL`
|
|
290
|
+
| Variable | Purpose |
|
|
291
|
+
| ---------------------- | --------------------------------------------------------------------------------------------- |
|
|
292
|
+
| `FUNNEL_CHANNEL_ID` | Injected into the child process by `fnl claude`; the funnel MCP uses it to subscribe. |
|
|
293
|
+
| `FUNNEL_PORT` | Gateway port (default 9742). |
|
|
294
|
+
| `FUNNEL_GATEWAY_URL` | Gateway base URL used by MCP for both WS subscribe and HTTP reply (default `http://localhost:9742`). |
|
|
295
|
+
| `FUNNEL_GATEWAY_TOKEN` | Bearer token for the gateway HTTP / WS. Defaults to the contents of `~/.funnel/gateway.token`. |
|
|
276
296
|
|
|
277
297
|
## File layout
|
|
278
298
|
|
|
279
|
-
- Config: `~/.funnel/settings.json` (channels
|
|
299
|
+
- Config: `~/.funnel/settings.json` (channels with nested connectors / profiles)
|
|
280
300
|
- Connectors: `~/.funnel/connectors/<type>/<name>.(json|jsonl)`
|
|
281
301
|
- `slack/<name>.json`, `gh/<name>.json`, `discord/<name>.json`
|
|
282
302
|
- `schedule/<name>.jsonl` (one entry per line) and `schedule/<name>.state.json` (last-fired timestamps for catch-up)
|
|
283
|
-
- PID: `~/.funnel/gateway.pid`
|
|
303
|
+
- Gateway PID: `~/.funnel/gateway.pid`, token: `~/.funnel/gateway.token`
|
|
284
304
|
- Claude PIDs: `~/.funnel/claude/<profile>.pid`
|
|
285
|
-
- Event
|
|
286
|
-
-
|
|
305
|
+
- Event store: `/tmp/funnel/events/events.db` (SQLite; broadcaster events with replay-by-seq)
|
|
306
|
+
- Diagnostic log: `/tmp/funnel/funnel.log` (gateway lifecycle, connect/disconnect, listener boot — what `funnel gateway logs` tails as YAML)
|
|
307
|
+
- Process log: `/tmp/funnel/gateway.log` (daemon stdout/stderr)
|
|
287
308
|
|
|
288
309
|
## Links
|
|
289
310
|
|
|
290
311
|
- [GitHub](https://github.com/interactive-inc/open-claude-funnel)
|
|
291
312
|
- [Issues](https://github.com/interactive-inc/open-claude-funnel/issues)
|
|
292
313
|
- Coding rules and design principles: [CLAUDE.md](https://github.com/interactive-inc/open-claude-funnel/blob/main/CLAUDE.md)
|
|
293
|
-
- Design notes: [`.docs/`](https://github.com/interactive-inc/open-claude-funnel/tree/main/.docs)
|
|
294
314
|
|
|
295
315
|
## Development
|
|
296
316
|
|
|
297
317
|
```bash
|
|
298
318
|
git clone https://github.com/interactive-inc/open-claude-funnel.git
|
|
299
|
-
cd claude-funnel
|
|
300
|
-
bun install
|
|
301
|
-
bun link #
|
|
319
|
+
cd open-claude-funnel
|
|
320
|
+
bun install # postinstall builds dist/bin.js
|
|
321
|
+
bun link # symlinks fnl / funnel → dist/bin.js
|
|
322
|
+
bun run build # rebuild after editing the cli
|
|
302
323
|
bun test # run tests
|
|
303
324
|
bunx tsc -b # type check
|
|
325
|
+
bun lib/bin.ts ... # run the cli from source (no build) for fast iteration
|
|
304
326
|
```
|
|
305
327
|
|
|
306
328
|
## License
|