@interactive-inc/claude-funnel 0.52.0 → 0.53.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.
@@ -183,4 +183,17 @@ var FunnelSettingsStore = class extends FunnelSettingsReader {
183
183
  }
184
184
  };
185
185
  //#endregion
186
- export { resolveFunnelDir as a, channelConfigSchema as c, settingsSchema as d, connectorConfigSchema as f, SETTINGS_PATH as i, channelDeliveryModeSchema as l, FUNNEL_DIR as n, resolveFunnelPort as o, NodeFunnelIdGenerator as p, FunnelSettingsStore as r, SETTINGS_VERSION as s, DEFAULT_GATEWAY_PORT as t, profileConfigSchema as u };
186
+ //#region lib/gateway/gateway-base-url.ts
187
+ /**
188
+ * The HTTP base URL of a gateway daemon on the loopback interface. The daemon
189
+ * always binds 127.0.0.1 for its management API (only the WS `/ws` endpoint is
190
+ * ever exposed off-box), so every in-process HTTP client — publisher, listeners
191
+ * client, MCP channel server — talks to it here. Centralizing the construction
192
+ * keeps the host/port shape in one place instead of re-spelling
193
+ * `http://127.0.0.1:${port}` at each call site.
194
+ */
195
+ function gatewayLoopbackUrl(port) {
196
+ return `http://127.0.0.1:${port}`;
197
+ }
198
+ //#endregion
199
+ export { SETTINGS_PATH as a, SETTINGS_VERSION as c, profileConfigSchema as d, settingsSchema as f, FunnelSettingsStore as i, channelConfigSchema as l, NodeFunnelIdGenerator as m, DEFAULT_GATEWAY_PORT as n, resolveFunnelDir as o, connectorConfigSchema as p, FUNNEL_DIR as r, resolveFunnelPort as s, gatewayLoopbackUrl as t, channelDeliveryModeSchema as u };
package/dist/gateway.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { _ as connectorConnectionEventSchema, a as ConnectorConnectionStatus, c as ConnectorProcessedQuery, d as ConnectorRawEvent, f as ConnectorRawQuery, g as StoredRawEvent, h as StoredProcessedEvent, i as ConnectorConnectionRecord, l as ConnectorProcessedRecord, m as StoredConnectionEvent, n as ConnectorConnectionEvent, o as ConnectorDiagnosticLog, p as ConnectorRawRecord, r as ConnectorConnectionQuery, s as ConnectorProcessedEvent, t as CONNECTOR_CONNECTION_STATUSES, u as ConnectorQuery, v as connectorProcessedEventSchema, y as connectorRawEventSchema } from "./connector-diagnostic-log-yTOojKUR.js";
2
- import { $ as FunnelGatewayToken, G as SqliteFunnelEventLog, H as MemoryConnectorDiagnosticLog, J as PublishResponse, K as FunnelChannelPublisher, Q as DEFAULT_GATEWAY_TOKEN_PATH, U as SqliteConnectorDiagnosticLog, W as MemoryFunnelEventLog, X as publishRequestSchema, Y as PublishResult, Z as publishResponseSchema, at as Env, ct as FunnelListenerSupervisor, dt as FunnelBroadcaster, et as FunnelGatewayServer, ft as ReplayableEvent, it as funnelEventSchema, lt as BroadcastEvent, nt as FunnelEventLog, ot as GatewayEmitInput, q as PublishRequest, rt as FunnelEventRecord, st as GatewayRouteDeps, t as GatewayApp, tt as FunnelEvent, ut as BroadcastSubscriber } from "./index-NFs2jzCa.js";
3
- export { BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDiagnosticLog, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelGatewayServer, FunnelGatewayToken, FunnelListenerSupervisor, type GatewayApp, type GatewayEmitInput, type GatewayRouteDeps, type Env as GatewayServerEnv, MemoryConnectorDiagnosticLog, MemoryFunnelEventLog, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, StoredConnectionEvent, StoredProcessedEvent, StoredRawEvent, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, funnelEventSchema, publishRequestSchema, publishResponseSchema };
2
+ import { $ as DEFAULT_GATEWAY_TOKEN_PATH, G as MemoryFunnelEventLog, J as PublishRequest, K as SqliteFunnelEventLog, Q as publishResponseSchema, U as MemoryConnectorDiagnosticLog, W as SqliteConnectorDiagnosticLog, X as PublishResult, Y as PublishResponse, Z as publishRequestSchema, _t as FunnelBroadcaster, at as FunnelGatewayServer, ct as FunnelEventLog, dt as Env, et as FunnelGatewayToken, ft as GatewayEmitInput, gt as BroadcastSubscriber, ht as BroadcastEvent, it as channelWsUrl, lt as FunnelEventRecord, mt as FunnelListenerSupervisor, nt as ChannelWsUrlInput, ot as GatewayEventStore, pt as GatewayRouteDeps, q as FunnelChannelPublisher, rt as channelWsProtocols, st as FunnelEvent, t as GatewayApp, tt as gatewayLoopbackUrl, ut as funnelEventSchema, vt as ReplayableEvent } from "./index-DF5VmCPJ.js";
3
+ export { BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, ChannelWsUrlInput, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDiagnosticLog, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelGatewayServer, FunnelGatewayToken, FunnelListenerSupervisor, type GatewayApp, type GatewayEmitInput, GatewayEventStore, type GatewayRouteDeps, type Env as GatewayServerEnv, MemoryConnectorDiagnosticLog, MemoryFunnelEventLog, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, StoredConnectionEvent, StoredProcessedEvent, StoredRawEvent, channelWsProtocols, channelWsUrl, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, funnelEventSchema, gatewayLoopbackUrl, publishRequestSchema, publishResponseSchema };
package/dist/gateway.js CHANGED
@@ -1,2 +1,3 @@
1
- import { _ as FunnelBroadcaster, a as connectorConnectionEventSchema, b as publishResponseSchema, c as MemoryFunnelEventLog, d as FunnelGatewayServer, g as funnelEventSchema, h as FunnelEventLog, i as ConnectorDiagnosticLog, l as DEFAULT_GATEWAY_TOKEN_PATH, m as SqliteFunnelEventLog, n as SqliteConnectorDiagnosticLog, o as connectorProcessedEventSchema, p as FunnelListenerSupervisor, r as CONNECTOR_CONNECTION_STATUSES, s as connectorRawEventSchema, t as MemoryConnectorDiagnosticLog, u as FunnelGatewayToken, v as FunnelChannelPublisher, y as publishRequestSchema } from "./memory-connector-diagnostic-log-CrW1ltLM.js";
2
- export { CONNECTOR_CONNECTION_STATUSES, ConnectorDiagnosticLog, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEventLog, FunnelGatewayServer, FunnelGatewayToken, FunnelListenerSupervisor, MemoryConnectorDiagnosticLog, MemoryFunnelEventLog, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, funnelEventSchema, publishRequestSchema, publishResponseSchema };
1
+ import { t as gatewayLoopbackUrl } from "./gateway-base-url-ssk_He5G.js";
2
+ import { S as publishResponseSchema, _ as FunnelEventLog, a as connectorConnectionEventSchema, b as FunnelChannelPublisher, c as MemoryFunnelEventLog, d as DEFAULT_GATEWAY_TOKEN_PATH, f as FunnelGatewayToken, g as SqliteFunnelEventLog, h as FunnelListenerSupervisor, i as ConnectorDiagnosticLog, l as channelWsProtocols, n as SqliteConnectorDiagnosticLog, o as connectorProcessedEventSchema, p as FunnelGatewayServer, r as CONNECTOR_CONNECTION_STATUSES, s as connectorRawEventSchema, t as MemoryConnectorDiagnosticLog, u as channelWsUrl, v as funnelEventSchema, x as publishRequestSchema, y as FunnelBroadcaster } from "./memory-connector-diagnostic-log-COUWCsT_.js";
3
+ export { CONNECTOR_CONNECTION_STATUSES, ConnectorDiagnosticLog, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEventLog, FunnelGatewayServer, FunnelGatewayToken, FunnelListenerSupervisor, MemoryConnectorDiagnosticLog, MemoryFunnelEventLog, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, channelWsProtocols, channelWsUrl, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, funnelEventSchema, gatewayLoopbackUrl, publishRequestSchema, publishResponseSchema };
@@ -1,10 +1,10 @@
1
1
  import { n as FunnelIdGenerator, s as Settings, t as FunnelSettingsReader } from "./settings-reader-BSU6JyvM.js";
2
- import { n as FunnelClaude, t as FileProcessGuard } from "./file-process-guard-BgrVHe9I.js";
2
+ import { n as FunnelClaude, t as FileProcessGuard } from "./file-process-guard-DMeLB6Zd.js";
3
3
  import { S as FunnelLogger, b as FunnelConnectorListener, c as ConnectorProcessedQuery, f as ConnectorRawQuery, g as StoredRawEvent, h as StoredProcessedEvent, i as ConnectorConnectionRecord, l as ConnectorProcessedRecord, m as StoredConnectionEvent, o as ConnectorDiagnosticLog, p as ConnectorRawRecord, r as ConnectorConnectionQuery } from "./connector-diagnostic-log-yTOojKUR.js";
4
4
  import { a as RunOptions, i as ProcessSnapshot, n as DetachOptions, o as RunResult, r as FunnelProcessRunner, t as AttachOptions } from "./process-runner-DfniuWVU.js";
5
5
  import { n as FunnelFileSystem, t as FileStat } from "./file-system-BeOKXjlV.js";
6
6
  import { t as FunnelProfiles } from "./profiles-f0mNmEyP.js";
7
- import { a as ChannelConnectorView, d as ConnectorConfig, i as FunnelTokenPrompter, l as ScheduleListenerOptions, m as FunnelLocalConfig, n as FunnelLocalConfigSync, o as FunnelChannels, s as FunnelClock, u as SlackListenerOptions } from "./local-config-sync-BdsrDZOu.js";
7
+ import { a as ChannelConnectorView, d as ConnectorConfig, i as FunnelTokenPrompter, l as ScheduleListenerOptions, m as FunnelLocalConfig, n as FunnelLocalConfigSync, o as FunnelChannels, s as FunnelClock, u as SlackListenerOptions } from "./local-config-sync-Cq39mT6p.js";
8
8
  import { hc } from "hono/client";
9
9
  import { z } from "zod";
10
10
  import * as _$hono_factory0 from "hono/factory";
@@ -306,12 +306,26 @@ declare abstract class FunnelEventLog {
306
306
  }
307
307
  //#endregion
308
308
  //#region lib/gateway/gateway-server.d.ts
309
- type Deps$5 = {
309
+ /**
310
+ * Where the gateway's durable replay log lives. The two ways to specify it are
311
+ * mutually exclusive — modeled as a union so you can't pass both (the old shape
312
+ * silently ignored `dbPath` when `eventLog` was also given).
313
+ *
314
+ * - omit both → SQLite at the default path (`<os.tmpdir()>/funnel/events.db`)
315
+ * - `dbPath` → SQLite at a custom path (parent dir created on demand)
316
+ * - `eventLog` → bring your own `FunnelEventLog` (e.g. `MemoryFunnelEventLog`)
317
+ */
318
+ type GatewayEventStore = {
319
+ dbPath?: string;
320
+ eventLog?: undefined;
321
+ } | {
322
+ dbPath?: undefined;
323
+ eventLog: FunnelEventLog;
324
+ };
325
+ type Deps$5 = GatewayEventStore & {
310
326
  channels: FunnelChannels;
311
327
  port?: number; /** Bind address for `Bun.serve`. Defaults to `127.0.0.1` (loopback only). Set to `0.0.0.0` to expose on the network. */
312
- hostname?: string; /** SQLite event store file path. Parent directory is created on demand. Defaults to `<os.tmpdir()>/funnel/events.db`. Ignored when `eventLog` is supplied. */
313
- dbPath?: string; /** Durable replay log. Defaults to a `SqliteFunnelEventLog` at `dbPath`. Inject a `MemoryFunnelEventLog` (or any `FunnelEventLog`) to swap or disable persistence. */
314
- eventLog?: FunnelEventLog;
328
+ hostname?: string;
315
329
  process?: FunnelProcessRunner;
316
330
  clock?: FunnelClock;
317
331
  logger?: FunnelLogger; /** Host hook for surfacing internal exceptions (broadcaster / supervisor). Defaults to no-op. */
@@ -320,6 +334,13 @@ type Deps$5 = {
320
334
  dir?: string;
321
335
  killCompetingSlack?: boolean; /** Bearer token required for `/listeners*`, `/status`, and `/ws`. Empty string disables auth (tests only). */
322
336
  token?: string;
337
+ /**
338
+ * Permit binding a non-loopback hostname without a token. Off by default:
339
+ * `start()` throws when `hostname` is reachable off-box and `token` is empty,
340
+ * because every privileged endpoint would then be open to the network. Set
341
+ * this only when you've deliberately fronted the gateway with your own auth.
342
+ */
343
+ allowInsecureHost?: boolean;
323
344
  /**
324
345
  * Additional hono app mounted before the built-in gateway routes.
325
346
  * Use to embed host-specific endpoints (e.g. an MCP route, custom `/api/*`).
@@ -358,6 +379,7 @@ declare class FunnelGatewayServer {
358
379
  private readonly dir;
359
380
  private readonly killCompetingSlack;
360
381
  private readonly token;
382
+ private readonly allowInsecureHost;
361
383
  private readonly broadcaster;
362
384
  private readonly eventLog;
363
385
  private readonly supervisor;
@@ -419,6 +441,51 @@ declare class FunnelGatewayServer {
419
441
  private lookupConnectorId;
420
442
  }
421
443
  //#endregion
444
+ //#region lib/gateway/channel-ws-url.d.ts
445
+ /**
446
+ * Builds the WebSocket URL a client uses to subscribe to a gateway channel.
447
+ *
448
+ * The gateway's `/ws` upgrade handler reads three query params — `channel`
449
+ * (required), `id` (the subscriber id for targeted delivery), and `since`
450
+ * (replay offset). Forgetting `channel=` silently drops the subscription
451
+ * (the broadcaster never matches the client), which has caused outages when
452
+ * callers hand-built the URL with string concatenation. This builder makes
453
+ * `channel` a required field, so the mistake becomes a compile error.
454
+ *
455
+ * `subscriberId` enables targeted delivery: events carrying `meta.target=<id>`
456
+ * reach only this client. Omit it to receive the channel's fanout.
457
+ *
458
+ * Pair with `channelWsProtocols()` to authenticate the upgrade when the
459
+ * gateway requires a token.
460
+ */
461
+ type ChannelWsUrlInput = {
462
+ /** Base WS endpoint, e.g. `ws://localhost:9743/ws`. Existing query is preserved. */base: string; /** Channel name to subscribe to. Required — the broadcaster filters by it. */
463
+ channel: string; /** Opaque subscriber id for targeted delivery (`meta.target=<id>`). Omit for fanout. */
464
+ subscriberId?: string; /** Replay from this event offset (inclusive). Omit to receive only new events. */
465
+ since?: number;
466
+ };
467
+ declare function channelWsUrl(input: ChannelWsUrlInput): string;
468
+ /**
469
+ * Builds the `Sec-WebSocket-Protocol` values that authenticate a gateway WS
470
+ * upgrade. Browser `WebSocket` cannot set an `Authorization` header, so the
471
+ * gateway also accepts the token as a `funnel.token.<token>` subprotocol.
472
+ * Returns an empty array when no token is given (auth disabled / loopback).
473
+ *
474
+ * Usage: `new WebSocket(channelWsUrl({ base, channel }), channelWsProtocols(token))`
475
+ */
476
+ declare function channelWsProtocols(token?: string | null): string[];
477
+ //#endregion
478
+ //#region lib/gateway/gateway-base-url.d.ts
479
+ /**
480
+ * The HTTP base URL of a gateway daemon on the loopback interface. The daemon
481
+ * always binds 127.0.0.1 for its management API (only the WS `/ws` endpoint is
482
+ * ever exposed off-box), so every in-process HTTP client — publisher, listeners
483
+ * client, MCP channel server — talks to it here. Centralizing the construction
484
+ * keeps the host/port shape in one place instead of re-spelling
485
+ * `http://127.0.0.1:${port}` at each call site.
486
+ */
487
+ declare function gatewayLoopbackUrl(port: number): string;
488
+ //#endregion
422
489
  //#region lib/gateway/gateway-token.d.ts
423
490
  type Deps$4 = {
424
491
  fs?: FunnelFileSystem;
@@ -832,6 +899,18 @@ type Props$5 = {
832
899
  */
833
900
  tokenPrompter?: FunnelTokenPrompter;
834
901
  };
902
+ /**
903
+ * Options for `Funnel.gatewayServer()`. The event store is a union (`dbPath`
904
+ * xor `eventLog`) so the two storage modes can't be mixed.
905
+ */
906
+ type GatewayServerOptions = GatewayEventStore & {
907
+ port?: number;
908
+ hostname?: string;
909
+ killCompetingSlack?: boolean;
910
+ token?: string; /** Permit a non-loopback `hostname` without a token. See FunnelGatewayServer. */
911
+ allowInsecureHost?: boolean;
912
+ extraRoutes?: Hono<Env$1>;
913
+ };
835
914
  /**
836
915
  * Facade that wires every funnel facet together and exposes the public surface.
837
916
  *
@@ -882,15 +961,7 @@ declare class Funnel {
882
961
  * this returns a class that runs `Bun.serve` + listeners inside the current process —
883
962
  * useful for tests, embedding, or custom hosts.
884
963
  */
885
- gatewayServer(options?: {
886
- port?: number;
887
- hostname?: string;
888
- dbPath?: string;
889
- killCompetingSlack?: boolean;
890
- token?: string;
891
- eventLog?: FunnelEventLog;
892
- extraRoutes?: Hono<Env$1>;
893
- }): FunnelGatewayServer;
964
+ gatewayServer(options?: GatewayServerOptions): FunnelGatewayServer;
894
965
  /**
895
966
  * Create a ProcessGuard scoped to this Funnel's home directory.
896
967
  * Useful for hosts that need to check or manage singleton PID files
@@ -1252,7 +1323,7 @@ declare const routes: _$hono_hono_base0.HonoBase<Env, {
1252
1323
  connectors: {
1253
1324
  id: string;
1254
1325
  name: string;
1255
- type: "schedule" | "slack" | "discord" | "gh";
1326
+ type: "discord" | "schedule" | "slack" | "gh";
1256
1327
  }[];
1257
1328
  }[];
1258
1329
  outputFormat: "json";
@@ -3407,4 +3478,4 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env$1, {
3407
3478
  };
3408
3479
  }, "/", "/channels/:channel/publish">;
3409
3480
  //#endregion
3410
- export { FunnelGatewayToken as $, FUNNEL_DIR as A, ListenerOpResult as B, ProcessListStub as C, MockFunnelSettingsReader as D, NodeFunnelFileSystem as E, Funnel as F, SqliteFunnelEventLog as G, MemoryConnectorDiagnosticLog as H, FunnelDebugReport as I, PublishResponse as J, FunnelChannelPublisher as K, FunnelListenersClient as L, SETTINGS_PATH as M, resolveFunnelDir as N, createSettings as O, resolveFunnelPort as P, DEFAULT_GATEWAY_TOKEN_PATH as Q, ListListenersResult as R, MemoryProcessSyncHandler as S, MemoryFunnelFileSystem as T, SqliteConnectorDiagnosticLog as U, FunnelGateway as V, MemoryFunnelEventLog as W, publishRequestSchema as X, PublishResult as Y, publishResponseSchema as Z, AliveStub as _, toRequest as a, Env$1 as at, MemoryProcessHandler as b, ConnectorDiagnosticSqlReader as c, FunnelListenerSupervisor as ct, MemoryFunnelClock as d, FunnelBroadcaster as dt, FunnelGatewayServer as et, NodeFunnelClock as f, ReplayableEvent as ft, NodeFunnelLogger as g, MemoryFunnelLogger as h, queryToCliArgs as i, funnelEventSchema as it, FunnelSettingsStore as j, DEFAULT_GATEWAY_PORT as k, MemoryFunnelIdGenerator as l, BroadcastEvent as lt, LogEntry as m, CliApp as n, FunnelEventLog as nt, Env as o, GatewayEmitInput as ot, NoopFunnelLogger as p, OnFunnelError as pt, PublishRequest as q, routes as r, FunnelEventRecord as rt, factory as s, GatewayRouteDeps as st, GatewayApp as t, FunnelEvent as tt, NodeFunnelIdGenerator as u, BroadcastSubscriber as ut, MemoryFunnelProcessRunner as v, NodeFunnelProcessRunner as w, MemoryProcessResponse as x, MemoryProcessCall as y, ListenerEntry as z };
3481
+ export { DEFAULT_GATEWAY_TOKEN_PATH as $, FUNNEL_DIR as A, ListenerEntry as B, ProcessListStub as C, MockFunnelSettingsReader as D, NodeFunnelFileSystem as E, Funnel as F, MemoryFunnelEventLog as G, FunnelGateway as H, GatewayServerOptions as I, PublishRequest as J, SqliteFunnelEventLog as K, FunnelDebugReport as L, SETTINGS_PATH as M, resolveFunnelDir as N, createSettings as O, resolveFunnelPort as P, publishResponseSchema as Q, FunnelListenersClient as R, MemoryProcessSyncHandler as S, MemoryFunnelFileSystem as T, MemoryConnectorDiagnosticLog as U, ListenerOpResult as V, SqliteConnectorDiagnosticLog as W, PublishResult as X, PublishResponse as Y, publishRequestSchema as Z, AliveStub as _, FunnelBroadcaster as _t, toRequest as a, FunnelGatewayServer as at, MemoryProcessHandler as b, ConnectorDiagnosticSqlReader as c, FunnelEventLog as ct, MemoryFunnelClock as d, Env$1 as dt, FunnelGatewayToken as et, NodeFunnelClock as f, GatewayEmitInput as ft, NodeFunnelLogger as g, BroadcastSubscriber as gt, MemoryFunnelLogger as h, BroadcastEvent as ht, queryToCliArgs as i, channelWsUrl as it, FunnelSettingsStore as j, DEFAULT_GATEWAY_PORT as k, MemoryFunnelIdGenerator as l, FunnelEventRecord as lt, LogEntry as m, FunnelListenerSupervisor as mt, CliApp as n, ChannelWsUrlInput as nt, Env as o, GatewayEventStore as ot, NoopFunnelLogger as p, GatewayRouteDeps as pt, FunnelChannelPublisher as q, routes as r, channelWsProtocols as rt, factory as s, FunnelEvent as st, GatewayApp as t, gatewayLoopbackUrl as tt, NodeFunnelIdGenerator as u, funnelEventSchema as ut, MemoryFunnelProcessRunner as v, ReplayableEvent as vt, NodeFunnelProcessRunner as w, MemoryProcessResponse as x, MemoryProcessCall as y, OnFunnelError as yt, ListListenersResult as z };
package/dist/index.d.ts CHANGED
@@ -2,10 +2,10 @@ import { a as ProfileConfig, c as channelConfigSchema, d as settingsSchema, i as
2
2
  import { S as FunnelLogger, _ as connectorConnectionEventSchema, a as ConnectorConnectionStatus, b as FunnelConnectorListener, c as ConnectorProcessedQuery, d as ConnectorRawEvent, f as ConnectorRawQuery, g as StoredRawEvent, h as StoredProcessedEvent, i as ConnectorConnectionRecord, l as ConnectorProcessedRecord, m as StoredConnectionEvent, n as ConnectorConnectionEvent, o as ConnectorDiagnosticLog, p as ConnectorRawRecord, r as ConnectorConnectionQuery, s as ConnectorProcessedEvent, t as CONNECTOR_CONNECTION_STATUSES, u as ConnectorQuery, v as connectorProcessedEventSchema, x as NotifyFn, y as connectorRawEventSchema } from "./connector-diagnostic-log-yTOojKUR.js";
3
3
  import { a as RunOptions, i as ProcessSnapshot, n as DetachOptions, o as RunResult, r as FunnelProcessRunner, t as AttachOptions } from "./process-runner-DfniuWVU.js";
4
4
  import { n as FunnelFileSystem, t as FileStat } from "./file-system-BeOKXjlV.js";
5
- import { a as ChannelConnectorView, c as FunnelConnectorFactory, d as ConnectorConfig, f as ConnectorType, l as ScheduleListenerOptions, o as FunnelChannels, p as connectorConfigSchema, s as FunnelClock, u as SlackListenerOptions } from "./local-config-sync-BdsrDZOu.js";
5
+ import { a as ChannelConnectorView, c as FunnelConnectorFactory, d as ConnectorConfig, f as ConnectorType, l as ScheduleListenerOptions, o as FunnelChannels, p as connectorConfigSchema, s as FunnelClock, u as SlackListenerOptions } from "./local-config-sync-Cq39mT6p.js";
6
6
  import { a as ScheduleEntry, c as scheduleEntrySchema, i as ScheduleConnectorConfig, o as scheduleCatchupPolicySchema, r as ScheduleCatchupPolicy, s as scheduleConnectorSchema } from "./schedule-listener-CUyUFFR1.js";
7
7
  import { a as slackConnectorSchema, c as SlackProcessedEmit, d as SlackSkipReason, i as SlackConnectorConfig, l as SlackProcessedSkip, o as FunnelSlackEventProcessor, s as SlackProcessed, u as SlackRawEvent } from "./slack-listener-Bv5xI9gC.js";
8
8
  import { n as discordConnectorSchema, t as DiscordConnectorConfig } from "./discord-connector-schema-R0Uu-3ns.js";
9
9
  import { n as ghConnectorSchema, t as GhConnectorConfig } from "./gh-connector-schema-eoTtHbY6.js";
10
- import { $ as FunnelGatewayToken, A as FUNNEL_DIR, B as ListenerOpResult, C as ProcessListStub, D as MockFunnelSettingsReader, E as NodeFunnelFileSystem, F as Funnel, G as SqliteFunnelEventLog, H as MemoryConnectorDiagnosticLog, I as FunnelDebugReport, J as PublishResponse, K as FunnelChannelPublisher, L as FunnelListenersClient, M as SETTINGS_PATH, N as resolveFunnelDir, O as createSettings, P as resolveFunnelPort, Q as DEFAULT_GATEWAY_TOKEN_PATH, R as ListListenersResult, S as MemoryProcessSyncHandler, T as MemoryFunnelFileSystem, U as SqliteConnectorDiagnosticLog, V as FunnelGateway, W as MemoryFunnelEventLog, X as publishRequestSchema, Y as PublishResult, Z as publishResponseSchema, _ as AliveStub, a as toRequest, at as Env$1, b as MemoryProcessHandler, c as ConnectorDiagnosticSqlReader, ct as FunnelListenerSupervisor, d as MemoryFunnelClock, dt as FunnelBroadcaster, et as FunnelGatewayServer, f as NodeFunnelClock, ft as ReplayableEvent, g as NodeFunnelLogger, h as MemoryFunnelLogger, i as queryToCliArgs, it as funnelEventSchema, j as FunnelSettingsStore, k as DEFAULT_GATEWAY_PORT, l as MemoryFunnelIdGenerator, lt as BroadcastEvent, m as LogEntry, n as CliApp, nt as FunnelEventLog, o as Env, ot as GatewayEmitInput, p as NoopFunnelLogger, pt as OnFunnelError, q as PublishRequest, r as routes, rt as FunnelEventRecord, s as factory, st as GatewayRouteDeps, t as GatewayApp, tt as FunnelEvent, u as NodeFunnelIdGenerator, ut as BroadcastSubscriber, v as MemoryFunnelProcessRunner, w as NodeFunnelProcessRunner, x as MemoryProcessResponse, y as MemoryProcessCall, z as ListenerEntry } from "./index-NFs2jzCa.js";
11
- export { AliveStub, AttachOptions, BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, ChannelConfig, ChannelConnectorView, ChannelDeliveryMode, CliApp, ConnectorConfig, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDiagnosticLog, ConnectorDiagnosticSqlReader, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, ConnectorType, DEFAULT_GATEWAY_PORT, DEFAULT_GATEWAY_TOKEN_PATH, DetachOptions, DiscordConnectorConfig, Env, FUNNEL_DIR, FileStat, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelDebugReport, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLogger, FunnelProcessRunner, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, GatewayApp, GatewayEmitInput, GatewayRouteDeps, Env$1 as GatewayServerEnv, GhConnectorConfig, ListListenersResult, ListenerEntry, ListenerOpResult, LogEntry, MemoryConnectorDiagnosticLog, MemoryFunnelClock, MemoryFunnelEventLog, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryProcessCall, MemoryProcessHandler, MemoryProcessResponse, MemoryProcessSyncHandler, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NoopFunnelLogger, NotifyFn, OnFunnelError, ProcessListStub, ProcessSnapshot, ProfileConfig, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, RunOptions, RunResult, SETTINGS_PATH, SETTINGS_VERSION, ScheduleCatchupPolicy, ScheduleConnectorConfig, ScheduleEntry, ScheduleListenerOptions, Settings, SlackConnectorConfig, SlackListenerOptions, SlackProcessed, SlackProcessedEmit, SlackProcessedSkip, SlackRawEvent, SlackSkipReason, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, StoredConnectionEvent, StoredProcessedEvent, StoredRawEvent, channelConfigSchema, channelDeliveryModeSchema, routes as cliRoutes, connectorConfigSchema, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, createSettings, discordConnectorSchema, factory, funnelEventSchema, ghConnectorSchema, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, resolveFunnelDir, resolveFunnelPort, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, toRequest };
10
+ import { $ as DEFAULT_GATEWAY_TOKEN_PATH, A as FUNNEL_DIR, B as ListenerEntry, C as ProcessListStub, D as MockFunnelSettingsReader, E as NodeFunnelFileSystem, F as Funnel, G as MemoryFunnelEventLog, H as FunnelGateway, I as GatewayServerOptions, J as PublishRequest, K as SqliteFunnelEventLog, L as FunnelDebugReport, M as SETTINGS_PATH, N as resolveFunnelDir, O as createSettings, P as resolveFunnelPort, Q as publishResponseSchema, R as FunnelListenersClient, S as MemoryProcessSyncHandler, T as MemoryFunnelFileSystem, U as MemoryConnectorDiagnosticLog, V as ListenerOpResult, W as SqliteConnectorDiagnosticLog, X as PublishResult, Y as PublishResponse, Z as publishRequestSchema, _ as AliveStub, _t as FunnelBroadcaster, a as toRequest, at as FunnelGatewayServer, b as MemoryProcessHandler, c as ConnectorDiagnosticSqlReader, ct as FunnelEventLog, d as MemoryFunnelClock, dt as Env$1, et as FunnelGatewayToken, f as NodeFunnelClock, ft as GatewayEmitInput, g as NodeFunnelLogger, gt as BroadcastSubscriber, h as MemoryFunnelLogger, ht as BroadcastEvent, i as queryToCliArgs, it as channelWsUrl, j as FunnelSettingsStore, k as DEFAULT_GATEWAY_PORT, l as MemoryFunnelIdGenerator, lt as FunnelEventRecord, m as LogEntry, mt as FunnelListenerSupervisor, n as CliApp, nt as ChannelWsUrlInput, o as Env, ot as GatewayEventStore, p as NoopFunnelLogger, pt as GatewayRouteDeps, q as FunnelChannelPublisher, r as routes, rt as channelWsProtocols, s as factory, st as FunnelEvent, t as GatewayApp, tt as gatewayLoopbackUrl, u as NodeFunnelIdGenerator, ut as funnelEventSchema, v as MemoryFunnelProcessRunner, vt as ReplayableEvent, w as NodeFunnelProcessRunner, x as MemoryProcessResponse, y as MemoryProcessCall, yt as OnFunnelError, z as ListListenersResult } from "./index-DF5VmCPJ.js";
11
+ export { AliveStub, AttachOptions, BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, ChannelConfig, ChannelConnectorView, ChannelDeliveryMode, ChannelWsUrlInput, CliApp, ConnectorConfig, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDiagnosticLog, ConnectorDiagnosticSqlReader, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, ConnectorType, DEFAULT_GATEWAY_PORT, DEFAULT_GATEWAY_TOKEN_PATH, DetachOptions, DiscordConnectorConfig, Env, FUNNEL_DIR, FileStat, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelDebugReport, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLogger, FunnelProcessRunner, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, GatewayApp, GatewayEmitInput, GatewayEventStore, GatewayRouteDeps, Env$1 as GatewayServerEnv, GatewayServerOptions, GhConnectorConfig, ListListenersResult, ListenerEntry, ListenerOpResult, LogEntry, MemoryConnectorDiagnosticLog, MemoryFunnelClock, MemoryFunnelEventLog, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryProcessCall, MemoryProcessHandler, MemoryProcessResponse, MemoryProcessSyncHandler, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NoopFunnelLogger, NotifyFn, OnFunnelError, ProcessListStub, ProcessSnapshot, ProfileConfig, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, RunOptions, RunResult, SETTINGS_PATH, SETTINGS_VERSION, ScheduleCatchupPolicy, ScheduleConnectorConfig, ScheduleEntry, ScheduleListenerOptions, Settings, SlackConnectorConfig, SlackListenerOptions, SlackProcessed, SlackProcessedEmit, SlackProcessedSkip, SlackRawEvent, SlackSkipReason, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, StoredConnectionEvent, StoredProcessedEvent, StoredRawEvent, channelConfigSchema, channelDeliveryModeSchema, channelWsProtocols, channelWsUrl, routes as cliRoutes, connectorConfigSchema, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, createSettings, discordConnectorSchema, factory, funnelEventSchema, gatewayLoopbackUrl, ghConnectorSchema, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, resolveFunnelDir, resolveFunnelPort, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, toRequest };
package/dist/index.js CHANGED
@@ -8,14 +8,14 @@ import { t as FunnelFileSystem } from "./file-system-PWKKU7lA.js";
8
8
  import { t as NodeFunnelFileSystem } from "./node-file-system-BcrmWN9I.js";
9
9
  import { n as FunnelSlackEventProcessor, r as FunnelSlackAdapter, t as FunnelSlackListener } from "./slack-listener-ClQuHhEF.js";
10
10
  import { n as FunnelIdGenerator, t as FunnelSettingsReader } from "./settings-reader-DPqrpV7s.js";
11
- import { a as resolveFunnelDir, c as channelConfigSchema, d as settingsSchema, f as connectorConfigSchema, i as SETTINGS_PATH, l as channelDeliveryModeSchema, n as FUNNEL_DIR, o as resolveFunnelPort, p as NodeFunnelIdGenerator, r as FunnelSettingsStore, s as SETTINGS_VERSION, t as DEFAULT_GATEWAY_PORT, u as profileConfigSchema } from "./settings-store-D2XSXTyt.js";
11
+ import { a as SETTINGS_PATH, c as SETTINGS_VERSION, d as profileConfigSchema, f as settingsSchema, i as FunnelSettingsStore, l as channelConfigSchema, m as NodeFunnelIdGenerator, n as DEFAULT_GATEWAY_PORT, o as resolveFunnelDir, p as connectorConfigSchema, r as FUNNEL_DIR, s as resolveFunnelPort, t as gatewayLoopbackUrl, u as channelDeliveryModeSchema } from "./gateway-base-url-ssk_He5G.js";
12
12
  import { t as discordConnectorSchema } from "./discord-connector-schema-CBDyGdOI.js";
13
13
  import { n as scheduleConnectorSchema, r as scheduleEntrySchema, t as scheduleCatchupPolicySchema } from "./schedule-connector-schema-iCI61gzU.js";
14
14
  import { t as slackConnectorSchema } from "./slack-connector-schema-BCNWluHM.js";
15
- import { a as FileProcessGuard, i as FunnelMcp, o as FunnelClaude } from "./mcp-Dr-nIBwN.js";
16
- import { a as FunnelLocalConfig, n as NodeFunnelTokenPrompter, r as FunnelLocalConfigSync, t as funnelJsonSchema } from "./local-config-json-schema-8IHjS4Q7.js";
15
+ import { a as FileProcessGuard, i as FunnelMcp, o as FunnelClaude } from "./mcp-QeNCBhOD.js";
16
+ import { a as FunnelLocalConfig, n as NodeFunnelTokenPrompter, r as FunnelLocalConfigSync, t as funnelJsonSchema } from "./local-config-json-schema-D8i-BogY.js";
17
17
  import { t as FunnelProfiles } from "./profiles-wMRnjSid.js";
18
- import { _ as FunnelBroadcaster, a as connectorConnectionEventSchema, b as publishResponseSchema, c as MemoryFunnelEventLog, d as FunnelGatewayServer, f as ConnectorDiagnosticSqlReader, g as funnelEventSchema, h as FunnelEventLog, i as ConnectorDiagnosticLog, l as DEFAULT_GATEWAY_TOKEN_PATH, m as SqliteFunnelEventLog, n as SqliteConnectorDiagnosticLog, o as connectorProcessedEventSchema, p as FunnelListenerSupervisor, r as CONNECTOR_CONNECTION_STATUSES, s as connectorRawEventSchema, t as MemoryConnectorDiagnosticLog, u as FunnelGatewayToken, v as FunnelChannelPublisher, x as funnelTmpDir, y as publishRequestSchema } from "./memory-connector-diagnostic-log-CrW1ltLM.js";
18
+ import { C as funnelTmpDir, S as publishResponseSchema, _ as FunnelEventLog, a as connectorConnectionEventSchema, b as FunnelChannelPublisher, c as MemoryFunnelEventLog, d as DEFAULT_GATEWAY_TOKEN_PATH, f as FunnelGatewayToken, g as SqliteFunnelEventLog, h as FunnelListenerSupervisor, i as ConnectorDiagnosticLog, l as channelWsProtocols, m as ConnectorDiagnosticSqlReader, n as SqliteConnectorDiagnosticLog, o as connectorProcessedEventSchema, p as FunnelGatewayServer, r as CONNECTOR_CONNECTION_STATUSES, s as connectorRawEventSchema, t as MemoryConnectorDiagnosticLog, u as channelWsUrl, v as funnelEventSchema, x as publishRequestSchema, y as FunnelBroadcaster } from "./memory-connector-diagnostic-log-COUWCsT_.js";
19
19
  import { dirname, join, resolve } from "node:path";
20
20
  import { hc } from "hono/client";
21
21
  import { appendFileSync, existsSync, mkdirSync } from "node:fs";
@@ -931,7 +931,7 @@ var FunnelListenersClient = class {
931
931
  async list() {
932
932
  if (!this.isDaemonRunning()) return { state: "offline" };
933
933
  try {
934
- const res = await fetch(`http://127.0.0.1:${this.port}/listeners`, { headers: this.authHeaders() });
934
+ const res = await fetch(`${gatewayLoopbackUrl(this.port)}/listeners`, { headers: this.authHeaders() });
935
935
  if (!res.ok) return {
936
936
  state: "error",
937
937
  reason: `HTTP ${res.status}`
@@ -973,7 +973,7 @@ var FunnelListenersClient = class {
973
973
  }
974
974
  async call(method, path) {
975
975
  try {
976
- const res = await fetch(`http://127.0.0.1:${this.port}${path}`, {
976
+ const res = await fetch(`${gatewayLoopbackUrl(this.port)}${path}`, {
977
977
  method,
978
978
  headers: this.authHeaders()
979
979
  });
@@ -1223,8 +1223,7 @@ var Funnel = class Funnel {
1223
1223
  channels: this.channels,
1224
1224
  port: options.port,
1225
1225
  hostname: options.hostname,
1226
- dbPath: options.dbPath,
1227
- eventLog: options.eventLog,
1226
+ ...options.eventLog ? { eventLog: options.eventLog } : { dbPath: options.dbPath },
1228
1227
  process: this.process,
1229
1228
  clock: this.clock,
1230
1229
  logger: this.logger,
@@ -1232,6 +1231,7 @@ var Funnel = class Funnel {
1232
1231
  dir: this.paths.dir,
1233
1232
  killCompetingSlack: options.killCompetingSlack,
1234
1233
  token: options.token ?? this.gatewayToken.ensure(),
1234
+ allowInsecureHost: options.allowInsecureHost,
1235
1235
  extraRoutes: options.extraRoutes
1236
1236
  });
1237
1237
  }
@@ -3516,4 +3516,4 @@ const routes = factory.createApp().onError((error, c) => {
3516
3516
  return c.text(`error: ${error instanceof Error ? error.message : String(error)}`, 400);
3517
3517
  }).get("/claude", ...claudeHandler).get("/channels", ...channelsGroupHandler).post("/channels/add", ...channelsAddHelpHandler).post("/channels/add/:channel", ...channelsAddHandler).post("/channels/remove", ...channelsRemoveHelpHandler).post("/channels/remove/:channel", ...channelsRemoveHandler).post("/channels/rename/:channel/:newName", ...channelsRenameHandler).post("/channels/:channel/rename/:newName", ...channelsRenameHandler).post("/channels/rename", ...channelsRenameHelpHandler).post("/channels/:channel/rename", ...channelsChannelRenameHelpHandler).post("/channels/:channel/set/delivery/:mode", ...channelsSetDeliveryHandler).post("/channels/publish", ...channelsPublishHelpHandler).post("/channels/:channel/publish", ...channelsPublishHandler).get("/channels/:channel/validate", ...channelsValidateHandler).get("/channels/validate", ...channelsValidateHelpHandler).get("/channels/:channel", ...channelsShowHandler).get("/channels/:channel/connectors", ...channelsConnectorsGroupHandler).post("/channels/:channel/connectors/add", ...channelsConnectorsAddHelpHandler).post("/channels/:channel/connectors/add/:connector", ...channelsConnectorsAddHandler).post("/channels/:channel/connectors/remove", ...channelsConnectorsRemoveHelpHandler).post("/channels/:channel/connectors/remove/:connector", ...channelsConnectorsRemoveHandler).post("/channels/:channel/connectors/set", ...channelsConnectorsSetHelpHandler).post("/channels/:channel/connectors/set/:connector", ...channelsConnectorsSetHandler).post("/channels/:channel/connectors/rename/:connector/:newName", ...channelsConnectorsRenameHandler).post("/channels/:channel/connectors/:connector/rename/:newName", ...channelsConnectorsRenameHandler).post("/channels/:channel/connectors/rename", ...channelsConnectorsRenameHelpHandler).post("/channels/:channel/connectors/:connector/rename", ...channelsConnectorRenameHelpHandler).post("/channels/:channel/connectors/:connector/request", ...channelsConnectorsRequestHandler).get("/channels/:channel/connectors/:connector", ...channelsConnectorsShowHandler).get("/channels/:channel/connectors/:connector/schedules", ...channelsConnectorsSchedulesGroupHandler).post("/channels/:channel/connectors/:connector/schedules/add", ...channelsConnectorSchedulesAddHelpHandler).post("/channels/:channel/connectors/:connector/schedules/add/:id", ...channelsConnectorsSchedulesAddHandler).post("/channels/:channel/connectors/:connector/schedules/remove", ...channelsConnectorSchedulesRemoveHelpHandler).post("/channels/:channel/connectors/:connector/schedules/remove/:id", ...channelsConnectorsSchedulesRemoveHandler).get("/profiles", ...profilesGroupHandler).post("/profiles/add", ...profilesAddHelpHandler).post("/profiles/add/:profile", ...profilesAddHandler).post("/profiles/set", ...profilesSetHelpHandler).post("/profiles/set/:profile", ...profilesSetHandler).post("/profiles/remove", ...profilesRemoveHelpHandler).post("/profiles/remove/:profile", ...profilesRemoveHandler).post("/profiles/rename/:profile/:newName", ...profilesRenameHandler).post("/profiles/:profile/rename/:newName", ...profilesRenameHandler).post("/profiles/rename", ...profilesRenameHelpHandler).post("/profiles/:profile/rename", ...profilesProfileRenameHelpHandler).post("/profiles/:profile/as-default", ...profilesAsDefaultHandler).get("/profiles/:profile/run", ...profilesLaunchHandler).get("/profiles/:profile", ...profilesLaunchHandler).get("/gateway", ...gatewayGroupHandler).get("/gateway/status", ...gatewayStatusHandler).get("/gateway/start", ...gatewayStartHandler).get("/gateway/stop", ...gatewayStopHandler).get("/gateway/restart", ...gatewayRestartHandler).get("/gateway/run", ...gatewayRunHandler).get("/gateway/logs", ...gatewayLogsHandler).get("/gateway/sql", ...gatewaySqlHandler).get("/gateway/listeners", ...gatewayListenersHandler).get("/debug", ...debugHandler).get("/debug/events", ...debugEventsHandler).get("/debug/dropped", ...debugDroppedHandler).get("/debug/errors", ...debugErrorsHandler).get("/debug/replay", ...debugReplayHandler).get("/schema", ...schemaHandler).get("/status", ...statusHandler).get("/update", ...updateHandler);
3518
3518
  //#endregion
3519
- export { CONNECTOR_CONNECTION_STATUSES, ConnectorDiagnosticLog, ConnectorDiagnosticSqlReader, DEFAULT_GATEWAY_PORT, DEFAULT_GATEWAY_TOKEN_PATH, FUNNEL_DIR, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelEventLog, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLogger, FunnelProcessRunner, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, MemoryConnectorDiagnosticLog, MemoryFunnelClock, MemoryFunnelEventLog, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NoopFunnelLogger, SETTINGS_PATH, SETTINGS_VERSION, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, channelConfigSchema, channelDeliveryModeSchema, routes as cliRoutes, connectorConfigSchema, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, createSettings, discordConnectorSchema, factory, funnelEventSchema, ghConnectorSchema, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, resolveFunnelDir, resolveFunnelPort, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, toRequest };
3519
+ export { CONNECTOR_CONNECTION_STATUSES, ConnectorDiagnosticLog, ConnectorDiagnosticSqlReader, DEFAULT_GATEWAY_PORT, DEFAULT_GATEWAY_TOKEN_PATH, FUNNEL_DIR, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelEventLog, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLogger, FunnelProcessRunner, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, MemoryConnectorDiagnosticLog, MemoryFunnelClock, MemoryFunnelEventLog, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NoopFunnelLogger, SETTINGS_PATH, SETTINGS_VERSION, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, channelConfigSchema, channelDeliveryModeSchema, channelWsProtocols, channelWsUrl, routes as cliRoutes, connectorConfigSchema, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, createSettings, discordConnectorSchema, factory, funnelEventSchema, gatewayLoopbackUrl, ghConnectorSchema, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, resolveFunnelDir, resolveFunnelPort, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, toRequest };
@@ -122,6 +122,18 @@ var FunnelLocalConfig = class {
122
122
  }
123
123
  };
124
124
  //#endregion
125
+ //#region lib/connectors/either-token.ts
126
+ function botTokenSlot(slot) {
127
+ if (slot.env !== void 0) return { botTokenEnv: slot.env };
128
+ if (slot.literal !== void 0) return { botToken: slot.literal };
129
+ return {};
130
+ }
131
+ function appTokenSlot(slot) {
132
+ if (slot.env !== void 0) return { appTokenEnv: slot.env };
133
+ if (slot.literal !== void 0) return { appToken: slot.literal };
134
+ return {};
135
+ }
136
+ //#endregion
125
137
  //#region lib/engine/token-prompter/token-prompter.ts
126
138
  /**
127
139
  * Asks the user for a secret value on stdin. Used as a last resort when a
@@ -223,7 +235,14 @@ var FunnelLocalConfigSync = class {
223
235
  id: this.channels.addConnector(channelName, {
224
236
  type: "slack",
225
237
  name: spec.name,
226
- ...update,
238
+ ...botTokenSlot({
239
+ literal: bot.token,
240
+ env: bot.tokenEnv
241
+ }),
242
+ ...appTokenSlot({
243
+ literal: app.token,
244
+ env: app.tokenEnv
245
+ }),
227
246
  ...spec.minify !== void 0 ? { minify: spec.minify } : {}
228
247
  }).id,
229
248
  name: spec.name,
@@ -260,7 +279,10 @@ var FunnelLocalConfigSync = class {
260
279
  id: this.channels.addConnector(channelName, {
261
280
  type: "discord",
262
281
  name: spec.name,
263
- ...update
282
+ ...botTokenSlot({
283
+ literal: bot.token,
284
+ env: bot.tokenEnv
285
+ })
264
286
  }).id,
265
287
  name: spec.name,
266
288
  changed: true
@@ -2,7 +2,7 @@ import { i as ChannelDeliveryMode, n as FunnelIdGenerator, r as ChannelConfig, t
2
2
  import { S as FunnelLogger, b as FunnelConnectorListener, o as ConnectorDiagnosticLog } from "./connector-diagnostic-log-yTOojKUR.js";
3
3
  import { r as FunnelProcessRunner } from "./process-runner-DfniuWVU.js";
4
4
  import { n as FunnelFileSystem } from "./file-system-BeOKXjlV.js";
5
- import { n as FunnelConnectorAdapter, t as CallInput } from "./connector-adapter-DKgsVuMH.js";
5
+ import { n as FunnelConnectorAdapter, t as CallInput } from "./connector-adapter-CePYBTgW.js";
6
6
  import { a as ScheduleEntry, n as ScheduleOnFired } from "./schedule-listener-CUyUFFR1.js";
7
7
  import { n as SlackOnAppCreated, r as SlackPreprocessEvent } from "./slack-listener-Bv5xI9gC.js";
8
8
  import { z } from "zod";
@@ -148,6 +148,27 @@ declare const connectorConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
148
148
  type ConnectorConfig = z.infer<typeof connectorConfigSchema>;
149
149
  type ConnectorType = ConnectorConfig["type"];
150
150
  //#endregion
151
+ //#region lib/connectors/either-token.d.ts
152
+ /**
153
+ * A single connector token slot is supplied one of two non-empty ways, which
154
+ * are mutually exclusive, or left empty:
155
+ *
156
+ * - the literal secret (`botToken: "xoxb-…"`)
157
+ * - the *name* of an env var holding it (`botTokenEnv: "SLACK_BOT_TOKEN"`)
158
+ * - neither — left for the CLI / TTY prompt to fill in at launch
159
+ *
160
+ * `EitherToken<"botToken", "botTokenEnv">` makes "both set at once" a compile
161
+ * error while still allowing "neither". Compose multiple slots with `&` (a slack
162
+ * connector intersects a bot slot and an app slot); the intersection keeps each
163
+ * slot independently exclusive without enumerating the cross-product.
164
+ *
165
+ * To build a value, use the slot helpers below (`botTokenSlot` etc.). They take
166
+ * a resolved `{ literal, env }` and return the exclusive shape. A generic
167
+ * builder can't: TS can't prove a `Record<Env, …>` omits the `Literal` key when
168
+ * both are free type params, so each helper fixes concrete key names instead.
169
+ */
170
+ type EitherToken<Literal extends string, Env extends string> = (Partial<Record<Literal, string>> & Partial<Record<Env, never>>) | (Partial<Record<Literal, never>> & Partial<Record<Env, string>>);
171
+ //#endregion
151
172
  //#region lib/connectors/connector-factory.d.ts
152
173
  type SlackListenerOptions = {
153
174
  onAppCreated?: SlackOnAppCreated;
@@ -224,24 +245,18 @@ type ChannelConnectorView = ConnectorConfig & {
224
245
  channelId: string;
225
246
  channelName: string;
226
247
  };
227
- type AddConnectorInput = {
248
+ type AddConnectorInput = ({
228
249
  type: "slack";
229
250
  name: string;
230
- botToken?: string;
231
- appToken?: string;
232
- botTokenEnv?: string;
233
- appTokenEnv?: string;
234
251
  minify?: boolean;
235
- } | {
252
+ } & EitherToken<"botToken", "botTokenEnv"> & EitherToken<"appToken", "appTokenEnv">) | {
236
253
  type: "gh";
237
254
  name: string;
238
255
  pollInterval?: number;
239
- } | {
256
+ } | ({
240
257
  type: "discord";
241
258
  name: string;
242
- botToken?: string;
243
- botTokenEnv?: string;
244
- } | {
259
+ } & EitherToken<"botToken", "botTokenEnv">) | {
245
260
  type: "schedule";
246
261
  name: string;
247
262
  entries?: ScheduleEntry[];
@@ -1,3 +1,3 @@
1
- import { C as profileSpecSchema, S as localConfigSchema, _ as LOCAL_CONFIG_FILENAME, b as channelSpecSchema, g as ConnectorSpec, h as ChannelSpec, i as FunnelTokenPrompter, m as FunnelLocalConfig, n as FunnelLocalConfigSync, r as LocalConfigSyncResult, t as ConnectorSyncOutcome, v as LocalConfig, x as connectorSpecSchema, y as ProfileSpec } from "./local-config-sync-BdsrDZOu.js";
2
- import { i as funnelJsonSchema, n as NodeFunnelTokenPrompter, r as FunnelLocalConfigWriter, t as MemoryFunnelTokenPrompter } from "./memory-token-prompter-B5FFCsGP.js";
1
+ import { C as profileSpecSchema, S as localConfigSchema, _ as LOCAL_CONFIG_FILENAME, b as channelSpecSchema, g as ConnectorSpec, h as ChannelSpec, i as FunnelTokenPrompter, m as FunnelLocalConfig, n as FunnelLocalConfigSync, r as LocalConfigSyncResult, t as ConnectorSyncOutcome, v as LocalConfig, x as connectorSpecSchema, y as ProfileSpec } from "./local-config-sync-Cq39mT6p.js";
2
+ import { i as funnelJsonSchema, n as NodeFunnelTokenPrompter, r as FunnelLocalConfigWriter, t as MemoryFunnelTokenPrompter } from "./memory-token-prompter-CKV7VBM5.js";
3
3
  export { ChannelSpec, ConnectorSpec, ConnectorSyncOutcome, FunnelLocalConfig, FunnelLocalConfigSync, FunnelLocalConfigWriter, FunnelTokenPrompter, LOCAL_CONFIG_FILENAME, LocalConfig, LocalConfigSyncResult, MemoryFunnelTokenPrompter, NodeFunnelTokenPrompter, ProfileSpec, channelSpecSchema, connectorSpecSchema, funnelJsonSchema, localConfigSchema, profileSpecSchema };
@@ -1,3 +1,3 @@
1
- import { a as FunnelLocalConfig, c as connectorSpecSchema, i as FunnelTokenPrompter, l as localConfigSchema, n as NodeFunnelTokenPrompter, o as LOCAL_CONFIG_FILENAME, r as FunnelLocalConfigSync, s as channelSpecSchema, t as funnelJsonSchema, u as profileSpecSchema } from "./local-config-json-schema-8IHjS4Q7.js";
2
- import { n as FunnelLocalConfigWriter, t as MemoryFunnelTokenPrompter } from "./memory-token-prompter-CLerGsgM.js";
1
+ import { a as FunnelLocalConfig, c as connectorSpecSchema, i as FunnelTokenPrompter, l as localConfigSchema, n as NodeFunnelTokenPrompter, o as LOCAL_CONFIG_FILENAME, r as FunnelLocalConfigSync, s as channelSpecSchema, t as funnelJsonSchema, u as profileSpecSchema } from "./local-config-json-schema-D8i-BogY.js";
2
+ import { n as FunnelLocalConfigWriter, t as MemoryFunnelTokenPrompter } from "./memory-token-prompter-Q7Snwsv2.js";
3
3
  export { FunnelLocalConfig, FunnelLocalConfigSync, FunnelLocalConfigWriter, FunnelTokenPrompter, LOCAL_CONFIG_FILENAME, MemoryFunnelTokenPrompter, NodeFunnelTokenPrompter, channelSpecSchema, connectorSpecSchema, funnelJsonSchema, localConfigSchema, profileSpecSchema };
@@ -1,6 +1,6 @@
1
1
  import { n as NodeFunnelProcessRunner } from "./gh-connector-schema-o3Q1-ojL.js";
2
2
  import { t as NodeFunnelFileSystem } from "./node-file-system-BcrmWN9I.js";
3
- import { n as FUNNEL_DIR, o as resolveFunnelPort, p as NodeFunnelIdGenerator } from "./settings-store-D2XSXTyt.js";
3
+ import { m as NodeFunnelIdGenerator, r as FUNNEL_DIR, s as resolveFunnelPort } from "./gateway-base-url-ssk_He5G.js";
4
4
  import { join } from "node:path";
5
5
  import { z } from "zod";
6
6
  //#region lib/engine/claude/claude.ts
@@ -1,6 +1,6 @@
1
1
  import { n as NodeFunnelProcessRunner } from "./gh-connector-schema-o3Q1-ojL.js";
2
2
  import { t as NodeFunnelFileSystem } from "./node-file-system-BcrmWN9I.js";
3
- import { n as FUNNEL_DIR, o as resolveFunnelPort } from "./settings-store-D2XSXTyt.js";
3
+ import { r as FUNNEL_DIR, s as resolveFunnelPort, t as gatewayLoopbackUrl } from "./gateway-base-url-ssk_He5G.js";
4
4
  import { dirname, join } from "node:path";
5
5
  import { chmodSync, existsSync, mkdirSync } from "node:fs";
6
6
  import { z } from "zod";
@@ -65,7 +65,7 @@ var FunnelChannelPublisher = class {
65
65
  async publish(channelName, request) {
66
66
  if (!this.isDaemonRunning()) return OFFLINE;
67
67
  try {
68
- const url = `http://127.0.0.1:${this.port}/channels/${encodeURIComponent(channelName)}/publish`;
68
+ const url = `${gatewayLoopbackUrl(this.port)}/channels/${encodeURIComponent(channelName)}/publish`;
69
69
  const res = await fetch(url, {
70
70
  method: "POST",
71
71
  headers: {
@@ -1040,10 +1040,18 @@ const zParam = (schema) => zValidator("param", schema, (result, c) => {
1040
1040
  });
1041
1041
  //#endregion
1042
1042
  //#region lib/gateway/routes/channels.connectors.call.ts
1043
+ const jsonValueSchema = z.lazy(() => z.union([
1044
+ z.string(),
1045
+ z.number(),
1046
+ z.boolean(),
1047
+ z.null(),
1048
+ z.array(jsonValueSchema),
1049
+ z.record(z.string(), jsonValueSchema)
1050
+ ]));
1043
1051
  const bodySchema = z.object({
1044
1052
  method: z.string().min(1),
1045
1053
  path: z.string().min(1),
1046
- body: z.unknown().optional()
1054
+ body: jsonValueSchema.optional()
1047
1055
  });
1048
1056
  /**
1049
1057
  * POST /channels/:channel/connectors/:connector/call
@@ -1064,7 +1072,7 @@ const channelsConnectorsCallHandler = factory.createHandlers(zParam(z.object({
1064
1072
  const result = await c.var.deps.channels.call(param.channel, param.connector, {
1065
1073
  method: parsed.data.method,
1066
1074
  path: parsed.data.path,
1067
- body: parsed.data.body ?? {}
1075
+ body: parsed.data.body
1068
1076
  });
1069
1077
  return c.json({
1070
1078
  ok: true,
@@ -1448,6 +1456,7 @@ var FunnelGatewayServer = class {
1448
1456
  dir;
1449
1457
  killCompetingSlack;
1450
1458
  token;
1459
+ allowInsecureHost;
1451
1460
  broadcaster;
1452
1461
  eventLog;
1453
1462
  supervisor;
@@ -1467,6 +1476,7 @@ var FunnelGatewayServer = class {
1467
1476
  this.dir = deps.dir ?? FUNNEL_DIR;
1468
1477
  this.killCompetingSlack = deps.killCompetingSlack ?? true;
1469
1478
  this.token = deps.token ?? "";
1479
+ this.allowInsecureHost = deps.allowInsecureHost ?? false;
1470
1480
  this.extraRoutes = deps.extraRoutes ?? null;
1471
1481
  const clock = deps.clock;
1472
1482
  this.nowMs = clock ? () => clock.millis() : () => Date.now();
@@ -1503,7 +1513,7 @@ var FunnelGatewayServer = class {
1503
1513
  }
1504
1514
  async start() {
1505
1515
  if (this.server) return this.server;
1506
- if (!this.token && !LOOPBACK_HOSTS.has(this.hostname)) this.logger?.warn("gateway auth is disabled on a non-loopback bind every endpoint is reachable without a token", { hostname: this.hostname });
1516
+ if (!this.token && !LOOPBACK_HOSTS.has(this.hostname) && !this.allowInsecureHost) throw new Error(`refusing to start gateway: hostname "${this.hostname}" is reachable off-box but no token is set. Set a token, bind to loopback (127.0.0.1), or pass allowInsecureHost: true.`);
1507
1517
  const app = this.buildApp();
1508
1518
  this.startedAt = this.nowMs();
1509
1519
  this.server = Bun.serve({
@@ -1775,6 +1785,27 @@ var FunnelGatewayToken = class {
1775
1785
  };
1776
1786
  const DEFAULT_GATEWAY_TOKEN_PATH = join(homedir(), ".funnel", TOKEN_FILE_NAME);
1777
1787
  //#endregion
1788
+ //#region lib/gateway/channel-ws-url.ts
1789
+ function channelWsUrl(input) {
1790
+ const url = new URL(input.base);
1791
+ url.searchParams.set("channel", input.channel);
1792
+ if (input.subscriberId !== void 0) url.searchParams.set("id", input.subscriberId);
1793
+ if (input.since !== void 0) url.searchParams.set("since", String(input.since));
1794
+ return url.toString();
1795
+ }
1796
+ /**
1797
+ * Builds the `Sec-WebSocket-Protocol` values that authenticate a gateway WS
1798
+ * upgrade. Browser `WebSocket` cannot set an `Authorization` header, so the
1799
+ * gateway also accepts the token as a `funnel.token.<token>` subprotocol.
1800
+ * Returns an empty array when no token is given (auth disabled / loopback).
1801
+ *
1802
+ * Usage: `new WebSocket(channelWsUrl({ base, channel }), channelWsProtocols(token))`
1803
+ */
1804
+ function channelWsProtocols(token) {
1805
+ if (!token) return [];
1806
+ return [`funnel.token.${token}`];
1807
+ }
1808
+ //#endregion
1778
1809
  //#region lib/gateway/memory-funnel-event-log.ts
1779
1810
  /**
1780
1811
  * In-process `FunnelEventLog` backed by a plain array. Used by tests and by
@@ -2242,4 +2273,4 @@ const takeRecent = (events, limit) => {
2242
2273
  return events.slice(-limit);
2243
2274
  };
2244
2275
  //#endregion
2245
- export { FunnelBroadcaster as _, connectorConnectionEventSchema as a, publishResponseSchema as b, MemoryFunnelEventLog as c, FunnelGatewayServer as d, ConnectorDiagnosticSqlReader as f, funnelEventSchema as g, FunnelEventLog as h, ConnectorDiagnosticLog as i, DEFAULT_GATEWAY_TOKEN_PATH as l, SqliteFunnelEventLog as m, SqliteConnectorDiagnosticLog as n, connectorProcessedEventSchema as o, FunnelListenerSupervisor as p, CONNECTOR_CONNECTION_STATUSES as r, connectorRawEventSchema as s, MemoryConnectorDiagnosticLog as t, FunnelGatewayToken as u, FunnelChannelPublisher as v, funnelTmpDir as x, publishRequestSchema as y };
2276
+ export { funnelTmpDir as C, publishResponseSchema as S, FunnelEventLog as _, connectorConnectionEventSchema as a, FunnelChannelPublisher as b, MemoryFunnelEventLog as c, DEFAULT_GATEWAY_TOKEN_PATH as d, FunnelGatewayToken as f, SqliteFunnelEventLog as g, FunnelListenerSupervisor as h, ConnectorDiagnosticLog as i, channelWsProtocols as l, ConnectorDiagnosticSqlReader as m, SqliteConnectorDiagnosticLog as n, connectorProcessedEventSchema as o, FunnelGatewayServer as p, CONNECTOR_CONNECTION_STATUSES as r, connectorRawEventSchema as s, MemoryConnectorDiagnosticLog as t, channelWsUrl as u, funnelEventSchema as v, publishRequestSchema as x, FunnelBroadcaster as y };
@@ -1,5 +1,5 @@
1
1
  import { n as FunnelFileSystem } from "./file-system-BeOKXjlV.js";
2
- import { i as FunnelTokenPrompter } from "./local-config-sync-BdsrDZOu.js";
2
+ import { i as FunnelTokenPrompter } from "./local-config-sync-Cq39mT6p.js";
3
3
 
4
4
  //#region lib/engine/local-config/local-config-json-schema.d.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { i as FunnelTokenPrompter, o as LOCAL_CONFIG_FILENAME } from "./local-config-json-schema-8IHjS4Q7.js";
1
+ import { i as FunnelTokenPrompter, o as LOCAL_CONFIG_FILENAME } from "./local-config-json-schema-D8i-BogY.js";
2
2
  import { join } from "node:path";
3
3
  //#region lib/engine/local-config/local-config-writer.ts
4
4
  const isRecord = (value) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interactive-inc/claude-funnel",
3
- "version": "0.52.0",
3
+ "version": "0.53.0",
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",
@@ -1,11 +0,0 @@
1
- //#region lib/connectors/connector-adapter.d.ts
2
- type CallInput = {
3
- method: string;
4
- path: string;
5
- body?: unknown;
6
- };
7
- declare abstract class FunnelConnectorAdapter {
8
- abstract call(input: CallInput): Promise<unknown>;
9
- }
10
- //#endregion
11
- export { FunnelConnectorAdapter as n, CallInput as t };