@interactive-inc/claude-funnel 0.15.2 → 0.17.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
@@ -50,15 +50,16 @@ const channelConfigSchema = z.object({
50
50
  id: z.string(),
51
51
  name: z.string(),
52
52
  delivery: channelDeliveryModeSchema.default("fanout"),
53
+ /** Args prepended to the claude argv on every launch bound to this channel. */
54
+ options: z.array(z.string()).default([]),
55
+ /** Env vars layered under the launched claude process. process.env wins on collision. */
56
+ env: z.record(z.string(), z.string()).default({}),
53
57
  connectors: z.array(connectorConfigSchema).default([])
54
58
  });
55
59
  const profileConfigSchema = z.object({
56
60
  name: z.string(),
57
61
  path: z.string(),
58
- subAgent: z.string(),
59
- channelId: z.string(),
60
- /** Forwards `--brief` to claude on launch (enables the SendUserMessage tool). */
61
- brief: z.boolean().optional()
62
+ channelId: z.string()
62
63
  });
63
64
  const SETTINGS_VERSION = 1;
64
65
  const settingsSchema = z.object({
@@ -305,6 +306,8 @@ var FunnelChannels = class {
305
306
  id: this.idGenerator.generate(),
306
307
  name: input.name,
307
308
  delivery: input.delivery ?? "fanout",
309
+ options: input.options ?? [],
310
+ env: input.env ?? {},
308
311
  connectors: []
309
312
  };
310
313
  settings.channels.push(channel);
@@ -317,6 +320,18 @@ var FunnelChannels = class {
317
320
  channel.delivery = delivery;
318
321
  this.store.write(settings);
319
322
  }
323
+ setOptions(name, options) {
324
+ const settings = this.store.read();
325
+ const channel = this.requireChannel(settings, name);
326
+ channel.options = options;
327
+ this.store.write(settings);
328
+ }
329
+ setEnv(name, env) {
330
+ const settings = this.store.read();
331
+ const channel = this.requireChannel(settings, name);
332
+ channel.env = env;
333
+ this.store.write(settings);
334
+ }
320
335
  remove(name) {
321
336
  const settings = this.store.read();
322
337
  const index = settings.channels.findIndex((c) => c.name === name);
@@ -567,12 +582,11 @@ var FunnelClaude = class {
567
582
  this.writePidFile(options.profileName);
568
583
  this.installCleanup(options.profileName);
569
584
  }
570
- const claudeArgs = this.buildArgs(options, cwd);
571
- const env = this.buildEnv(channel.id, options.extraEnv);
585
+ const claudeArgs = this.buildArgs(channel.options, options.userArgs ?? [], cwd);
586
+ const env = this.buildEnv(channel.id, channel.env);
572
587
  this.logger.info(`claude launch`, {
573
588
  channel: options.channel,
574
589
  channelId: channel.id,
575
- subAgent: options.subAgent,
576
590
  cwd
577
591
  });
578
592
  try {
@@ -628,17 +642,15 @@ var FunnelClaude = class {
628
642
  if (!state) return false;
629
643
  return !state.startsWith("Z");
630
644
  }
631
- buildArgs(options, cwd) {
632
- const result = [...options.userArgs ?? []];
645
+ buildArgs(channelOptions, userArgs, cwd) {
646
+ const result = [...channelOptions, ...userArgs];
633
647
  const mcpName = this.mcp.findInstalledName(cwd);
634
648
  if (mcpName && !result.includes("--dangerously-load-development-channels") && !result.includes("--channels")) result.push("--dangerously-load-development-channels", `server:${mcpName}`);
635
- if (!result.includes("--agent") && options.subAgent) result.push("--agent", options.subAgent);
636
- if (options.brief && !result.includes("--brief")) result.push("--brief");
637
649
  return result;
638
650
  }
639
- buildEnv(channelId, extraEnv) {
651
+ buildEnv(channelId, channelEnv) {
640
652
  const env = {};
641
- if (extraEnv) for (const [key, value] of Object.entries(extraEnv)) env[key] = value;
653
+ for (const [key, value] of Object.entries(channelEnv)) env[key] = value;
642
654
  for (const [key, value] of Object.entries(globalThis.process.env)) if (typeof value === "string") env[key] = value;
643
655
  env.FUNNEL_CHANNEL_ID = channelId;
644
656
  return env;
@@ -737,20 +749,16 @@ var MemoryFunnelIdGenerator = class extends FunnelIdGenerator {
737
749
  /**
738
750
  * Per-repo launch config (`funnel.json`).
739
751
  *
740
- * `fnl claude` reads this when no --profile / --channel is given and uses it
741
- * to set the channel binding, sub-agent, and brief flag. When `connectors`
742
- * is declared, missing channels/connectors are materialized into the local
743
- * `~/.funnel/settings.json` on launch.
752
+ * `fnl claude` reads this when no --profile is given and picks one of the
753
+ * declared channels (`--channel <name>` selects by name; otherwise the first
754
+ * entry wins). The chosen channel is materialized into
755
+ * `~/.funnel/settings.json` on launch — token fields in connectors resolve
756
+ * via literal / `env.<field>` / TTY prompt.
744
757
  *
745
- * Token fields per connector resolve in this order:
746
- *
747
- * 1. Literal value at the field itself (e.g. `botToken: "xoxb-..."`)
748
- * 2. Env-var reference at `env.<field>` (e.g. `env: { botToken: "SLACK_BOT_TOKEN" }`);
749
- * resolved from process.env first, then ./.env.local
750
- * 3. Field omitted everywhere → prompted for once on a TTY and persisted to
751
- * `~/.funnel/settings.json`; non-TTY launches fail fast.
752
- *
753
- * `funnel.json` itself is never written to. Only `channel` is required.
758
+ * Top-level `options` and `env` are defaults shared by every channel: each
759
+ * channel's own `options` is appended after the shared ones (CLI semantics
760
+ * keep the later flag winning), and `env` is a shallow merge with the
761
+ * channel's keys overriding the shared ones.
754
762
  */
755
763
  const slackEnvSchema = z.object({
756
764
  botToken: z.string().optional(),
@@ -785,14 +793,19 @@ const connectorSpecSchema = z.discriminatedUnion("type", [
785
793
  ghConnectorSpecSchema,
786
794
  scheduleConnectorSpecSchema
787
795
  ]);
788
- const localConfigSchema = z.object({
789
- $schema: z.string().optional(),
790
- channel: z.string(),
791
- /** Extra args forwarded to the claude CLI. Prepended before user-supplied CLI args so user args still win on collision (e.g. --model, --agent, --brief, --resume, positional session ids). */
796
+ const channelSpecSchema = z.object({
797
+ name: z.string(),
798
+ /** Args prepended to the claude argv on every launch bound to this channel. */
792
799
  options: z.array(z.string()).optional(),
800
+ /** Env vars layered under the launched claude process. process.env wins on collision. */
793
801
  env: z.record(z.string(), z.string()).optional(),
794
802
  connectors: z.array(connectorSpecSchema).optional()
795
803
  });
804
+ const localConfigSchema = z.object({
805
+ $schema: z.string().optional(),
806
+ /** Declared channels. First entry is the default; --channel <name> selects by name. */
807
+ channels: z.array(channelSpecSchema).min(1)
808
+ });
796
809
  const LOCAL_CONFIG_FILENAME = "funnel.json";
797
810
  const LOCAL_ENV_FILENAME = ".env.local";
798
811
  //#endregion
@@ -878,9 +891,20 @@ var FunnelLocalConfig = class {
878
891
  var FunnelTokenPrompter = class {};
879
892
  //#endregion
880
893
  //#region lib/engine/local-config/local-config-sync.ts
894
+ const arraysEqual = (a, b) => {
895
+ if (a.length !== b.length) return false;
896
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
897
+ return true;
898
+ };
899
+ const recordsEqual = (a, b) => {
900
+ const keys = Object.keys(a);
901
+ if (keys.length !== Object.keys(b).length) return false;
902
+ for (const key of keys) if (a[key] !== b[key]) return false;
903
+ return true;
904
+ };
881
905
  /**
882
- * Reconciles a `funnel.json` spec with `~/.funnel/settings.json`. The spec
883
- * is the source of truth for the channel it declares:
906
+ * Reconciles a single funnel.json channel spec with `~/.funnel/settings.json`.
907
+ * The spec is the source of truth for the channel it declares:
884
908
  *
885
909
  * - missing channel → created
886
910
  * - declared connector matched by name → tokens reconciled
@@ -889,9 +913,10 @@ var FunnelTokenPrompter = class {};
889
913
  * - declared connector with no match → added
890
914
  * - any connector left in the channel that the spec did not touch → removed
891
915
  *
892
- * Removal only fires when funnel.json has a `connectors` field. An absent
893
- * field means "do not manage connectors from here" and leaves everything in
894
- * `~/.funnel` alone.
916
+ * Removal only fires when the channel spec has a `connectors` field. An
917
+ * absent field means "do not manage connectors from here" and leaves
918
+ * everything in `~/.funnel` alone. Other channels in funnel.json (not
919
+ * passed to this call) are untouched.
895
920
  */
896
921
  var FunnelLocalConfigSync = class {
897
922
  channels;
@@ -905,16 +930,27 @@ var FunnelLocalConfigSync = class {
905
930
  this.env = deps.env ?? process.env;
906
931
  Object.freeze(this);
907
932
  }
908
- async ensure(local, cwd) {
909
- if (!this.channels.get(local.channel)) this.channels.add({ name: local.channel });
910
- if (local.connectors === void 0) return;
933
+ async ensure(channel, cwd) {
934
+ const existing = this.channels.get(channel.name);
935
+ if (!existing) this.channels.add({
936
+ name: channel.name,
937
+ options: channel.options ?? [],
938
+ env: channel.env ?? {}
939
+ });
940
+ else {
941
+ const nextOptions = channel.options ?? [];
942
+ const nextEnv = channel.env ?? {};
943
+ if (!arraysEqual(existing.options, nextOptions)) this.channels.setOptions(channel.name, nextOptions);
944
+ if (!recordsEqual(existing.env, nextEnv)) this.channels.setEnv(channel.name, nextEnv);
945
+ }
946
+ if (channel.connectors === void 0) return;
911
947
  const dotenv = this.dotenv.read(cwd);
912
948
  const touched = /* @__PURE__ */ new Set();
913
- for (const spec of local.connectors) {
914
- const id = await this.ensureConnector(local.channel, spec, dotenv);
949
+ for (const spec of channel.connectors) {
950
+ const id = await this.ensureConnector(channel.name, spec, dotenv);
915
951
  touched.add(id);
916
952
  }
917
- this.removeExtras(local.channel, touched);
953
+ this.removeExtras(channel.name, touched);
918
954
  }
919
955
  async ensureConnector(channelName, spec, dotenv) {
920
956
  if (spec.type === "slack") return await this.ensureSlack(channelName, spec, dotenv);
@@ -1311,7 +1347,6 @@ var FunnelProfiles = class {
1311
1347
  profile.channelId = fields.channelId;
1312
1348
  }
1313
1349
  if (fields.path !== void 0) profile.path = fields.path;
1314
- if (fields.subAgent !== void 0) profile.subAgent = fields.subAgent;
1315
1350
  this.store.write(settings);
1316
1351
  }
1317
1352
  };
@@ -3357,6 +3392,7 @@ var Funnel = class Funnel {
3357
3392
  process: this.process,
3358
3393
  clock: this.clock,
3359
3394
  logger: this.logger,
3395
+ dir: this.paths.dir,
3360
3396
  killCompetingSlack: options.killCompetingSlack,
3361
3397
  token: options.token ?? this.gatewayToken.ensure(),
3362
3398
  extraRoutes: options.extraRoutes
@@ -4075,19 +4111,22 @@ examples:
4075
4111
  const claudeHelp = `funnel claude — launch Claude Code
4076
4112
 
4077
4113
  usage:
4078
- funnel claude launch using funnel.json in cwd, or the default profile
4114
+ funnel claude launch the first channel from funnel.json, or the default profile
4115
+ funnel claude --channel <name> with funnel.json: select that channel; without: raw launch
4079
4116
  funnel claude -p <name> launch a named profile
4080
4117
  funnel claude --profile <name> (long form)
4081
- funnel claude --channel <name> raw launch (no profile, cwd = current dir)
4082
4118
  funnel claude [...] any other argument is forwarded to the claude CLI
4083
4119
 
4084
- resolution order when no --profile / --channel is given:
4085
- 1. ./funnel.json in the current directory
4086
- 2. the default profile (first entry in fnl profiles)
4120
+ resolution order:
4121
+ 1. --help print this help
4122
+ 2. --profile <name> named profile (ignores funnel.json)
4123
+ 3. ./funnel.json in the current directory + --channel selects (or first wins)
4124
+ 4. --channel <name> with no funnel.json → raw launch using an existing settings.json channel
4125
+ 5. the default profile (first entry in fnl profiles)
4087
4126
 
4088
4127
  funnel-specific options (everything else passes through to claude verbatim):
4089
4128
  -p, --profile profile name to launch
4090
- --channel channel name (raw launch, ignored when --profile is given)
4129
+ --channel channel name (selects from funnel.json, or raw-launches if no funnel.json)
4091
4130
  -h, --help show this help
4092
4131
 
4093
4132
  Positional args, unknown short flags (e.g. -c, -r), and claude's own flags
@@ -4114,22 +4153,21 @@ const claudeHandler = factory.createHandlers(zValidator$1("query", z.object({
4114
4153
  const exitCode = await funnel.claude.launch({
4115
4154
  channel: profile.channelId,
4116
4155
  cwd: profile.path,
4117
- subAgent: profile.subAgent,
4118
4156
  userArgs,
4119
- profileName: profile.name,
4120
- brief: profile.brief
4157
+ profileName: profile.name
4121
4158
  });
4122
4159
  process.exit(exitCode);
4123
4160
  }
4124
4161
  const cwd = process.cwd();
4125
4162
  const local = funnel.localConfig.read(cwd);
4126
4163
  if (local) {
4127
- await funnel.localConfigSync.ensure(local, cwd);
4164
+ const picked = query.channel !== void 0 ? local.channels.find((c) => c.name === query.channel) : local.channels[0];
4165
+ if (!picked) throw new HTTPException(404, { message: query.channel ? `channel "${query.channel}" is not declared in funnel.json` : `funnel.json declares no channels` });
4166
+ await funnel.localConfigSync.ensure(picked, cwd);
4128
4167
  const exitCode = await funnel.claude.launch({
4129
- channel: local.channel,
4168
+ channel: picked.name,
4130
4169
  cwd,
4131
- userArgs: [...local.options ?? [], ...userArgs],
4132
- extraEnv: local.env
4170
+ userArgs
4133
4171
  });
4134
4172
  process.exit(exitCode);
4135
4173
  }
@@ -4138,10 +4176,8 @@ const claudeHandler = factory.createHandlers(zValidator$1("query", z.object({
4138
4176
  const exitCode = await funnel.claude.launch({
4139
4177
  channel: defaultProfile.channelId,
4140
4178
  cwd: defaultProfile.path,
4141
- subAgent: defaultProfile.subAgent,
4142
4179
  userArgs,
4143
- profileName: defaultProfile.name,
4144
- brief: defaultProfile.brief
4180
+ profileName: defaultProfile.name
4145
4181
  });
4146
4182
  process.exit(exitCode);
4147
4183
  });
@@ -4371,18 +4407,18 @@ examples:
4371
4407
  //#region lib/cli/routes/profiles.add.$profile.ts
4372
4408
  const addHelp = `funnel profiles add — add a profile
4373
4409
 
4374
- usage: funnel profiles add <name> --path <path> --sub-agent <agent> --channel <channel-name> [--brief]
4410
+ usage: funnel profiles add <name> --path <path> --channel <channel-name>
4375
4411
 
4376
4412
  options:
4377
- --path working directory passed to claude as cwd
4378
- --sub-agent sub-agent name passed to claude --agent
4379
- --channel channel name (resolved to channel id internally)
4380
- --brief forward --brief to claude on launch (enables SendUserMessage tool)`;
4413
+ --path working directory passed to claude as cwd
4414
+ --channel channel name (resolved to channel id internally)
4415
+
4416
+ Per-launch flags like --agent or --brief now live on the channel itself
4417
+ (set with \`fnl channels <name> set options ...\`), so profiles are only
4418
+ \`{ name, path, channelId }\`.`;
4381
4419
  const profilesAddHandler = factory.createHandlers(zValidator$1("param", z.object({ profile: z.string() })), zValidator$1("query", z.object({
4382
4420
  path: z.string(),
4383
- "sub-agent": z.string(),
4384
- channel: z.string(),
4385
- brief: z.coerce.boolean().optional()
4421
+ channel: z.string()
4386
4422
  }), addHelp), (c) => {
4387
4423
  const param = c.req.valid("param");
4388
4424
  const query = c.req.valid("query");
@@ -4392,9 +4428,7 @@ const profilesAddHandler = factory.createHandlers(zValidator$1("param", z.object
4392
4428
  funnel.profiles.add({
4393
4429
  name: param.profile,
4394
4430
  path: query.path,
4395
- subAgent: query["sub-agent"],
4396
- channelId: channel.id,
4397
- ...query.brief !== void 0 ? { brief: query.brief } : {}
4431
+ channelId: channel.id
4398
4432
  });
4399
4433
  return c.text(`added profile "${param.profile}"`);
4400
4434
  });
@@ -4437,7 +4471,6 @@ const profilesLaunchHandler = factory.createHandlers(zValidator$1("param", z.obj
4437
4471
  const exitCode = await funnel.claude.launch({
4438
4472
  channel: profile.channelId,
4439
4473
  cwd: profile.path,
4440
- subAgent: profile.subAgent,
4441
4474
  userArgs: queryToCliArgs(c.req.url, RESERVED_KEYS),
4442
4475
  profileName: profile.name
4443
4476
  });
@@ -4457,25 +4490,19 @@ const profilesRemoveHandler = factory.createHandlers(zValidator$1("param", z.obj
4457
4490
  //#region lib/cli/routes/profiles.set.$profile.ts
4458
4491
  const setHelp = `funnel profiles <name> set — update a profile
4459
4492
 
4460
- usage: funnel profiles <name> set [--path <path>] [--sub-agent <agent>] [--channel <channel-name>] [--brief | --no-brief]`;
4493
+ usage: funnel profiles <name> set [--path <path>] [--channel <channel-name>]`;
4461
4494
  const profilesSetHandler = factory.createHandlers(zValidator$1("param", z.object({ profile: z.string() })), zValidator$1("query", z.object({
4462
4495
  path: z.string().optional(),
4463
- "sub-agent": z.string().optional(),
4464
- channel: z.string().optional(),
4465
- brief: z.coerce.boolean().optional(),
4466
- "no-brief": z.coerce.boolean().optional()
4496
+ channel: z.string().optional()
4467
4497
  }), setHelp), (c) => {
4468
4498
  const param = c.req.valid("param");
4469
4499
  const query = c.req.valid("query");
4470
4500
  const funnel = c.var.funnel;
4471
4501
  const channel = query.channel !== void 0 ? funnel.channels.get(query.channel) : null;
4472
4502
  if (query.channel !== void 0 && !channel) throw new HTTPException(400, { message: `channel "${query.channel}" not found` });
4473
- const brief = query["no-brief"] ? false : query.brief;
4474
4503
  funnel.profiles.update(param.profile, {
4475
4504
  path: query.path,
4476
- subAgent: query["sub-agent"],
4477
- channelId: channel?.id,
4478
- ...brief !== void 0 ? { brief } : {}
4505
+ channelId: channel?.id
4479
4506
  });
4480
4507
  return c.text(`updated profile "${param.profile}"`);
4481
4508
  });
@@ -4485,23 +4512,27 @@ usage: funnel profiles [subcommand]
4485
4512
 
4486
4513
  subcommands:
4487
4514
  (none) list (first entry is the default)
4488
- add <name> --path <path> --sub-agent <agent> --channel <channel>
4489
- <name> set [--path ...] [--sub-agent ...] [--channel ...]
4515
+ add <name> --path <path> --channel <channel>
4516
+ <name> set [--path ...] [--channel ...]
4490
4517
  <name> as-default move profile to the front (becomes default)
4491
4518
  rename <old> <new> rename
4492
4519
  remove <name> remove
4493
4520
  <name> run launch (sugar for fnl claude -p <name>)
4494
4521
  <name> launch (alias for run)
4495
4522
 
4523
+ Per-launch flags like --agent or --brief now live on the channel itself
4524
+ (set with \`fnl channels <name> set options ...\`), so profiles are only
4525
+ \`{ name, path, channelId }\`.
4526
+
4496
4527
  examples:
4497
- funnel profiles add cto --path /repo/myapp --sub-agent cto --channel prod-inbox
4528
+ funnel profiles add cto --path /repo/myapp --channel prod-inbox
4498
4529
  funnel profiles cto as-default
4499
4530
  funnel profiles cto run`), (c) => {
4500
4531
  const profiles = c.var.funnel.profiles.list();
4501
4532
  if (profiles.length === 0) return c.text("no profiles");
4502
4533
  const lines = profiles.map((profile, index) => {
4503
4534
  const tag = index === 0 ? " (default)" : "";
4504
- return `${profile.name}${tag} [path=${profile.path}, sub-agent=${profile.subAgent}, channel=${profile.channelId}]`;
4535
+ return `${profile.name}${tag} [path=${profile.path}, channel=${profile.channelId}]`;
4505
4536
  });
4506
4537
  return c.text(lines.join("\n"));
4507
4538
  });
@@ -4555,7 +4586,7 @@ const statusHandler = factory.createHandlers(zValidator$1("query", z.object({}),
4555
4586
  const tag = index === 0 ? " (default)" : "";
4556
4587
  const channel = funnel.channels.getById(profile.channelId);
4557
4588
  const channelLabel = channel ? channel.name : `id:${profile.channelId}`;
4558
- lines.push(` - ${profile.name}${tag} [path=${profile.path}, sub-agent=${profile.subAgent}, channel=${channelLabel}]`);
4589
+ lines.push(` - ${profile.name}${tag} [path=${profile.path}, channel=${channelLabel}]`);
4559
4590
  }
4560
4591
  lines.push("");
4561
4592
  if (!gatewayStatus.running) lines.push("gateway: not running");
@@ -4933,7 +4964,7 @@ function ProfileLauncher(props) {
4933
4964
  children: profile.name
4934
4965
  }), /* @__PURE__ */ jsx("span", {
4935
4966
  fg: funnel.faint,
4936
- children: ` → channel ${profile.channelId} · path ${profile.path} · sub-agent ${profile.subAgent}`
4967
+ children: ` → channel ${profile.channelId} · path ${profile.path}`
4937
4968
  })]
4938
4969
  }, profile.name);
4939
4970
  })
@@ -6448,9 +6479,6 @@ function ProfilesView(props) {
6448
6479
  } else if (field === "path") {
6449
6480
  const next = raw.trim();
6450
6481
  if (next) props.funnel.profiles.update(profile.name, { path: next });
6451
- } else if (field === "sub-agent") {
6452
- const next = raw.trim();
6453
- if (next) props.funnel.profiles.update(profile.name, { subAgent: next });
6454
6482
  }
6455
6483
  } catch (error) {
6456
6484
  props.funnel.logger.error(error instanceof Error ? error.message : String(error));
@@ -6474,7 +6502,6 @@ function ProfilesView(props) {
6474
6502
  props.funnel.profiles.add({
6475
6503
  name,
6476
6504
  path: "",
6477
- subAgent: "",
6478
6505
  channelId
6479
6506
  });
6480
6507
  props.setFocusedKey(fieldKey(name, "name"));
@@ -6508,14 +6535,6 @@ function ProfilesView(props) {
6508
6535
  onCommit: (raw) => commit(profile, "path", raw),
6509
6536
  placeholder: "repository path"
6510
6537
  }),
6511
- /* @__PURE__ */ jsx(EditableField, {
6512
- label: "sub-agent",
6513
- initialValue: profile.subAgent,
6514
- focused: props.focusedKey === fieldKey(profile.name, "sub-agent"),
6515
- onFocus: () => props.setFocusedKey(fieldKey(profile.name, "sub-agent")),
6516
- onCommit: (raw) => commit(profile, "sub-agent", raw),
6517
- placeholder: "claude --agent value"
6518
- }),
6519
6538
  /* @__PURE__ */ jsx(EditableField, {
6520
6539
  label: "channel",
6521
6540
  initialValue: profile.channelId,
@@ -6641,7 +6660,6 @@ function App(props) {
6641
6660
  await props.funnel.claude.launch({
6642
6661
  channel: profile.channelId,
6643
6662
  cwd: profile.path,
6644
- subAgent: profile.subAgent,
6645
6663
  profileName: profile.name
6646
6664
  });
6647
6665
  } catch (error) {
@@ -6831,4 +6849,4 @@ async function launchTui(funnel) {
6831
6849
  });
6832
6850
  }
6833
6851
  //#endregion
6834
- export { DEFAULT_GATEWAY_TOKEN_PATH, FUNNEL_DIR, FUNNEL_MCP_COMMAND, FUNNEL_MCP_NAME, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClaude, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelDotenvReader, FunnelEventStore, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLocalConfig, FunnelLocalConfigSync, FunnelLogger, FunnelMcp, FunnelProcessRunner, FunnelProfiles, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, FunnelTokenPrompter, LOCAL_CONFIG_FILENAME, LOCAL_ENV_FILENAME, MemoryFunnelClock, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryFunnelTokenPrompter, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NodeFunnelTokenPrompter, NoopFunnelLogger, SETTINGS_PATH, SETTINGS_VERSION, channelConfigSchema, channelDeliveryModeSchema, app as cliApp, connectorConfigSchema, connectorSpecSchema, createCliApp, createSettings, discordConnectorSchema, factory, funnelEventSchema, funnelJsonSchema, ghConnectorSchema, launchTui, localConfigSchema, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, startChannelServer, toRequest };
6852
+ export { DEFAULT_GATEWAY_TOKEN_PATH, FUNNEL_DIR, FUNNEL_MCP_COMMAND, FUNNEL_MCP_NAME, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClaude, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelDotenvReader, FunnelEventStore, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLocalConfig, FunnelLocalConfigSync, FunnelLogger, FunnelMcp, FunnelProcessRunner, FunnelProfiles, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, FunnelTokenPrompter, LOCAL_CONFIG_FILENAME, LOCAL_ENV_FILENAME, MemoryFunnelClock, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryFunnelTokenPrompter, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NodeFunnelTokenPrompter, NoopFunnelLogger, SETTINGS_PATH, SETTINGS_VERSION, channelConfigSchema, channelDeliveryModeSchema, channelSpecSchema, app as cliApp, connectorConfigSchema, connectorSpecSchema, createCliApp, createSettings, discordConnectorSchema, factory, funnelEventSchema, funnelJsonSchema, ghConnectorSchema, launchTui, localConfigSchema, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, startChannelServer, toRequest };