@interactive-inc/claude-funnel 0.20.1 → 0.22.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/index.js CHANGED
@@ -1,12 +1,12 @@
1
- import { i as FunnelDiscordAdapter, n as FunnelDiscordListener, t as discordConnectorSchema } from "./discord-connector-schema-ygf5Df-2.js";
2
- import { n as FunnelLogger, r as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-DQz_BGOD.js";
3
- import { a as FunnelProcessRunner, i as NodeFunnelProcessRunner, n as FunnelGhListener, r as FunnelGhAdapter, t as ghConnectorSchema } from "./gh-connector-schema-CD5HIkrd.js";
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-FxP7LPlx.js";
5
- import { i as FunnelSlackAdapter, n as FunnelSlackListener, r as FunnelSlackEventProcessor, t as slackConnectorSchema } from "./slack-connector-schema-BM9xshol.js";
1
+ import { i as FunnelDiscordAdapter, n as FunnelDiscordListener, t as discordConnectorSchema } from "./discord-connector-schema-CR8RJ08_.js";
2
+ import { i as FunnelConnectorListener, n as funnelTmpDir, r as FunnelLogger, t as NodeFunnelLogger } from "./node-logger-B97ZiGwj.js";
3
+ import { a as FunnelProcessRunner, i as NodeFunnelProcessRunner, n as FunnelGhListener, r as FunnelGhAdapter, t as ghConnectorSchema } from "./gh-connector-schema-CAC24s0r.js";
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-BZpH6ZmR.js";
5
+ import { i as FunnelSlackAdapter, n as FunnelSlackListener, r as FunnelSlackEventProcessor, t as slackConnectorSchema } from "./slack-connector-schema-B3jr-RTH.js";
6
6
  import { dirname, join, resolve } from "node:path";
7
7
  import { existsSync, mkdirSync, readFileSync } from "node:fs";
8
- import { z } from "zod";
9
8
  import { homedir } from "node:os";
9
+ import { z } from "zod";
10
10
  import { stderr, stdin } from "node:process";
11
11
  import { fileURLToPath } from "node:url";
12
12
  import { timingSafeEqual } from "node:crypto";
@@ -647,17 +647,7 @@ var FunnelClaude = class {
647
647
  globalThis.process.once("exit", () => this.removePidFile(profileName));
648
648
  }
649
649
  isProcessAlive(pid) {
650
- const result = this.process.runSync([
651
- "ps",
652
- "-p",
653
- String(pid),
654
- "-o",
655
- "state="
656
- ]);
657
- if (result.exitCode !== 0) return false;
658
- const state = result.stdout.trim();
659
- if (!state) return false;
660
- return !state.startsWith("Z");
650
+ return this.process.isAlive(pid);
661
651
  }
662
652
  buildArgs(channelOptions, userArgs, cwd, sessionId) {
663
653
  const result = [...channelOptions, ...userArgs];
@@ -1332,6 +1322,8 @@ var MemoryFunnelProcessRunner = class extends FunnelProcessRunner {
1332
1322
  killed = [];
1333
1323
  handler = () => empty;
1334
1324
  syncHandler = () => empty;
1325
+ aliveStub = null;
1326
+ listStub = null;
1335
1327
  on(handler) {
1336
1328
  this.handler = handler;
1337
1329
  return this;
@@ -1340,6 +1332,14 @@ var MemoryFunnelProcessRunner = class extends FunnelProcessRunner {
1340
1332
  this.syncHandler = handler;
1341
1333
  return this;
1342
1334
  }
1335
+ onIsAlive(stub) {
1336
+ this.aliveStub = stub;
1337
+ return this;
1338
+ }
1339
+ onListProcessesContaining(stub) {
1340
+ this.listStub = stub;
1341
+ return this;
1342
+ }
1343
1343
  async run(command, options = {}) {
1344
1344
  this.calls.push({
1345
1345
  kind: "run",
@@ -1391,6 +1391,24 @@ var MemoryFunnelProcessRunner = class extends FunnelProcessRunner {
1391
1391
  signal
1392
1392
  });
1393
1393
  }
1394
+ isAlive(pid) {
1395
+ if (this.aliveStub) return this.aliveStub(pid);
1396
+ const result = this.syncHandler([
1397
+ "ps",
1398
+ "-p",
1399
+ String(pid),
1400
+ "-o",
1401
+ "state="
1402
+ ]);
1403
+ if ((result.exitCode ?? 0) !== 0) return false;
1404
+ const state = (result.stdout ?? "").trim();
1405
+ if (!state) return false;
1406
+ return !state.startsWith("Z");
1407
+ }
1408
+ listProcessesContaining(marker) {
1409
+ if (this.listStub) return this.listStub(marker);
1410
+ return [];
1411
+ }
1394
1412
  };
1395
1413
  //#endregion
1396
1414
  //#region lib/engine/profiles/profiles.ts
@@ -1749,7 +1767,6 @@ const resolveDaemonScript = () => {
1749
1767
  //#endregion
1750
1768
  //#region lib/gateway/gateway.ts
1751
1769
  const DEFAULT_PORT$1 = 9742;
1752
- const DEFAULT_TMP_DIR$1 = "/tmp/funnel";
1753
1770
  const STARTUP_TIMEOUT_MS = 5e3;
1754
1771
  const SIGTERM_TIMEOUT_MS = 2e3;
1755
1772
  const POLL_INTERVAL_MS$1 = 100;
@@ -1771,7 +1788,6 @@ var FunnelGateway = class {
1771
1788
  clock;
1772
1789
  dir;
1773
1790
  pidFile;
1774
- logDir;
1775
1791
  gatewayLog;
1776
1792
  tmpDir;
1777
1793
  port;
@@ -1781,9 +1797,8 @@ var FunnelGateway = class {
1781
1797
  this.fs = deps.fs ?? defaultFs$1;
1782
1798
  this.clock = deps.clock ?? defaultClock;
1783
1799
  this.dir = deps.dir ?? FUNNEL_DIR;
1784
- this.tmpDir = deps.tmpDir ?? DEFAULT_TMP_DIR$1;
1800
+ this.tmpDir = deps.tmpDir ?? funnelTmpDir();
1785
1801
  this.pidFile = join(this.dir, "gateway.pid");
1786
- this.logDir = join(this.tmpDir, "events");
1787
1802
  this.gatewayLog = join(this.tmpDir, "gateway.log");
1788
1803
  this.port = deps.port ?? DEFAULT_PORT$1;
1789
1804
  this.sleep = deps.sleep ?? defaultSleep$1;
@@ -1808,11 +1823,10 @@ var FunnelGateway = class {
1808
1823
  this.fs.mkdirSync(this.tmpDir, { recursive: true });
1809
1824
  const gatewayScript = resolveDaemonScript();
1810
1825
  const command = this.buildStartCommand(gatewayScript, options);
1811
- this.process.detach([
1812
- "bash",
1813
- "-c",
1814
- command
1815
- ]);
1826
+ this.process.detach(command, {
1827
+ stdoutFile: this.gatewayLog,
1828
+ stderrFile: this.gatewayLog
1829
+ });
1816
1830
  const deadline = this.clock.millis() + STARTUP_TIMEOUT_MS;
1817
1831
  while (this.clock.millis() < deadline) {
1818
1832
  if (this.isRunning()) return true;
@@ -1821,7 +1835,19 @@ var FunnelGateway = class {
1821
1835
  return this.isRunning();
1822
1836
  }
1823
1837
  buildStartCommand(gatewayScript, options = {}) {
1824
- return `nohup ${options.caffeinate !== false && globalThis.process.platform === "darwin" ? "caffeinate -i " : ""}bun ${gatewayScript} ${`funnel-gateway[${this.dir}]`} >> ${this.gatewayLog} 2>&1 &`;
1838
+ const tag = `funnel-gateway[${this.dir}]`;
1839
+ if (options.caffeinate !== false && globalThis.process.platform === "darwin") return [
1840
+ "caffeinate",
1841
+ "-is",
1842
+ "bun",
1843
+ gatewayScript,
1844
+ tag
1845
+ ];
1846
+ return [
1847
+ "bun",
1848
+ gatewayScript,
1849
+ tag
1850
+ ];
1825
1851
  }
1826
1852
  async stop() {
1827
1853
  const pid = this.readPid();
@@ -1873,9 +1899,6 @@ var FunnelGateway = class {
1873
1899
  started
1874
1900
  };
1875
1901
  }
1876
- getLogDir() {
1877
- return this.logDir;
1878
- }
1879
1902
  getGatewayLog() {
1880
1903
  return this.gatewayLog;
1881
1904
  }
@@ -1897,17 +1920,7 @@ var FunnelGateway = class {
1897
1920
  this.fs.unlink(this.pidFile);
1898
1921
  }
1899
1922
  isProcessAlive(pid) {
1900
- const result = this.process.runSync([
1901
- "ps",
1902
- "-p",
1903
- String(pid),
1904
- "-o",
1905
- "state="
1906
- ]);
1907
- if (result.exitCode !== 0) return false;
1908
- const state = result.stdout.trim();
1909
- if (!state) return false;
1910
- return !state.startsWith("Z");
1923
+ return this.process.isAlive(pid);
1911
1924
  }
1912
1925
  };
1913
1926
  //#endregion
@@ -2728,36 +2741,24 @@ const titleFor = (dir) => `funnel-gateway[${dir}]`;
2728
2741
  * which is the only situation that causes a real conflict (duplicate Slack
2729
2742
  * Socket Mode connections with the same tokens). Daemons rooted at a
2730
2743
  * different `~/.funnel/` are left alone — they hold different tokens and
2731
- * speak to different Slack apps. The daemon advertises its dir via
2732
- * `process.title = "funnel-gateway[<dir>]"`, which this routine matches.
2744
+ * speak to different Slack apps. The daemon advertises its dir via the
2745
+ * `funnel-gateway[<dir>]` marker appended to argv (also assigned to
2746
+ * `process.title` on POSIX). `FunnelProcessRunner.listProcessesContaining`
2747
+ * absorbs the POSIX/Windows enumeration difference behind the marker match.
2733
2748
  */
2734
2749
  const killCompetingSlackGateways = async (props) => {
2735
2750
  const runner = props.process ?? defaultProcess;
2736
2751
  const logger = props.logger ?? defaultLogger$1;
2737
- const result = await runner.run([
2738
- "ps",
2739
- "-e",
2740
- "-o",
2741
- "pid=,args="
2742
- ]);
2743
- if (result.exitCode !== 0) return [];
2744
2752
  const expectedTitle = titleFor(props.dir);
2753
+ const snapshots = runner.listProcessesContaining(expectedTitle);
2745
2754
  const killed = [];
2746
- for (const raw of result.stdout.split("\n")) {
2747
- const line = raw.trim();
2748
- if (!line) continue;
2749
- const match = /^(\d+)\s+(.+)$/.exec(line);
2750
- if (!match) continue;
2751
- const pid = Number(match[1]);
2752
- const args = match[2];
2753
- if (!Number.isInteger(pid) || pid <= 0) continue;
2754
- if (pid === props.selfPid) continue;
2755
- if (!args.includes(expectedTitle)) continue;
2756
- runner.kill(pid, "SIGTERM");
2757
- killed.push(pid);
2755
+ for (const snapshot of snapshots) {
2756
+ if (snapshot.pid === props.selfPid) continue;
2757
+ runner.kill(snapshot.pid, "SIGTERM");
2758
+ killed.push(snapshot.pid);
2758
2759
  logger.info("killed competing Slack gateway process", {
2759
- pid,
2760
- args: args.slice(0, 160)
2760
+ pid: snapshot.pid,
2761
+ args: snapshot.command.slice(0, 160)
2761
2762
  });
2762
2763
  }
2763
2764
  return killed;
@@ -2923,8 +2924,7 @@ const gatewayRoutes = factory$1.createApp().get("/health", ...healthHandler).get
2923
2924
  //#endregion
2924
2925
  //#region lib/gateway/gateway-server.ts
2925
2926
  const DEFAULT_PORT = 9742;
2926
- const DEFAULT_LOG_DIR = "/tmp/funnel/events";
2927
- const DB_FILENAME = "events.db";
2927
+ const defaultDbPath = () => join(funnelTmpDir(), "events.db");
2928
2928
  const defaultLogger = new NodeFunnelLogger();
2929
2929
  /**
2930
2930
  * In-process gateway: runs `Bun.serve` (HTTP + WebSocket /ws), boots connector
@@ -2940,7 +2940,7 @@ var FunnelGatewayServer = class {
2940
2940
  channels;
2941
2941
  settings;
2942
2942
  port;
2943
- logDir;
2943
+ dbPath;
2944
2944
  process;
2945
2945
  logger;
2946
2946
  selfPid;
@@ -2958,7 +2958,7 @@ var FunnelGatewayServer = class {
2958
2958
  this.channels = deps.channels;
2959
2959
  this.settings = deps.settings;
2960
2960
  this.port = deps.port ?? DEFAULT_PORT;
2961
- this.logDir = deps.logDir ?? DEFAULT_LOG_DIR;
2961
+ this.dbPath = deps.dbPath ?? defaultDbPath();
2962
2962
  this.process = deps.process;
2963
2963
  this.logger = deps.logger ?? defaultLogger;
2964
2964
  this.selfPid = deps.selfPid ?? globalThis.process.pid;
@@ -2968,9 +2968,10 @@ var FunnelGatewayServer = class {
2968
2968
  this.extraRoutes = deps.extraRoutes ?? null;
2969
2969
  const clock = deps.clock;
2970
2970
  this.nowMs = clock ? () => clock.millis() : () => Date.now();
2971
- if (!existsSync(this.logDir)) mkdirSync(this.logDir, { recursive: true });
2971
+ const dbDir = dirname(this.dbPath);
2972
+ if (!existsSync(dbDir)) mkdirSync(dbDir, { recursive: true });
2972
2973
  this.eventStore = new FunnelEventStore({
2973
- path: join(this.logDir, DB_FILENAME),
2974
+ path: this.dbPath,
2974
2975
  now: this.nowMs
2975
2976
  });
2976
2977
  this.broadcaster = new FunnelBroadcaster({
@@ -3174,7 +3175,7 @@ var FunnelGatewayServer = class {
3174
3175
  channel: entry.channelName,
3175
3176
  connector: entry.name
3176
3177
  });
3177
- this.logger.info(`event store: ${join(this.logDir, DB_FILENAME)}`);
3178
+ this.logger.info(`event store: ${this.dbPath}`);
3178
3179
  this.logger.info("funnel gateway running");
3179
3180
  }
3180
3181
  /**
@@ -3361,7 +3362,6 @@ var FunnelListenersClient = class {
3361
3362
  };
3362
3363
  //#endregion
3363
3364
  //#region lib/funnel.ts
3364
- const DEFAULT_TMP_DIR = "/tmp/funnel";
3365
3365
  const SANDBOX_DIR = "/sandbox/.funnel";
3366
3366
  const SANDBOX_TMP_DIR = "/sandbox/tmp";
3367
3367
  /**
@@ -3411,7 +3411,7 @@ var Funnel = class Funnel {
3411
3411
  const dir = this.props.dir ?? FUNNEL_DIR;
3412
3412
  return {
3413
3413
  dir,
3414
- tmpDir: this.props.tmpDir ?? DEFAULT_TMP_DIR,
3414
+ tmpDir: this.props.tmpDir ?? funnelTmpDir(),
3415
3415
  settings: join(dir, "settings.json")
3416
3416
  };
3417
3417
  }
@@ -3591,7 +3591,7 @@ var Funnel = class Funnel {
3591
3591
  channels: this.channels,
3592
3592
  settings: this.store,
3593
3593
  port: options.port,
3594
- logDir: options.logDir,
3594
+ dbPath: options.dbPath,
3595
3595
  process: this.process,
3596
3596
  clock: this.clock,
3597
3597
  logger: this.logger,
@@ -4445,13 +4445,13 @@ usage: funnel gateway logs [-n <N>]
4445
4445
  options:
4446
4446
  -n <N> number of trailing lines to show (default: 20)
4447
4447
 
4448
- Tails /tmp/funnel/funnel.log (the daemon's diagnostic stream — gateway
4448
+ Tails ${join(funnelTmpDir(), "funnel.log")} (the daemon's diagnostic stream — gateway
4449
4449
  lifecycle, channel connect/disconnect, listener boot). Exit with SIGINT.
4450
4450
  Output is formatted as YAML.
4451
4451
 
4452
4452
  Domain events fanned out to WebSocket clients live in the SQLite event
4453
- store (<logDir>/events.db); they are not shown here. Subscribe via the
4454
- WS endpoint or query the store directly.
4453
+ store (${join(funnelTmpDir(), "events.db")}); they are not shown here. Subscribe via
4454
+ the WS endpoint or query the store directly.
4455
4455
 
4456
4456
  examples:
4457
4457
  funnel gateway logs
@@ -4525,7 +4525,7 @@ const gatewayRestartHandler = factory.createHandlers(zValidator$1("query", z.obj
4525
4525
  usage: funnel gateway restart [--no-caffeine]
4526
4526
 
4527
4527
  Stops the running process then starts it again in background.
4528
- On macOS wraps with caffeinate -i by default. Use --no-caffeine to disable.
4528
+ On macOS wraps with caffeinate -is by default. Use --no-caffeine to disable.
4529
4529
 
4530
4530
  examples:
4531
4531
  funnel gateway restart
@@ -4544,7 +4544,7 @@ const gatewayRunHandler = factory.createHandlers(zValidator$1("query", z.object(
4544
4544
  usage: funnel gateway run [--no-caffeine]
4545
4545
 
4546
4546
  For developers. The process is tied to the current terminal and exits on SIGINT / SIGTERM.
4547
- On macOS wraps with caffeinate -i by default. Use --no-caffeine to disable.
4547
+ On macOS wraps with caffeinate -is by default. Use --no-caffeine to disable.
4548
4548
 
4549
4549
  For normal usage prefer funnel gateway start.
4550
4550
 
@@ -4556,28 +4556,31 @@ examples:
4556
4556
  const gatewayScript = resolveDaemonScript();
4557
4557
  const command = query["no-caffeine"] !== "true" && process.platform === "darwin" ? [
4558
4558
  "caffeinate",
4559
- "-i",
4559
+ "-is",
4560
4560
  "bun",
4561
4561
  gatewayScript
4562
4562
  ] : ["bun", gatewayScript];
4563
4563
  const exitCode = await funnel.process.attach(command);
4564
4564
  process.exit(exitCode);
4565
4565
  });
4566
- const gatewayStartHandler = factory.createHandlers(zValidator$1("query", z.object({ "no-caffeine": z.string().optional() }), `funnel gateway start — start the gateway in background
4566
+ //#endregion
4567
+ //#region lib/cli/routes/gateway.start.ts
4568
+ const startHelp = `funnel gateway start — start the gateway in background
4567
4569
 
4568
4570
  usage: funnel gateway start [--no-caffeine]
4569
4571
 
4570
- Daemonized with nohup, so it keeps running after the terminal is closed.
4571
- On macOS wraps the process with caffeinate -i by default to prevent idle sleep.
4572
+ Spawned as a detached background process so it keeps running after the terminal is closed.
4573
+ On macOS wraps the process with caffeinate -is by default to prevent idle and system sleep.
4572
4574
  Use --no-caffeine to disable caffeinate.
4573
4575
 
4574
4576
  port: 9742 (override via FUNNEL_PORT)
4575
4577
  pid: ~/.funnel/gateway.pid
4576
- log: /tmp/funnel/gateway.log
4578
+ log: ${join(funnelTmpDir(), "gateway.log")}
4577
4579
 
4578
4580
  examples:
4579
4581
  funnel gateway start
4580
- funnel gateway start --no-caffeine`), async (c) => {
4582
+ funnel gateway start --no-caffeine`;
4583
+ const gatewayStartHandler = factory.createHandlers(zValidator$1("query", z.object({ "no-caffeine": z.string().optional() }), startHelp), async (c) => {
4581
4584
  const query = c.req.valid("query");
4582
4585
  const funnel = c.var.funnel;
4583
4586
  if (funnel.gateway.isRunning()) {
@@ -20,7 +20,7 @@ declare abstract class FunnelConnectorListener {
20
20
  //#region lib/engine/logger/logger.d.ts
21
21
  /**
22
22
  * Structured logger with three levels and an optional log-file path.
23
- * Defaults to NodeFunnelLogger (appends to /tmp/funnel/funnel.log);
23
+ * Defaults to NodeFunnelLogger (appends to `<os.tmpdir()>/funnel/funnel.log`);
24
24
  * MemoryFunnelLogger captures entries in memory and NoopFunnelLogger silences output.
25
25
  */
26
26
  declare abstract class FunnelLogger {
@@ -1,5 +1,6 @@
1
1
  import { dirname, join } from "node:path";
2
2
  import { appendFileSync, mkdirSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
3
4
  //#region lib/connectors/connector-listener.ts
4
5
  /**
5
6
  * Long-lived event source for one connector.
@@ -21,19 +22,31 @@ var FunnelConnectorListener = class {
21
22
  //#region lib/engine/logger/logger.ts
22
23
  /**
23
24
  * Structured logger with three levels and an optional log-file path.
24
- * Defaults to NodeFunnelLogger (appends to /tmp/funnel/funnel.log);
25
+ * Defaults to NodeFunnelLogger (appends to `<os.tmpdir()>/funnel/funnel.log`);
25
26
  * MemoryFunnelLogger captures entries in memory and NoopFunnelLogger silences output.
26
27
  */
27
28
  var FunnelLogger = class {};
28
29
  //#endregion
30
+ //#region lib/engine/settings/tmp-dir.ts
31
+ /**
32
+ * Resolves the funnel temp/log root for the current OS. Defaults to
33
+ * `<os.tmpdir()>/funnel` so Windows lands under `%TEMP%\funnel` and POSIX
34
+ * lands under `/tmp/funnel`. Callers may override via `FUNNEL_TMP_DIR`.
35
+ */
36
+ function funnelTmpDir() {
37
+ const override = process.env.FUNNEL_TMP_DIR;
38
+ if (override && override.length > 0) return override;
39
+ return join(tmpdir(), "funnel");
40
+ }
41
+ //#endregion
29
42
  //#region lib/engine/logger/node-logger.ts
30
- const DEFAULT_LOG_FILE = join("/tmp/funnel", "funnel.log");
43
+ const defaultLogFile = () => join(funnelTmpDir(), "funnel.log");
31
44
  var NodeFunnelLogger = class extends FunnelLogger {
32
45
  file;
33
46
  now;
34
47
  constructor(props = {}) {
35
48
  super();
36
- this.file = props.file ?? DEFAULT_LOG_FILE;
49
+ this.file = props.file ?? defaultLogFile();
37
50
  this.now = props.now ?? (() => /* @__PURE__ */ new Date());
38
51
  Object.freeze(this);
39
52
  }
@@ -58,4 +71,4 @@ var NodeFunnelLogger = class extends FunnelLogger {
58
71
  }
59
72
  };
60
73
  //#endregion
61
- export { FunnelLogger as n, FunnelConnectorListener as r, NodeFunnelLogger as t };
74
+ export { FunnelConnectorListener as i, funnelTmpDir as n, FunnelLogger as r, NodeFunnelLogger as t };
@@ -1,4 +1,4 @@
1
- import { r as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-DQz_BGOD.js";
1
+ import { i as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-B97ZiGwj.js";
2
2
  import { dirname } from "node:path";
3
3
  import { appendFileSync, chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { z } from "zod";
@@ -1,4 +1,4 @@
1
- import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "./logger-CTlXs7z4.js";
1
+ import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "./logger-B3aXsVcX.js";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region lib/connectors/schedule-connector-schema.d.ts
@@ -1,5 +1,5 @@
1
1
  import { t as FunnelConnectorAdapter } from "./connector-adapter-D5Utumgz.js";
2
- import { r as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-DQz_BGOD.js";
2
+ import { i as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-B97ZiGwj.js";
3
3
  import { z } from "zod";
4
4
  import { WebClient } from "@slack/web-api";
5
5
  import { App, LogLevel } from "@slack/bolt";
@@ -1,4 +1,4 @@
1
- import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "./logger-CTlXs7z4.js";
1
+ import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "./logger-B3aXsVcX.js";
2
2
  import { z } from "zod";
3
3
  import { App } from "@slack/bolt";
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interactive-inc/claude-funnel",
3
- "version": "0.20.1",
3
+ "version": "0.22.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",