@interactive-inc/claude-funnel 0.10.1 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +106 -56
- package/dist/bin.js +532 -505
- package/dist/connectors/schedule.d.ts +2 -49
- package/dist/connectors/schedule.js +1 -1
- package/dist/connectors/slack.d.ts +4 -20
- package/dist/connectors/slack.js +1 -1
- package/dist/gateway/daemon.js +214 -212
- package/dist/index.d.ts +463 -164
- package/dist/index.js +561 -36
- package/dist/{schedule-connector-schema-CkuIQ0JQ.js → schedule-connector-schema-FxP7LPlx.js} +11 -0
- package/dist/{file-system-Co60LrmR.d.ts → schedule-listener-BPodvbld.d.ts} +56 -1
- package/dist/{slack-connector-schema-Cd22WiHB.js → slack-connector-schema-B4hsf3AY.js} +10 -1
- package/dist/slack-listener-CHj6uMY-.d.ts +74 -0
- package/package.json +2 -1
- package/schemas/funnel.schema.json +144 -0
- package/dist/slack-event-processor-CS-bAit9.d.ts +0 -43
package/dist/index.d.ts
CHANGED
|
@@ -2,10 +2,11 @@ import { n as FunnelConnectorAdapter, t as CallInput } from "./connector-adapter
|
|
|
2
2
|
import { n as discordConnectorSchema, t as DiscordConnectorConfig } from "./discord-connector-schema-Dww2I4zH.js";
|
|
3
3
|
import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "./logger-CTlXs7z4.js";
|
|
4
4
|
import { a as FunnelProcessRunner, i as DetachOptions, n as ghConnectorSchema, o as RunOptions, r as AttachOptions, s as RunResult, t as GhConnectorConfig } from "./gh-connector-schema-BZFAS-p-.js";
|
|
5
|
-
import { a as
|
|
6
|
-
import { a as SlackRawEvent, i as
|
|
5
|
+
import { a as FunnelFileSystem, c as ScheduleEntry, d as scheduleEntrySchema, i as FileStat, l as scheduleCatchupPolicySchema, n as ScheduleOnFired, o as ScheduleCatchupPolicy, s as ScheduleConnectorConfig, u as scheduleConnectorSchema } from "./schedule-listener-BPodvbld.js";
|
|
6
|
+
import { a as SlackProcessed, c as SlackRawEvent, i as FunnelSlackEventProcessor, l as SlackConnectorConfig, n as SlackOnAppCreated, o as SlackProcessedEmit, r as SlackPreprocessEvent, s as SlackProcessedSkip, u as slackConnectorSchema } from "./slack-listener-CHj6uMY-.js";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import * as _$hono_factory0 from "hono/factory";
|
|
9
|
+
import { Hono } from "hono";
|
|
9
10
|
import { Server, ServerWebSocket } from "bun";
|
|
10
11
|
import * as _$hono_utils_http_status0 from "hono/utils/http-status";
|
|
11
12
|
import * as _$hono_hono_base0 from "hono/hono-base";
|
|
@@ -55,11 +56,20 @@ type ConnectorConfig = z.infer<typeof connectorConfigSchema>;
|
|
|
55
56
|
type ConnectorType = ConnectorConfig["type"];
|
|
56
57
|
//#endregion
|
|
57
58
|
//#region lib/connectors/connector-factory.d.ts
|
|
58
|
-
type
|
|
59
|
+
type SlackListenerOptions = {
|
|
60
|
+
onAppCreated?: SlackOnAppCreated;
|
|
61
|
+
preprocessEvent?: SlackPreprocessEvent;
|
|
62
|
+
};
|
|
63
|
+
type ScheduleListenerOptions = {
|
|
64
|
+
onFired?: ScheduleOnFired;
|
|
65
|
+
};
|
|
66
|
+
type Deps$15 = {
|
|
59
67
|
fs?: FunnelFileSystem;
|
|
60
68
|
process?: FunnelProcessRunner;
|
|
61
69
|
logger?: FunnelLogger;
|
|
62
|
-
dir?: string;
|
|
70
|
+
dir?: string; /** Per-listener hooks for the slack connector type. Threaded into every Slack listener built by this factory. */
|
|
71
|
+
slackListenerOptions?: SlackListenerOptions; /** Per-listener hooks for the schedule connector type. Threaded into every Schedule listener built by this factory. */
|
|
72
|
+
scheduleListenerOptions?: ScheduleListenerOptions;
|
|
63
73
|
};
|
|
64
74
|
/**
|
|
65
75
|
* Pure factory for per-type listeners and adapters. The factory has no CRUD
|
|
@@ -68,13 +78,19 @@ type Deps$12 = {
|
|
|
68
78
|
*
|
|
69
79
|
* `dir` is the funnel home (defaults to ~/.funnel); per-connector state files
|
|
70
80
|
* land at `<dir>/channels/<channel-id>/connectors/<connector-id>/state.json`.
|
|
81
|
+
*
|
|
82
|
+
* Host integrations can supply per-type listener hooks via
|
|
83
|
+
* `slackListenerOptions` / `scheduleListenerOptions` — e.g. to attach a
|
|
84
|
+
* Bolt `app.action` handler or to drop one-shot schedule entries on fire.
|
|
71
85
|
*/
|
|
72
86
|
declare class FunnelConnectorFactory {
|
|
73
87
|
private readonly fs;
|
|
74
88
|
private readonly process;
|
|
75
89
|
private readonly logger;
|
|
76
90
|
private readonly dir;
|
|
77
|
-
|
|
91
|
+
private readonly slackListenerOptions;
|
|
92
|
+
private readonly scheduleListenerOptions;
|
|
93
|
+
constructor(deps?: Deps$15);
|
|
78
94
|
createListener(channelId: string, config: ConnectorConfig): FunnelConnectorListener;
|
|
79
95
|
createAdapter(config: ConnectorConfig): FunnelConnectorAdapter | null;
|
|
80
96
|
connectorDir(channelId: string, connectorId: string): string;
|
|
@@ -252,7 +268,7 @@ declare abstract class FunnelSettingsReader {
|
|
|
252
268
|
}
|
|
253
269
|
//#endregion
|
|
254
270
|
//#region lib/engine/channels/channels.d.ts
|
|
255
|
-
type Deps$
|
|
271
|
+
type Deps$14 = {
|
|
256
272
|
store: FunnelSettingsReader;
|
|
257
273
|
factory: FunnelConnectorFactory;
|
|
258
274
|
profileChecker: ProfileChannelChecker;
|
|
@@ -295,7 +311,7 @@ declare class FunnelChannels {
|
|
|
295
311
|
private readonly profileChecker;
|
|
296
312
|
private readonly clock;
|
|
297
313
|
private readonly idGenerator;
|
|
298
|
-
constructor(deps: Deps$
|
|
314
|
+
constructor(deps: Deps$14);
|
|
299
315
|
list(): ChannelConfig[];
|
|
300
316
|
get(name: string): ChannelConfig | null;
|
|
301
317
|
getById(id: string): ChannelConfig | null;
|
|
@@ -353,7 +369,7 @@ type GatewayController = {
|
|
|
353
369
|
//#region lib/engine/mcp/mcp.d.ts
|
|
354
370
|
declare const FUNNEL_MCP_COMMAND = "funnel";
|
|
355
371
|
declare const FUNNEL_MCP_NAME = "funnel";
|
|
356
|
-
type Deps$
|
|
372
|
+
type Deps$13 = {
|
|
357
373
|
fs?: FunnelFileSystem;
|
|
358
374
|
};
|
|
359
375
|
/**
|
|
@@ -363,7 +379,7 @@ type Deps$10 = {
|
|
|
363
379
|
*/
|
|
364
380
|
declare class FunnelMcp {
|
|
365
381
|
private readonly fs;
|
|
366
|
-
constructor(deps?: Deps$
|
|
382
|
+
constructor(deps?: Deps$13);
|
|
367
383
|
install(repoPath: string): void;
|
|
368
384
|
uninstall(repoPath: string): void;
|
|
369
385
|
findInstalledName(cwd: string): string | null;
|
|
@@ -379,9 +395,10 @@ type LaunchOptions = {
|
|
|
379
395
|
subAgent?: string;
|
|
380
396
|
userArgs?: string[];
|
|
381
397
|
profileName?: string; /** Forward `--brief` to claude on launch (enables the SendUserMessage tool). */
|
|
382
|
-
brief?: boolean;
|
|
398
|
+
brief?: boolean; /** Extra env vars merged under process.env (process.env wins on collision). */
|
|
399
|
+
extraEnv?: Record<string, string>;
|
|
383
400
|
};
|
|
384
|
-
type Deps$
|
|
401
|
+
type Deps$12 = {
|
|
385
402
|
channels: FunnelChannels;
|
|
386
403
|
mcp: FunnelMcp;
|
|
387
404
|
gateway: GatewayController;
|
|
@@ -404,7 +421,7 @@ declare class FunnelClaude {
|
|
|
404
421
|
private readonly fs;
|
|
405
422
|
private readonly logger;
|
|
406
423
|
private readonly pidDir;
|
|
407
|
-
constructor(deps: Deps$
|
|
424
|
+
constructor(deps: Deps$12);
|
|
408
425
|
launch(options: LaunchOptions): Promise<number>;
|
|
409
426
|
isRunning(profileName: string): boolean;
|
|
410
427
|
private pidPath;
|
|
@@ -417,6 +434,151 @@ declare class FunnelClaude {
|
|
|
417
434
|
private buildEnv;
|
|
418
435
|
}
|
|
419
436
|
//#endregion
|
|
437
|
+
//#region lib/engine/local-config/dotenv-reader.d.ts
|
|
438
|
+
type Deps$11 = {
|
|
439
|
+
fs: FunnelFileSystem;
|
|
440
|
+
};
|
|
441
|
+
/**
|
|
442
|
+
* Minimal `.env.local` parser. Supports `KEY=value` lines, blank lines, and
|
|
443
|
+
* `#` comments. Strips matching surrounding single or double quotes. No
|
|
444
|
+
* interpolation, no `export` prefix — anything fancier should live in a real
|
|
445
|
+
* env file loaded by the shell.
|
|
446
|
+
*/
|
|
447
|
+
declare class FunnelDotenvReader {
|
|
448
|
+
private readonly fs;
|
|
449
|
+
constructor(deps: Deps$11);
|
|
450
|
+
read(cwd: string): Record<string, string>;
|
|
451
|
+
}
|
|
452
|
+
//#endregion
|
|
453
|
+
//#region lib/engine/local-config/local-config-schema.d.ts
|
|
454
|
+
declare const connectorSpecSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
455
|
+
type: z.ZodLiteral<"slack">;
|
|
456
|
+
name: z.ZodString;
|
|
457
|
+
botToken: z.ZodOptional<z.ZodString>;
|
|
458
|
+
appToken: z.ZodOptional<z.ZodString>;
|
|
459
|
+
env: z.ZodOptional<z.ZodObject<{
|
|
460
|
+
botToken: z.ZodOptional<z.ZodString>;
|
|
461
|
+
appToken: z.ZodOptional<z.ZodString>;
|
|
462
|
+
}, z.core.$strip>>;
|
|
463
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
464
|
+
type: z.ZodLiteral<"discord">;
|
|
465
|
+
name: z.ZodString;
|
|
466
|
+
botToken: z.ZodOptional<z.ZodString>;
|
|
467
|
+
env: z.ZodOptional<z.ZodObject<{
|
|
468
|
+
botToken: z.ZodOptional<z.ZodString>;
|
|
469
|
+
}, z.core.$strip>>;
|
|
470
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
471
|
+
type: z.ZodLiteral<"gh">;
|
|
472
|
+
name: z.ZodString;
|
|
473
|
+
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
474
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
475
|
+
type: z.ZodLiteral<"schedule">;
|
|
476
|
+
name: z.ZodString;
|
|
477
|
+
}, z.core.$strip>], "type">;
|
|
478
|
+
type ConnectorSpec = z.infer<typeof connectorSpecSchema>;
|
|
479
|
+
declare const localConfigSchema: z.ZodObject<{
|
|
480
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
481
|
+
channel: z.ZodString;
|
|
482
|
+
options: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
483
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
484
|
+
connectors: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
485
|
+
type: z.ZodLiteral<"slack">;
|
|
486
|
+
name: z.ZodString;
|
|
487
|
+
botToken: z.ZodOptional<z.ZodString>;
|
|
488
|
+
appToken: z.ZodOptional<z.ZodString>;
|
|
489
|
+
env: z.ZodOptional<z.ZodObject<{
|
|
490
|
+
botToken: z.ZodOptional<z.ZodString>;
|
|
491
|
+
appToken: z.ZodOptional<z.ZodString>;
|
|
492
|
+
}, z.core.$strip>>;
|
|
493
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
494
|
+
type: z.ZodLiteral<"discord">;
|
|
495
|
+
name: z.ZodString;
|
|
496
|
+
botToken: z.ZodOptional<z.ZodString>;
|
|
497
|
+
env: z.ZodOptional<z.ZodObject<{
|
|
498
|
+
botToken: z.ZodOptional<z.ZodString>;
|
|
499
|
+
}, z.core.$strip>>;
|
|
500
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
501
|
+
type: z.ZodLiteral<"gh">;
|
|
502
|
+
name: z.ZodString;
|
|
503
|
+
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
504
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
505
|
+
type: z.ZodLiteral<"schedule">;
|
|
506
|
+
name: z.ZodString;
|
|
507
|
+
}, z.core.$strip>], "type">>>;
|
|
508
|
+
}, z.core.$strip>;
|
|
509
|
+
type LocalConfig = z.infer<typeof localConfigSchema>;
|
|
510
|
+
declare const LOCAL_CONFIG_FILENAME = "funnel.json";
|
|
511
|
+
declare const LOCAL_ENV_FILENAME = ".env.local";
|
|
512
|
+
//#endregion
|
|
513
|
+
//#region lib/engine/local-config/local-config.d.ts
|
|
514
|
+
type Deps$10 = {
|
|
515
|
+
fs: FunnelFileSystem;
|
|
516
|
+
};
|
|
517
|
+
/**
|
|
518
|
+
* Reads `funnel.json` from a directory. Returns `null` when the file is
|
|
519
|
+
* absent so callers can fall through to other resolution paths (default
|
|
520
|
+
* profile, help). Throws on present-but-invalid files so misconfiguration
|
|
521
|
+
* surfaces loudly instead of silently launching the wrong channel.
|
|
522
|
+
*/
|
|
523
|
+
declare class FunnelLocalConfig {
|
|
524
|
+
private readonly fs;
|
|
525
|
+
constructor(deps: Deps$10);
|
|
526
|
+
read(cwd: string): LocalConfig | null;
|
|
527
|
+
}
|
|
528
|
+
//#endregion
|
|
529
|
+
//#region lib/engine/token-prompter/token-prompter.d.ts
|
|
530
|
+
/**
|
|
531
|
+
* Asks the user for a secret value on stdin. Used as a last resort when a
|
|
532
|
+
* funnel.json token field is absent and not present in `~/.funnel`. The Node
|
|
533
|
+
* implementation refuses to prompt when stdin is not a TTY so non-interactive
|
|
534
|
+
* launches (CI, agent spawning agent, daemons) fail fast instead of hanging.
|
|
535
|
+
*/
|
|
536
|
+
declare abstract class FunnelTokenPrompter {
|
|
537
|
+
abstract promptSecret(label: string): Promise<string>;
|
|
538
|
+
}
|
|
539
|
+
//#endregion
|
|
540
|
+
//#region lib/engine/local-config/local-config-sync.d.ts
|
|
541
|
+
type Deps$9 = {
|
|
542
|
+
channels: FunnelChannels;
|
|
543
|
+
dotenv: FunnelDotenvReader;
|
|
544
|
+
prompter: FunnelTokenPrompter;
|
|
545
|
+
env?: NodeJS.ProcessEnv;
|
|
546
|
+
};
|
|
547
|
+
/**
|
|
548
|
+
* Reconciles a `funnel.json` spec with `~/.funnel/settings.json`. The spec
|
|
549
|
+
* is the source of truth for the channel it declares:
|
|
550
|
+
*
|
|
551
|
+
* - missing channel → created
|
|
552
|
+
* - declared connector matched by name → tokens reconciled
|
|
553
|
+
* - declared connector matched by token in the same channel under a
|
|
554
|
+
* different name → renamed in place (then tokens reconciled)
|
|
555
|
+
* - declared connector with no match → added
|
|
556
|
+
* - any connector left in the channel that the spec did not touch → removed
|
|
557
|
+
*
|
|
558
|
+
* Removal only fires when funnel.json has a `connectors` field. An absent
|
|
559
|
+
* field means "do not manage connectors from here" and leaves everything in
|
|
560
|
+
* `~/.funnel` alone.
|
|
561
|
+
*/
|
|
562
|
+
declare class FunnelLocalConfigSync {
|
|
563
|
+
private readonly channels;
|
|
564
|
+
private readonly dotenv;
|
|
565
|
+
private readonly prompter;
|
|
566
|
+
private readonly env;
|
|
567
|
+
constructor(deps: Deps$9);
|
|
568
|
+
ensure(local: LocalConfig, cwd: string): Promise<void>;
|
|
569
|
+
private ensureConnector;
|
|
570
|
+
private ensureSlack;
|
|
571
|
+
private ensureDiscord;
|
|
572
|
+
private ensureGh;
|
|
573
|
+
private ensureSchedule;
|
|
574
|
+
private findExistingSlack;
|
|
575
|
+
private findExistingDiscord;
|
|
576
|
+
private findSlackByToken;
|
|
577
|
+
private findDiscordByToken;
|
|
578
|
+
private removeExtras;
|
|
579
|
+
private resolveField;
|
|
580
|
+
}
|
|
581
|
+
//#endregion
|
|
420
582
|
//#region lib/engine/profiles/profiles.d.ts
|
|
421
583
|
type Deps$8 = {
|
|
422
584
|
store: FunnelSettingsReader;
|
|
@@ -495,62 +657,6 @@ declare class FunnelChannelPublisher {
|
|
|
495
657
|
private authHeaders;
|
|
496
658
|
}
|
|
497
659
|
//#endregion
|
|
498
|
-
//#region lib/gateway/gateway.d.ts
|
|
499
|
-
type Deps$6 = {
|
|
500
|
-
process?: FunnelProcessRunner;
|
|
501
|
-
fs?: FunnelFileSystem;
|
|
502
|
-
clock?: FunnelClock;
|
|
503
|
-
dir?: string;
|
|
504
|
-
tmpDir?: string;
|
|
505
|
-
port?: number;
|
|
506
|
-
sleep?: (ms: number) => Promise<void>;
|
|
507
|
-
};
|
|
508
|
-
/**
|
|
509
|
-
* Manages the gateway daemon as a separate process via PID file.
|
|
510
|
-
* Use `start()` to spawn `bun daemon.ts` in the background and `stop()` to
|
|
511
|
-
* terminate it. For an in-process gateway, use `Funnel.gatewayServer` instead.
|
|
512
|
-
*/
|
|
513
|
-
declare class FunnelGateway {
|
|
514
|
-
private readonly process;
|
|
515
|
-
private readonly fs;
|
|
516
|
-
private readonly clock;
|
|
517
|
-
private readonly pidFile;
|
|
518
|
-
private readonly logDir;
|
|
519
|
-
private readonly gatewayLog;
|
|
520
|
-
private readonly tmpDir;
|
|
521
|
-
private readonly port;
|
|
522
|
-
private readonly sleep;
|
|
523
|
-
constructor(deps?: Deps$6);
|
|
524
|
-
isRunning(): boolean;
|
|
525
|
-
getStatus(): {
|
|
526
|
-
running: boolean;
|
|
527
|
-
pid: number | null;
|
|
528
|
-
port: number;
|
|
529
|
-
};
|
|
530
|
-
start(options?: {
|
|
531
|
-
caffeinate?: boolean;
|
|
532
|
-
}): Promise<boolean>;
|
|
533
|
-
buildStartCommand(gatewayScript: string, options?: {
|
|
534
|
-
caffeinate?: boolean;
|
|
535
|
-
}): string;
|
|
536
|
-
stop(): Promise<boolean>;
|
|
537
|
-
restart(options?: {
|
|
538
|
-
onlyIfRunning?: boolean;
|
|
539
|
-
caffeinate?: boolean;
|
|
540
|
-
}): Promise<{
|
|
541
|
-
ok: boolean;
|
|
542
|
-
wasRunning: boolean;
|
|
543
|
-
stopped: boolean;
|
|
544
|
-
started: boolean;
|
|
545
|
-
}>;
|
|
546
|
-
getLogDir(): string;
|
|
547
|
-
getGatewayLog(): string;
|
|
548
|
-
getPort(): number;
|
|
549
|
-
private readPid;
|
|
550
|
-
private removePid;
|
|
551
|
-
private isProcessAlive;
|
|
552
|
-
}
|
|
553
|
-
//#endregion
|
|
554
660
|
//#region lib/gateway/broadcaster.d.ts
|
|
555
661
|
type ClientData = {
|
|
556
662
|
/** Stable channel id (uuid) that the WS client subscribed to. */channel: string; /** Human-facing channel name resolved at upgrade time, kept for log readability. */
|
|
@@ -576,7 +682,7 @@ type BroadcastSubscriber = (event: ReplayableEvent) => void;
|
|
|
576
682
|
type ReplaySource = {
|
|
577
683
|
loadSince(since: number): ReplayableEvent[];
|
|
578
684
|
};
|
|
579
|
-
type Deps$
|
|
685
|
+
type Deps$6 = {
|
|
580
686
|
logger?: FunnelLogger;
|
|
581
687
|
maxBufferedBytes?: number;
|
|
582
688
|
now?: () => number; /** Number of recent events kept in the in-memory replay buffer. */
|
|
@@ -627,7 +733,7 @@ declare class FunnelBroadcaster {
|
|
|
627
733
|
private droppedSlowClients;
|
|
628
734
|
private lastBroadcastAt;
|
|
629
735
|
private latestOffset;
|
|
630
|
-
constructor(deps?: Deps$
|
|
736
|
+
constructor(deps?: Deps$6);
|
|
631
737
|
getMetrics(): BroadcasterMetrics;
|
|
632
738
|
/**
|
|
633
739
|
* Returns events with offset > since, filtered by the connector subscription
|
|
@@ -663,82 +769,6 @@ declare class FunnelBroadcaster {
|
|
|
663
769
|
seedLatestOffset(offset: number): void;
|
|
664
770
|
}
|
|
665
771
|
//#endregion
|
|
666
|
-
//#region lib/gateway/funnel-event-store.d.ts
|
|
667
|
-
/**
|
|
668
|
-
* Replayable event payload persisted by the gateway. Domain events the
|
|
669
|
-
* broadcaster emits to WS clients land here so reconnects across daemon
|
|
670
|
-
* restarts can be served from disk. System events (gateway start, channel
|
|
671
|
-
* connected, etc.) are routed to `FunnelLogger` instead — they never go
|
|
672
|
-
* through this store, which keeps the seq space clean for replay.
|
|
673
|
-
*/
|
|
674
|
-
declare const funnelEventSchema: z.ZodObject<{
|
|
675
|
-
type: z.ZodString;
|
|
676
|
-
content: z.ZodString;
|
|
677
|
-
channel_id: z.ZodNullable<z.ZodString>;
|
|
678
|
-
connector_id: z.ZodNullable<z.ZodString>;
|
|
679
|
-
meta: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
680
|
-
}, z.core.$strip>;
|
|
681
|
-
type FunnelEvent = z.infer<typeof funnelEventSchema>;
|
|
682
|
-
type Props$5 = {
|
|
683
|
-
/** SQLite database file path. Created on first write. ":memory:" for tests. */path: string; /** Override for tests. Defaults to `Date.now`. */
|
|
684
|
-
now?: () => number; /** Optional row cap. Pruned on every insert. */
|
|
685
|
-
maxRows?: number; /** Optional age cap in ms. Pruned on every insert. */
|
|
686
|
-
maxAgeMs?: number;
|
|
687
|
-
};
|
|
688
|
-
/**
|
|
689
|
-
* SQLite-backed event store. One indexed table holds every broadcaster
|
|
690
|
-
* event with `channel_id` and `connector_id` as dedicated columns, so
|
|
691
|
-
* per-channel and per-connector replay is an indexed range scan.
|
|
692
|
-
*
|
|
693
|
-
* Concurrency: `seq` is `INTEGER PRIMARY KEY`, so SQLite assigns it
|
|
694
|
-
* atomically. The broadcaster owns its own offset counter at runtime
|
|
695
|
-
* (seeded from `findMaxOffset()` at startup); each broadcaster event
|
|
696
|
-
* flows in here via `record()` with that pre-assigned offset, which the
|
|
697
|
-
* sink stores via `write()` — PK uniqueness catches double-emit bugs.
|
|
698
|
-
*
|
|
699
|
-
* System events (gateway lifecycle, channel connect/disconnect, etc.) do
|
|
700
|
-
* NOT go through this store. They are diagnostic only and live in
|
|
701
|
-
* `FunnelLogger`'s file so the seq space here stays exclusive to
|
|
702
|
-
* broadcaster traffic. This is what makes the broadcaster's seq seeding
|
|
703
|
-
* (`getMaxSeq()` at startup) correct without per-event coordination.
|
|
704
|
-
*/
|
|
705
|
-
declare class FunnelEventStore {
|
|
706
|
-
private readonly sink;
|
|
707
|
-
private readonly now;
|
|
708
|
-
constructor(props: Props$5);
|
|
709
|
-
/**
|
|
710
|
-
* Persist a broadcaster-driven event with its assigned offset. Caller
|
|
711
|
-
* (the gateway-server) supplies the offset from `broadcaster.broadcast()`
|
|
712
|
-
* so this store and the broadcaster's in-memory ring stay aligned.
|
|
713
|
-
*/
|
|
714
|
-
record(props: {
|
|
715
|
-
content: string;
|
|
716
|
-
channelId: string | null;
|
|
717
|
-
connectorId: string | null;
|
|
718
|
-
meta: Record<string, string> | null;
|
|
719
|
-
offset: number;
|
|
720
|
-
}): void;
|
|
721
|
-
/**
|
|
722
|
-
* Returns events with offset > since. Filtering by channel/connector is
|
|
723
|
-
* the broadcaster's responsibility (it knows the client's subscription),
|
|
724
|
-
* so this returns the full slice and lets the caller filter.
|
|
725
|
-
*/
|
|
726
|
-
loadSince(since: number): ReplayableEvent[];
|
|
727
|
-
/**
|
|
728
|
-
* Returns events for one channel (and optionally one connector). Used
|
|
729
|
-
* by the gateway logs CLI for scoped queries. Channel/connector filters
|
|
730
|
-
* are indexed columns, so this is an indexed range scan.
|
|
731
|
-
*/
|
|
732
|
-
loadForChannel(props: {
|
|
733
|
-
channelId: string;
|
|
734
|
-
connectorId?: string;
|
|
735
|
-
sinceSeq?: number;
|
|
736
|
-
limit?: number;
|
|
737
|
-
}): ReplayableEvent[];
|
|
738
|
-
findMaxOffset(): number;
|
|
739
|
-
close(): void;
|
|
740
|
-
}
|
|
741
|
-
//#endregion
|
|
742
772
|
//#region lib/gateway/listener-supervisor.d.ts
|
|
743
773
|
type ConnectorRegistry = {
|
|
744
774
|
listAllConnectors(): ChannelConnectorView[];
|
|
@@ -749,7 +779,7 @@ type ConnectorRegistry = {
|
|
|
749
779
|
} | null;
|
|
750
780
|
};
|
|
751
781
|
type SupervisorNotify = (channelName: string, connectorName: string, content: string, meta?: Record<string, string>) => Promise<void>;
|
|
752
|
-
type Deps$
|
|
782
|
+
type Deps$5 = {
|
|
753
783
|
channels: ConnectorRegistry;
|
|
754
784
|
notify: SupervisorNotify;
|
|
755
785
|
logger?: FunnelLogger;
|
|
@@ -794,7 +824,7 @@ declare class FunnelListenerSupervisor {
|
|
|
794
824
|
private readonly now;
|
|
795
825
|
private healthCheckTimer;
|
|
796
826
|
private healthCheckInFlight;
|
|
797
|
-
constructor(deps: Deps$
|
|
827
|
+
constructor(deps: Deps$5);
|
|
798
828
|
static keyOf(channelName: string, connectorName: string): string;
|
|
799
829
|
isRunning(channelName: string, connectorName: string): boolean;
|
|
800
830
|
list(): ListenerEntryStatus[];
|
|
@@ -821,6 +851,164 @@ declare class FunnelListenerSupervisor {
|
|
|
821
851
|
private recoverDead;
|
|
822
852
|
}
|
|
823
853
|
//#endregion
|
|
854
|
+
//#region lib/gateway/routes/route-deps.d.ts
|
|
855
|
+
type GatewayEmitInput = {
|
|
856
|
+
channel: string;
|
|
857
|
+
connector?: string;
|
|
858
|
+
content: string;
|
|
859
|
+
meta?: Record<string, string>;
|
|
860
|
+
};
|
|
861
|
+
type GatewayRouteDeps = {
|
|
862
|
+
selfPid: number;
|
|
863
|
+
broadcaster: FunnelBroadcaster;
|
|
864
|
+
supervisor: FunnelListenerSupervisor;
|
|
865
|
+
channels: FunnelChannels;
|
|
866
|
+
uptimeMs: () => number;
|
|
867
|
+
emit: (input: GatewayEmitInput) => {
|
|
868
|
+
offset: number;
|
|
869
|
+
};
|
|
870
|
+
};
|
|
871
|
+
//#endregion
|
|
872
|
+
//#region lib/gateway/factory.d.ts
|
|
873
|
+
type Env$1 = {
|
|
874
|
+
Variables: {
|
|
875
|
+
deps: GatewayRouteDeps;
|
|
876
|
+
};
|
|
877
|
+
};
|
|
878
|
+
//#endregion
|
|
879
|
+
//#region lib/gateway/gateway.d.ts
|
|
880
|
+
type Deps$4 = {
|
|
881
|
+
process?: FunnelProcessRunner;
|
|
882
|
+
fs?: FunnelFileSystem;
|
|
883
|
+
clock?: FunnelClock;
|
|
884
|
+
dir?: string;
|
|
885
|
+
tmpDir?: string;
|
|
886
|
+
port?: number;
|
|
887
|
+
sleep?: (ms: number) => Promise<void>;
|
|
888
|
+
};
|
|
889
|
+
/**
|
|
890
|
+
* Manages the gateway daemon as a separate process via PID file.
|
|
891
|
+
* Use `start()` to spawn `bun daemon.ts` in the background and `stop()` to
|
|
892
|
+
* terminate it. For an in-process gateway, use `Funnel.gatewayServer` instead.
|
|
893
|
+
*/
|
|
894
|
+
declare class FunnelGateway {
|
|
895
|
+
private readonly process;
|
|
896
|
+
private readonly fs;
|
|
897
|
+
private readonly clock;
|
|
898
|
+
private readonly dir;
|
|
899
|
+
private readonly pidFile;
|
|
900
|
+
private readonly logDir;
|
|
901
|
+
private readonly gatewayLog;
|
|
902
|
+
private readonly tmpDir;
|
|
903
|
+
private readonly port;
|
|
904
|
+
private readonly sleep;
|
|
905
|
+
constructor(deps?: Deps$4);
|
|
906
|
+
isRunning(): boolean;
|
|
907
|
+
getStatus(): {
|
|
908
|
+
running: boolean;
|
|
909
|
+
pid: number | null;
|
|
910
|
+
port: number;
|
|
911
|
+
};
|
|
912
|
+
start(options?: {
|
|
913
|
+
caffeinate?: boolean;
|
|
914
|
+
}): Promise<boolean>;
|
|
915
|
+
buildStartCommand(gatewayScript: string, options?: {
|
|
916
|
+
caffeinate?: boolean;
|
|
917
|
+
}): string;
|
|
918
|
+
stop(): Promise<boolean>;
|
|
919
|
+
restart(options?: {
|
|
920
|
+
onlyIfRunning?: boolean;
|
|
921
|
+
caffeinate?: boolean;
|
|
922
|
+
}): Promise<{
|
|
923
|
+
ok: boolean;
|
|
924
|
+
wasRunning: boolean;
|
|
925
|
+
stopped: boolean;
|
|
926
|
+
started: boolean;
|
|
927
|
+
}>;
|
|
928
|
+
getLogDir(): string;
|
|
929
|
+
getGatewayLog(): string;
|
|
930
|
+
getPort(): number;
|
|
931
|
+
private readPid;
|
|
932
|
+
private removePid;
|
|
933
|
+
private isProcessAlive;
|
|
934
|
+
}
|
|
935
|
+
//#endregion
|
|
936
|
+
//#region lib/gateway/funnel-event-store.d.ts
|
|
937
|
+
/**
|
|
938
|
+
* Replayable event payload persisted by the gateway. Domain events the
|
|
939
|
+
* broadcaster emits to WS clients land here so reconnects across daemon
|
|
940
|
+
* restarts can be served from disk. System events (gateway start, channel
|
|
941
|
+
* connected, etc.) are routed to `FunnelLogger` instead — they never go
|
|
942
|
+
* through this store, which keeps the seq space clean for replay.
|
|
943
|
+
*/
|
|
944
|
+
declare const funnelEventSchema: z.ZodObject<{
|
|
945
|
+
type: z.ZodString;
|
|
946
|
+
content: z.ZodString;
|
|
947
|
+
channel_id: z.ZodNullable<z.ZodString>;
|
|
948
|
+
connector_id: z.ZodNullable<z.ZodString>;
|
|
949
|
+
meta: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
950
|
+
}, z.core.$strip>;
|
|
951
|
+
type FunnelEvent = z.infer<typeof funnelEventSchema>;
|
|
952
|
+
type Props$6 = {
|
|
953
|
+
/** SQLite database file path. Created on first write. ":memory:" for tests. */path: string; /** Override for tests. Defaults to `Date.now`. */
|
|
954
|
+
now?: () => number; /** Optional row cap. Pruned on every insert. */
|
|
955
|
+
maxRows?: number; /** Optional age cap in ms. Pruned on every insert. */
|
|
956
|
+
maxAgeMs?: number;
|
|
957
|
+
};
|
|
958
|
+
/**
|
|
959
|
+
* SQLite-backed event store. One indexed table holds every broadcaster
|
|
960
|
+
* event with `channel_id` and `connector_id` as dedicated columns, so
|
|
961
|
+
* per-channel and per-connector replay is an indexed range scan.
|
|
962
|
+
*
|
|
963
|
+
* Concurrency: `seq` is `INTEGER PRIMARY KEY`, so SQLite assigns it
|
|
964
|
+
* atomically. The broadcaster owns its own offset counter at runtime
|
|
965
|
+
* (seeded from `findMaxOffset()` at startup); each broadcaster event
|
|
966
|
+
* flows in here via `record()` with that pre-assigned offset, which the
|
|
967
|
+
* sink stores via `write()` — PK uniqueness catches double-emit bugs.
|
|
968
|
+
*
|
|
969
|
+
* System events (gateway lifecycle, channel connect/disconnect, etc.) do
|
|
970
|
+
* NOT go through this store. They are diagnostic only and live in
|
|
971
|
+
* `FunnelLogger`'s file so the seq space here stays exclusive to
|
|
972
|
+
* broadcaster traffic. This is what makes the broadcaster's seq seeding
|
|
973
|
+
* (`getMaxSeq()` at startup) correct without per-event coordination.
|
|
974
|
+
*/
|
|
975
|
+
declare class FunnelEventStore {
|
|
976
|
+
private readonly sink;
|
|
977
|
+
private readonly now;
|
|
978
|
+
constructor(props: Props$6);
|
|
979
|
+
/**
|
|
980
|
+
* Persist a broadcaster-driven event with its assigned offset. Caller
|
|
981
|
+
* (the gateway-server) supplies the offset from `broadcaster.broadcast()`
|
|
982
|
+
* so this store and the broadcaster's in-memory ring stay aligned.
|
|
983
|
+
*/
|
|
984
|
+
record(props: {
|
|
985
|
+
content: string;
|
|
986
|
+
channelId: string | null;
|
|
987
|
+
connectorId: string | null;
|
|
988
|
+
meta: Record<string, string> | null;
|
|
989
|
+
offset: number;
|
|
990
|
+
}): void;
|
|
991
|
+
/**
|
|
992
|
+
* Returns events with offset > since. Filtering by channel/connector is
|
|
993
|
+
* the broadcaster's responsibility (it knows the client's subscription),
|
|
994
|
+
* so this returns the full slice and lets the caller filter.
|
|
995
|
+
*/
|
|
996
|
+
loadSince(since: number): ReplayableEvent[];
|
|
997
|
+
/**
|
|
998
|
+
* Returns events for one channel (and optionally one connector). Used
|
|
999
|
+
* by the gateway logs CLI for scoped queries. Channel/connector filters
|
|
1000
|
+
* are indexed columns, so this is an indexed range scan.
|
|
1001
|
+
*/
|
|
1002
|
+
loadForChannel(props: {
|
|
1003
|
+
channelId: string;
|
|
1004
|
+
connectorId?: string;
|
|
1005
|
+
sinceSeq?: number;
|
|
1006
|
+
limit?: number;
|
|
1007
|
+
}): ReplayableEvent[];
|
|
1008
|
+
findMaxOffset(): number;
|
|
1009
|
+
close(): void;
|
|
1010
|
+
}
|
|
1011
|
+
//#endregion
|
|
824
1012
|
//#region lib/gateway/gateway-server.d.ts
|
|
825
1013
|
type Deps$3 = {
|
|
826
1014
|
channels: FunnelChannels;
|
|
@@ -830,9 +1018,17 @@ type Deps$3 = {
|
|
|
830
1018
|
process?: FunnelProcessRunner;
|
|
831
1019
|
clock?: FunnelClock;
|
|
832
1020
|
logger?: FunnelLogger;
|
|
833
|
-
selfPid?: number;
|
|
1021
|
+
selfPid?: number; /** Funnel home dir, used to scope kill-competing to daemons rooted at the same dir. Defaults to FUNNEL_DIR. */
|
|
1022
|
+
dir?: string;
|
|
834
1023
|
killCompetingSlack?: boolean; /** Bearer token required for `/listeners*`, `/status`, and `/ws`. Empty string disables auth (tests only). */
|
|
835
1024
|
token?: string;
|
|
1025
|
+
/**
|
|
1026
|
+
* Additional hono app mounted before the built-in gateway routes.
|
|
1027
|
+
* Use to embed host-specific endpoints (e.g. an MCP route, custom `/api/*`).
|
|
1028
|
+
* Host routes are mounted first; built-in `/listeners`, `/status`,
|
|
1029
|
+
* `/channels`, `/health` are mounted after and take precedence on conflict.
|
|
1030
|
+
*/
|
|
1031
|
+
extraRoutes?: Hono<Env$1>;
|
|
836
1032
|
};
|
|
837
1033
|
type WsData = {
|
|
838
1034
|
/** Stable channel id (uuid) the client subscribed to. "" for tap-all clients. */channel: string; /** Resolved channel name (for log readability). null for tap-all or unknown. */
|
|
@@ -860,12 +1056,14 @@ declare class FunnelGatewayServer {
|
|
|
860
1056
|
private readonly process?;
|
|
861
1057
|
private readonly logger;
|
|
862
1058
|
private readonly selfPid;
|
|
1059
|
+
private readonly dir;
|
|
863
1060
|
private readonly killCompetingSlack;
|
|
864
1061
|
private readonly token;
|
|
865
1062
|
private readonly broadcaster;
|
|
866
1063
|
private readonly eventStore;
|
|
867
1064
|
private readonly supervisor;
|
|
868
1065
|
private readonly nowMs;
|
|
1066
|
+
private readonly extraRoutes;
|
|
869
1067
|
private startedAt;
|
|
870
1068
|
private server;
|
|
871
1069
|
constructor(deps: Deps$3);
|
|
@@ -1000,15 +1198,27 @@ declare class FunnelListenersClient {
|
|
|
1000
1198
|
}
|
|
1001
1199
|
//#endregion
|
|
1002
1200
|
//#region lib/funnel.d.ts
|
|
1003
|
-
type Props$
|
|
1201
|
+
type Props$5 = {
|
|
1004
1202
|
/** Settings persistence (channels with nested connectors / profiles). Defaults to a FunnelSettingsStore rooted at `dir`. */store?: FunnelSettingsReader; /** Filesystem boundary. Replace with MemoryFunnelFileSystem to sandbox all disk I/O. */
|
|
1005
1203
|
fs?: FunnelFileSystem; /** Process runner used by gateway / claude / gh listener. Replace with MemoryFunnelProcessRunner for tests. */
|
|
1006
1204
|
process?: FunnelProcessRunner; /** Logger flowed into every facet. Replace with MemoryFunnelLogger or NoopFunnelLogger to silence/inspect. */
|
|
1007
1205
|
logger?: FunnelLogger; /** Clock used by schedule listener, gh poll watermarks, and gateway timeouts. */
|
|
1008
1206
|
clock?: FunnelClock; /** ID generator for channel and connector ids. Use MemoryFunnelIdGenerator for deterministic tests. */
|
|
1009
|
-
idGenerator?: FunnelIdGenerator; /**
|
|
1207
|
+
idGenerator?: FunnelIdGenerator; /** Prompter used by FunnelLocalConfigSync when funnel.json omits a token. Defaults to a TTY-only stdin prompter. */
|
|
1208
|
+
tokenPrompter?: FunnelTokenPrompter; /** Funnel home directory (settings.json + per-channel/per-connector dirs). Defaults to ~/.funnel. */
|
|
1010
1209
|
dir?: string; /** Temp / runtime directory (gateway logs and PID adjacent files). Defaults to /tmp/funnel. */
|
|
1011
1210
|
tmpDir?: string;
|
|
1211
|
+
/**
|
|
1212
|
+
* Host integration hooks for Slack listeners — `onAppCreated` for attaching
|
|
1213
|
+
* Bolt `app.action` handlers, `preprocessEvent` for transforming/dropping
|
|
1214
|
+
* raw Slack events before the built-in processor sees them.
|
|
1215
|
+
*/
|
|
1216
|
+
slackListenerOptions?: SlackListenerOptions;
|
|
1217
|
+
/**
|
|
1218
|
+
* Host integration hooks for Schedule listeners — `onFired` is invoked after
|
|
1219
|
+
* each successful fire, useful for dropping one-shot entries.
|
|
1220
|
+
*/
|
|
1221
|
+
scheduleListenerOptions?: ScheduleListenerOptions;
|
|
1012
1222
|
};
|
|
1013
1223
|
/**
|
|
1014
1224
|
* Facade exposing every funnel facet as a getter.
|
|
@@ -1032,13 +1242,13 @@ type Props$4 = {
|
|
|
1032
1242
|
declare class Funnel {
|
|
1033
1243
|
private readonly props;
|
|
1034
1244
|
private readonly memos;
|
|
1035
|
-
constructor(props?: Props$
|
|
1245
|
+
constructor(props?: Props$5);
|
|
1036
1246
|
/**
|
|
1037
1247
|
* Sandboxed Funnel wired with in-memory implementations for every IO boundary.
|
|
1038
1248
|
* Touches no real disk, processes, wall-clock time, or UUIDs — safe for tests
|
|
1039
1249
|
* and ad-hoc experiments. Override individual fields by passing them in `props`.
|
|
1040
1250
|
*/
|
|
1041
|
-
static inMemory(props?: Props$
|
|
1251
|
+
static inMemory(props?: Props$5): Funnel;
|
|
1042
1252
|
/** Resolved on-disk paths the facade will read/write when methods are called. Pure compute, not memoized. */
|
|
1043
1253
|
get paths(): {
|
|
1044
1254
|
dir: string;
|
|
@@ -1063,6 +1273,14 @@ declare class Funnel {
|
|
|
1063
1273
|
get channels(): FunnelChannels;
|
|
1064
1274
|
/** Launch profiles (named presets for `fnl claude`: path + sub-agent + channel id). */
|
|
1065
1275
|
get profiles(): FunnelProfiles;
|
|
1276
|
+
/** Reads `funnel.json` from a cwd. `fnl claude` consults it before falling back to the default profile. */
|
|
1277
|
+
get localConfig(): FunnelLocalConfig;
|
|
1278
|
+
/** Parses `.env.local` from a cwd (used by sync to back $VAR references). */
|
|
1279
|
+
get dotenv(): FunnelDotenvReader;
|
|
1280
|
+
/** Secret prompter. Defaults to a TTY-only stdin reader; tests inject MemoryFunnelTokenPrompter. */
|
|
1281
|
+
get tokenPrompter(): FunnelTokenPrompter;
|
|
1282
|
+
/** Reconciles funnel.json's channel + connectors with `~/.funnel/settings.json` on launch. */
|
|
1283
|
+
get localConfigSync(): FunnelLocalConfigSync;
|
|
1066
1284
|
/** funnel MCP installer (writes/removes `.mcp.json` entries in target repos). */
|
|
1067
1285
|
get mcp(): FunnelMcp;
|
|
1068
1286
|
/** Launch Claude Code with a channel injected via env, MCP installed, gateway ensured. */
|
|
@@ -1093,6 +1311,13 @@ declare class Funnel {
|
|
|
1093
1311
|
logDir?: string;
|
|
1094
1312
|
killCompetingSlack?: boolean; /** Override the auth token. Defaults to the persisted gateway.token. Pass "" to disable auth (tests). */
|
|
1095
1313
|
token?: string;
|
|
1314
|
+
/**
|
|
1315
|
+
* Additional hono app mounted before the built-in gateway routes.
|
|
1316
|
+
* Use to embed host-specific endpoints (e.g. an MCP route, custom `/api/*`).
|
|
1317
|
+
* Host routes are mounted first; built-in `/listeners`, `/status`,
|
|
1318
|
+
* `/channels`, `/health` are mounted after and take precedence on conflict.
|
|
1319
|
+
*/
|
|
1320
|
+
extraRoutes?: Hono<Env$1>;
|
|
1096
1321
|
}): FunnelGatewayServer;
|
|
1097
1322
|
}
|
|
1098
1323
|
//#endregion
|
|
@@ -1105,6 +1330,15 @@ type ChannelServerOptions = {
|
|
|
1105
1330
|
};
|
|
1106
1331
|
declare const startChannelServer: (options?: ChannelServerOptions) => Promise<void>;
|
|
1107
1332
|
//#endregion
|
|
1333
|
+
//#region lib/engine/local-config/local-config-json-schema.d.ts
|
|
1334
|
+
/**
|
|
1335
|
+
* Generates the JSON Schema (draft 2020-12) for `funnel.json`. Useful for
|
|
1336
|
+
* `$schema` references in committed `funnel.json` files so editors can give
|
|
1337
|
+
* autocomplete and validation for channel / subAgent / env / connectors[]
|
|
1338
|
+
* without anyone hand-maintaining a separate schema.
|
|
1339
|
+
*/
|
|
1340
|
+
declare const funnelJsonSchema: () => Record<string, unknown>;
|
|
1341
|
+
//#endregion
|
|
1108
1342
|
//#region lib/engine/settings/settings-store.d.ts
|
|
1109
1343
|
declare const FUNNEL_DIR: string;
|
|
1110
1344
|
declare const SETTINGS_PATH: string;
|
|
@@ -1147,7 +1381,7 @@ declare class NodeFunnelFileSystem extends FunnelFileSystem {
|
|
|
1147
1381
|
}
|
|
1148
1382
|
//#endregion
|
|
1149
1383
|
//#region lib/engine/fs/memory-file-system.d.ts
|
|
1150
|
-
type Props$
|
|
1384
|
+
type Props$4 = {
|
|
1151
1385
|
dirs?: string[];
|
|
1152
1386
|
files?: Record<string, string>;
|
|
1153
1387
|
mtimes?: Record<string, number>;
|
|
@@ -1160,7 +1394,7 @@ declare class MemoryFunnelFileSystem extends FunnelFileSystem {
|
|
|
1160
1394
|
private readonly mtimes;
|
|
1161
1395
|
private readonly modes;
|
|
1162
1396
|
private readonly now;
|
|
1163
|
-
constructor(props?: Props$
|
|
1397
|
+
constructor(props?: Props$4);
|
|
1164
1398
|
existsSync(path: string): boolean;
|
|
1165
1399
|
readFileSync(path: string): string;
|
|
1166
1400
|
writeFileSync(path: string, data: string): void;
|
|
@@ -1232,14 +1466,14 @@ declare class MemoryFunnelProcessRunner extends FunnelProcessRunner {
|
|
|
1232
1466
|
}
|
|
1233
1467
|
//#endregion
|
|
1234
1468
|
//#region lib/engine/logger/node-logger.d.ts
|
|
1235
|
-
type Props$
|
|
1469
|
+
type Props$3 = {
|
|
1236
1470
|
file?: string;
|
|
1237
1471
|
now?: () => Date;
|
|
1238
1472
|
};
|
|
1239
1473
|
declare class NodeFunnelLogger extends FunnelLogger {
|
|
1240
1474
|
readonly file: string;
|
|
1241
1475
|
private readonly now;
|
|
1242
|
-
constructor(props?: Props$
|
|
1476
|
+
constructor(props?: Props$3);
|
|
1243
1477
|
info(message: string, meta?: Record<string, unknown>): void;
|
|
1244
1478
|
warn(message: string, meta?: Record<string, unknown>): void;
|
|
1245
1479
|
error(message: string, meta?: Record<string, unknown>): void;
|
|
@@ -1275,12 +1509,12 @@ declare class NodeFunnelClock extends FunnelClock {
|
|
|
1275
1509
|
}
|
|
1276
1510
|
//#endregion
|
|
1277
1511
|
//#region lib/engine/time/memory-clock.d.ts
|
|
1278
|
-
type Props$
|
|
1512
|
+
type Props$2 = {
|
|
1279
1513
|
start?: Date;
|
|
1280
1514
|
};
|
|
1281
1515
|
declare class MemoryFunnelClock extends FunnelClock {
|
|
1282
1516
|
private current;
|
|
1283
|
-
constructor(props?: Props$
|
|
1517
|
+
constructor(props?: Props$2);
|
|
1284
1518
|
now(): Date;
|
|
1285
1519
|
set(date: Date): void;
|
|
1286
1520
|
advance(ms: number): void;
|
|
@@ -1292,16 +1526,43 @@ declare class NodeFunnelIdGenerator extends FunnelIdGenerator {
|
|
|
1292
1526
|
}
|
|
1293
1527
|
//#endregion
|
|
1294
1528
|
//#region lib/engine/id/memory-id-generator.d.ts
|
|
1295
|
-
type Props = {
|
|
1529
|
+
type Props$1 = {
|
|
1296
1530
|
prefix?: string;
|
|
1297
1531
|
};
|
|
1298
1532
|
declare class MemoryFunnelIdGenerator extends FunnelIdGenerator {
|
|
1299
1533
|
private counter;
|
|
1300
1534
|
private readonly prefix;
|
|
1301
|
-
constructor(props?: Props);
|
|
1535
|
+
constructor(props?: Props$1);
|
|
1302
1536
|
generate(): string;
|
|
1303
1537
|
}
|
|
1304
1538
|
//#endregion
|
|
1539
|
+
//#region lib/engine/token-prompter/node-token-prompter.d.ts
|
|
1540
|
+
/**
|
|
1541
|
+
* Reads a secret from stdin in raw mode. Echoes a `*` per byte so the user
|
|
1542
|
+
* can see progress without exposing the token. Refuses to prompt when stdin
|
|
1543
|
+
* is not a TTY — callers should surface the resulting error with a hint
|
|
1544
|
+
* pointing at the corresponding env var or CLI command.
|
|
1545
|
+
*/
|
|
1546
|
+
declare class NodeFunnelTokenPrompter extends FunnelTokenPrompter {
|
|
1547
|
+
promptSecret(label: string): Promise<string>;
|
|
1548
|
+
private readSecret;
|
|
1549
|
+
}
|
|
1550
|
+
//#endregion
|
|
1551
|
+
//#region lib/engine/token-prompter/memory-token-prompter.d.ts
|
|
1552
|
+
type Props = {
|
|
1553
|
+
answers?: Record<string, string>;
|
|
1554
|
+
};
|
|
1555
|
+
/**
|
|
1556
|
+
* Pre-seeded answers keyed by prompt label. Tests configure the map up front;
|
|
1557
|
+
* unmapped labels throw so the test surfaces unexpected prompts loudly.
|
|
1558
|
+
*/
|
|
1559
|
+
declare class MemoryFunnelTokenPrompter extends FunnelTokenPrompter {
|
|
1560
|
+
private readonly answers;
|
|
1561
|
+
readonly asked: string[];
|
|
1562
|
+
constructor(props?: Props);
|
|
1563
|
+
promptSecret(label: string): Promise<string>;
|
|
1564
|
+
}
|
|
1565
|
+
//#endregion
|
|
1305
1566
|
//#region lib/cli/factory.d.ts
|
|
1306
1567
|
type Env = {
|
|
1307
1568
|
Variables: {
|
|
@@ -1352,7 +1613,7 @@ declare const createCliApp: (funnel: Funnel) => _$hono_hono_base0.HonoBase<Env,
|
|
|
1352
1613
|
channel?: string | undefined;
|
|
1353
1614
|
};
|
|
1354
1615
|
};
|
|
1355
|
-
output: "funnel claude — launch Claude Code\n\nusage:\n funnel claude launch
|
|
1616
|
+
output: "funnel claude — launch Claude Code\n\nusage:\n funnel claude launch using funnel.json in cwd, or the default profile\n funnel claude -p <name> launch a named profile\n funnel claude --profile <name> (long form)\n funnel claude --channel <name> raw launch (no profile, cwd = current dir)\n funnel claude [...] any other argument is forwarded to the claude CLI\n\nresolution order when no --profile / --channel is given:\n 1. ./funnel.json in the current directory\n 2. the default profile (first entry in fnl profiles)\n\nfunnel-specific options (everything else passes through to claude verbatim):\n -p, --profile profile name to launch\n --channel channel name (raw launch, ignored when --profile is given)\n -h, --help show this help\n\nPositional args, unknown short flags (e.g. -c, -r), and claude's own flags\n(--agent, --resume, --model, --print, --output-format ...) are all forwarded.\nOn launch the FUNNEL_CHANNEL_ID env var is set and MCP connects to the gateway.";
|
|
1356
1617
|
outputFormat: "text";
|
|
1357
1618
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
1358
1619
|
};
|
|
@@ -2572,6 +2833,25 @@ ${string}`;
|
|
|
2572
2833
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2573
2834
|
};
|
|
2574
2835
|
};
|
|
2836
|
+
} & {
|
|
2837
|
+
"/schema": {
|
|
2838
|
+
$get: {
|
|
2839
|
+
input: {
|
|
2840
|
+
query: Record<string, never>;
|
|
2841
|
+
};
|
|
2842
|
+
output: string;
|
|
2843
|
+
outputFormat: "text";
|
|
2844
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2845
|
+
} | {
|
|
2846
|
+
input: {
|
|
2847
|
+
query: Record<string, never>;
|
|
2848
|
+
};
|
|
2849
|
+
output: `${string}
|
|
2850
|
+
`;
|
|
2851
|
+
outputFormat: "text";
|
|
2852
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2853
|
+
};
|
|
2854
|
+
};
|
|
2575
2855
|
} & {
|
|
2576
2856
|
"/status": {
|
|
2577
2857
|
$get: {
|
|
@@ -2624,7 +2904,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
2624
2904
|
channel?: string | undefined;
|
|
2625
2905
|
};
|
|
2626
2906
|
};
|
|
2627
|
-
output: "funnel claude — launch Claude Code\n\nusage:\n funnel claude launch
|
|
2907
|
+
output: "funnel claude — launch Claude Code\n\nusage:\n funnel claude launch using funnel.json in cwd, or the default profile\n funnel claude -p <name> launch a named profile\n funnel claude --profile <name> (long form)\n funnel claude --channel <name> raw launch (no profile, cwd = current dir)\n funnel claude [...] any other argument is forwarded to the claude CLI\n\nresolution order when no --profile / --channel is given:\n 1. ./funnel.json in the current directory\n 2. the default profile (first entry in fnl profiles)\n\nfunnel-specific options (everything else passes through to claude verbatim):\n -p, --profile profile name to launch\n --channel channel name (raw launch, ignored when --profile is given)\n -h, --help show this help\n\nPositional args, unknown short flags (e.g. -c, -r), and claude's own flags\n(--agent, --resume, --model, --print, --output-format ...) are all forwarded.\nOn launch the FUNNEL_CHANNEL_ID env var is set and MCP connects to the gateway.";
|
|
2628
2908
|
outputFormat: "text";
|
|
2629
2909
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2630
2910
|
};
|
|
@@ -3844,6 +4124,25 @@ ${string}`;
|
|
|
3844
4124
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3845
4125
|
};
|
|
3846
4126
|
};
|
|
4127
|
+
} & {
|
|
4128
|
+
"/schema": {
|
|
4129
|
+
$get: {
|
|
4130
|
+
input: {
|
|
4131
|
+
query: Record<string, never>;
|
|
4132
|
+
};
|
|
4133
|
+
output: string;
|
|
4134
|
+
outputFormat: "text";
|
|
4135
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4136
|
+
} | {
|
|
4137
|
+
input: {
|
|
4138
|
+
query: Record<string, never>;
|
|
4139
|
+
};
|
|
4140
|
+
output: `${string}
|
|
4141
|
+
`;
|
|
4142
|
+
outputFormat: "text";
|
|
4143
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4144
|
+
};
|
|
4145
|
+
};
|
|
3847
4146
|
} & {
|
|
3848
4147
|
"/status": {
|
|
3849
4148
|
$get: {
|
|
@@ -3878,4 +4177,4 @@ ${string}`;
|
|
|
3878
4177
|
//#region lib/tui/tui.d.ts
|
|
3879
4178
|
declare function launchTui(funnel: Funnel): Promise<void>;
|
|
3880
4179
|
//#endregion
|
|
3881
|
-
export { AttachOptions, BroadcastEvent, BroadcastSubscriber, ChannelConfig, ChannelConnectorView, ChannelDeliveryMode, ChannelServerOptions, ConnectorConfig, ConnectorType, DEFAULT_GATEWAY_TOKEN_PATH, DetachOptions, DiscordConnectorConfig, Env, FUNNEL_DIR, FUNNEL_MCP_COMMAND, FUNNEL_MCP_NAME, FileStat, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClaude, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelEvent, FunnelEventStore, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLogger, FunnelMcp, FunnelProcessRunner, FunnelProfiles, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, GhConnectorConfig, LaunchOptions, ListListenersResult, ListenerEntry, ListenerOpResult, LogEntry, MemoryFunnelClock, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryProcessCall, MemoryProcessHandler, MemoryProcessResponse, MemoryProcessSyncHandler, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NoopFunnelLogger, NotifyFn, ProfileConfig, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, RunOptions, RunResult, SETTINGS_PATH, SETTINGS_VERSION, ScheduleCatchupPolicy, ScheduleConnectorConfig, ScheduleEntry, Settings, SlackConnectorConfig, SlackProcessed, SlackProcessedEmit, SlackProcessedSkip, SlackRawEvent, channelConfigSchema, channelDeliveryModeSchema, app as cliApp, connectorConfigSchema, createCliApp, createSettings, discordConnectorSchema, factory, funnelEventSchema, ghConnectorSchema, launchTui, profileConfigSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, startChannelServer, toRequest };
|
|
4180
|
+
export { AttachOptions, BroadcastEvent, BroadcastSubscriber, ChannelConfig, ChannelConnectorView, ChannelDeliveryMode, ChannelServerOptions, ConnectorConfig, ConnectorSpec, ConnectorType, DEFAULT_GATEWAY_TOKEN_PATH, DetachOptions, DiscordConnectorConfig, Env, FUNNEL_DIR, FUNNEL_MCP_COMMAND, FUNNEL_MCP_NAME, FileStat, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClaude, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelDotenvReader, FunnelEvent, FunnelEventStore, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLocalConfig, FunnelLocalConfigSync, FunnelLogger, FunnelMcp, FunnelProcessRunner, FunnelProfiles, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, FunnelTokenPrompter, GhConnectorConfig, LOCAL_CONFIG_FILENAME, LOCAL_ENV_FILENAME, LaunchOptions, ListListenersResult, ListenerEntry, ListenerOpResult, LocalConfig, LogEntry, MemoryFunnelClock, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryFunnelTokenPrompter, MemoryProcessCall, MemoryProcessHandler, MemoryProcessResponse, MemoryProcessSyncHandler, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NodeFunnelTokenPrompter, NoopFunnelLogger, NotifyFn, ProfileConfig, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, RunOptions, RunResult, SETTINGS_PATH, SETTINGS_VERSION, ScheduleCatchupPolicy, ScheduleConnectorConfig, ScheduleEntry, ScheduleListenerOptions, Settings, SlackConnectorConfig, SlackListenerOptions, SlackProcessed, SlackProcessedEmit, SlackProcessedSkip, SlackRawEvent, 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 };
|