@interactive-inc/claude-funnel 0.10.0 → 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 (228) hide show
  1. package/dist/bin.js +448 -448
  2. package/dist/connectors/slack.d.ts +1 -29
  3. package/dist/gateway/daemon.js +166 -166
  4. package/dist/index.d.ts +4 -11
  5. package/dist/index.js +133 -120
  6. package/dist/slack-event-processor-CS-bAit9.d.ts +43 -0
  7. package/package.json +1 -6
  8. package/dist/slack-connector-schema-D7zAHN8k.d.ts +0 -15
  9. package/lib/bin.ts +0 -3
  10. package/lib/cli/factory.ts +0 -10
  11. package/lib/cli/index.ts +0 -85
  12. package/lib/cli/router/query-to-cli-args.ts +0 -20
  13. package/lib/cli/router/to-request.ts +0 -113
  14. package/lib/cli/router/validator.ts +0 -27
  15. package/lib/cli/routes/channels.$channel.connectors.$connector.rename.$newName.ts +0 -27
  16. package/lib/cli/routes/channels.$channel.connectors.$connector.request.ts +0 -40
  17. package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.add.$id.ts +0 -41
  18. package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.remove.$id.ts +0 -22
  19. package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.ts +0 -23
  20. package/lib/cli/routes/channels.$channel.connectors.$connector.ts +0 -26
  21. package/lib/cli/routes/channels.$channel.connectors.add.$connector.ts +0 -92
  22. package/lib/cli/routes/channels.$channel.connectors.remove.$connector.ts +0 -22
  23. package/lib/cli/routes/channels.$channel.connectors.set.$connector.ts +0 -63
  24. package/lib/cli/routes/channels.$channel.connectors.ts +0 -26
  25. package/lib/cli/routes/channels.$channel.publish.ts +0 -52
  26. package/lib/cli/routes/channels.$channel.rename.$newName.ts +0 -22
  27. package/lib/cli/routes/channels.$channel.set.delivery.$mode.ts +0 -34
  28. package/lib/cli/routes/channels.$channel.ts +0 -34
  29. package/lib/cli/routes/channels.add.$channel.ts +0 -33
  30. package/lib/cli/routes/channels.remove.$channel.ts +0 -20
  31. package/lib/cli/routes/channels.ts +0 -39
  32. package/lib/cli/routes/claude.ts +0 -70
  33. package/lib/cli/routes/gateway.listeners.ts +0 -41
  34. package/lib/cli/routes/gateway.logs.ts +0 -123
  35. package/lib/cli/routes/gateway.restart.ts +0 -50
  36. package/lib/cli/routes/gateway.run.ts +0 -41
  37. package/lib/cli/routes/gateway.start.ts +0 -50
  38. package/lib/cli/routes/gateway.status.ts +0 -19
  39. package/lib/cli/routes/gateway.stop.ts +0 -32
  40. package/lib/cli/routes/gateway.ts +0 -55
  41. package/lib/cli/routes/index.ts +0 -219
  42. package/lib/cli/routes/profiles.$profile.as-default.ts +0 -22
  43. package/lib/cli/routes/profiles.$profile.rename.$newName.ts +0 -22
  44. package/lib/cli/routes/profiles.$profile.run.ts +0 -36
  45. package/lib/cli/routes/profiles.add.$profile.ts +0 -49
  46. package/lib/cli/routes/profiles.remove.$profile.ts +0 -20
  47. package/lib/cli/routes/profiles.set.$profile.ts +0 -45
  48. package/lib/cli/routes/profiles.ts +0 -40
  49. package/lib/cli/routes/status.ts +0 -93
  50. package/lib/cli/routes/update.ts +0 -27
  51. package/lib/connectors/connector-adapter.ts +0 -9
  52. package/lib/connectors/connector-config-schema.ts +0 -16
  53. package/lib/connectors/connector-factory.ts +0 -94
  54. package/lib/connectors/connector-listener.ts +0 -20
  55. package/lib/connectors/discord-adapter.ts +0 -51
  56. package/lib/connectors/discord-connector-schema.ts +0 -12
  57. package/lib/connectors/discord-event-processor.ts +0 -48
  58. package/lib/connectors/discord-listener.ts +0 -111
  59. package/lib/connectors/discord.ts +0 -4
  60. package/lib/connectors/gh-adapter.ts +0 -48
  61. package/lib/connectors/gh-connector-schema.ts +0 -12
  62. package/lib/connectors/gh-listener.ts +0 -137
  63. package/lib/connectors/gh.ts +0 -3
  64. package/lib/connectors/match-cron.ts +0 -78
  65. package/lib/connectors/schedule-connector-schema.ts +0 -33
  66. package/lib/connectors/schedule-listener.ts +0 -207
  67. package/lib/connectors/schedule-state-store.ts +0 -54
  68. package/lib/connectors/schedule.ts +0 -4
  69. package/lib/connectors/slack-adapter.ts +0 -36
  70. package/lib/connectors/slack-connector-schema.ts +0 -13
  71. package/lib/connectors/slack-event-processor.ts +0 -97
  72. package/lib/connectors/slack-listener.ts +0 -97
  73. package/lib/connectors/slack.ts +0 -4
  74. package/lib/engine/channels/channels.ts +0 -520
  75. package/lib/engine/claude/claude.ts +0 -205
  76. package/lib/engine/claude/gateway-controller.ts +0 -4
  77. package/lib/engine/fs/file-system.ts +0 -23
  78. package/lib/engine/fs/memory-file-system.ts +0 -102
  79. package/lib/engine/fs/node-file-system.ts +0 -68
  80. package/lib/engine/http/http-client.ts +0 -17
  81. package/lib/engine/http/memory-http-client.ts +0 -36
  82. package/lib/engine/http/node-http-client.ts +0 -23
  83. package/lib/engine/id/id-generator.ts +0 -7
  84. package/lib/engine/id/memory-id-generator.ts +0 -20
  85. package/lib/engine/id/node-id-generator.ts +0 -7
  86. package/lib/engine/logger/logger.ts +0 -11
  87. package/lib/engine/logger/memory-logger.ts +0 -28
  88. package/lib/engine/logger/node-logger.ts +0 -49
  89. package/lib/engine/logger/noop-logger.ts +0 -9
  90. package/lib/engine/mcp/channel-server.ts +0 -123
  91. package/lib/engine/mcp/channel-subscriber.ts +0 -82
  92. package/lib/engine/mcp/mcp.ts +0 -126
  93. package/lib/engine/mcp/read-channel-connectors.ts +0 -34
  94. package/lib/engine/mcp/read-gateway-token.ts +0 -16
  95. package/lib/engine/mcp/usage-hint-for-type.ts +0 -15
  96. package/lib/engine/process/memory-process-runner.ts +0 -88
  97. package/lib/engine/process/node-process-runner.ts +0 -91
  98. package/lib/engine/process/process-runner.ts +0 -33
  99. package/lib/engine/profiles/profile-channel-checker.ts +0 -7
  100. package/lib/engine/profiles/profiles.ts +0 -126
  101. package/lib/engine/settings/mock-settings-reader.ts +0 -27
  102. package/lib/engine/settings/settings-reader.ts +0 -6
  103. package/lib/engine/settings/settings-schema.ts +0 -48
  104. package/lib/engine/settings/settings-store.ts +0 -110
  105. package/lib/engine/time/clock.ts +0 -15
  106. package/lib/engine/time/memory-clock.ts +0 -26
  107. package/lib/engine/time/node-clock.ts +0 -7
  108. package/lib/funnel.ts +0 -294
  109. package/lib/gateway/auth-middleware.ts +0 -44
  110. package/lib/gateway/broadcaster.ts +0 -319
  111. package/lib/gateway/channel-publisher.ts +0 -67
  112. package/lib/gateway/daemon.ts +0 -47
  113. package/lib/gateway/factory.ts +0 -10
  114. package/lib/gateway/funnel-event-store.ts +0 -155
  115. package/lib/gateway/gateway-server.ts +0 -426
  116. package/lib/gateway/gateway-token.ts +0 -79
  117. package/lib/gateway/gateway.ts +0 -209
  118. package/lib/gateway/kill-competing-slack-gateways.ts +0 -56
  119. package/lib/gateway/listener-supervisor.ts +0 -339
  120. package/lib/gateway/listeners-client.ts +0 -128
  121. package/lib/gateway/publish-schema.ts +0 -27
  122. package/lib/gateway/resolve-daemon-script.ts +0 -26
  123. package/lib/gateway/routes/channels.connectors.call.ts +0 -39
  124. package/lib/gateway/routes/channels.publish.ts +0 -44
  125. package/lib/gateway/routes/health.ts +0 -13
  126. package/lib/gateway/routes/index.ts +0 -26
  127. package/lib/gateway/routes/listeners.list.ts +0 -6
  128. package/lib/gateway/routes/listeners.restart.ts +0 -15
  129. package/lib/gateway/routes/listeners.start.ts +0 -15
  130. package/lib/gateway/routes/listeners.stop.ts +0 -15
  131. package/lib/gateway/routes/route-deps.ts +0 -19
  132. package/lib/gateway/routes/status.ts +0 -15
  133. package/lib/gateway/routes/validator.ts +0 -17
  134. package/lib/index.ts +0 -67
  135. package/lib/logger/leuco-human-file-writer.ts +0 -65
  136. package/lib/logger/leuco-human-logger.ts +0 -98
  137. package/lib/logger/leuco-human-record.ts +0 -16
  138. package/lib/logger/leuco-human-stdout-writer.ts +0 -26
  139. package/lib/logger/leuco-human-writer.ts +0 -14
  140. package/lib/logger/leuco-logger-memory-sink.ts +0 -67
  141. package/lib/logger/leuco-logger-record.ts +0 -13
  142. package/lib/logger/leuco-logger-sink.ts +0 -33
  143. package/lib/logger/leuco-logger-sqlite-sink.ts +0 -355
  144. package/lib/logger/leuco-logger.ts +0 -135
  145. package/lib/tui/app.tsx +0 -357
  146. package/lib/tui/components/add-row.tsx +0 -18
  147. package/lib/tui/components/brand.tsx +0 -27
  148. package/lib/tui/components/card.tsx +0 -44
  149. package/lib/tui/components/detail-bar.tsx +0 -46
  150. package/lib/tui/components/editable-field.tsx +0 -33
  151. package/lib/tui/components/empty-state.tsx +0 -11
  152. package/lib/tui/components/gateway-status.tsx +0 -66
  153. package/lib/tui/components/keymap.tsx +0 -29
  154. package/lib/tui/components/menu-item.tsx +0 -73
  155. package/lib/tui/components/menu.tsx +0 -26
  156. package/lib/tui/components/panel-header.tsx +0 -22
  157. package/lib/tui/components/readonly-field.tsx +0 -18
  158. package/lib/tui/components/section-header.tsx +0 -25
  159. package/lib/tui/components/selection-accent.tsx +0 -32
  160. package/lib/tui/components/session-item.tsx +0 -33
  161. package/lib/tui/components/session-list.tsx +0 -33
  162. package/lib/tui/components/ui/hascii/accordion-item.tsx +0 -88
  163. package/lib/tui/components/ui/hascii/accordion.tsx +0 -96
  164. package/lib/tui/components/ui/hascii/alert-dialog.tsx +0 -43
  165. package/lib/tui/components/ui/hascii/badge.tsx +0 -51
  166. package/lib/tui/components/ui/hascii/breadcrumb.tsx +0 -58
  167. package/lib/tui/components/ui/hascii/button.tsx +0 -194
  168. package/lib/tui/components/ui/hascii/card-content.tsx +0 -14
  169. package/lib/tui/components/ui/hascii/card-description.tsx +0 -13
  170. package/lib/tui/components/ui/hascii/card-footer.tsx +0 -14
  171. package/lib/tui/components/ui/hascii/card-header.tsx +0 -14
  172. package/lib/tui/components/ui/hascii/card-title.tsx +0 -13
  173. package/lib/tui/components/ui/hascii/card.tsx +0 -27
  174. package/lib/tui/components/ui/hascii/checkbox.tsx +0 -65
  175. package/lib/tui/components/ui/hascii/command.tsx +0 -159
  176. package/lib/tui/components/ui/hascii/dialog-content.tsx +0 -14
  177. package/lib/tui/components/ui/hascii/dialog-description.tsx +0 -13
  178. package/lib/tui/components/ui/hascii/dialog-footer.tsx +0 -14
  179. package/lib/tui/components/ui/hascii/dialog-header.tsx +0 -14
  180. package/lib/tui/components/ui/hascii/dialog-title.tsx +0 -13
  181. package/lib/tui/components/ui/hascii/dialog.tsx +0 -27
  182. package/lib/tui/components/ui/hascii/file-tree.tsx +0 -142
  183. package/lib/tui/components/ui/hascii/focus-group.tsx +0 -62
  184. package/lib/tui/components/ui/hascii/form-item.tsx +0 -43
  185. package/lib/tui/components/ui/hascii/input-otp.tsx +0 -86
  186. package/lib/tui/components/ui/hascii/input.tsx +0 -130
  187. package/lib/tui/components/ui/hascii/pagination.tsx +0 -105
  188. package/lib/tui/components/ui/hascii/progress.tsx +0 -28
  189. package/lib/tui/components/ui/hascii/select.tsx +0 -131
  190. package/lib/tui/components/ui/hascii/separator.tsx +0 -35
  191. package/lib/tui/components/ui/hascii/sidebar-content.tsx +0 -23
  192. package/lib/tui/components/ui/hascii/sidebar-header.tsx +0 -14
  193. package/lib/tui/components/ui/hascii/sidebar-menu-item.tsx +0 -67
  194. package/lib/tui/components/ui/hascii/sidebar.tsx +0 -24
  195. package/lib/tui/components/ui/hascii/skeleton.tsx +0 -60
  196. package/lib/tui/components/ui/hascii/slider.tsx +0 -91
  197. package/lib/tui/components/ui/hascii/snackbar.tsx +0 -75
  198. package/lib/tui/components/ui/hascii/sparkline.tsx +0 -53
  199. package/lib/tui/components/ui/hascii/spinner.tsx +0 -47
  200. package/lib/tui/components/ui/hascii/stepper.tsx +0 -54
  201. package/lib/tui/components/ui/hascii/switch.tsx +0 -66
  202. package/lib/tui/components/ui/hascii/table.tsx +0 -95
  203. package/lib/tui/components/ui/hascii/tabs.tsx +0 -59
  204. package/lib/tui/components/ui/hascii/toggle-group-item.tsx +0 -45
  205. package/lib/tui/components/ui/hascii/toggle-group.tsx +0 -99
  206. package/lib/tui/components/ui/hascii/tree.tsx +0 -104
  207. package/lib/tui/components/view-shell.tsx +0 -44
  208. package/lib/tui/filter-input.tsx +0 -33
  209. package/lib/tui/hooks/hascii/use-pressable.ts +0 -54
  210. package/lib/tui/parse-comma-list.ts +0 -14
  211. package/lib/tui/profile-launcher.tsx +0 -61
  212. package/lib/tui/scrollbar-options.ts +0 -19
  213. package/lib/tui/sidebar.tsx +0 -50
  214. package/lib/tui/theme.ts +0 -40
  215. package/lib/tui/tui.tsx +0 -20
  216. package/lib/tui/types.ts +0 -38
  217. package/lib/tui/unique-name.ts +0 -18
  218. package/lib/tui/use-event-stream.ts +0 -133
  219. package/lib/tui/use-snapshot.ts +0 -99
  220. package/lib/tui/utils/hascii/form-item-context.tsx +0 -23
  221. package/lib/tui/utils/hascii/input-focus-context.tsx +0 -31
  222. package/lib/tui/utils/hascii/theme-context.tsx +0 -26
  223. package/lib/tui/utils/hascii/theme.ts +0 -176
  224. package/lib/tui/views/channels-view.tsx +0 -108
  225. package/lib/tui/views/connectors-view.tsx +0 -164
  226. package/lib/tui/views/events-view.tsx +0 -160
  227. package/lib/tui/views/listeners-view.tsx +0 -80
  228. package/lib/tui/views/profiles-view.tsx +0 -152
package/dist/index.d.ts CHANGED
@@ -3,10 +3,10 @@ import { n as discordConnectorSchema, t as DiscordConnectorConfig } from "./disc
3
3
  import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "./logger-CTlXs7z4.js";
4
4
  import { a as FunnelProcessRunner, i as DetachOptions, n as ghConnectorSchema, o as RunOptions, r as AttachOptions, s as RunResult, t as GhConnectorConfig } from "./gh-connector-schema-BZFAS-p-.js";
5
5
  import { a as ScheduleEntry, c as scheduleEntrySchema, i as ScheduleConnectorConfig, n as FunnelFileSystem, o as scheduleCatchupPolicySchema, r as ScheduleCatchupPolicy, s as scheduleConnectorSchema, t as FileStat } from "./file-system-Co60LrmR.js";
6
- import { n as slackConnectorSchema, t as SlackConnectorConfig } from "./slack-connector-schema-D7zAHN8k.js";
6
+ import { a as SlackRawEvent, i as SlackProcessedSkip, n as SlackProcessed, o as SlackConnectorConfig, r as SlackProcessedEmit, s as slackConnectorSchema, t as FunnelSlackEventProcessor } from "./slack-event-processor-CS-bAit9.js";
7
7
  import { z } from "zod";
8
- import { Server, ServerWebSocket } from "bun";
9
8
  import * as _$hono_factory0 from "hono/factory";
9
+ import { Server, ServerWebSocket } from "bun";
10
10
  import * as _$hono_utils_http_status0 from "hono/utils/http-status";
11
11
  import * as _$hono_hono_base0 from "hono/hono-base";
12
12
 
@@ -339,13 +339,7 @@ declare class FunnelChannels {
339
339
  listener: FunnelConnectorListener;
340
340
  }[];
341
341
  private requireChannel;
342
- private requireConnector;
343
- private requireSlackConnector;
344
- private requireGhConnector;
345
- private requireDiscordConnector;
346
- private requireScheduleConnector;
347
342
  private assertNoTokenCollision;
348
- private tokensOf;
349
343
  }
350
344
  //#endregion
351
345
  //#region lib/engine/claude/gateway-controller.d.ts
@@ -1037,7 +1031,7 @@ type Props$4 = {
1037
1031
  */
1038
1032
  declare class Funnel {
1039
1033
  private readonly props;
1040
- private readonly cache;
1034
+ private readonly memos;
1041
1035
  constructor(props?: Props$4);
1042
1036
  /**
1043
1037
  * Sandboxed Funnel wired with in-memory implementations for every IO boundary.
@@ -1045,7 +1039,6 @@ declare class Funnel {
1045
1039
  * and ad-hoc experiments. Override individual fields by passing them in `props`.
1046
1040
  */
1047
1041
  static inMemory(props?: Props$4): Funnel;
1048
- private memo;
1049
1042
  /** Resolved on-disk paths the facade will read/write when methods are called. Pure compute, not memoized. */
1050
1043
  get paths(): {
1051
1044
  dir: string;
@@ -3885,4 +3878,4 @@ ${string}`;
3885
3878
  //#region lib/tui/tui.d.ts
3886
3879
  declare function launchTui(funnel: Funnel): Promise<void>;
3887
3880
  //#endregion
3888
- export { AttachOptions, BroadcastEvent, BroadcastSubscriber, ChannelConfig, ChannelConnectorView, ChannelDeliveryMode, ChannelServerOptions, ConnectorConfig, ConnectorType, DEFAULT_GATEWAY_TOKEN_PATH, DetachOptions, DiscordConnectorConfig, Env, FUNNEL_DIR, FUNNEL_MCP_COMMAND, FUNNEL_MCP_NAME, FileStat, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClaude, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelEvent, FunnelEventStore, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLogger, FunnelMcp, FunnelProcessRunner, FunnelProfiles, FunnelSettingsReader, FunnelSettingsStore, GhConnectorConfig, LaunchOptions, ListListenersResult, ListenerEntry, ListenerOpResult, LogEntry, MemoryFunnelClock, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryProcessCall, MemoryProcessHandler, MemoryProcessResponse, MemoryProcessSyncHandler, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NoopFunnelLogger, NotifyFn, ProfileConfig, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, RunOptions, RunResult, SETTINGS_PATH, SETTINGS_VERSION, ScheduleCatchupPolicy, type ScheduleConnectorConfig, ScheduleEntry, Settings, SlackConnectorConfig, channelConfigSchema, channelDeliveryModeSchema, app as cliApp, connectorConfigSchema, createCliApp, createSettings, discordConnectorSchema, factory, funnelEventSchema, ghConnectorSchema, launchTui, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, startChannelServer, toRequest };
3881
+ export { AttachOptions, BroadcastEvent, BroadcastSubscriber, ChannelConfig, ChannelConnectorView, ChannelDeliveryMode, ChannelServerOptions, ConnectorConfig, ConnectorType, DEFAULT_GATEWAY_TOKEN_PATH, DetachOptions, DiscordConnectorConfig, Env, FUNNEL_DIR, FUNNEL_MCP_COMMAND, FUNNEL_MCP_NAME, FileStat, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClaude, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelEvent, FunnelEventStore, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLogger, FunnelMcp, FunnelProcessRunner, FunnelProfiles, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, GhConnectorConfig, LaunchOptions, ListListenersResult, ListenerEntry, ListenerOpResult, LogEntry, MemoryFunnelClock, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryProcessCall, MemoryProcessHandler, MemoryProcessResponse, MemoryProcessSyncHandler, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NoopFunnelLogger, NotifyFn, ProfileConfig, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, RunOptions, RunResult, SETTINGS_PATH, SETTINGS_VERSION, ScheduleCatchupPolicy, ScheduleConnectorConfig, ScheduleEntry, Settings, SlackConnectorConfig, SlackProcessed, SlackProcessedEmit, SlackProcessedSkip, SlackRawEvent, channelConfigSchema, channelDeliveryModeSchema, app as cliApp, connectorConfigSchema, createCliApp, createSettings, discordConnectorSchema, factory, funnelEventSchema, ghConnectorSchema, launchTui, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, startChannelServer, toRequest };
package/dist/index.js CHANGED
@@ -2,18 +2,18 @@ import { i as FunnelDiscordAdapter, n as FunnelDiscordListener, t as discordConn
2
2
  import { n as FunnelLogger, r as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-DQz_BGOD.js";
3
3
  import { a as FunnelProcessRunner, i as NodeFunnelProcessRunner, n as FunnelGhListener, r as FunnelGhAdapter, t as ghConnectorSchema } from "./gh-connector-schema-2ml29MBC.js";
4
4
  import { a as ScheduleStateStore, i as FunnelScheduleListener, n as scheduleConnectorSchema, o as NodeFunnelFileSystem, r as scheduleEntrySchema, s as FunnelFileSystem, t as scheduleCatchupPolicySchema } from "./schedule-connector-schema-CkuIQ0JQ.js";
5
- import { i as FunnelSlackAdapter, n as FunnelSlackListener, t as slackConnectorSchema } from "./slack-connector-schema-Cd22WiHB.js";
5
+ import { i as FunnelSlackAdapter, n as FunnelSlackListener, r as FunnelSlackEventProcessor, t as slackConnectorSchema } from "./slack-connector-schema-Cd22WiHB.js";
6
6
  import { dirname, join, resolve } from "node:path";
7
7
  import { existsSync, mkdirSync, readFileSync } from "node:fs";
8
8
  import { z } from "zod";
9
9
  import { homedir } from "node:os";
10
- import "bun";
10
+ import { fileURLToPath } from "node:url";
11
11
  import { timingSafeEqual } from "node:crypto";
12
12
  import { createFactory } from "hono/factory";
13
13
  import { Database } from "bun:sqlite";
14
14
  import { HTTPException } from "hono/http-exception";
15
15
  import { zValidator } from "@hono/zod-validator";
16
- import { Server as Server$1 } from "@modelcontextprotocol/sdk/server/index.js";
16
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
17
17
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
18
18
  import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
19
19
  import { stringify } from "yaml";
@@ -183,6 +183,40 @@ var FunnelConnectorFactory = class {
183
183
  }
184
184
  };
185
185
  //#endregion
186
+ //#region lib/engine/channels/connector-tokens.ts
187
+ /**
188
+ * Return every secret token contained in a connector config. Used by token
189
+ * collision detection at add/update time so the same Slack bot or Discord
190
+ * bot cannot be registered under two connectors. Centralizes the per-type
191
+ * switch so the channels facade does not embed type-specific knowledge.
192
+ */
193
+ function connectorTokens(connector) {
194
+ switch (connector.type) {
195
+ case "slack": return [connector.botToken, connector.appToken];
196
+ case "discord": return [connector.botToken];
197
+ case "gh":
198
+ case "schedule": return [];
199
+ }
200
+ }
201
+ //#endregion
202
+ //#region lib/engine/channels/require-connector.ts
203
+ function isConnectorOfType(connector, type) {
204
+ return connector.type === type;
205
+ }
206
+ /**
207
+ * Look up a connector by name and narrow its discriminated union to a single
208
+ * variant via a type predicate. Throws if the connector is missing or has the
209
+ * wrong `type`. Replaces per-type `requireXxxConnector` privates — adding a
210
+ * new connector type only touches the `ConnectorConfig` union, not this
211
+ * helper.
212
+ */
213
+ function requireConnectorOfType(channel, connectorName, type) {
214
+ const connector = channel.connectors.find((c) => c.name === connectorName);
215
+ if (!connector) throw new Error(`connector "${connectorName}" not found in channel "${channel.name}"`);
216
+ if (!isConnectorOfType(connector, type)) throw new Error(`connector "${connectorName}" is type "${connector.type}", not "${type}"`);
217
+ return connector;
218
+ }
219
+ //#endregion
186
220
  //#region lib/engine/time/clock.ts
187
221
  /**
188
222
  * Time boundary. Default NodeFunnelClock returns `new Date()`; MemoryFunnelClock
@@ -320,39 +354,41 @@ var FunnelChannels = class {
320
354
  const now = this.clock.iso();
321
355
  const createdAt = now;
322
356
  const updatedAt = now;
323
- if (input.type === "slack") return {
324
- id,
325
- type: "slack",
326
- name: input.name,
327
- botToken: input.botToken,
328
- appToken: input.appToken,
329
- createdAt,
330
- updatedAt
331
- };
332
- if (input.type === "gh") return {
333
- id,
334
- type: "gh",
335
- name: input.name,
336
- ...input.pollInterval !== void 0 ? { pollInterval: input.pollInterval } : {},
337
- createdAt,
338
- updatedAt
339
- };
340
- if (input.type === "discord") return {
341
- id,
342
- type: "discord",
343
- name: input.name,
344
- botToken: input.botToken,
345
- createdAt,
346
- updatedAt
347
- };
348
- return {
349
- id,
350
- type: "schedule",
351
- name: input.name,
352
- entries: input.entries ?? [],
353
- createdAt,
354
- updatedAt
355
- };
357
+ switch (input.type) {
358
+ case "slack": return {
359
+ id,
360
+ type: "slack",
361
+ name: input.name,
362
+ botToken: input.botToken,
363
+ appToken: input.appToken,
364
+ createdAt,
365
+ updatedAt
366
+ };
367
+ case "gh": return {
368
+ id,
369
+ type: "gh",
370
+ name: input.name,
371
+ ...input.pollInterval !== void 0 ? { pollInterval: input.pollInterval } : {},
372
+ createdAt,
373
+ updatedAt
374
+ };
375
+ case "discord": return {
376
+ id,
377
+ type: "discord",
378
+ name: input.name,
379
+ botToken: input.botToken,
380
+ createdAt,
381
+ updatedAt
382
+ };
383
+ case "schedule": return {
384
+ id,
385
+ type: "schedule",
386
+ name: input.name,
387
+ entries: input.entries ?? [],
388
+ createdAt,
389
+ updatedAt
390
+ };
391
+ }
356
392
  }
357
393
  removeConnector(channelName, connectorName) {
358
394
  const settings = this.store.read();
@@ -374,8 +410,7 @@ var FunnelChannels = class {
374
410
  }
375
411
  updateSlackConnector(channelName, connectorName, fields) {
376
412
  const settings = this.store.read();
377
- const channel = this.requireChannel(settings, channelName);
378
- const connector = this.requireSlackConnector(channel, connectorName);
413
+ const connector = requireConnectorOfType(this.requireChannel(settings, channelName), connectorName, "slack");
379
414
  const updated = {
380
415
  ...connector,
381
416
  botToken: fields.botToken ?? connector.botToken,
@@ -388,16 +423,14 @@ var FunnelChannels = class {
388
423
  }
389
424
  updateGhConnector(channelName, connectorName, fields) {
390
425
  const settings = this.store.read();
391
- const channel = this.requireChannel(settings, channelName);
392
- const connector = this.requireGhConnector(channel, connectorName);
426
+ const connector = requireConnectorOfType(this.requireChannel(settings, channelName), connectorName, "gh");
393
427
  if (fields.pollInterval !== void 0) connector.pollInterval = fields.pollInterval;
394
428
  connector.updatedAt = this.clock.iso();
395
429
  this.store.write(settings);
396
430
  }
397
431
  updateDiscordConnector(channelName, connectorName, fields) {
398
432
  const settings = this.store.read();
399
- const channel = this.requireChannel(settings, channelName);
400
- const connector = this.requireDiscordConnector(channel, connectorName);
433
+ const connector = requireConnectorOfType(this.requireChannel(settings, channelName), connectorName, "discord");
401
434
  const updated = {
402
435
  ...connector,
403
436
  botToken: fields.botToken ?? connector.botToken,
@@ -408,13 +441,11 @@ var FunnelChannels = class {
408
441
  this.store.write(settings);
409
442
  }
410
443
  listScheduleEntries(channelName, connectorName) {
411
- const channel = this.requireChannel(this.store.read(), channelName);
412
- return this.requireScheduleConnector(channel, connectorName).entries;
444
+ return requireConnectorOfType(this.requireChannel(this.store.read(), channelName), connectorName, "schedule").entries;
413
445
  }
414
446
  addScheduleEntry(channelName, connectorName, entry) {
415
447
  const settings = this.store.read();
416
- const channel = this.requireChannel(settings, channelName);
417
- const connector = this.requireScheduleConnector(channel, connectorName);
448
+ const connector = requireConnectorOfType(this.requireChannel(settings, channelName), connectorName, "schedule");
418
449
  const persisted = {
419
450
  id: entry.id ?? this.idGenerator.generate(),
420
451
  cron: entry.cron,
@@ -429,8 +460,7 @@ var FunnelChannels = class {
429
460
  }
430
461
  removeScheduleEntry(channelName, connectorName, id) {
431
462
  const settings = this.store.read();
432
- const channel = this.requireChannel(settings, channelName);
433
- const connector = this.requireScheduleConnector(channel, connectorName);
463
+ const connector = requireConnectorOfType(this.requireChannel(settings, channelName), connectorName, "schedule");
434
464
  const index = connector.entries.findIndex((e) => e.id === id);
435
465
  if (index < 0) throw new Error(`schedule entry "${id}" not found`);
436
466
  connector.entries.splice(index, 1);
@@ -470,44 +500,14 @@ var FunnelChannels = class {
470
500
  if (!channel) throw new Error(`channel "${name}" not found`);
471
501
  return channel;
472
502
  }
473
- requireConnector(channel, connectorName) {
474
- const connector = channel.connectors.find((c) => c.name === connectorName);
475
- if (!connector) throw new Error(`connector "${connectorName}" not found in channel "${channel.name}"`);
476
- return connector;
477
- }
478
- requireSlackConnector(channel, connectorName) {
479
- const connector = this.requireConnector(channel, connectorName);
480
- if (connector.type !== "slack") throw new Error(`connector "${connectorName}" is type "${connector.type}", not "slack"`);
481
- return connector;
482
- }
483
- requireGhConnector(channel, connectorName) {
484
- const connector = this.requireConnector(channel, connectorName);
485
- if (connector.type !== "gh") throw new Error(`connector "${connectorName}" is type "${connector.type}", not "gh"`);
486
- return connector;
487
- }
488
- requireDiscordConnector(channel, connectorName) {
489
- const connector = this.requireConnector(channel, connectorName);
490
- if (connector.type !== "discord") throw new Error(`connector "${connectorName}" is type "${connector.type}", not "discord"`);
491
- return connector;
492
- }
493
- requireScheduleConnector(channel, connectorName) {
494
- const connector = this.requireConnector(channel, connectorName);
495
- if (connector.type !== "schedule") throw new Error(`connector "${connectorName}" is type "${connector.type}", not "schedule"`);
496
- return connector;
497
- }
498
503
  assertNoTokenCollision(settings, candidate) {
499
- const tokens = this.tokensOf(candidate);
504
+ const tokens = connectorTokens(candidate);
500
505
  if (tokens.length === 0) return;
501
506
  for (const channel of settings.channels) for (const other of channel.connectors) {
502
507
  if (other.id === candidate.id) continue;
503
- for (const token of this.tokensOf(other)) if (tokens.includes(token)) throw new Error(`token already in use by connector "${other.name}" in channel "${channel.name}"`);
508
+ for (const token of connectorTokens(other)) if (tokens.includes(token)) throw new Error(`token already in use by connector "${other.name}" in channel "${channel.name}"`);
504
509
  }
505
510
  }
506
- tokensOf(connector) {
507
- if (connector.type === "slack") return [connector.botToken, connector.appToken];
508
- if (connector.type === "discord") return [connector.botToken];
509
- return [];
510
- }
511
511
  };
512
512
  //#endregion
513
513
  //#region lib/engine/claude/claude.ts
@@ -1096,14 +1096,18 @@ var FunnelChannelPublisher = class {
1096
1096
  * The candidates cover:
1097
1097
  * 1. dev: this helper lives at lib/gateway/, so daemon.ts is its sibling
1098
1098
  * 2. built sibling: dist/gateway/daemon.js if the helper itself ends up at dist/gateway/
1099
- * 3. bundled: when this helper is inlined into dist/bin.js, import.meta.dir is dist/,
1099
+ * 3. bundled: when this helper is inlined into dist/bin.js, the helper's dir is dist/,
1100
1100
  * and daemon.js lives at dist/gateway/daemon.js
1101
+ *
1102
+ * `import.meta.url` works in both Bun and Node test runners; `import.meta.dir`
1103
+ * is Bun-only and breaks vitest.
1101
1104
  */
1102
1105
  const resolveDaemonScript = () => {
1106
+ const here = dirname(fileURLToPath(import.meta.url));
1103
1107
  const candidates = [
1104
- resolve(import.meta.dir, "./daemon.ts"),
1105
- resolve(import.meta.dir, "./daemon.js"),
1106
- resolve(import.meta.dir, "./gateway/daemon.js")
1108
+ resolve(here, "./daemon.ts"),
1109
+ resolve(here, "./daemon.js"),
1110
+ resolve(here, "./gateway/daemon.js")
1107
1111
  ];
1108
1112
  for (const candidate of candidates) if (existsSync(candidate)) return candidate;
1109
1113
  throw new Error(`daemon script not found (looked in ${candidates.join(", ")})`);
@@ -1174,8 +1178,8 @@ var FunnelGateway = class {
1174
1178
  "-c",
1175
1179
  command
1176
1180
  ]);
1177
- const deadline = Date.now() + STARTUP_TIMEOUT_MS;
1178
- while (Date.now() < deadline) {
1181
+ const deadline = this.clock.millis() + STARTUP_TIMEOUT_MS;
1182
+ while (this.clock.millis() < deadline) {
1179
1183
  if (this.isRunning()) return true;
1180
1184
  await this.sleep(POLL_INTERVAL_MS$1);
1181
1185
  }
@@ -2737,7 +2741,7 @@ const SANDBOX_TMP_DIR = "/sandbox/tmp";
2737
2741
  * ```
2738
2742
  */
2739
2743
  var Funnel = class Funnel {
2740
- cache = /* @__PURE__ */ new Map();
2744
+ memos = {};
2741
2745
  constructor(props = {}) {
2742
2746
  this.props = props;
2743
2747
  Object.freeze(this);
@@ -2759,12 +2763,6 @@ var Funnel = class Funnel {
2759
2763
  tmpDir: props.tmpDir ?? SANDBOX_TMP_DIR
2760
2764
  });
2761
2765
  }
2762
- memo(key, build) {
2763
- if (this.cache.has(key)) return this.cache.get(key);
2764
- const value = build();
2765
- this.cache.set(key, value);
2766
- return value;
2767
- }
2768
2766
  /** Resolved on-disk paths the facade will read/write when methods are called. Pure compute, not memoized. */
2769
2767
  get paths() {
2770
2768
  const dir = this.props.dir ?? FUNNEL_DIR;
@@ -2776,61 +2774,71 @@ var Funnel = class Funnel {
2776
2774
  }
2777
2775
  /** Filesystem boundary. Defaults to NodeFunnelFileSystem. */
2778
2776
  get fs() {
2779
- return this.memo("fs", () => this.props.fs ?? new NodeFunnelFileSystem());
2777
+ if (!this.memos.fs) this.memos.fs = this.props.fs ?? new NodeFunnelFileSystem();
2778
+ return this.memos.fs;
2780
2779
  }
2781
2780
  /** Process runner boundary. Defaults to NodeFunnelProcessRunner. */
2782
2781
  get process() {
2783
- return this.memo("process", () => this.props.process ?? new NodeFunnelProcessRunner());
2782
+ if (!this.memos.process) this.memos.process = this.props.process ?? new NodeFunnelProcessRunner();
2783
+ return this.memos.process;
2784
2784
  }
2785
2785
  /** Logger boundary. Defaults to NodeFunnelLogger. */
2786
2786
  get logger() {
2787
- return this.memo("logger", () => this.props.logger ?? new NodeFunnelLogger());
2787
+ if (!this.memos.logger) this.memos.logger = this.props.logger ?? new NodeFunnelLogger();
2788
+ return this.memos.logger;
2788
2789
  }
2789
2790
  /** Clock boundary. Defaults to NodeFunnelClock. */
2790
2791
  get clock() {
2791
- return this.memo("clock", () => this.props.clock ?? new NodeFunnelClock());
2792
+ if (!this.memos.clock) this.memos.clock = this.props.clock ?? new NodeFunnelClock();
2793
+ return this.memos.clock;
2792
2794
  }
2793
2795
  /** ID generator boundary. Defaults to NodeFunnelIdGenerator. */
2794
2796
  get idGenerator() {
2795
- return this.memo("idGenerator", () => this.props.idGenerator ?? new NodeFunnelIdGenerator());
2797
+ if (!this.memos.idGenerator) this.memos.idGenerator = this.props.idGenerator ?? new NodeFunnelIdGenerator();
2798
+ return this.memos.idGenerator;
2796
2799
  }
2797
2800
  /** Settings reader. If not injected, a FunnelSettingsStore rooted at `dir` is created. */
2798
2801
  get store() {
2799
- return this.memo("store", () => this.props.store ?? new FunnelSettingsStore({
2802
+ if (!this.memos.store) this.memos.store = this.props.store ?? new FunnelSettingsStore({
2800
2803
  path: this.paths.settings,
2801
2804
  fs: this.fs
2802
- }));
2805
+ });
2806
+ return this.memos.store;
2803
2807
  }
2804
2808
  /** Pure factory that constructs per-type listeners and adapters from connector configs. */
2805
2809
  get factory() {
2806
- return this.memo("factory", () => new FunnelConnectorFactory({
2810
+ if (!this.memos.factory) this.memos.factory = new FunnelConnectorFactory({
2807
2811
  fs: this.fs,
2808
2812
  process: this.process,
2809
2813
  logger: this.logger,
2810
2814
  dir: this.paths.dir
2811
- }));
2815
+ });
2816
+ return this.memos.factory;
2812
2817
  }
2813
2818
  /** Channel CRUD + nested connector CRUD + schedule entries + listener/adapter dispatch. */
2814
2819
  get channels() {
2815
- return this.memo("channels", () => new FunnelChannels({
2820
+ if (!this.memos.channels) this.memos.channels = new FunnelChannels({
2816
2821
  store: this.store,
2817
2822
  factory: this.factory,
2818
2823
  profileChecker: this.profiles,
2819
2824
  clock: this.clock,
2820
2825
  idGenerator: this.idGenerator
2821
- }));
2826
+ });
2827
+ return this.memos.channels;
2822
2828
  }
2823
2829
  /** Launch profiles (named presets for `fnl claude`: path + sub-agent + channel id). */
2824
2830
  get profiles() {
2825
- return this.memo("profiles", () => new FunnelProfiles({ store: this.store }));
2831
+ if (!this.memos.profiles) this.memos.profiles = new FunnelProfiles({ store: this.store });
2832
+ return this.memos.profiles;
2826
2833
  }
2827
2834
  /** funnel MCP installer (writes/removes `.mcp.json` entries in target repos). */
2828
2835
  get mcp() {
2829
- return this.memo("mcp", () => new FunnelMcp({ fs: this.fs }));
2836
+ if (!this.memos.mcp) this.memos.mcp = new FunnelMcp({ fs: this.fs });
2837
+ return this.memos.mcp;
2830
2838
  }
2831
2839
  /** Launch Claude Code with a channel injected via env, MCP installed, gateway ensured. */
2832
2840
  get claude() {
2833
- return this.memo("claude", () => new FunnelClaude({
2841
+ if (!this.memos.claude) this.memos.claude = new FunnelClaude({
2834
2842
  channels: this.channels,
2835
2843
  mcp: this.mcp,
2836
2844
  gateway: this.gateway,
@@ -2838,24 +2846,27 @@ var Funnel = class Funnel {
2838
2846
  process: this.process,
2839
2847
  logger: this.logger,
2840
2848
  dir: this.paths.dir
2841
- }));
2849
+ });
2850
+ return this.memos.claude;
2842
2851
  }
2843
2852
  /** Gateway daemon controller (PID-file, start/stop the separate `bun daemon.ts` process). */
2844
2853
  get gateway() {
2845
- return this.memo("gateway", () => new FunnelGateway({
2854
+ if (!this.memos.gateway) this.memos.gateway = new FunnelGateway({
2846
2855
  fs: this.fs,
2847
2856
  process: this.process,
2848
2857
  clock: this.clock,
2849
2858
  dir: this.paths.dir,
2850
2859
  tmpDir: this.paths.tmpDir
2851
- }));
2860
+ });
2861
+ return this.memos.gateway;
2852
2862
  }
2853
2863
  /** Read / generate the daemon's gateway token (mode 0600 file under `dir`). */
2854
2864
  get gatewayToken() {
2855
- return this.memo("gatewayToken", () => new FunnelGatewayToken({
2865
+ if (!this.memos.gatewayToken) this.memos.gatewayToken = new FunnelGatewayToken({
2856
2866
  fs: this.fs,
2857
2867
  dir: this.paths.dir
2858
- }));
2868
+ });
2869
+ return this.memos.gatewayToken;
2859
2870
  }
2860
2871
  /**
2861
2872
  * HTTP client for `POST /channels/:channel/publish` on the running gateway
@@ -2863,15 +2874,16 @@ var Funnel = class Funnel {
2863
2874
  * connector. Returns `{ state: "offline" }` if the daemon isn't up.
2864
2875
  */
2865
2876
  get publisher() {
2866
- return this.memo("publisher", () => {
2877
+ if (!this.memos.publisher) {
2867
2878
  const gateway = this.gateway;
2868
2879
  const token = this.gatewayToken;
2869
- return new FunnelChannelPublisher({
2880
+ this.memos.publisher = new FunnelChannelPublisher({
2870
2881
  port: gateway.getPort(),
2871
2882
  isDaemonRunning: () => gateway.isRunning(),
2872
2883
  getToken: () => token.read()
2873
2884
  });
2874
- });
2885
+ }
2886
+ return this.memos.publisher;
2875
2887
  }
2876
2888
  /**
2877
2889
  * HTTP client for listener operations on the running gateway daemon.
@@ -2879,15 +2891,16 @@ var Funnel = class Funnel {
2879
2891
  * paths stay write-only without parsing strings.
2880
2892
  */
2881
2893
  get listeners() {
2882
- return this.memo("listeners", () => {
2894
+ if (!this.memos.listeners) {
2883
2895
  const gateway = this.gateway;
2884
2896
  const token = this.gatewayToken;
2885
- return new FunnelListenersClient({
2897
+ this.memos.listeners = new FunnelListenersClient({
2886
2898
  port: gateway.getPort(),
2887
2899
  isDaemonRunning: () => gateway.isRunning(),
2888
2900
  getToken: () => token.read()
2889
2901
  });
2890
- });
2902
+ }
2903
+ return this.memos.listeners;
2891
2904
  }
2892
2905
  /**
2893
2906
  * In-process gateway server. Unlike `gateway.start()` (which spawns a daemon),
@@ -3016,7 +3029,7 @@ const startChannelServer = async (options = {}) => {
3016
3029
  const channelId = options.channelId ?? process.env.FUNNEL_CHANNEL_ID;
3017
3030
  const channel = channelId ? readChannelConnectors(dir, channelId) : null;
3018
3031
  const token = options.token ?? readGatewayToken(dir);
3019
- const server = new Server$1({
3032
+ const server = new Server({
3020
3033
  name: FUNNEL_MCP_NAME,
3021
3034
  version: "1.0.0"
3022
3035
  }, {
@@ -6293,4 +6306,4 @@ async function launchTui(funnel) {
6293
6306
  });
6294
6307
  }
6295
6308
  //#endregion
6296
- export { DEFAULT_GATEWAY_TOKEN_PATH, FUNNEL_DIR, FUNNEL_MCP_COMMAND, FUNNEL_MCP_NAME, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClaude, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelEventStore, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLogger, FunnelMcp, FunnelProcessRunner, FunnelProfiles, FunnelSettingsReader, FunnelSettingsStore, MemoryFunnelClock, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NoopFunnelLogger, SETTINGS_PATH, SETTINGS_VERSION, channelConfigSchema, channelDeliveryModeSchema, app as cliApp, connectorConfigSchema, createCliApp, createSettings, discordConnectorSchema, factory, funnelEventSchema, ghConnectorSchema, launchTui, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, startChannelServer, toRequest };
6309
+ export { DEFAULT_GATEWAY_TOKEN_PATH, FUNNEL_DIR, FUNNEL_MCP_COMMAND, FUNNEL_MCP_NAME, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClaude, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelEventStore, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLogger, FunnelMcp, FunnelProcessRunner, FunnelProfiles, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, MemoryFunnelClock, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NoopFunnelLogger, SETTINGS_PATH, SETTINGS_VERSION, channelConfigSchema, channelDeliveryModeSchema, app as cliApp, connectorConfigSchema, createCliApp, createSettings, discordConnectorSchema, factory, funnelEventSchema, ghConnectorSchema, launchTui, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, startChannelServer, toRequest };
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+
3
+ //#region lib/connectors/slack-connector-schema.d.ts
4
+ declare const slackConnectorSchema: z.ZodObject<{
5
+ id: z.ZodString;
6
+ name: z.ZodString;
7
+ type: z.ZodLiteral<"slack">;
8
+ botToken: z.ZodString;
9
+ appToken: z.ZodString;
10
+ createdAt: z.ZodOptional<z.ZodString>;
11
+ updatedAt: z.ZodOptional<z.ZodString>;
12
+ }, z.core.$strip>;
13
+ type SlackConnectorConfig = z.infer<typeof slackConnectorSchema>;
14
+ //#endregion
15
+ //#region lib/connectors/slack-event-processor.d.ts
16
+ type SlackRawEvent = Record<string, unknown>;
17
+ type SlackProcessedSkip = {
18
+ skip: true;
19
+ };
20
+ type SlackProcessedEmit = {
21
+ skip: false;
22
+ content: string;
23
+ meta: Record<string, string>;
24
+ shouldReact: boolean;
25
+ channel: string;
26
+ timestamp: string;
27
+ };
28
+ type SlackProcessed = SlackProcessedSkip | SlackProcessedEmit;
29
+ type Props = {
30
+ ownBotUserId: string;
31
+ ownBotId: string;
32
+ now?: () => number;
33
+ };
34
+ declare class FunnelSlackEventProcessor {
35
+ private readonly ownBotUserId;
36
+ private readonly ownBotId;
37
+ private readonly now;
38
+ private readonly dedup;
39
+ constructor(props: Props);
40
+ process(event: SlackRawEvent): SlackProcessed;
41
+ }
42
+ //#endregion
43
+ export { SlackRawEvent as a, SlackProcessedSkip as i, SlackProcessed as n, SlackConnectorConfig as o, SlackProcessedEmit as r, slackConnectorSchema as s, FunnelSlackEventProcessor as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interactive-inc/claude-funnel",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "Hub CLI that routes external events (Slack / GitHub / Discord) to Claude Code agents through subscription channels over MCP.",
5
5
  "keywords": [
6
6
  "bun",
@@ -27,11 +27,6 @@
27
27
  "funnel": "./dist/bin.js"
28
28
  },
29
29
  "files": [
30
- "lib/**/*.ts",
31
- "lib/**/*.tsx",
32
- "!lib/**/*.test.ts",
33
- "!lib/**/*.test.tsx",
34
- "!lib/**/*.bun-test.ts",
35
30
  "dist/**/*",
36
31
  "README.md",
37
32
  "LICENSE"
@@ -1,15 +0,0 @@
1
- import { z } from "zod";
2
-
3
- //#region lib/connectors/slack-connector-schema.d.ts
4
- declare const slackConnectorSchema: z.ZodObject<{
5
- id: z.ZodString;
6
- name: z.ZodString;
7
- type: z.ZodLiteral<"slack">;
8
- botToken: z.ZodString;
9
- appToken: z.ZodString;
10
- createdAt: z.ZodOptional<z.ZodString>;
11
- updatedAt: z.ZodOptional<z.ZodString>;
12
- }, z.core.$strip>;
13
- type SlackConnectorConfig = z.infer<typeof slackConnectorSchema>;
14
- //#endregion
15
- export { slackConnectorSchema as n, SlackConnectorConfig as t };
package/lib/bin.ts DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- import "@/cli"
@@ -1,10 +0,0 @@
1
- import { createFactory } from "hono/factory"
2
- import type { Funnel } from "@/funnel"
3
-
4
- export type Env = {
5
- Variables: {
6
- funnel: Funnel
7
- }
8
- }
9
-
10
- export const factory = createFactory<Env>()