@interactive-inc/claude-funnel 0.64.0 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/gateway.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { n as gatewayLoopbackUrl } from "./loopback-fetch-CVNuN3YZ.js";
2
- import { S as connectorRawEventSchema, _ as MemoryConnectorDiagnosticLog, a as DEFAULT_GATEWAY_TOKEN_PATH, b as connectorConnectionEventSchema, c as FunnelListenerRegistry, d as funnelEventSchema, f as FunnelBroadcaster, g as publishResponseSchema, h as publishRequestSchema, i as channelWsUrl, l as SqliteFunnelEventLog, m as FunnelChannelPublisher, n as MemoryFunnelEventLog, o as FunnelGatewayToken, r as channelWsProtocols, s as FunnelGatewayServer, t as SqliteConnectorDiagnosticLog, u as FunnelEventLog, v as CONNECTOR_CONNECTION_STATUSES, x as connectorProcessedEventSchema, y as ConnectorDiagnosticLog } from "./sqlite-diagnostic-log-DOTPW-tG.js";
2
+ import { S as connectorRawEventSchema, _ as MemoryConnectorDiagnosticLog, a as DEFAULT_GATEWAY_TOKEN_PATH, b as connectorConnectionEventSchema, c as FunnelListenerRegistry, d as funnelEventSchema, f as FunnelBroadcaster, g as publishResponseSchema, h as publishRequestSchema, i as channelWsUrl, l as SqliteFunnelEventLog, m as FunnelChannelPublisher, n as MemoryFunnelEventLog, o as FunnelGatewayToken, r as channelWsProtocols, s as FunnelGatewayServer, t as SqliteConnectorDiagnosticLog, u as FunnelEventLog, v as CONNECTOR_CONNECTION_STATUSES, x as connectorProcessedEventSchema, y as ConnectorDiagnosticLog } from "./sqlite-diagnostic-log-CwhXE9Qh.js";
3
3
  export { CONNECTOR_CONNECTION_STATUSES, ConnectorDiagnosticLog, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEventLog, FunnelGatewayServer, FunnelGatewayToken, FunnelListenerRegistry, MemoryConnectorDiagnosticLog, MemoryFunnelEventLog, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, channelWsProtocols, channelWsUrl, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, funnelEventSchema, gatewayLoopbackUrl, publishRequestSchema, publishResponseSchema };
package/dist/index.d.ts CHANGED
@@ -291,8 +291,27 @@ declare class Funnel {
291
291
  * gateway pid/token, claude pids) at a repo-local `<repo>/.funnel` and never
292
292
  * touch the global home. Read at call time, not module load, so a daemon
293
293
  * spawned with the env set resolves the override.
294
+ *
295
+ * The override goes through `expandHomeDir` so a consumer .mcp.json can write
296
+ * `FUNNEL_DIR: "~/.nocker/funnel"` or `"${HOME}/.nocker/funnel"` and have it
297
+ * land on the right path on macOS, Linux, and Windows — Claude Code's `${VAR}`
298
+ * expansion only resolves whichever env happens to be set on the host shell
299
+ * (`$HOME` is unset on vanilla Windows cmd/PowerShell, `$USERPROFILE` is unset
300
+ * on macOS/Linux), so funnel takes the second swing here.
294
301
  */
295
302
  declare function resolveFunnelDir(): string;
303
+ /**
304
+ * Resolves the three forms a consumer might write for the user home dir:
305
+ * a leading `~` / `~/`, the literal `${HOME}` token, and the literal
306
+ * `${USERPROFILE}` token. The expansion is intentionally narrow — only the
307
+ * home-dir tokens are substituted, no general shell-variable expansion — so
308
+ * an accidentally embedded `${USERPROFILE}` in a path on macOS does not
309
+ * silently turn into a different (Windows-style) path elsewhere. Normalizes
310
+ * Windows backslashes to forward slashes after expansion because Node's
311
+ * `path` operations accept either on Windows but the cross-platform pieces
312
+ * (URL building, glob matching) prefer forward slashes.
313
+ */
314
+ declare function expandHomeDir(input: string): string;
296
315
  declare const DEFAULT_GATEWAY_PORT = 9742;
297
316
  /**
298
317
  * Resolves the gateway port. Defaults to 9742 — the port a programmatically
@@ -1715,4 +1734,4 @@ declare const routes: _$hono_hono_base0.HonoBase<Env, {
1715
1734
  }, "/", "/update">;
1716
1735
  type CliApp = typeof routes;
1717
1736
  //#endregion
1718
- export { AddConnectorInput, AliveStub, AttachOptions, BaseConnectorConfig, BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, CallInput, ChannelConfig, ChannelConnectorView, ChannelDeliveryMode, ChannelDiagnosis, ChannelWsUrlInput, type CliApp, ConnectorAdapterDeps, ConnectorBuildContext, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDescriptor, ConnectorDiagnosticLog, ConnectorDiagnosticSqlReader, ConnectorListenerDeps, ConnectorOperation, ConnectorOperationContext, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, ConnectorUpdateContext, DEFAULT_GATEWAY_PORT, DEFAULT_GATEWAY_TOKEN_PATH, DetachOptions, DiagnoseAllReport, DiagnosisStatus, DiagnosticConnectionError, DiagnosticEvent, DiagnosticsChannelSource, DiagnosticsGatewayProbe, DiagnosticsPublisher, DiagnosticsTokenReader, DiscordConnectorConfig, DocsTopicListing, DoctorFixMode, DoctorReport, Env, FUNNEL_DIR, FileStat, Funnel, FunnelAuthFailedError, FunnelBroadcaster, FunnelChannelAlreadyExistsError, FunnelChannelNotFoundError, FunnelChannelPublisher, FunnelChannels, FunnelClock, FunnelConnectorAdapter, FunnelConnectorListener, FunnelConnectorNotFoundError, FunnelConnectorRegistry, FunnelConnectorTypeMismatchError, FunnelDiagnostics, FunnelDocs, FunnelDoctor, FunnelError, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelFileSystem, FunnelGateway, FunnelGatewayBindError, FunnelGatewayServer, FunnelGatewayToken, FunnelHttpClient, FunnelIdGenerator, FunnelListenerRegistry, FunnelListenersClient, FunnelLogger, FunnelProcessRunner, FunnelRecovery, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, FunnelTokenCollisionError, FunnelTokenPrompter, type GatewayApp, type GatewayEmitInput, GatewayEventStore, type GatewayRouteDeps, type Env$1 as GatewayServerEnv, GatewayServerOptions, GhConnectorConfig, HttpRequest, HttpResponse, JsonValue, ListListenersResult, ListenerEntry, ListenerOpResult, LogEntry, MemoryConnectorDiagnosticLog, MemoryFunnelClock, MemoryFunnelEventLog, MemoryFunnelFileSystem, MemoryFunnelHttpClient, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryFunnelTokenPrompter, MemoryHttpHandler, MemoryHttpResponse, MemoryProcessCall, MemoryProcessHandler, MemoryProcessResponse, MemoryProcessSyncHandler, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelHttpClient, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NodeFunnelTokenPrompter, NoopFunnelLogger, NotifyFn, OnFunnelError, ProcessListStub, ProcessSnapshot, ProfileConfig, PublishRequest, PublishResponse, PublishResult, RecoveryAction, RecoveryChannelSource, RecoveryGatewayControl, RecoveryListenerControl, RecoveryResult, ReplayResult, ReplayableEvent, RunOptions, RunResult, SETTINGS_PATH, SETTINGS_VERSION, ScheduleCatchupPolicy, ScheduleConnectorConfig, ScheduleEntry, Settings, SlackConnectorConfig, SlackEvent, SlackMessageEvent, SlackProcessed, SlackProcessedEmit, SlackProcessedSkip, SlackRawEvent, SlackReactionEvent, SlackSkipReason, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, StartTimeStub, StoredConnectionEvent, StoredProcessedEvent, StoredRawEvent, baseConnectorConfigSchema, buildServiceRoutes, channelConfigSchema, channelDeliveryModeSchema, channelWsProtocols, channelWsUrl, routes as cliRoutes, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, createSettings, discordConnectorSchema, factory, funnelEventSchema, gatewayLoopbackUrl, ghConnectorSchema, previewOf, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryRows, queryToCliArgs, resolveFunnelDir, resolveFunnelPort, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, toDiagnosticConnectionError, toDiagnosticEvent, toRequest };
1737
+ export { AddConnectorInput, AliveStub, AttachOptions, BaseConnectorConfig, BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, CallInput, ChannelConfig, ChannelConnectorView, ChannelDeliveryMode, ChannelDiagnosis, ChannelWsUrlInput, type CliApp, ConnectorAdapterDeps, ConnectorBuildContext, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDescriptor, ConnectorDiagnosticLog, ConnectorDiagnosticSqlReader, ConnectorListenerDeps, ConnectorOperation, ConnectorOperationContext, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, ConnectorUpdateContext, DEFAULT_GATEWAY_PORT, DEFAULT_GATEWAY_TOKEN_PATH, DetachOptions, DiagnoseAllReport, DiagnosisStatus, DiagnosticConnectionError, DiagnosticEvent, DiagnosticsChannelSource, DiagnosticsGatewayProbe, DiagnosticsPublisher, DiagnosticsTokenReader, DiscordConnectorConfig, DocsTopicListing, DoctorFixMode, DoctorReport, Env, FUNNEL_DIR, FileStat, Funnel, FunnelAuthFailedError, FunnelBroadcaster, FunnelChannelAlreadyExistsError, FunnelChannelNotFoundError, FunnelChannelPublisher, FunnelChannels, FunnelClock, FunnelConnectorAdapter, FunnelConnectorListener, FunnelConnectorNotFoundError, FunnelConnectorRegistry, FunnelConnectorTypeMismatchError, FunnelDiagnostics, FunnelDocs, FunnelDoctor, FunnelError, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelFileSystem, FunnelGateway, FunnelGatewayBindError, FunnelGatewayServer, FunnelGatewayToken, FunnelHttpClient, FunnelIdGenerator, FunnelListenerRegistry, FunnelListenersClient, FunnelLogger, FunnelProcessRunner, FunnelRecovery, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, FunnelTokenCollisionError, FunnelTokenPrompter, type GatewayApp, type GatewayEmitInput, GatewayEventStore, type GatewayRouteDeps, type Env$1 as GatewayServerEnv, GatewayServerOptions, GhConnectorConfig, HttpRequest, HttpResponse, JsonValue, ListListenersResult, ListenerEntry, ListenerOpResult, LogEntry, MemoryConnectorDiagnosticLog, MemoryFunnelClock, MemoryFunnelEventLog, MemoryFunnelFileSystem, MemoryFunnelHttpClient, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryFunnelTokenPrompter, MemoryHttpHandler, MemoryHttpResponse, MemoryProcessCall, MemoryProcessHandler, MemoryProcessResponse, MemoryProcessSyncHandler, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelHttpClient, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NodeFunnelTokenPrompter, NoopFunnelLogger, NotifyFn, OnFunnelError, ProcessListStub, ProcessSnapshot, ProfileConfig, PublishRequest, PublishResponse, PublishResult, RecoveryAction, RecoveryChannelSource, RecoveryGatewayControl, RecoveryListenerControl, RecoveryResult, ReplayResult, ReplayableEvent, RunOptions, RunResult, SETTINGS_PATH, SETTINGS_VERSION, ScheduleCatchupPolicy, ScheduleConnectorConfig, ScheduleEntry, Settings, SlackConnectorConfig, SlackEvent, SlackMessageEvent, SlackProcessed, SlackProcessedEmit, SlackProcessedSkip, SlackRawEvent, SlackReactionEvent, SlackSkipReason, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, StartTimeStub, StoredConnectionEvent, StoredProcessedEvent, StoredRawEvent, baseConnectorConfigSchema, buildServiceRoutes, channelConfigSchema, channelDeliveryModeSchema, channelWsProtocols, channelWsUrl, routes as cliRoutes, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, createSettings, discordConnectorSchema, expandHomeDir, factory, funnelEventSchema, gatewayLoopbackUrl, ghConnectorSchema, previewOf, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryRows, queryToCliArgs, resolveFunnelDir, resolveFunnelPort, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, toDiagnosticConnectionError, toDiagnosticEvent, toRequest };
package/dist/index.js CHANGED
@@ -5,9 +5,9 @@ import { t as FunnelLogger } from "./logger-B6iyNbxM.js";
5
5
  import { n as FunnelProcessRunner, t as NodeFunnelProcessRunner } from "./node-process-runner-DxTvycoK.js";
6
6
  import { n as FunnelHttpClient, t as NodeFunnelHttpClient } from "./node-http-client-u00atiKx.js";
7
7
  import { n as FunnelIdGenerator, t as FunnelSettingsReader } from "./settings-reader-9FcX3qS1.js";
8
- import { a as resolveFunnelDir, c as channelConfigSchema, d as settingsSchema, f as baseConnectorConfigSchema, 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-C2QdOH-t.js";
8
+ import { a as expandHomeDir, c as SETTINGS_VERSION, d as profileConfigSchema, f as settingsSchema, i as SETTINGS_PATH, l as channelConfigSchema, m as NodeFunnelIdGenerator, n as FUNNEL_DIR, o as resolveFunnelDir, p as baseConnectorConfigSchema, r as FunnelSettingsStore, s as resolveFunnelPort, t as DEFAULT_GATEWAY_PORT, u as channelDeliveryModeSchema } from "./settings-store-ccv291GV.js";
9
9
  import { a as FunnelConnectorTypeMismatchError, c as FunnelTokenCollisionError, i as FunnelConnectorNotFoundError, n as FunnelChannelAlreadyExistsError, o as FunnelError, r as FunnelChannelNotFoundError, s as FunnelGatewayBindError, t as FunnelAuthFailedError } from "./funnel-error-0t1MK1R6.js";
10
- import { a as FunnelMcp, o as FunnelFileProcessGuard, s as FunnelClaude, t as renderYaml } from "./yaml-render--J1_3BSA.js";
10
+ import { a as FunnelMcp, o as FunnelFileProcessGuard, s as FunnelClaude, t as renderYaml } from "./yaml-render-DVEtYuF1.js";
11
11
  import { a as toDiagnosticEvent, i as toDiagnosticConnectionError, n as previewOf, r as queryRows, t as FunnelDiagnostics } from "./funnel-diagnostics-Cvk6Sk4x.js";
12
12
  import { t as ConnectorDiagnosticSqlReader } from "./diagnostic-sql-reader-oXZnWFf_.js";
13
13
  import { t as FunnelDoctor } from "./funnel-doctor-XrI2GBH8.js";
@@ -18,7 +18,7 @@ import { t as ghConnectorSchema } from "./gh-connector-schema-CAqIhzGr.js";
18
18
  import { t as slackConnectorSchema } from "./slack-connector-schema-Dem8to4P.js";
19
19
  import { t as FunnelProfiles } from "./profiles-ZHLONml4.js";
20
20
  import { t as FunnelRecovery } from "./funnel-recovery-DKnEutUS.js";
21
- import { C as funnelTmpDir, S as connectorRawEventSchema, _ as MemoryConnectorDiagnosticLog, a as DEFAULT_GATEWAY_TOKEN_PATH, b as connectorConnectionEventSchema, c as FunnelListenerRegistry, d as funnelEventSchema, f as FunnelBroadcaster, g as publishResponseSchema, h as publishRequestSchema, i as channelWsUrl, l as SqliteFunnelEventLog, m as FunnelChannelPublisher, n as MemoryFunnelEventLog, o as FunnelGatewayToken, p as requireBearerToken, r as channelWsProtocols, s as FunnelGatewayServer, t as SqliteConnectorDiagnosticLog, u as FunnelEventLog, v as CONNECTOR_CONNECTION_STATUSES, x as connectorProcessedEventSchema, y as ConnectorDiagnosticLog } from "./sqlite-diagnostic-log-DOTPW-tG.js";
21
+ import { C as funnelTmpDir, S as connectorRawEventSchema, _ as MemoryConnectorDiagnosticLog, a as DEFAULT_GATEWAY_TOKEN_PATH, b as connectorConnectionEventSchema, c as FunnelListenerRegistry, d as funnelEventSchema, f as FunnelBroadcaster, g as publishResponseSchema, h as publishRequestSchema, i as channelWsUrl, l as SqliteFunnelEventLog, m as FunnelChannelPublisher, n as MemoryFunnelEventLog, o as FunnelGatewayToken, p as requireBearerToken, r as channelWsProtocols, s as FunnelGatewayServer, t as SqliteConnectorDiagnosticLog, u as FunnelEventLog, v as CONNECTOR_CONNECTION_STATUSES, x as connectorProcessedEventSchema, y as ConnectorDiagnosticLog } from "./sqlite-diagnostic-log-CwhXE9Qh.js";
22
22
  import { t as FunnelConnectorAdapter } from "./connector-adapter-Dvs8N7ew.js";
23
23
  import { t as FunnelConnectorListener } from "./connector-listener-mPGZYa8e.js";
24
24
  import { t as FunnelSlackEventProcessor } from "./slack-event-processor-xFDG3US0.js";
@@ -3408,4 +3408,4 @@ const routes = factory.createApp().onError((error, c) => {
3408
3408
  return c.text(`error: ${error instanceof Error ? error.message : String(error)}`, 400);
3409
3409
  }).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("/debug/raw", ...debugRawHandler).get("/debug/connection", ...debugConnectionHandler).get("/debug/logs", ...debugLogsHandler).get("/docs", ...docsIndexHandler).get("/docs/:topic", ...docsTopicHandler).get("/doctor", ...doctorHandler).get("/schema", ...schemaHandler).get("/status", ...statusHandler).get("/update", ...updateHandler);
3410
3410
  //#endregion
3411
- export { CONNECTOR_CONNECTION_STATUSES, ConnectorDiagnosticLog, ConnectorDiagnosticSqlReader, DEFAULT_GATEWAY_PORT, DEFAULT_GATEWAY_TOKEN_PATH, FUNNEL_DIR, Funnel, FunnelAuthFailedError, FunnelBroadcaster, FunnelChannelAlreadyExistsError, FunnelChannelNotFoundError, FunnelChannelPublisher, FunnelChannels, FunnelClock, FunnelConnectorAdapter, FunnelConnectorListener, FunnelConnectorNotFoundError, FunnelConnectorRegistry, FunnelConnectorTypeMismatchError, FunnelDiagnostics, FunnelDocs, FunnelDoctor, FunnelError, FunnelEventLog, FunnelFileSystem, FunnelGateway, FunnelGatewayBindError, FunnelGatewayServer, FunnelGatewayToken, FunnelHttpClient, FunnelIdGenerator, FunnelListenerRegistry, FunnelListenersClient, FunnelLogger, FunnelProcessRunner, FunnelRecovery, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, FunnelTokenCollisionError, FunnelTokenPrompter, MemoryConnectorDiagnosticLog, MemoryFunnelClock, MemoryFunnelEventLog, MemoryFunnelFileSystem, MemoryFunnelHttpClient, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryFunnelTokenPrompter, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelHttpClient, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NodeFunnelTokenPrompter, NoopFunnelLogger, SETTINGS_PATH, SETTINGS_VERSION, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, baseConnectorConfigSchema, buildServiceRoutes, channelConfigSchema, channelDeliveryModeSchema, channelWsProtocols, channelWsUrl, routes as cliRoutes, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, createSettings, discordConnectorSchema, factory, funnelEventSchema, gatewayLoopbackUrl, ghConnectorSchema, previewOf, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryRows, queryToCliArgs, resolveFunnelDir, resolveFunnelPort, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, toDiagnosticConnectionError, toDiagnosticEvent, toRequest };
3411
+ export { CONNECTOR_CONNECTION_STATUSES, ConnectorDiagnosticLog, ConnectorDiagnosticSqlReader, DEFAULT_GATEWAY_PORT, DEFAULT_GATEWAY_TOKEN_PATH, FUNNEL_DIR, Funnel, FunnelAuthFailedError, FunnelBroadcaster, FunnelChannelAlreadyExistsError, FunnelChannelNotFoundError, FunnelChannelPublisher, FunnelChannels, FunnelClock, FunnelConnectorAdapter, FunnelConnectorListener, FunnelConnectorNotFoundError, FunnelConnectorRegistry, FunnelConnectorTypeMismatchError, FunnelDiagnostics, FunnelDocs, FunnelDoctor, FunnelError, FunnelEventLog, FunnelFileSystem, FunnelGateway, FunnelGatewayBindError, FunnelGatewayServer, FunnelGatewayToken, FunnelHttpClient, FunnelIdGenerator, FunnelListenerRegistry, FunnelListenersClient, FunnelLogger, FunnelProcessRunner, FunnelRecovery, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, FunnelTokenCollisionError, FunnelTokenPrompter, MemoryConnectorDiagnosticLog, MemoryFunnelClock, MemoryFunnelEventLog, MemoryFunnelFileSystem, MemoryFunnelHttpClient, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryFunnelTokenPrompter, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelHttpClient, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NodeFunnelTokenPrompter, NoopFunnelLogger, SETTINGS_PATH, SETTINGS_VERSION, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, baseConnectorConfigSchema, buildServiceRoutes, channelConfigSchema, channelDeliveryModeSchema, channelWsProtocols, channelWsUrl, routes as cliRoutes, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, createSettings, discordConnectorSchema, expandHomeDir, factory, funnelEventSchema, gatewayLoopbackUrl, ghConnectorSchema, previewOf, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryRows, queryToCliArgs, resolveFunnelDir, resolveFunnelPort, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, toDiagnosticConnectionError, toDiagnosticEvent, toRequest };
@@ -96,12 +96,39 @@ const settingsSchema = z.object({
96
96
  * gateway pid/token, claude pids) at a repo-local `<repo>/.funnel` and never
97
97
  * touch the global home. Read at call time, not module load, so a daemon
98
98
  * spawned with the env set resolves the override.
99
+ *
100
+ * The override goes through `expandHomeDir` so a consumer .mcp.json can write
101
+ * `FUNNEL_DIR: "~/.nocker/funnel"` or `"${HOME}/.nocker/funnel"` and have it
102
+ * land on the right path on macOS, Linux, and Windows — Claude Code's `${VAR}`
103
+ * expansion only resolves whichever env happens to be set on the host shell
104
+ * (`$HOME` is unset on vanilla Windows cmd/PowerShell, `$USERPROFILE` is unset
105
+ * on macOS/Linux), so funnel takes the second swing here.
99
106
  */
100
107
  function resolveFunnelDir() {
101
108
  const override = process.env.FUNNEL_DIR;
102
- if (override && override.length > 0) return override;
109
+ if (override && override.length > 0) return expandHomeDir(override);
103
110
  return join(homedir(), ".funnel");
104
111
  }
112
+ /**
113
+ * Resolves the three forms a consumer might write for the user home dir:
114
+ * a leading `~` / `~/`, the literal `${HOME}` token, and the literal
115
+ * `${USERPROFILE}` token. The expansion is intentionally narrow — only the
116
+ * home-dir tokens are substituted, no general shell-variable expansion — so
117
+ * an accidentally embedded `${USERPROFILE}` in a path on macOS does not
118
+ * silently turn into a different (Windows-style) path elsewhere. Normalizes
119
+ * Windows backslashes to forward slashes after expansion because Node's
120
+ * `path` operations accept either on Windows but the cross-platform pieces
121
+ * (URL building, glob matching) prefer forward slashes.
122
+ */
123
+ function expandHomeDir(input) {
124
+ const home = homedir();
125
+ let result = input;
126
+ if (result === "~") return home;
127
+ if (result.startsWith("~/") || result.startsWith("~\\")) result = home + result.slice(1);
128
+ result = result.split("${HOME}").join(home);
129
+ result = result.split("${USERPROFILE}").join(home);
130
+ return result.replace(/\\/g, "/");
131
+ }
105
132
  const DEFAULT_GATEWAY_PORT = 9742;
106
133
  /**
107
134
  * Resolves the gateway port. Defaults to 9742 — the port a programmatically
@@ -213,4 +240,4 @@ var FunnelSettingsStore = class extends FunnelSettingsReader {
213
240
  }
214
241
  };
215
242
  //#endregion
216
- export { resolveFunnelDir as a, channelConfigSchema as c, settingsSchema as d, baseConnectorConfigSchema 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 };
243
+ export { expandHomeDir as a, SETTINGS_VERSION as c, profileConfigSchema as d, settingsSchema as f, SETTINGS_PATH as i, channelConfigSchema as l, NodeFunnelIdGenerator as m, FUNNEL_DIR as n, resolveFunnelDir as o, baseConnectorConfigSchema as p, FunnelSettingsStore as r, resolveFunnelPort as s, DEFAULT_GATEWAY_PORT as t, channelDeliveryModeSchema as u };
@@ -1,7 +1,7 @@
1
1
  import { n as gatewayLoopbackUrl, t as loopbackFetch } from "./loopback-fetch-CVNuN3YZ.js";
2
2
  import { t as NodeFunnelFileSystem } from "./node-file-system-BOXIHW_Q.js";
3
3
  import { t as NodeFunnelProcessRunner } from "./node-process-runner-DxTvycoK.js";
4
- import { n as FUNNEL_DIR, o as resolveFunnelPort } from "./settings-store-C2QdOH-t.js";
4
+ import { n as FUNNEL_DIR, s as resolveFunnelPort } from "./settings-store-ccv291GV.js";
5
5
  import { t as FunnelAuthFailedError } from "./funnel-error-0t1MK1R6.js";
6
6
  import { t as ConnectorDiagnosticSqlReader } from "./diagnostic-sql-reader-oXZnWFf_.js";
7
7
  import { t as FunnelLogSqliteSink } from "./funnel-log-sqlite-sink-DLYkY0pZ.js";
@@ -1,6 +1,6 @@
1
1
  import { t as NodeFunnelFileSystem } from "./node-file-system-BOXIHW_Q.js";
2
2
  import { t as NodeFunnelProcessRunner } from "./node-process-runner-DxTvycoK.js";
3
- import { n as FUNNEL_DIR, o as resolveFunnelPort, p as NodeFunnelIdGenerator } from "./settings-store-C2QdOH-t.js";
3
+ import { m as NodeFunnelIdGenerator, n as FUNNEL_DIR, s as resolveFunnelPort } from "./settings-store-ccv291GV.js";
4
4
  import { join } from "node:path";
5
5
  import { stringify } from "yaml";
6
6
  //#region lib/engine/claude/claude.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interactive-inc/claude-funnel",
3
- "version": "0.64.0",
3
+ "version": "0.65.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",