@interactive-inc/claude-funnel 0.36.0 → 0.38.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/README.md +244 -322
- package/dist/bin.js +554 -509
- package/dist/gateway/daemon.js +275 -237
- package/dist/index.d.ts +1904 -2308
- package/dist/index.js +1698 -312
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -4,11 +4,13 @@ import { S as NotifyFn, _ as connectorConnectionEventSchema, a as ConnectorConne
|
|
|
4
4
|
import { a as FunnelProcessRunner, c as RunResult, i as DetachOptions, n as ghConnectorSchema, o as ProcessSnapshot, r as AttachOptions, s as RunOptions, t as GhConnectorConfig } from "./gh-connector-schema-CQmEWzdV.js";
|
|
5
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-3M6WkH1Y.js";
|
|
6
6
|
import { a as SlackProcessed, c as SlackRawEvent, d as slackConnectorSchema, i as FunnelSlackEventProcessor, l as SlackSkipReason, n as SlackOnAppCreated, o as SlackProcessedEmit, r as SlackPreprocessEvent, s as SlackProcessedSkip, u as SlackConnectorConfig } from "./slack-listener-9UdAn_ui.js";
|
|
7
|
+
import { hc } from "hono/client";
|
|
7
8
|
import { z } from "zod";
|
|
8
9
|
import * as _$hono_factory0 from "hono/factory";
|
|
9
10
|
import { Hono } from "hono";
|
|
10
11
|
import { Server, ServerWebSocket } from "bun";
|
|
11
12
|
import * as _$hono_utils_http_status0 from "hono/utils/http-status";
|
|
13
|
+
import * as _$hono_utils_types0 from "hono/utils/types";
|
|
12
14
|
import * as _$hono_hono_base0 from "hono/hono-base";
|
|
13
15
|
|
|
14
16
|
//#region lib/connectors/connector-config-schema.d.ts
|
|
@@ -386,696 +388,1014 @@ declare class FunnelChannels {
|
|
|
386
388
|
private assertNoTokenCollision;
|
|
387
389
|
}
|
|
388
390
|
//#endregion
|
|
389
|
-
//#region lib/engine/
|
|
390
|
-
type GatewayController = {
|
|
391
|
-
isRunning(): boolean;
|
|
392
|
-
start(options?: {
|
|
393
|
-
caffeinate?: boolean;
|
|
394
|
-
}): Promise<boolean>;
|
|
395
|
-
};
|
|
396
|
-
//#endregion
|
|
397
|
-
//#region lib/engine/mcp/mcp.d.ts
|
|
398
|
-
declare const FUNNEL_MCP_COMMAND = "bun";
|
|
399
|
-
declare const FUNNEL_MCP_ARGS: string[];
|
|
400
|
-
declare const FUNNEL_MCP_NAME = "funnel";
|
|
401
|
-
type Deps$13 = {
|
|
402
|
-
fs?: FunnelFileSystem;
|
|
403
|
-
};
|
|
391
|
+
//#region lib/engine/error/on-funnel-error.d.ts
|
|
404
392
|
/**
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
393
|
+
* Host integration hook called when Funnel catches an exception that would
|
|
394
|
+
* otherwise be silently swallowed (subscriber throw, listener start failure,
|
|
395
|
+
* MCP forward failure, etc.). Pass `Sentry.captureException` from the host to
|
|
396
|
+
* pipe these into your error reporter. Defaults to a no-op when omitted.
|
|
397
|
+
*
|
|
398
|
+
* `context` carries the component name and any extra metadata the caller had
|
|
399
|
+
* at the catch site (channel / connector / subscriber id when available).
|
|
408
400
|
*/
|
|
409
|
-
|
|
410
|
-
private readonly fs;
|
|
411
|
-
constructor(deps?: Deps$13);
|
|
412
|
-
install(repoPath: string): void;
|
|
413
|
-
uninstall(repoPath: string): void;
|
|
414
|
-
findInstalledName(cwd: string): string | null;
|
|
415
|
-
private findServerName;
|
|
416
|
-
private isFunnelEntry;
|
|
417
|
-
private readConfig;
|
|
418
|
-
private writeConfig;
|
|
419
|
-
}
|
|
401
|
+
type OnFunnelError = (error: Error, context?: Record<string, unknown>) => void;
|
|
420
402
|
//#endregion
|
|
421
|
-
//#region lib/
|
|
422
|
-
type
|
|
423
|
-
|
|
424
|
-
|
|
403
|
+
//#region lib/gateway/broadcaster.d.ts
|
|
404
|
+
type ClientData = {
|
|
405
|
+
/** Stable channel id (uuid) that the WS client subscribed to. */channel: string; /** Human-facing channel name resolved at upgrade time, kept for log readability. */
|
|
406
|
+
channelName?: string | null; /** Connector names belonging to that channel; used by tap-all replay filtering. */
|
|
407
|
+
connectors: string[];
|
|
408
|
+
tapAll?: boolean; /** Routing mode resolved from channel config at upgrade time. Defaults to fanout. */
|
|
409
|
+
delivery?: "fanout" | "exclusive";
|
|
410
|
+
};
|
|
411
|
+
type BroadcastEvent = {
|
|
412
|
+
content: string;
|
|
413
|
+
meta?: Record<string, string>;
|
|
414
|
+
};
|
|
415
|
+
type ReplayableEvent = BroadcastEvent & {
|
|
416
|
+
offset: number;
|
|
425
417
|
};
|
|
418
|
+
type BroadcastSubscriber = (event: ReplayableEvent) => void;
|
|
426
419
|
/**
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
* so FunnelChannels can refuse to remove a channel that is still referenced.
|
|
432
|
-
*
|
|
433
|
-
* Each profile has a stable `id` (uuid) minted at `add`. That id is the unit
|
|
434
|
-
* everything internal keys on — the PID file, the resumable session id — so a
|
|
435
|
-
* rename never strands either. `name` is purely the CLI/TUI handle; the CRUD
|
|
436
|
-
* methods here take it because that is what the user types, but resolve to the
|
|
437
|
-
* id before touching id-keyed state. The first array entry is the default
|
|
438
|
-
* profile; `asDefault` reorders to put one first.
|
|
439
|
-
*
|
|
440
|
-
* `channelId` always stores the channel's stable id (uuid). CLI surfaces
|
|
441
|
-
* resolve channel name → id before calling `add`/`update` here.
|
|
420
|
+
* Optional persistent replay source. Wired in by the gateway-server with a
|
|
421
|
+
* `FunnelEventLog` (SQLite-backed by default) so reconnects across daemon
|
|
422
|
+
* restarts can recover events older than the in-memory buffer via an indexed
|
|
423
|
+
* `seq > since` range scan.
|
|
442
424
|
*/
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
private readonly idGenerator;
|
|
446
|
-
constructor(deps: Deps$12);
|
|
447
|
-
list(): ProfileConfig[];
|
|
448
|
-
get(name: string): ProfileConfig | null;
|
|
449
|
-
getById(id: string): ProfileConfig | null;
|
|
450
|
-
getDefault(): ProfileConfig | null;
|
|
451
|
-
add(input: {
|
|
452
|
-
name: string;
|
|
453
|
-
path: string;
|
|
454
|
-
channelId: string;
|
|
455
|
-
options?: string[];
|
|
456
|
-
env?: Record<string, string>;
|
|
457
|
-
resume?: boolean;
|
|
458
|
-
}): void;
|
|
459
|
-
remove(name: string): void;
|
|
460
|
-
rename(oldName: string, newName: string): void;
|
|
461
|
-
asDefault(name: string): void;
|
|
462
|
-
hasChannelRef(channelId: string): boolean;
|
|
463
|
-
/** Resumable claude session id last launched by this profile (by id), or null. */
|
|
464
|
-
getSessionId(id: string): string | null;
|
|
465
|
-
/** Records the claude session id this profile launched, overwriting any prior one. */
|
|
466
|
-
setSessionId(id: string, sessionId: string): void;
|
|
467
|
-
update(name: string, fields: Partial<Omit<ProfileConfig, "name">>): void;
|
|
468
|
-
}
|
|
469
|
-
//#endregion
|
|
470
|
-
//#region lib/engine/claude/claude.d.ts
|
|
471
|
-
type LaunchOptions = {
|
|
472
|
-
channel: string;
|
|
473
|
-
cwd?: string;
|
|
474
|
-
userArgs?: string[];
|
|
475
|
-
/** Stable id of the launching profile (uuid). Keys the singleton PID file and
|
|
476
|
-
* the resumable session. Absent for a profile-less launch (raw `--channel`),
|
|
477
|
-
* which never enforces singleton-ness and never resumes. */
|
|
478
|
-
profileId?: string; /** Args prepended to the claude argv (typically a profile's recipe). Defaults to none. */
|
|
479
|
-
options?: string[]; /** Env vars layered under the launched claude process. process.env wins on collision. */
|
|
480
|
-
env?: Record<string, string>;
|
|
481
|
-
/** Whether to inject a `--session-id`/`--resume` for this profile.
|
|
482
|
-
* Defaults to false: resuming is opt-in and only meaningful for a profile,
|
|
483
|
-
* since the persisted session is owned by the profile (by id). A launch
|
|
484
|
-
* without a profile always starts a fresh session regardless of this flag. */
|
|
485
|
-
resume?: boolean;
|
|
486
|
-
/** Invoked synchronously after the child claude process has been spawned, with its PID.
|
|
487
|
-
* Useful for hosts that need to register the spawned process before it exits
|
|
488
|
-
* (e.g. multi-session registries that track per-claude liveness). */
|
|
489
|
-
onSpawned?: (pid: number) => void;
|
|
490
|
-
/** Whether to install the funnel MCP entry into `.mcp.json` (default: true).
|
|
491
|
-
* Set to false when the host already provides its own MCP server entry and
|
|
492
|
-
* does not need the funnel binary as an MCP endpoint. */
|
|
493
|
-
installMcp?: boolean;
|
|
425
|
+
type ReplaySource = {
|
|
426
|
+
loadSince(since: number): ReplayableEvent[];
|
|
494
427
|
};
|
|
495
|
-
type Deps$
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
428
|
+
type Deps$13 = {
|
|
429
|
+
logger?: FunnelLogger; /** Host hook for surfacing subscriber-throw exceptions. Defaults to no-op. */
|
|
430
|
+
onError?: OnFunnelError;
|
|
431
|
+
maxBufferedBytes?: number;
|
|
432
|
+
now?: () => number; /** Number of recent events kept in the in-memory replay buffer. */
|
|
433
|
+
replayBufferSize?: number; /** Hard byte cap on replay buffer payloads. Older events are evicted FIFO until under this cap. */
|
|
434
|
+
replayBufferMaxBytes?: number; /** Persistent replay source consulted when the in-memory buffer cannot satisfy `since`. */
|
|
435
|
+
persistentReplay?: ReplaySource;
|
|
436
|
+
};
|
|
437
|
+
type BroadcasterMetrics = {
|
|
438
|
+
clients: number;
|
|
439
|
+
subscribers: number;
|
|
440
|
+
eventsBroadcast: number;
|
|
441
|
+
droppedSlowClients: number;
|
|
442
|
+
lastBroadcastAt: string | null; /** Latest emitted offset. Clients can `?since=<offset>` to ask for events strictly after this point. */
|
|
443
|
+
latestOffset: number; /** Oldest offset still held in the replay buffer. Older values cannot be replayed and trigger a full resync. */
|
|
444
|
+
oldestReplayableOffset: number | null;
|
|
505
445
|
};
|
|
506
446
|
/**
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
447
|
+
* In-process pub/sub for connector events.
|
|
448
|
+
*
|
|
449
|
+
* Two outbound paths:
|
|
450
|
+
* - WS clients connected via the gateway's `/ws` endpoint, scoped per channel
|
|
451
|
+
* - In-process subscribers registered via `subscribe()` (programmable API)
|
|
452
|
+
*
|
|
453
|
+
* Backpressure: if a WS client's `bufferedAmount` exceeds `maxBufferedBytes`
|
|
454
|
+
* (default 1 MiB), the client is closed with code 1009 and dropped from the
|
|
455
|
+
* registry to keep one slow consumer from blocking the daemon.
|
|
456
|
+
*
|
|
457
|
+
* Replay: every emitted event gets a strictly increasing `offset`. The latest
|
|
458
|
+
* `replayBufferSize` events are kept in memory; reconnecting WS clients can
|
|
459
|
+
* pass `?since=<offset>` and the broadcaster resends matching events before
|
|
460
|
+
* resuming the live stream. The in-memory ring covers short reconnects;
|
|
461
|
+
* older history is served from the event log wired in as `persistentReplay`.
|
|
511
462
|
*/
|
|
512
|
-
declare class
|
|
513
|
-
private readonly
|
|
514
|
-
private readonly
|
|
515
|
-
private readonly gateway;
|
|
516
|
-
private readonly profiles;
|
|
517
|
-
private readonly process;
|
|
518
|
-
private readonly fs;
|
|
519
|
-
private readonly idGenerator;
|
|
463
|
+
declare class FunnelBroadcaster {
|
|
464
|
+
private readonly clients;
|
|
465
|
+
private readonly subscribers;
|
|
520
466
|
private readonly logger;
|
|
521
|
-
private readonly
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
private
|
|
526
|
-
private
|
|
527
|
-
private
|
|
528
|
-
private
|
|
529
|
-
private
|
|
530
|
-
private
|
|
531
|
-
private
|
|
467
|
+
private readonly onError;
|
|
468
|
+
private readonly maxBufferedBytes;
|
|
469
|
+
private readonly now;
|
|
470
|
+
private readonly replayBufferSize;
|
|
471
|
+
private readonly replayBufferMaxBytes;
|
|
472
|
+
private readonly replayBuffer;
|
|
473
|
+
private readonly persistentReplay;
|
|
474
|
+
private readonly exclusiveCursor;
|
|
475
|
+
private replayBufferBytes;
|
|
476
|
+
private eventsBroadcast;
|
|
477
|
+
private droppedSlowClients;
|
|
478
|
+
private lastBroadcastAt;
|
|
479
|
+
private latestOffset;
|
|
480
|
+
constructor(deps?: Deps$13);
|
|
481
|
+
getMetrics(): BroadcasterMetrics;
|
|
532
482
|
/**
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
* session-shaping flag, since combining them would either confuse claude
|
|
536
|
-
* or override the explicit user intent.
|
|
483
|
+
* Returns events with offset > since, filtered by the connector subscription
|
|
484
|
+
* rules of `data`. Used at WS upgrade time when the client passes `?since=<offset>`.
|
|
537
485
|
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
486
|
+
* Two-tier lookup:
|
|
487
|
+
* 1. The in-memory ring buffer (covers short reconnects, last `replayBufferSize` events).
|
|
488
|
+
* 2. If `since` predates the oldest in-memory entry and a persistent replay source
|
|
489
|
+
* is wired in (SQLite by default), the gap is filled from it. This covers reconnects
|
|
490
|
+
* across daemon restarts where the in-memory buffer was lost.
|
|
543
491
|
*
|
|
544
|
-
*
|
|
545
|
-
* disk. claude errors out on `--resume <id>` for a missing conversation, and
|
|
546
|
-
* a persisted id can outlive its jsonl (claude pruned it, or the very first
|
|
547
|
-
* launch was aborted after the id was written but before the jsonl
|
|
548
|
-
* appeared). When the file is gone we mint a fresh session instead, which
|
|
549
|
-
* overwrites the dangling entry — so the store self-heals.
|
|
492
|
+
* Result is sorted ascending by offset and de-duplicated against the in-memory buffer.
|
|
550
493
|
*/
|
|
551
|
-
|
|
494
|
+
replaySince(since: number, data: ClientData): ReplayableEvent[];
|
|
495
|
+
private matchesClient;
|
|
552
496
|
/**
|
|
553
|
-
*
|
|
554
|
-
* (
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
* wrong guess can only ever produce a false negative (start fresh), never a
|
|
558
|
-
* bad resume.
|
|
497
|
+
* Returns the list of WS clients that should receive `event`. Tap=all clients always
|
|
498
|
+
* receive (passive observation). For each per-channel group:
|
|
499
|
+
* - fanout → every matching client receives
|
|
500
|
+
* - exclusive → exactly one client receives, picked round-robin per channel
|
|
559
501
|
*/
|
|
560
|
-
private
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
* at the catch site (channel / connector / subscriber id when available).
|
|
573
|
-
*/
|
|
574
|
-
type OnFunnelError = (error: Error, context?: Record<string, unknown>) => void;
|
|
575
|
-
//#endregion
|
|
576
|
-
//#region lib/engine/local-config/local-config-schema.d.ts
|
|
577
|
-
declare const connectorSpecSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
578
|
-
type: z.ZodLiteral<"slack">;
|
|
579
|
-
name: z.ZodString;
|
|
580
|
-
minify: z.ZodOptional<z.ZodBoolean>;
|
|
581
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
582
|
-
type: z.ZodLiteral<"discord">;
|
|
583
|
-
name: z.ZodString;
|
|
584
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
585
|
-
type: z.ZodLiteral<"gh">;
|
|
586
|
-
name: z.ZodString;
|
|
587
|
-
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
588
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
589
|
-
type: z.ZodLiteral<"schedule">;
|
|
590
|
-
name: z.ZodString;
|
|
591
|
-
}, z.core.$strip>], "type">;
|
|
592
|
-
type ConnectorSpec = z.infer<typeof connectorSpecSchema>;
|
|
593
|
-
declare const channelSpecSchema: z.ZodObject<{
|
|
594
|
-
name: z.ZodString;
|
|
595
|
-
connectors: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
596
|
-
type: z.ZodLiteral<"slack">;
|
|
597
|
-
name: z.ZodString;
|
|
598
|
-
minify: z.ZodOptional<z.ZodBoolean>;
|
|
599
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
600
|
-
type: z.ZodLiteral<"discord">;
|
|
601
|
-
name: z.ZodString;
|
|
602
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
603
|
-
type: z.ZodLiteral<"gh">;
|
|
604
|
-
name: z.ZodString;
|
|
605
|
-
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
606
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
607
|
-
type: z.ZodLiteral<"schedule">;
|
|
608
|
-
name: z.ZodString;
|
|
609
|
-
}, z.core.$strip>], "type">>>;
|
|
610
|
-
}, z.core.$strip>;
|
|
611
|
-
type ChannelSpec = z.infer<typeof channelSpecSchema>;
|
|
612
|
-
declare const profileSpecSchema: z.ZodObject<{
|
|
613
|
-
name: z.ZodString;
|
|
614
|
-
channel: z.ZodString;
|
|
615
|
-
options: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
616
|
-
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
617
|
-
resume: z.ZodOptional<z.ZodBoolean>;
|
|
618
|
-
}, z.core.$strip>;
|
|
619
|
-
type ProfileSpec = z.infer<typeof profileSpecSchema>;
|
|
620
|
-
declare const localConfigSchema: z.ZodObject<{
|
|
621
|
-
$schema: z.ZodOptional<z.ZodString>;
|
|
622
|
-
id: z.ZodOptional<z.ZodString>;
|
|
623
|
-
channels: z.ZodArray<z.ZodObject<{
|
|
624
|
-
name: z.ZodString;
|
|
625
|
-
connectors: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
626
|
-
type: z.ZodLiteral<"slack">;
|
|
627
|
-
name: z.ZodString;
|
|
628
|
-
minify: z.ZodOptional<z.ZodBoolean>;
|
|
629
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
630
|
-
type: z.ZodLiteral<"discord">;
|
|
631
|
-
name: z.ZodString;
|
|
632
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
633
|
-
type: z.ZodLiteral<"gh">;
|
|
634
|
-
name: z.ZodString;
|
|
635
|
-
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
636
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
637
|
-
type: z.ZodLiteral<"schedule">;
|
|
638
|
-
name: z.ZodString;
|
|
639
|
-
}, z.core.$strip>], "type">>>;
|
|
640
|
-
}, z.core.$strip>>;
|
|
641
|
-
profiles: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
642
|
-
name: z.ZodString;
|
|
643
|
-
channel: z.ZodString;
|
|
644
|
-
options: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
645
|
-
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
646
|
-
resume: z.ZodOptional<z.ZodBoolean>;
|
|
647
|
-
}, z.core.$strip>>>;
|
|
648
|
-
}, z.core.$strip>;
|
|
649
|
-
type LocalConfig = z.infer<typeof localConfigSchema>;
|
|
650
|
-
declare const LOCAL_CONFIG_FILENAME = "funnel.json";
|
|
651
|
-
//#endregion
|
|
652
|
-
//#region lib/engine/local-config/local-config.d.ts
|
|
653
|
-
type Deps$10 = {
|
|
654
|
-
fs: FunnelFileSystem;
|
|
655
|
-
};
|
|
656
|
-
/**
|
|
657
|
-
* Reads `funnel.json` from a directory. Returns `null` when the file is
|
|
658
|
-
* absent so callers can fall through to other resolution paths (default
|
|
659
|
-
* profile, help). Throws on present-but-invalid files so misconfiguration
|
|
660
|
-
* surfaces loudly instead of silently launching the wrong channel.
|
|
661
|
-
*/
|
|
662
|
-
declare class FunnelLocalConfig {
|
|
663
|
-
private readonly fs;
|
|
664
|
-
constructor(deps: Deps$10);
|
|
665
|
-
read(cwd: string): LocalConfig | null;
|
|
666
|
-
private assertProfilesValid;
|
|
667
|
-
}
|
|
668
|
-
//#endregion
|
|
669
|
-
//#region lib/engine/token-prompter/token-prompter.d.ts
|
|
670
|
-
/**
|
|
671
|
-
* Asks the user for a secret value on stdin. Used as a last resort when a
|
|
672
|
-
* funnel.json token field is absent and not present in `~/.funnel`. The Node
|
|
673
|
-
* implementation refuses to prompt when stdin is not a TTY so non-interactive
|
|
674
|
-
* launches (CI, agent spawning agent, daemons) fail fast instead of hanging.
|
|
675
|
-
*/
|
|
676
|
-
declare abstract class FunnelTokenPrompter {
|
|
677
|
-
abstract promptSecret(label: string): Promise<string>;
|
|
502
|
+
private pickRecipients;
|
|
503
|
+
addClient(ws: ServerWebSocket<unknown>, data: ClientData): void;
|
|
504
|
+
removeClient(ws: ServerWebSocket<unknown>): void;
|
|
505
|
+
getClientCount(): number;
|
|
506
|
+
listChannels(): {
|
|
507
|
+
channel: string;
|
|
508
|
+
connectors: string[];
|
|
509
|
+
}[];
|
|
510
|
+
subscribe(handler: BroadcastSubscriber): () => void;
|
|
511
|
+
broadcast(content: string, meta?: Record<string, string>): ReplayableEvent;
|
|
512
|
+
/** Forward-seed the offset counter (used at startup from the persisted event store). */
|
|
513
|
+
seedLatestOffset(offset: number): void;
|
|
678
514
|
}
|
|
679
515
|
//#endregion
|
|
680
|
-
//#region lib/
|
|
681
|
-
type
|
|
682
|
-
|
|
683
|
-
|
|
516
|
+
//#region lib/gateway/listener-supervisor.d.ts
|
|
517
|
+
type ConnectorRegistry = {
|
|
518
|
+
listAllConnectors(): ChannelConnectorView[];
|
|
519
|
+
createListener(channelName: string, connectorName: string): {
|
|
520
|
+
config: ConnectorConfig;
|
|
521
|
+
channelId: string;
|
|
522
|
+
listener: FunnelConnectorListener;
|
|
523
|
+
} | null;
|
|
684
524
|
};
|
|
685
|
-
type
|
|
686
|
-
|
|
687
|
-
|
|
525
|
+
type SupervisorNotify = (channelName: string, connectorName: string, content: string, meta?: Record<string, string>) => Promise<void>;
|
|
526
|
+
type Deps$12 = {
|
|
527
|
+
channels: ConnectorRegistry;
|
|
528
|
+
notify: SupervisorNotify;
|
|
529
|
+
logger?: FunnelLogger; /** Host hook for surfacing listener lifecycle exceptions. Defaults to no-op. */
|
|
530
|
+
onError?: OnFunnelError;
|
|
531
|
+
healthCheckIntervalMs?: number;
|
|
532
|
+
maxBackoffMs?: number;
|
|
533
|
+
sleep?: (ms: number) => Promise<void>;
|
|
534
|
+
now?: () => number;
|
|
688
535
|
};
|
|
689
|
-
type
|
|
690
|
-
|
|
691
|
-
|
|
536
|
+
type ListenerEntryStatus = {
|
|
537
|
+
channelName: string;
|
|
538
|
+
channelId: string;
|
|
539
|
+
name: string;
|
|
540
|
+
type: ConnectorConfig["type"];
|
|
541
|
+
alive: boolean;
|
|
542
|
+
events: number;
|
|
543
|
+
errors: number;
|
|
544
|
+
failureCount: number;
|
|
545
|
+
lastEventAt: string | null;
|
|
692
546
|
};
|
|
693
547
|
/**
|
|
694
|
-
*
|
|
695
|
-
* The spec is the source of truth for the channel it declares:
|
|
696
|
-
*
|
|
697
|
-
* - missing channel → created
|
|
698
|
-
* - declared connector matched by name → tokens reconciled
|
|
699
|
-
* - declared connector matched by token in the same channel under a
|
|
700
|
-
* different name → renamed in place (then tokens reconciled)
|
|
701
|
-
* - declared connector with no match → added
|
|
702
|
-
* - any connector left in the channel that the spec did not touch → removed
|
|
548
|
+
* Owns the running listener instances and their lifecycle.
|
|
703
549
|
*
|
|
704
|
-
*
|
|
705
|
-
*
|
|
706
|
-
*
|
|
707
|
-
*
|
|
550
|
+
* Lives in the gateway process and is the only place that calls
|
|
551
|
+
* `listener.start()` / `listener.stop()`. Each entry is keyed by
|
|
552
|
+
* `${channelName}/${connectorName}` so the same connector name can exist in
|
|
553
|
+
* multiple channels without colliding.
|
|
708
554
|
*
|
|
709
|
-
*
|
|
710
|
-
*
|
|
555
|
+
* Periodically polls each running listener's `isAlive()` and auto-restarts
|
|
556
|
+
* dead listeners with exponential backoff (1s, 2s, 4s, ... capped). Resets
|
|
557
|
+
* the backoff counter on successful restart.
|
|
711
558
|
*/
|
|
712
|
-
declare class
|
|
559
|
+
declare class FunnelListenerSupervisor {
|
|
713
560
|
private readonly channels;
|
|
714
|
-
private readonly
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
private
|
|
718
|
-
private
|
|
719
|
-
private
|
|
720
|
-
private
|
|
721
|
-
private
|
|
722
|
-
private
|
|
723
|
-
private
|
|
724
|
-
private
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
561
|
+
private readonly notify;
|
|
562
|
+
private readonly logger;
|
|
563
|
+
private readonly onError;
|
|
564
|
+
private readonly running;
|
|
565
|
+
private readonly failureCounts;
|
|
566
|
+
private readonly stats;
|
|
567
|
+
private readonly healthCheckIntervalMs;
|
|
568
|
+
private readonly maxBackoffMs;
|
|
569
|
+
private readonly sleep;
|
|
570
|
+
private readonly now;
|
|
571
|
+
private healthCheckTimer;
|
|
572
|
+
private healthCheckInFlight;
|
|
573
|
+
constructor(deps: Deps$12);
|
|
574
|
+
static keyOf(channelName: string, connectorName: string): string;
|
|
575
|
+
isRunning(channelName: string, connectorName: string): boolean;
|
|
576
|
+
list(): ListenerEntryStatus[];
|
|
577
|
+
start(channelName: string, connectorName: string): Promise<{
|
|
578
|
+
ok: boolean;
|
|
579
|
+
reason?: string;
|
|
580
|
+
}>;
|
|
581
|
+
stop(channelName: string, connectorName: string): Promise<{
|
|
582
|
+
ok: boolean;
|
|
583
|
+
reason?: string;
|
|
584
|
+
}>;
|
|
585
|
+
restart(channelName: string, connectorName: string): Promise<{
|
|
586
|
+
ok: boolean;
|
|
587
|
+
reason?: string;
|
|
588
|
+
}>;
|
|
589
|
+
startAll(): Promise<void>;
|
|
590
|
+
stopAll(): Promise<void>;
|
|
591
|
+
private ensureStats;
|
|
592
|
+
private recordEvent;
|
|
593
|
+
private recordError;
|
|
594
|
+
private startHealthCheck;
|
|
595
|
+
private stopHealthCheck;
|
|
596
|
+
private runHealthCheck;
|
|
597
|
+
private recoverDead;
|
|
734
598
|
}
|
|
735
599
|
//#endregion
|
|
736
|
-
//#region lib/
|
|
737
|
-
type
|
|
738
|
-
|
|
600
|
+
//#region lib/gateway/routes/route-deps.d.ts
|
|
601
|
+
type GatewayEmitInput = {
|
|
602
|
+
channel: string;
|
|
603
|
+
connector?: string;
|
|
604
|
+
content: string;
|
|
605
|
+
meta?: Record<string, string>;
|
|
606
|
+
};
|
|
607
|
+
type GatewayRouteDeps = {
|
|
608
|
+
selfPid: number;
|
|
609
|
+
broadcaster: FunnelBroadcaster;
|
|
610
|
+
supervisor: FunnelListenerSupervisor;
|
|
611
|
+
channels: FunnelChannels;
|
|
612
|
+
uptimeMs: () => number;
|
|
613
|
+
emit: (input: GatewayEmitInput) => {
|
|
614
|
+
offset: number;
|
|
615
|
+
};
|
|
739
616
|
};
|
|
740
|
-
/**
|
|
741
|
-
* The one path that mutates the repo-committed funnel.json, and it only ever
|
|
742
|
-
* inserts `id`. On first launch a repo has no `id`; funnel generates one and
|
|
743
|
-
* writes it back here so future launches resolve the same `~/.funnel/projects/<id>/`.
|
|
744
|
-
* Idempotent — a no-op once `id` is present. Kept separate from the read-only
|
|
745
|
-
* FunnelLocalConfig so reads stay side-effect free.
|
|
746
|
-
*/
|
|
747
|
-
declare class FunnelLocalConfigWriter {
|
|
748
|
-
private readonly fs;
|
|
749
|
-
constructor(deps: Deps$8);
|
|
750
|
-
ensureId(cwd: string, id: string): void;
|
|
751
|
-
}
|
|
752
617
|
//#endregion
|
|
753
|
-
//#region lib/gateway/
|
|
618
|
+
//#region lib/gateway/factory.d.ts
|
|
619
|
+
type Env$1 = {
|
|
620
|
+
Variables: {
|
|
621
|
+
deps: GatewayRouteDeps;
|
|
622
|
+
};
|
|
623
|
+
};
|
|
624
|
+
//#endregion
|
|
625
|
+
//#region lib/gateway/routes/index.d.ts
|
|
754
626
|
/**
|
|
755
|
-
*
|
|
756
|
-
*
|
|
757
|
-
*
|
|
758
|
-
*
|
|
627
|
+
* Top-level Hono app for the gateway daemon. Mounts every HTTP endpoint flat
|
|
628
|
+
* (the WebSocket /ws upgrade is handled directly by `Bun.serve`). Deps come
|
|
629
|
+
* from the `deps` variable set by `FunnelGatewayServer`'s middleware — same
|
|
630
|
+
* shape as CLI's `c.var.funnel`.
|
|
759
631
|
*/
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
632
|
+
type GatewayApp = ReturnType<typeof buildGatewayRoutes>;
|
|
633
|
+
declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env$1, {
|
|
634
|
+
"/health": {
|
|
635
|
+
$get: {
|
|
636
|
+
input: {};
|
|
637
|
+
output: {
|
|
638
|
+
ok: true;
|
|
639
|
+
pid: number;
|
|
640
|
+
clients: number;
|
|
641
|
+
listeners: {
|
|
642
|
+
channelName: string;
|
|
643
|
+
channelId: string;
|
|
644
|
+
name: string;
|
|
645
|
+
type: ConnectorConfig["type"];
|
|
646
|
+
alive: boolean;
|
|
647
|
+
events: number;
|
|
648
|
+
errors: number;
|
|
649
|
+
failureCount: number;
|
|
650
|
+
lastEventAt: string | null;
|
|
651
|
+
}[];
|
|
652
|
+
};
|
|
653
|
+
outputFormat: "json";
|
|
654
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
655
|
+
};
|
|
656
|
+
};
|
|
657
|
+
} & {
|
|
658
|
+
"/status": {
|
|
659
|
+
$get: {
|
|
660
|
+
input: {};
|
|
661
|
+
output: {
|
|
662
|
+
ok: true;
|
|
663
|
+
pid: number;
|
|
664
|
+
uptimeMs: number;
|
|
665
|
+
clients: {
|
|
666
|
+
channel: string;
|
|
667
|
+
connectors: string[];
|
|
668
|
+
}[];
|
|
669
|
+
listeners: {
|
|
670
|
+
channelName: string;
|
|
671
|
+
channelId: string;
|
|
672
|
+
name: string;
|
|
673
|
+
type: ConnectorConfig["type"];
|
|
674
|
+
alive: boolean;
|
|
675
|
+
events: number;
|
|
676
|
+
errors: number;
|
|
677
|
+
failureCount: number;
|
|
678
|
+
lastEventAt: string | null;
|
|
679
|
+
}[];
|
|
680
|
+
broadcaster: {
|
|
681
|
+
clients: number;
|
|
682
|
+
subscribers: number;
|
|
683
|
+
eventsBroadcast: number;
|
|
684
|
+
droppedSlowClients: number;
|
|
685
|
+
lastBroadcastAt: string | null;
|
|
686
|
+
latestOffset: number;
|
|
687
|
+
oldestReplayableOffset: number | null;
|
|
688
|
+
};
|
|
689
|
+
};
|
|
690
|
+
outputFormat: "json";
|
|
691
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
692
|
+
};
|
|
693
|
+
};
|
|
694
|
+
} & {
|
|
695
|
+
"/debug": {
|
|
696
|
+
$get: {
|
|
697
|
+
input: {};
|
|
698
|
+
output: {
|
|
699
|
+
pid: number;
|
|
700
|
+
uptimeMs: number;
|
|
701
|
+
eventsBroadcast: number;
|
|
702
|
+
channels: {
|
|
703
|
+
id: string;
|
|
704
|
+
name: string;
|
|
705
|
+
connectors: string[];
|
|
706
|
+
listener: {
|
|
707
|
+
alive: boolean;
|
|
708
|
+
events: number;
|
|
709
|
+
errors: number;
|
|
710
|
+
lastEventAt: string | null;
|
|
711
|
+
} | null;
|
|
712
|
+
claudeClients: number;
|
|
713
|
+
recentEvents: {
|
|
714
|
+
seq: number | null;
|
|
715
|
+
ts: number | null;
|
|
716
|
+
type: string;
|
|
717
|
+
outcome: string;
|
|
718
|
+
payload: string | null;
|
|
719
|
+
payloadParsed: {
|
|
720
|
+
[x: string]: _$hono_utils_types0.JSONValue;
|
|
721
|
+
} | null;
|
|
722
|
+
preview: string | null;
|
|
723
|
+
}[];
|
|
724
|
+
connectionErrors: {
|
|
725
|
+
ts: number | null;
|
|
726
|
+
type: string;
|
|
727
|
+
status: string;
|
|
728
|
+
detail: string | null;
|
|
729
|
+
}[];
|
|
730
|
+
diagnosis: {
|
|
731
|
+
status: "ok" | "warn" | "error";
|
|
732
|
+
message: string;
|
|
733
|
+
nextActions: string[];
|
|
734
|
+
rootCause: string | null;
|
|
735
|
+
};
|
|
736
|
+
}[];
|
|
737
|
+
};
|
|
738
|
+
outputFormat: "json";
|
|
739
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
740
|
+
};
|
|
741
|
+
};
|
|
742
|
+
} & {
|
|
743
|
+
"/listeners": {
|
|
744
|
+
$get: {
|
|
745
|
+
input: {};
|
|
746
|
+
output: {
|
|
747
|
+
listeners: {
|
|
748
|
+
channelName: string;
|
|
749
|
+
channelId: string;
|
|
750
|
+
name: string;
|
|
751
|
+
type: ConnectorConfig["type"];
|
|
752
|
+
alive: boolean;
|
|
753
|
+
events: number;
|
|
754
|
+
errors: number;
|
|
755
|
+
failureCount: number;
|
|
756
|
+
lastEventAt: string | null;
|
|
757
|
+
}[];
|
|
758
|
+
};
|
|
759
|
+
outputFormat: "json";
|
|
760
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
761
|
+
};
|
|
762
|
+
};
|
|
763
|
+
} & {
|
|
764
|
+
"/listeners/:channel/:connector/start": {
|
|
765
|
+
$post: {
|
|
766
|
+
input: {
|
|
767
|
+
param: {
|
|
768
|
+
channel: string;
|
|
769
|
+
connector: string;
|
|
770
|
+
};
|
|
771
|
+
};
|
|
772
|
+
output: {
|
|
773
|
+
ok: boolean;
|
|
774
|
+
reason: string;
|
|
775
|
+
};
|
|
776
|
+
outputFormat: "json";
|
|
777
|
+
status: 400;
|
|
778
|
+
} | {
|
|
779
|
+
input: {
|
|
780
|
+
param: {
|
|
781
|
+
channel: string;
|
|
782
|
+
connector: string;
|
|
783
|
+
};
|
|
784
|
+
};
|
|
785
|
+
output: {
|
|
786
|
+
ok: boolean;
|
|
787
|
+
reason?: string | undefined;
|
|
788
|
+
};
|
|
789
|
+
outputFormat: "json";
|
|
790
|
+
status: 200 | 400;
|
|
791
|
+
};
|
|
792
|
+
};
|
|
793
|
+
} & {
|
|
794
|
+
"/listeners/:channel/:connector": {
|
|
795
|
+
$delete: {
|
|
796
|
+
input: {
|
|
797
|
+
param: {
|
|
798
|
+
channel: string;
|
|
799
|
+
connector: string;
|
|
800
|
+
};
|
|
801
|
+
};
|
|
802
|
+
output: {
|
|
803
|
+
ok: boolean;
|
|
804
|
+
reason: string;
|
|
805
|
+
};
|
|
806
|
+
outputFormat: "json";
|
|
807
|
+
status: 400;
|
|
808
|
+
} | {
|
|
809
|
+
input: {
|
|
810
|
+
param: {
|
|
811
|
+
channel: string;
|
|
812
|
+
connector: string;
|
|
813
|
+
};
|
|
814
|
+
};
|
|
815
|
+
output: {
|
|
816
|
+
ok: boolean;
|
|
817
|
+
reason?: string | undefined;
|
|
818
|
+
};
|
|
819
|
+
outputFormat: "json";
|
|
820
|
+
status: 200 | 400;
|
|
821
|
+
};
|
|
822
|
+
};
|
|
823
|
+
} & {
|
|
824
|
+
"/listeners/:channel/:connector/restart": {
|
|
825
|
+
$post: {
|
|
826
|
+
input: {
|
|
827
|
+
param: {
|
|
828
|
+
channel: string;
|
|
829
|
+
connector: string;
|
|
830
|
+
};
|
|
831
|
+
};
|
|
832
|
+
output: {
|
|
833
|
+
ok: boolean;
|
|
834
|
+
reason: string;
|
|
835
|
+
};
|
|
836
|
+
outputFormat: "json";
|
|
837
|
+
status: 400;
|
|
838
|
+
} | {
|
|
839
|
+
input: {
|
|
840
|
+
param: {
|
|
841
|
+
channel: string;
|
|
842
|
+
connector: string;
|
|
843
|
+
};
|
|
844
|
+
};
|
|
845
|
+
output: {
|
|
846
|
+
ok: boolean;
|
|
847
|
+
reason?: string | undefined;
|
|
848
|
+
};
|
|
849
|
+
outputFormat: "json";
|
|
850
|
+
status: 200 | 400;
|
|
851
|
+
};
|
|
852
|
+
};
|
|
853
|
+
} & {
|
|
854
|
+
"/channels/:channel/connectors/:connector/call": {
|
|
855
|
+
$post: {
|
|
856
|
+
input: {
|
|
857
|
+
param: {
|
|
858
|
+
channel: string;
|
|
859
|
+
connector: string;
|
|
860
|
+
};
|
|
861
|
+
};
|
|
862
|
+
output: {
|
|
863
|
+
ok: boolean;
|
|
864
|
+
reason: string;
|
|
865
|
+
};
|
|
866
|
+
outputFormat: "json";
|
|
867
|
+
status: 400;
|
|
868
|
+
} | {
|
|
869
|
+
input: {
|
|
870
|
+
param: {
|
|
871
|
+
channel: string;
|
|
872
|
+
connector: string;
|
|
873
|
+
};
|
|
874
|
+
};
|
|
875
|
+
output: {
|
|
876
|
+
ok: true;
|
|
877
|
+
result: _$hono_utils_types0.JSONValue;
|
|
878
|
+
};
|
|
879
|
+
outputFormat: "json";
|
|
880
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
881
|
+
};
|
|
882
|
+
};
|
|
883
|
+
} & {
|
|
884
|
+
"/channels/:channel/publish": {
|
|
885
|
+
$post: {
|
|
886
|
+
input: {
|
|
887
|
+
param: {
|
|
888
|
+
channel: string;
|
|
889
|
+
};
|
|
890
|
+
} & {
|
|
891
|
+
json: {
|
|
892
|
+
content: string;
|
|
893
|
+
meta?: Record<string, string> | undefined;
|
|
894
|
+
connector?: string | undefined;
|
|
895
|
+
};
|
|
896
|
+
};
|
|
897
|
+
output: {
|
|
898
|
+
ok: boolean;
|
|
899
|
+
reason: string;
|
|
900
|
+
};
|
|
901
|
+
outputFormat: "json";
|
|
902
|
+
status: 400;
|
|
903
|
+
} | {
|
|
904
|
+
input: {
|
|
905
|
+
param: {
|
|
906
|
+
channel: string;
|
|
907
|
+
};
|
|
908
|
+
} & {
|
|
909
|
+
json: {
|
|
910
|
+
content: string;
|
|
911
|
+
meta?: Record<string, string> | undefined;
|
|
912
|
+
connector?: string | undefined;
|
|
913
|
+
};
|
|
914
|
+
};
|
|
915
|
+
output: {
|
|
916
|
+
ok: boolean;
|
|
917
|
+
reason: string;
|
|
918
|
+
};
|
|
919
|
+
outputFormat: "json";
|
|
920
|
+
status: 400;
|
|
921
|
+
} | {
|
|
922
|
+
input: {
|
|
923
|
+
param: {
|
|
924
|
+
channel: string;
|
|
925
|
+
};
|
|
926
|
+
} & {
|
|
927
|
+
json: {
|
|
928
|
+
content: string;
|
|
929
|
+
meta?: Record<string, string> | undefined;
|
|
930
|
+
connector?: string | undefined;
|
|
931
|
+
};
|
|
932
|
+
};
|
|
933
|
+
output: {
|
|
934
|
+
ok: true;
|
|
935
|
+
offset: number;
|
|
936
|
+
};
|
|
937
|
+
outputFormat: "json";
|
|
938
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
939
|
+
};
|
|
940
|
+
};
|
|
941
|
+
}, "/", "/channels/:channel/publish">;
|
|
942
|
+
//#endregion
|
|
943
|
+
//#region lib/engine/claude/gateway-controller.d.ts
|
|
944
|
+
type GatewayController = {
|
|
945
|
+
isRunning(): boolean;
|
|
946
|
+
start(options?: {
|
|
947
|
+
caffeinate?: boolean;
|
|
948
|
+
}): Promise<boolean>;
|
|
779
949
|
};
|
|
780
950
|
//#endregion
|
|
781
|
-
//#region lib/
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
951
|
+
//#region lib/engine/mcp/mcp.d.ts
|
|
952
|
+
declare const FUNNEL_MCP_COMMAND = "bun";
|
|
953
|
+
declare const FUNNEL_MCP_ARGS: string[];
|
|
954
|
+
declare const FUNNEL_MCP_NAME = "funnel";
|
|
955
|
+
type Deps$11 = {
|
|
956
|
+
fs?: FunnelFileSystem;
|
|
786
957
|
};
|
|
787
958
|
/**
|
|
788
|
-
*
|
|
789
|
-
*
|
|
790
|
-
*
|
|
959
|
+
* Installs/uninstalls the funnel MCP entry into a target repository's
|
|
960
|
+
* `.mcp.json`. Detects an existing entry by command match so renaming is
|
|
961
|
+
* preserved across re-installs.
|
|
791
962
|
*/
|
|
792
|
-
declare class
|
|
793
|
-
private readonly
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
private
|
|
963
|
+
declare class FunnelMcp {
|
|
964
|
+
private readonly fs;
|
|
965
|
+
constructor(deps?: Deps$11);
|
|
966
|
+
install(repoPath: string): void;
|
|
967
|
+
uninstall(repoPath: string): void;
|
|
968
|
+
findInstalledName(cwd: string): string | null;
|
|
969
|
+
private findServerName;
|
|
970
|
+
private isFunnelEntry;
|
|
971
|
+
private readConfig;
|
|
972
|
+
private writeConfig;
|
|
799
973
|
}
|
|
800
974
|
//#endregion
|
|
801
|
-
//#region lib/
|
|
802
|
-
type
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
connectors: string[];
|
|
806
|
-
tapAll?: boolean; /** Routing mode resolved from channel config at upgrade time. Defaults to fanout. */
|
|
807
|
-
delivery?: "fanout" | "exclusive";
|
|
975
|
+
//#region lib/engine/profiles/profiles.d.ts
|
|
976
|
+
type Deps$10 = {
|
|
977
|
+
store: FunnelSettingsReader;
|
|
978
|
+
idGenerator: FunnelIdGenerator;
|
|
808
979
|
};
|
|
809
|
-
type BroadcastEvent = {
|
|
810
|
-
content: string;
|
|
811
|
-
meta?: Record<string, string>;
|
|
812
|
-
};
|
|
813
|
-
type ReplayableEvent = BroadcastEvent & {
|
|
814
|
-
offset: number;
|
|
815
|
-
};
|
|
816
|
-
type BroadcastSubscriber = (event: ReplayableEvent) => void;
|
|
817
980
|
/**
|
|
818
|
-
*
|
|
819
|
-
*
|
|
820
|
-
*
|
|
821
|
-
* `
|
|
981
|
+
* Named launch presets for `fnl claude`. Each profile bundles a working
|
|
982
|
+
* directory, the channel id its Claude instance subscribes to, and the launch
|
|
983
|
+
* recipe (`options` prepended to the claude argv, `env` layered under the
|
|
984
|
+
* process, `resume` toggling session reuse). Implements ProfileChannelChecker
|
|
985
|
+
* so FunnelChannels can refuse to remove a channel that is still referenced.
|
|
986
|
+
*
|
|
987
|
+
* Each profile has a stable `id` (uuid) minted at `add`. That id is the unit
|
|
988
|
+
* everything internal keys on — the PID file, the resumable session id — so a
|
|
989
|
+
* rename never strands either. `name` is purely the CLI/TUI handle; the CRUD
|
|
990
|
+
* methods here take it because that is what the user types, but resolve to the
|
|
991
|
+
* id before touching id-keyed state. The first array entry is the default
|
|
992
|
+
* profile; `asDefault` reorders to put one first.
|
|
993
|
+
*
|
|
994
|
+
* `channelId` always stores the channel's stable id (uuid). CLI surfaces
|
|
995
|
+
* resolve channel name → id before calling `add`/`update` here.
|
|
822
996
|
*/
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
997
|
+
declare class FunnelProfiles {
|
|
998
|
+
private readonly store;
|
|
999
|
+
private readonly idGenerator;
|
|
1000
|
+
constructor(deps: Deps$10);
|
|
1001
|
+
list(): ProfileConfig[];
|
|
1002
|
+
get(name: string): ProfileConfig | null;
|
|
1003
|
+
getById(id: string): ProfileConfig | null;
|
|
1004
|
+
getDefault(): ProfileConfig | null;
|
|
1005
|
+
add(input: {
|
|
1006
|
+
name: string;
|
|
1007
|
+
path: string;
|
|
1008
|
+
channelId: string;
|
|
1009
|
+
options?: string[];
|
|
1010
|
+
env?: Record<string, string>;
|
|
1011
|
+
resume?: boolean;
|
|
1012
|
+
}): void;
|
|
1013
|
+
remove(name: string): void;
|
|
1014
|
+
rename(oldName: string, newName: string): void;
|
|
1015
|
+
asDefault(name: string): void;
|
|
1016
|
+
hasChannelRef(channelId: string): boolean;
|
|
1017
|
+
/** Resumable claude session id last launched by this profile (by id), or null. */
|
|
1018
|
+
getSessionId(id: string): string | null;
|
|
1019
|
+
/** Records the claude session id this profile launched, overwriting any prior one. */
|
|
1020
|
+
setSessionId(id: string, sessionId: string): void;
|
|
1021
|
+
update(name: string, fields: Partial<Omit<ProfileConfig, "name">>): void;
|
|
1022
|
+
}
|
|
1023
|
+
//#endregion
|
|
1024
|
+
//#region lib/engine/claude/claude.d.ts
|
|
1025
|
+
type LaunchOptions = {
|
|
1026
|
+
channel: string;
|
|
1027
|
+
cwd?: string;
|
|
1028
|
+
userArgs?: string[];
|
|
1029
|
+
/** Stable id of the launching profile (uuid). Keys the singleton PID file and
|
|
1030
|
+
* the resumable session. Absent for a profile-less launch (raw `--channel`),
|
|
1031
|
+
* which never enforces singleton-ness and never resumes. */
|
|
1032
|
+
profileId?: string; /** Args prepended to the claude argv (typically a profile's recipe). Defaults to none. */
|
|
1033
|
+
options?: string[]; /** Env vars layered under the launched claude process. process.env wins on collision. */
|
|
1034
|
+
env?: Record<string, string>;
|
|
1035
|
+
/** Whether to inject a `--session-id`/`--resume` for this profile.
|
|
1036
|
+
* Defaults to false: resuming is opt-in and only meaningful for a profile,
|
|
1037
|
+
* since the persisted session is owned by the profile (by id). A launch
|
|
1038
|
+
* without a profile always starts a fresh session regardless of this flag. */
|
|
1039
|
+
resume?: boolean;
|
|
1040
|
+
/** Invoked synchronously after the child claude process has been spawned, with its PID.
|
|
1041
|
+
* Useful for hosts that need to register the spawned process before it exits
|
|
1042
|
+
* (e.g. multi-session registries that track per-claude liveness). */
|
|
1043
|
+
onSpawned?: (pid: number) => void;
|
|
1044
|
+
/** Whether to install the funnel MCP entry into `.mcp.json` (default: true).
|
|
1045
|
+
* Set to false when the host already provides its own MCP server entry and
|
|
1046
|
+
* does not need the funnel binary as an MCP endpoint. */
|
|
1047
|
+
installMcp?: boolean;
|
|
834
1048
|
};
|
|
835
|
-
type
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
1049
|
+
type Deps$9 = {
|
|
1050
|
+
channels: FunnelChannels;
|
|
1051
|
+
mcp: FunnelMcp;
|
|
1052
|
+
gateway: GatewayController;
|
|
1053
|
+
profiles: FunnelProfiles;
|
|
1054
|
+
process?: FunnelProcessRunner;
|
|
1055
|
+
fs?: FunnelFileSystem;
|
|
1056
|
+
idGenerator?: FunnelIdGenerator;
|
|
1057
|
+
logger?: FunnelLogger;
|
|
1058
|
+
dir?: string;
|
|
843
1059
|
};
|
|
844
1060
|
/**
|
|
845
|
-
*
|
|
846
|
-
*
|
|
847
|
-
*
|
|
848
|
-
*
|
|
849
|
-
* - In-process subscribers registered via `subscribe()` (programmable API)
|
|
850
|
-
*
|
|
851
|
-
* Backpressure: if a WS client's `bufferedAmount` exceeds `maxBufferedBytes`
|
|
852
|
-
* (default 1 MiB), the client is closed with code 1009 and dropped from the
|
|
853
|
-
* registry to keep one slow consumer from blocking the daemon.
|
|
854
|
-
*
|
|
855
|
-
* Replay: every emitted event gets a strictly increasing `offset`. The latest
|
|
856
|
-
* `replayBufferSize` events are kept in memory; reconnecting WS clients can
|
|
857
|
-
* pass `?since=<offset>` and the broadcaster resends matching events before
|
|
858
|
-
* resuming the live stream. The in-memory ring covers short reconnects;
|
|
859
|
-
* older history is served from the event log wired in as `persistentReplay`.
|
|
1061
|
+
* Launches Claude Code with funnel pre-wired: ensures the gateway is running,
|
|
1062
|
+
* installs the funnel MCP into the target repo's `.mcp.json` if missing,
|
|
1063
|
+
* injects `FUNNEL_CHANNEL_ID` into the child env, and writes a per-profile
|
|
1064
|
+
* PID file to enforce singleton launches.
|
|
860
1065
|
*/
|
|
861
|
-
declare class
|
|
862
|
-
private readonly
|
|
863
|
-
private readonly
|
|
1066
|
+
declare class FunnelClaude {
|
|
1067
|
+
private readonly channels;
|
|
1068
|
+
private readonly mcp;
|
|
1069
|
+
private readonly gateway;
|
|
1070
|
+
private readonly profiles;
|
|
1071
|
+
private readonly process;
|
|
1072
|
+
private readonly fs;
|
|
1073
|
+
private readonly idGenerator;
|
|
864
1074
|
private readonly logger;
|
|
865
|
-
private readonly
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
private
|
|
870
|
-
private
|
|
871
|
-
private
|
|
872
|
-
private
|
|
873
|
-
private
|
|
874
|
-
private
|
|
875
|
-
private
|
|
876
|
-
private lastBroadcastAt;
|
|
877
|
-
private latestOffset;
|
|
878
|
-
constructor(deps?: Deps$6);
|
|
879
|
-
getMetrics(): BroadcasterMetrics;
|
|
1075
|
+
private readonly pidDir;
|
|
1076
|
+
constructor(deps: Deps$9);
|
|
1077
|
+
launch(options: LaunchOptions): Promise<number>;
|
|
1078
|
+
isRunning(profileId: string): boolean;
|
|
1079
|
+
private pidPath;
|
|
1080
|
+
private readPid;
|
|
1081
|
+
private writePidFile;
|
|
1082
|
+
private removePidFile;
|
|
1083
|
+
private installCleanup;
|
|
1084
|
+
private isProcessAlive;
|
|
1085
|
+
private buildArgs;
|
|
880
1086
|
/**
|
|
881
|
-
*
|
|
882
|
-
*
|
|
1087
|
+
* Decides whether funnel should resume an existing claude session or start
|
|
1088
|
+
* a freshly minted one. Backs off when the user already passed a
|
|
1089
|
+
* session-shaping flag, since combining them would either confuse claude
|
|
1090
|
+
* or override the explicit user intent.
|
|
883
1091
|
*
|
|
884
|
-
*
|
|
885
|
-
*
|
|
886
|
-
*
|
|
887
|
-
*
|
|
888
|
-
*
|
|
1092
|
+
* The session is owned by the profile (by id), not by cwd: two profiles
|
|
1093
|
+
* pointing at the same repo each keep their own conversation, and a launch
|
|
1094
|
+
* with no profile never resumes — so an unrelated session in the same repo
|
|
1095
|
+
* can't bleed in. The channel never enters into it; sessions belong to the
|
|
1096
|
+
* launch layer (profiles), keeping the transport layer ignorant of them.
|
|
889
1097
|
*
|
|
890
|
-
*
|
|
1098
|
+
* A persisted id is only resumed when its session jsonl still exists on
|
|
1099
|
+
* disk. claude errors out on `--resume <id>` for a missing conversation, and
|
|
1100
|
+
* a persisted id can outlive its jsonl (claude pruned it, or the very first
|
|
1101
|
+
* launch was aborted after the id was written but before the jsonl
|
|
1102
|
+
* appeared). When the file is gone we mint a fresh session instead, which
|
|
1103
|
+
* overwrites the dangling entry — so the store self-heals.
|
|
891
1104
|
*/
|
|
892
|
-
|
|
893
|
-
private matchesClient;
|
|
1105
|
+
private resolveSession;
|
|
894
1106
|
/**
|
|
895
|
-
*
|
|
896
|
-
*
|
|
897
|
-
*
|
|
898
|
-
*
|
|
1107
|
+
* Mirrors claude's session storage path
|
|
1108
|
+
* (`<config-dir>/projects/<cwd-with-slashes-as-dashes>/<id>.jsonl`) to check
|
|
1109
|
+
* whether a recorded session still exists AND is non-empty. Reads the same
|
|
1110
|
+
* `CLAUDE_CONFIG_DIR` the child will run under so the check matches reality; a
|
|
1111
|
+
* wrong guess can only ever produce a false negative (start fresh), never a
|
|
1112
|
+
* bad resume.
|
|
899
1113
|
*/
|
|
900
|
-
private
|
|
901
|
-
|
|
902
|
-
removeClient(ws: ServerWebSocket<unknown>): void;
|
|
903
|
-
getClientCount(): number;
|
|
904
|
-
listChannels(): {
|
|
905
|
-
channel: string;
|
|
906
|
-
connectors: string[];
|
|
907
|
-
}[];
|
|
908
|
-
subscribe(handler: BroadcastSubscriber): () => void;
|
|
909
|
-
broadcast(content: string, meta?: Record<string, string>): ReplayableEvent;
|
|
910
|
-
/** Forward-seed the offset counter (used at startup from the persisted event store). */
|
|
911
|
-
seedLatestOffset(offset: number): void;
|
|
1114
|
+
private sessionFileExists;
|
|
1115
|
+
private buildEnv;
|
|
912
1116
|
}
|
|
913
1117
|
//#endregion
|
|
914
|
-
//#region lib/
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
}
|
|
923
|
-
type
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
type
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
private ensureStats;
|
|
990
|
-
private recordEvent;
|
|
991
|
-
private recordError;
|
|
992
|
-
private startHealthCheck;
|
|
993
|
-
private stopHealthCheck;
|
|
994
|
-
private runHealthCheck;
|
|
995
|
-
private recoverDead;
|
|
996
|
-
}
|
|
997
|
-
//#endregion
|
|
998
|
-
//#region lib/gateway/routes/route-deps.d.ts
|
|
999
|
-
type GatewayEmitInput = {
|
|
1000
|
-
channel: string;
|
|
1001
|
-
connector?: string;
|
|
1002
|
-
content: string;
|
|
1003
|
-
meta?: Record<string, string>;
|
|
1004
|
-
};
|
|
1005
|
-
type GatewayRouteDeps = {
|
|
1006
|
-
selfPid: number;
|
|
1007
|
-
broadcaster: FunnelBroadcaster;
|
|
1008
|
-
supervisor: FunnelListenerSupervisor;
|
|
1009
|
-
channels: FunnelChannels;
|
|
1010
|
-
uptimeMs: () => number;
|
|
1011
|
-
emit: (input: GatewayEmitInput) => {
|
|
1012
|
-
offset: number;
|
|
1013
|
-
};
|
|
1014
|
-
};
|
|
1118
|
+
//#region lib/engine/local-config/local-config-schema.d.ts
|
|
1119
|
+
declare const connectorSpecSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1120
|
+
type: z.ZodLiteral<"slack">;
|
|
1121
|
+
name: z.ZodString;
|
|
1122
|
+
minify: z.ZodOptional<z.ZodBoolean>;
|
|
1123
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1124
|
+
type: z.ZodLiteral<"discord">;
|
|
1125
|
+
name: z.ZodString;
|
|
1126
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1127
|
+
type: z.ZodLiteral<"gh">;
|
|
1128
|
+
name: z.ZodString;
|
|
1129
|
+
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
1130
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1131
|
+
type: z.ZodLiteral<"schedule">;
|
|
1132
|
+
name: z.ZodString;
|
|
1133
|
+
}, z.core.$strip>], "type">;
|
|
1134
|
+
type ConnectorSpec = z.infer<typeof connectorSpecSchema>;
|
|
1135
|
+
declare const channelSpecSchema: z.ZodObject<{
|
|
1136
|
+
name: z.ZodString;
|
|
1137
|
+
connectors: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1138
|
+
type: z.ZodLiteral<"slack">;
|
|
1139
|
+
name: z.ZodString;
|
|
1140
|
+
minify: z.ZodOptional<z.ZodBoolean>;
|
|
1141
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1142
|
+
type: z.ZodLiteral<"discord">;
|
|
1143
|
+
name: z.ZodString;
|
|
1144
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1145
|
+
type: z.ZodLiteral<"gh">;
|
|
1146
|
+
name: z.ZodString;
|
|
1147
|
+
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
1148
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1149
|
+
type: z.ZodLiteral<"schedule">;
|
|
1150
|
+
name: z.ZodString;
|
|
1151
|
+
}, z.core.$strip>], "type">>>;
|
|
1152
|
+
}, z.core.$strip>;
|
|
1153
|
+
type ChannelSpec = z.infer<typeof channelSpecSchema>;
|
|
1154
|
+
declare const profileSpecSchema: z.ZodObject<{
|
|
1155
|
+
name: z.ZodString;
|
|
1156
|
+
channel: z.ZodString;
|
|
1157
|
+
options: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1158
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1159
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
1160
|
+
}, z.core.$strip>;
|
|
1161
|
+
type ProfileSpec = z.infer<typeof profileSpecSchema>;
|
|
1162
|
+
declare const localConfigSchema: z.ZodObject<{
|
|
1163
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
1164
|
+
id: z.ZodOptional<z.ZodString>;
|
|
1165
|
+
channels: z.ZodArray<z.ZodObject<{
|
|
1166
|
+
name: z.ZodString;
|
|
1167
|
+
connectors: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1168
|
+
type: z.ZodLiteral<"slack">;
|
|
1169
|
+
name: z.ZodString;
|
|
1170
|
+
minify: z.ZodOptional<z.ZodBoolean>;
|
|
1171
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1172
|
+
type: z.ZodLiteral<"discord">;
|
|
1173
|
+
name: z.ZodString;
|
|
1174
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1175
|
+
type: z.ZodLiteral<"gh">;
|
|
1176
|
+
name: z.ZodString;
|
|
1177
|
+
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
1178
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1179
|
+
type: z.ZodLiteral<"schedule">;
|
|
1180
|
+
name: z.ZodString;
|
|
1181
|
+
}, z.core.$strip>], "type">>>;
|
|
1182
|
+
}, z.core.$strip>>;
|
|
1183
|
+
profiles: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1184
|
+
name: z.ZodString;
|
|
1185
|
+
channel: z.ZodString;
|
|
1186
|
+
options: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1187
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1188
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
1189
|
+
}, z.core.$strip>>>;
|
|
1190
|
+
}, z.core.$strip>;
|
|
1191
|
+
type LocalConfig = z.infer<typeof localConfigSchema>;
|
|
1192
|
+
declare const LOCAL_CONFIG_FILENAME = "funnel.json";
|
|
1015
1193
|
//#endregion
|
|
1016
|
-
//#region lib/
|
|
1017
|
-
type
|
|
1018
|
-
|
|
1019
|
-
deps: GatewayRouteDeps;
|
|
1020
|
-
};
|
|
1194
|
+
//#region lib/engine/local-config/local-config.d.ts
|
|
1195
|
+
type Deps$8 = {
|
|
1196
|
+
fs: FunnelFileSystem;
|
|
1021
1197
|
};
|
|
1198
|
+
/**
|
|
1199
|
+
* Reads `funnel.json` from a directory. Returns `null` when the file is
|
|
1200
|
+
* absent so callers can fall through to other resolution paths (default
|
|
1201
|
+
* profile, help). Throws on present-but-invalid files so misconfiguration
|
|
1202
|
+
* surfaces loudly instead of silently launching the wrong channel.
|
|
1203
|
+
*/
|
|
1204
|
+
declare class FunnelLocalConfig {
|
|
1205
|
+
private readonly fs;
|
|
1206
|
+
constructor(deps: Deps$8);
|
|
1207
|
+
read(cwd: string): LocalConfig | null;
|
|
1208
|
+
private assertProfilesValid;
|
|
1209
|
+
}
|
|
1022
1210
|
//#endregion
|
|
1023
|
-
//#region lib/
|
|
1211
|
+
//#region lib/engine/token-prompter/token-prompter.d.ts
|
|
1024
1212
|
/**
|
|
1025
|
-
*
|
|
1026
|
-
*
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
* through this log, which keeps the offset space clean for replay.
|
|
1213
|
+
* Asks the user for a secret value on stdin. Used as a last resort when a
|
|
1214
|
+
* funnel.json token field is absent and not present in `~/.funnel`. The Node
|
|
1215
|
+
* implementation refuses to prompt when stdin is not a TTY so non-interactive
|
|
1216
|
+
* launches (CI, agent spawning agent, daemons) fail fast instead of hanging.
|
|
1030
1217
|
*/
|
|
1031
|
-
declare
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
type
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1218
|
+
declare abstract class FunnelTokenPrompter {
|
|
1219
|
+
abstract promptSecret(label: string): Promise<string>;
|
|
1220
|
+
}
|
|
1221
|
+
//#endregion
|
|
1222
|
+
//#region lib/engine/local-config/local-config-sync.d.ts
|
|
1223
|
+
type Deps$7 = {
|
|
1224
|
+
channels: FunnelChannels;
|
|
1225
|
+
prompter: FunnelTokenPrompter;
|
|
1226
|
+
};
|
|
1227
|
+
type ConnectorSyncOutcome = {
|
|
1228
|
+
name: string;
|
|
1229
|
+
changed: boolean;
|
|
1230
|
+
};
|
|
1231
|
+
type LocalConfigSyncResult = {
|
|
1232
|
+
touched: ConnectorSyncOutcome[];
|
|
1233
|
+
removed: string[];
|
|
1046
1234
|
};
|
|
1047
1235
|
/**
|
|
1048
|
-
*
|
|
1049
|
-
*
|
|
1050
|
-
* across restarts it both seeds the broadcaster's offset counter
|
|
1051
|
-
* (`findMaxOffset`) and serves reconnect replay (`loadSince`) from it.
|
|
1236
|
+
* Reconciles a single funnel.json channel spec with `~/.funnel/settings.json`.
|
|
1237
|
+
* The spec is the source of truth for the channel it declares:
|
|
1052
1238
|
*
|
|
1053
|
-
*
|
|
1054
|
-
*
|
|
1239
|
+
* - missing channel → created
|
|
1240
|
+
* - declared connector matched by name → tokens reconciled
|
|
1241
|
+
* - declared connector matched by token in the same channel under a
|
|
1242
|
+
* different name → renamed in place (then tokens reconciled)
|
|
1243
|
+
* - declared connector with no match → added
|
|
1244
|
+
* - any connector left in the channel that the spec did not touch → removed
|
|
1055
1245
|
*
|
|
1056
|
-
*
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1059
|
-
*
|
|
1246
|
+
* Removal only fires when the channel spec has a `connectors` field. An
|
|
1247
|
+
* absent field means "do not manage connectors from here" and leaves
|
|
1248
|
+
* everything in `~/.funnel` alone. Other channels in funnel.json (not
|
|
1249
|
+
* passed to this call) are untouched.
|
|
1250
|
+
*
|
|
1251
|
+
* Returns the per-connector change set so callers (e.g. the claude launcher)
|
|
1252
|
+
* can drive listener hot-reload on the gateway after settings are written.
|
|
1060
1253
|
*/
|
|
1061
|
-
declare
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1254
|
+
declare class FunnelLocalConfigSync {
|
|
1255
|
+
private readonly channels;
|
|
1256
|
+
private readonly prompter;
|
|
1257
|
+
constructor(deps: Deps$7);
|
|
1258
|
+
ensure(channel: ChannelSpec): Promise<LocalConfigSyncResult>;
|
|
1259
|
+
private ensureConnector;
|
|
1260
|
+
private ensureSlack;
|
|
1261
|
+
private ensureDiscord;
|
|
1262
|
+
private ensureGh;
|
|
1263
|
+
private ensureSchedule;
|
|
1264
|
+
private findExistingSlack;
|
|
1265
|
+
private findExistingDiscord;
|
|
1266
|
+
private removeExtras;
|
|
1267
|
+
/**
|
|
1268
|
+
* Decides how a single token slot is stored in settings.json. funnel.json
|
|
1269
|
+
* never carries tokens, so the only sources are a value already in
|
|
1270
|
+
* settings.json (carried over verbatim, whichever form it was — literal or an
|
|
1271
|
+
* `env`-var reference set via the CLI) or, on first sync, a TTY prompt for a
|
|
1272
|
+
* literal (throws when stdin is not a TTY). Either way the secret lands in the
|
|
1273
|
+
* repo-scoped settings, never in the repo itself.
|
|
1274
|
+
*/
|
|
1275
|
+
private resolveSlot;
|
|
1069
1276
|
}
|
|
1070
1277
|
//#endregion
|
|
1071
|
-
//#region lib/
|
|
1072
|
-
type Deps$
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1278
|
+
//#region lib/engine/local-config/local-config-writer.d.ts
|
|
1279
|
+
type Deps$6 = {
|
|
1280
|
+
fs: FunnelFileSystem;
|
|
1281
|
+
};
|
|
1282
|
+
/**
|
|
1283
|
+
* The one path that mutates the repo-committed funnel.json, and it only ever
|
|
1284
|
+
* inserts `id`. On first launch a repo has no `id`; funnel generates one and
|
|
1285
|
+
* writes it back here so future launches resolve the same `~/.funnel/projects/<id>/`.
|
|
1286
|
+
* Idempotent — a no-op once `id` is present. Kept separate from the read-only
|
|
1287
|
+
* FunnelLocalConfig so reads stay side-effect free.
|
|
1288
|
+
*/
|
|
1289
|
+
declare class FunnelLocalConfigWriter {
|
|
1290
|
+
private readonly fs;
|
|
1291
|
+
constructor(deps: Deps$6);
|
|
1292
|
+
ensureId(cwd: string, id: string): void;
|
|
1293
|
+
}
|
|
1294
|
+
//#endregion
|
|
1295
|
+
//#region lib/gateway/publish-schema.d.ts
|
|
1296
|
+
/**
|
|
1297
|
+
* Shared schema for `POST /channels/:channel/publish` — used by both the
|
|
1298
|
+
* gateway route handler (input validation) and the CLI / programmable client
|
|
1299
|
+
* (request shape). The route resolves `channel` from the path; this body
|
|
1300
|
+
* covers everything else.
|
|
1301
|
+
*/
|
|
1302
|
+
declare const publishRequestSchema: z.ZodObject<{
|
|
1303
|
+
content: z.ZodString;
|
|
1304
|
+
meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1305
|
+
connector: z.ZodOptional<z.ZodString>;
|
|
1306
|
+
}, z.core.$strip>;
|
|
1307
|
+
type PublishRequest = z.infer<typeof publishRequestSchema>;
|
|
1308
|
+
declare const publishResponseSchema: z.ZodObject<{
|
|
1309
|
+
ok: z.ZodLiteral<true>;
|
|
1310
|
+
offset: z.ZodNumber;
|
|
1311
|
+
}, z.core.$strip>;
|
|
1312
|
+
type PublishResponse = z.infer<typeof publishResponseSchema>;
|
|
1313
|
+
type PublishResult = {
|
|
1314
|
+
state: "ok";
|
|
1315
|
+
offset: number;
|
|
1316
|
+
} | {
|
|
1317
|
+
state: "offline";
|
|
1318
|
+
} | {
|
|
1319
|
+
state: "error";
|
|
1320
|
+
reason: string;
|
|
1321
|
+
};
|
|
1322
|
+
//#endregion
|
|
1323
|
+
//#region lib/gateway/channel-publisher.d.ts
|
|
1324
|
+
type Deps$5 = {
|
|
1325
|
+
port: number;
|
|
1326
|
+
isDaemonRunning: () => boolean; /** Returns the daemon's gateway token, or null if unavailable. Sent as `Authorization: Bearer`. */
|
|
1327
|
+
getToken?: () => string | null;
|
|
1328
|
+
};
|
|
1329
|
+
/**
|
|
1330
|
+
* HTTP client for `POST /channels/:channel/publish` on a running gateway
|
|
1331
|
+
* daemon. Returns `{ state: "offline" }` when the daemon isn't up so callers
|
|
1332
|
+
* can branch without exceptions, mirroring `FunnelListenersClient`.
|
|
1333
|
+
*/
|
|
1334
|
+
declare class FunnelChannelPublisher {
|
|
1335
|
+
private readonly port;
|
|
1336
|
+
private readonly isDaemonRunning;
|
|
1337
|
+
private readonly getToken;
|
|
1338
|
+
constructor(deps: Deps$5);
|
|
1339
|
+
publish(channelName: string, request: PublishRequest): Promise<PublishResult>;
|
|
1340
|
+
private authHeaders;
|
|
1341
|
+
}
|
|
1342
|
+
//#endregion
|
|
1343
|
+
//#region lib/gateway/funnel-event-log.d.ts
|
|
1344
|
+
/**
|
|
1345
|
+
* Replayable event payload persisted by the gateway. Domain events the
|
|
1346
|
+
* broadcaster emits to WS clients land here so reconnects across daemon
|
|
1347
|
+
* restarts can be served from disk. System events (gateway start, channel
|
|
1348
|
+
* connected, etc.) are routed to `FunnelLogger` instead — they never go
|
|
1349
|
+
* through this log, which keeps the offset space clean for replay.
|
|
1350
|
+
*/
|
|
1351
|
+
declare const funnelEventSchema: z.ZodObject<{
|
|
1352
|
+
type: z.ZodString;
|
|
1353
|
+
content: z.ZodString;
|
|
1354
|
+
channel_id: z.ZodNullable<z.ZodString>;
|
|
1355
|
+
connector_id: z.ZodNullable<z.ZodString>;
|
|
1356
|
+
meta: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1357
|
+
}, z.core.$strip>;
|
|
1358
|
+
type FunnelEvent = z.infer<typeof funnelEventSchema>;
|
|
1359
|
+
/** One broadcast event to persist, carrying the offset the broadcaster assigned. */
|
|
1360
|
+
type FunnelEventRecord = {
|
|
1361
|
+
content: string;
|
|
1362
|
+
channelId: string | null;
|
|
1363
|
+
connectorId: string | null;
|
|
1364
|
+
meta: Record<string, string> | null;
|
|
1365
|
+
offset: number;
|
|
1366
|
+
};
|
|
1367
|
+
/**
|
|
1368
|
+
* Durable, append-only log of broadcaster events keyed by the offset the
|
|
1369
|
+
* broadcaster assigns. The gateway persists every domain event here, and
|
|
1370
|
+
* across restarts it both seeds the broadcaster's offset counter
|
|
1371
|
+
* (`findMaxOffset`) and serves reconnect replay (`loadSince`) from it.
|
|
1372
|
+
*
|
|
1373
|
+
* `loadSince` is the only method the broadcaster itself needs, which makes
|
|
1374
|
+
* any implementation assignable to the broadcaster's narrow `ReplaySource`.
|
|
1375
|
+
*
|
|
1376
|
+
* Implementations:
|
|
1377
|
+
* - `SqliteFunnelEventLog` — the default; durable across daemon restarts.
|
|
1378
|
+
* - `MemoryFunnelEventLog` — an in-process double for tests and embedders
|
|
1379
|
+
* that do not need durability (replay is lost when the process exits).
|
|
1380
|
+
*/
|
|
1381
|
+
declare abstract class FunnelEventLog {
|
|
1382
|
+
abstract record(record: FunnelEventRecord): void;
|
|
1383
|
+
abstract loadSince(since: number): ReplayableEvent[];
|
|
1384
|
+
abstract findMaxOffset(): number;
|
|
1385
|
+
/** Drop every stored event and reclaim the file. The broadcaster's in-memory
|
|
1386
|
+
* offset counter is unaffected, so offsets keep increasing after a clear. */
|
|
1387
|
+
abstract clear(): void;
|
|
1388
|
+
abstract close(): void;
|
|
1389
|
+
}
|
|
1390
|
+
//#endregion
|
|
1391
|
+
//#region lib/gateway/gateway.d.ts
|
|
1392
|
+
type Deps$4 = {
|
|
1393
|
+
process?: FunnelProcessRunner;
|
|
1394
|
+
fs?: FunnelFileSystem;
|
|
1395
|
+
clock?: FunnelClock;
|
|
1396
|
+
dir?: string;
|
|
1397
|
+
tmpDir?: string;
|
|
1398
|
+
port?: number;
|
|
1079
1399
|
sleep?: (ms: number) => Promise<void>;
|
|
1080
1400
|
};
|
|
1081
1401
|
/**
|
|
@@ -1324,6 +1644,34 @@ declare class FunnelListenersClient {
|
|
|
1324
1644
|
private call;
|
|
1325
1645
|
}
|
|
1326
1646
|
//#endregion
|
|
1647
|
+
//#region lib/gateway/funnel-debug.d.ts
|
|
1648
|
+
type FunnelDebugReport = {
|
|
1649
|
+
gateway: {
|
|
1650
|
+
running: boolean;
|
|
1651
|
+
pid: number | null;
|
|
1652
|
+
port: number | null;
|
|
1653
|
+
uptimeMs: number | null;
|
|
1654
|
+
};
|
|
1655
|
+
channels: Array<{
|
|
1656
|
+
name: string;
|
|
1657
|
+
connectors: string[];
|
|
1658
|
+
listener: {
|
|
1659
|
+
alive: boolean;
|
|
1660
|
+
events: number;
|
|
1661
|
+
errors: number;
|
|
1662
|
+
lastEventAt: string | null;
|
|
1663
|
+
} | null;
|
|
1664
|
+
claudeConnected: boolean;
|
|
1665
|
+
claudeClientCount: number;
|
|
1666
|
+
}>;
|
|
1667
|
+
recentEvents: Array<{
|
|
1668
|
+
ts: number;
|
|
1669
|
+
outcome: string;
|
|
1670
|
+
payload: string | null;
|
|
1671
|
+
preview: string | null;
|
|
1672
|
+
}> | null;
|
|
1673
|
+
};
|
|
1674
|
+
//#endregion
|
|
1327
1675
|
//#region lib/funnel.d.ts
|
|
1328
1676
|
type Props$8 = {
|
|
1329
1677
|
/** 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. */
|
|
@@ -1466,6 +1814,8 @@ declare class Funnel {
|
|
|
1466
1814
|
*/
|
|
1467
1815
|
extraRoutes?: Hono<Env$1>;
|
|
1468
1816
|
}): FunnelGatewayServer;
|
|
1817
|
+
debug(channelName?: string): Promise<FunnelDebugReport>;
|
|
1818
|
+
gatewayClient(): ReturnType<typeof hc<GatewayApp>>;
|
|
1469
1819
|
}
|
|
1470
1820
|
//#endregion
|
|
1471
1821
|
//#region lib/engine/mcp/channel-server.d.ts
|
|
@@ -1742,1543 +2092,219 @@ type Props$3 = {
|
|
|
1742
2092
|
};
|
|
1743
2093
|
/**
|
|
1744
2094
|
* Pre-seeded answers keyed by prompt label. Tests configure the map up front;
|
|
1745
|
-
* unmapped labels throw so the test surfaces unexpected prompts loudly.
|
|
1746
|
-
*/
|
|
1747
|
-
declare class MemoryFunnelTokenPrompter extends FunnelTokenPrompter {
|
|
1748
|
-
private readonly answers;
|
|
1749
|
-
readonly asked: string[];
|
|
1750
|
-
constructor(props?: Props$3);
|
|
1751
|
-
promptSecret(label: string): Promise<string>;
|
|
1752
|
-
}
|
|
1753
|
-
//#endregion
|
|
1754
|
-
//#region lib/gateway/sqlite-funnel-event-log.d.ts
|
|
1755
|
-
type Props$2 = {
|
|
1756
|
-
/** SQLite database file path. Created on first write. ":memory:" for tests. */path: string; /** Override for tests. Defaults to `Date.now`. */
|
|
1757
|
-
now?: () => number; /** Optional row cap. Pruned on every insert. */
|
|
1758
|
-
maxRows?: number; /** Optional age cap in ms. Pruned on every insert. */
|
|
1759
|
-
maxAgeMs?: number; /** Optional on-disk byte cap. Checked periodically; on overflow the oldest rows are dropped toward targetBytes and the file is VACUUMed. */
|
|
1760
|
-
maxBytes?: number; /** Shrink target when maxBytes is exceeded. Defaults to maxBytes/4. */
|
|
1761
|
-
targetBytes?: number;
|
|
1762
|
-
};
|
|
1763
|
-
/**
|
|
1764
|
-
* SQLite-backed `FunnelEventLog`. One indexed table holds every broadcaster
|
|
1765
|
-
* event with `channel_id` and `connector_id` as dedicated columns, so
|
|
1766
|
-
* per-channel and per-connector replay is an indexed range scan.
|
|
1767
|
-
*
|
|
1768
|
-
* Concurrency: `seq` is `INTEGER PRIMARY KEY`, so SQLite assigns it
|
|
1769
|
-
* atomically. The broadcaster owns its own offset counter at runtime
|
|
1770
|
-
* (seeded from `findMaxOffset()` at startup); each broadcaster event
|
|
1771
|
-
* flows in here via `record()` with that pre-assigned offset, which the
|
|
1772
|
-
* sink stores via `write()` — PK uniqueness catches double-emit bugs.
|
|
1773
|
-
*
|
|
1774
|
-
* System events (gateway lifecycle, channel connect/disconnect, etc.) do
|
|
1775
|
-
* NOT go through this store. They are diagnostic only and live in
|
|
1776
|
-
* `FunnelLogger`'s file so the seq space here stays exclusive to
|
|
1777
|
-
* broadcaster traffic. This is what makes the broadcaster's seq seeding
|
|
1778
|
-
* (`getMaxSeq()` at startup) correct without per-event coordination.
|
|
1779
|
-
*/
|
|
1780
|
-
declare class SqliteFunnelEventLog extends FunnelEventLog {
|
|
1781
|
-
private readonly sink;
|
|
1782
|
-
private readonly now;
|
|
1783
|
-
constructor(props: Props$2);
|
|
1784
|
-
/**
|
|
1785
|
-
* Persist a broadcaster-driven event with its assigned offset. Caller
|
|
1786
|
-
* (the gateway-server) supplies the offset from `broadcaster.broadcast()`
|
|
1787
|
-
* so this store and the broadcaster's in-memory ring stay aligned.
|
|
1788
|
-
*/
|
|
1789
|
-
record(record: FunnelEventRecord): void;
|
|
1790
|
-
/**
|
|
1791
|
-
* Returns events with offset > since. Filtering by channel/connector is
|
|
1792
|
-
* the broadcaster's responsibility (it knows the client's subscription),
|
|
1793
|
-
* so this returns the full slice and lets the caller filter.
|
|
1794
|
-
*/
|
|
1795
|
-
loadSince(since: number): ReplayableEvent[];
|
|
1796
|
-
/**
|
|
1797
|
-
* Returns events for one channel (and optionally one connector). Used
|
|
1798
|
-
* by the gateway logs CLI for scoped queries. Channel/connector filters
|
|
1799
|
-
* are indexed columns, so this is an indexed range scan.
|
|
1800
|
-
*/
|
|
1801
|
-
loadForChannel(props: {
|
|
1802
|
-
channelId: string;
|
|
1803
|
-
connectorId?: string;
|
|
1804
|
-
sinceSeq?: number;
|
|
1805
|
-
limit?: number;
|
|
1806
|
-
}): ReplayableEvent[];
|
|
1807
|
-
findMaxOffset(): number;
|
|
1808
|
-
clear(): void;
|
|
1809
|
-
close(): void;
|
|
1810
|
-
}
|
|
1811
|
-
//#endregion
|
|
1812
|
-
//#region lib/gateway/memory-funnel-event-log.d.ts
|
|
1813
|
-
/**
|
|
1814
|
-
* In-process `FunnelEventLog` backed by a plain array. Used by tests and by
|
|
1815
|
-
* embedders that do not need durability — replay works within the process
|
|
1816
|
-
* lifetime but is lost when the process exits. Unlike the SQLite log it does
|
|
1817
|
-
* not truncate content or prune, so it is not meant for unbounded production
|
|
1818
|
-
* traffic.
|
|
1819
|
-
*/
|
|
1820
|
-
declare class MemoryFunnelEventLog extends FunnelEventLog {
|
|
1821
|
-
private readonly events;
|
|
1822
|
-
constructor();
|
|
1823
|
-
record(record: FunnelEventRecord): void;
|
|
1824
|
-
loadSince(since: number): ReplayableEvent[];
|
|
1825
|
-
findMaxOffset(): number;
|
|
1826
|
-
clear(): void;
|
|
1827
|
-
close(): void;
|
|
1828
|
-
}
|
|
1829
|
-
//#endregion
|
|
1830
|
-
//#region lib/gateway/sqlite-connector-diagnostic-log.d.ts
|
|
1831
|
-
type Props$1 = {
|
|
1832
|
-
/** SQLite file for the raw (pre-filter) table. ":memory:" for tests. */rawPath: string; /** SQLite file for the processed (verdict) table. ":memory:" for tests. */
|
|
1833
|
-
processedPath: string; /** SQLite file for the connection (lifecycle) table. ":memory:" for tests. */
|
|
1834
|
-
connectionPath: string;
|
|
1835
|
-
now?: () => number; /** Row cap for the processed and connection tables. Pruned on every insert. */
|
|
1836
|
-
maxRows?: number;
|
|
1837
|
-
/**
|
|
1838
|
-
* Row cap for the raw table specifically. Raw rows can each hold up to
|
|
1839
|
-
* `RAW_PAYLOAD_CAP` bytes, so they want a tighter cap than the small
|
|
1840
|
-
* processed/connection verdict rows. Defaults to `maxRows` when unset.
|
|
1841
|
-
*/
|
|
1842
|
-
rawMaxRows?: number; /** Age cap in ms for all tables — bounds how long untouched payloads (with PII) live. Pruned on every insert. */
|
|
1843
|
-
maxAgeMs?: number; /** When set, `insert()` errors (disk full, WAL lock) are logged instead of silently dropped. */
|
|
1844
|
-
logger?: FunnelLogger;
|
|
1845
|
-
};
|
|
1846
|
-
/**
|
|
1847
|
-
* Default `ConnectorDiagnosticLog`: three independent `LeucoLoggerSqliteSink`s, one
|
|
1848
|
-
* per table (raw / processed / connection), in separate files. Each sink
|
|
1849
|
-
* indexes the columns its queries filter on — `event_id` / `connector_id` /
|
|
1850
|
-
* `channel_id` for raw, plus `outcome` for processed and `status` for
|
|
1851
|
-
* connection — so those lookups are indexed scans (`type` is a fixed column
|
|
1852
|
-
* the sink extracts separately, not an index, so filtering by it is a scan).
|
|
1853
|
-
*
|
|
1854
|
-
* The raw table offloads any payload over `RAW_PAYLOAD_CAP`: rather than
|
|
1855
|
-
* truncating mid-string (which yields unparseable JSON), it replaces the
|
|
1856
|
-
* body with a small JSON object that keeps the diagnostic essentials and
|
|
1857
|
-
* records the dropped size under `_funnel_oversized`. Every stored payload
|
|
1858
|
-
* therefore stays valid JSON.
|
|
1859
|
-
*/
|
|
1860
|
-
declare class SqliteConnectorDiagnosticLog extends ConnectorDiagnosticLog {
|
|
1861
|
-
private readonly raw;
|
|
1862
|
-
private readonly processed;
|
|
1863
|
-
private readonly connection;
|
|
1864
|
-
private readonly now;
|
|
1865
|
-
private readonly logger;
|
|
1866
|
-
constructor(props: Props$1);
|
|
1867
|
-
recordRaw(record: ConnectorRawRecord): void;
|
|
1868
|
-
recordProcessed(record: ConnectorProcessedRecord): void;
|
|
1869
|
-
recordConnection(record: ConnectorConnectionRecord): void;
|
|
1870
|
-
private report;
|
|
1871
|
-
queryRaw(query: ConnectorRawQuery): StoredRawEvent[];
|
|
1872
|
-
queryProcessed(query: ConnectorProcessedQuery): StoredProcessedEvent[];
|
|
1873
|
-
queryConnection(query: ConnectorConnectionQuery): StoredConnectionEvent[];
|
|
1874
|
-
clear(): void;
|
|
1875
|
-
close(): void;
|
|
1876
|
-
}
|
|
1877
|
-
//#endregion
|
|
1878
|
-
//#region lib/gateway/memory-connector-diagnostic-log.d.ts
|
|
1879
|
-
/**
|
|
1880
|
-
* In-process `ConnectorDiagnosticLog` backed by one array per table. Used by tests
|
|
1881
|
-
* and embedders that do not need durability. Like the SQLite log it keeps
|
|
1882
|
-
* `seq` per-table (each array's 1-based position) and returns the most recent
|
|
1883
|
-
* `limit` rows oldest-first; unlike it, it never prunes and never offloads
|
|
1884
|
-
* oversized payloads — it keeps whatever the caller hands it, which is fine
|
|
1885
|
-
* for the bounded volumes a test produces. Payload-validity is therefore a
|
|
1886
|
-
* SQLite-only guarantee; do not write a test that leans on this double
|
|
1887
|
-
* rejecting a malformed payload.
|
|
1888
|
-
*/
|
|
1889
|
-
declare class MemoryConnectorDiagnosticLog extends ConnectorDiagnosticLog {
|
|
1890
|
-
private readonly now;
|
|
1891
|
-
private readonly raws;
|
|
1892
|
-
private readonly processeds;
|
|
1893
|
-
private readonly connections;
|
|
1894
|
-
constructor(now?: () => number);
|
|
1895
|
-
recordRaw(record: ConnectorRawRecord): void;
|
|
1896
|
-
recordProcessed(record: ConnectorProcessedRecord): void;
|
|
1897
|
-
recordConnection(record: ConnectorConnectionRecord): void;
|
|
1898
|
-
queryRaw(query: ConnectorRawQuery): StoredRawEvent[];
|
|
1899
|
-
queryProcessed(query: ConnectorProcessedQuery): StoredProcessedEvent[];
|
|
1900
|
-
queryConnection(query: ConnectorConnectionQuery): StoredConnectionEvent[];
|
|
1901
|
-
clear(): void;
|
|
1902
|
-
close(): void;
|
|
1903
|
-
}
|
|
1904
|
-
//#endregion
|
|
1905
|
-
//#region lib/gateway/connector-diagnostic-sql-reader.d.ts
|
|
1906
|
-
type Props = {
|
|
1907
|
-
/** SQLite file holding the raw (pre-filter) table. */rawPath: string; /** SQLite file holding the processed (verdict) table. */
|
|
1908
|
-
processedPath: string; /** SQLite file holding the connection (lifecycle) table. */
|
|
1909
|
-
connectionPath: string;
|
|
1910
|
-
};
|
|
1911
|
-
type Row = Record<string, unknown>;
|
|
1912
|
-
/**
|
|
1913
|
-
* Read-only SQL surface over the three diagnostic tables, for Claude to query
|
|
1914
|
-
* the log with arbitrary `SELECT`s. It opens all files read-only and exposes
|
|
1915
|
-
* three views — `raw`, `processed`, `connection` — that hide the storage
|
|
1916
|
-
* details (the physical table is `leuco_log` and each row's columns live
|
|
1917
|
-
* inside a JSON `event` blob): the views surface the columns as plain fields,
|
|
1918
|
-
* with `payload` already pulled out of the nested JSON.
|
|
1919
|
-
*
|
|
1920
|
-
* The tables are separate files. `raw` and `processed` share an `event_id`,
|
|
1921
|
-
* so a `JOIN` answers "the event arrived, but what verdict did it get?";
|
|
1922
|
-
* `connection` answers the other half — "did the listener ever connect at
|
|
1923
|
-
* all?". Writes are impossible: the connection is read-only and `query`
|
|
1924
|
-
* rejects anything but a single `SELECT`.
|
|
1925
|
-
*/
|
|
1926
|
-
declare class ConnectorDiagnosticSqlReader {
|
|
1927
|
-
private readonly db;
|
|
1928
|
-
constructor(props: Props);
|
|
1929
|
-
/**
|
|
1930
|
-
* Run one read-only `SELECT` and return the rows. Returns an `Error` (rather
|
|
1931
|
-
* than throwing) for a non-SELECT statement or a SQL error, so the caller
|
|
1932
|
-
* can surface the message without a stack trace.
|
|
1933
|
-
*/
|
|
1934
|
-
query(sql: string): Row[] | Error;
|
|
1935
|
-
close(): void;
|
|
1936
|
-
}
|
|
1937
|
-
//#endregion
|
|
1938
|
-
//#region lib/cli/factory.d.ts
|
|
1939
|
-
type Env = {
|
|
1940
|
-
|
|
1941
|
-
funnel: Funnel;
|
|
1942
|
-
};
|
|
1943
|
-
};
|
|
1944
|
-
declare const factory: _$hono_factory0.Factory<Env, string>;
|
|
1945
|
-
//#endregion
|
|
1946
|
-
//#region lib/cli/router/to-request.d.ts
|
|
1947
|
-
declare const toRequest: (args: string[]) => {
|
|
1948
|
-
method: string;
|
|
1949
|
-
path: string;
|
|
1950
|
-
url: string;
|
|
1951
|
-
};
|
|
1952
|
-
//#endregion
|
|
1953
|
-
//#region lib/cli/router/query-to-cli-args.d.ts
|
|
1954
|
-
declare const queryToCliArgs: (url: string, reservedKeys?: string[]) => string[];
|
|
1955
|
-
//#endregion
|
|
1956
|
-
//#region lib/cli/routes/index.d.ts
|
|
1957
|
-
/**
|
|
1958
|
-
* Build the CLI Hono app wired to a specific Funnel instance.
|
|
1959
|
-
* Exposed so library consumers can mount the same routes their `fnl` CLI
|
|
1960
|
-
* uses against a custom Funnel (e.g. one with sandboxed boundaries).
|
|
1961
|
-
*
|
|
1962
|
-
* All CLI verbs (`add` / `remove` / `set` / `rename` / `as-default` / `request`) map to POST in
|
|
1963
|
-
* to-request.ts and stay in the URL as a literal segment. Read paths (list / show / launch) keep GET.
|
|
1964
|
-
* Help shortcuts at parameterless URLs return the help text directly so `funnel <verb>` (no args) is
|
|
1965
|
-
* informative instead of 404.
|
|
1966
|
-
*/
|
|
1967
|
-
declare const createCliApp: (funnel: Funnel) => _$hono_hono_base0.HonoBase<Env, {
|
|
1968
|
-
"/claude": {
|
|
1969
|
-
$get: {
|
|
1970
|
-
input: {
|
|
1971
|
-
query: {
|
|
1972
|
-
[x: string]: string | string[];
|
|
1973
|
-
profile?: string | undefined;
|
|
1974
|
-
channel?: string | undefined;
|
|
1975
|
-
};
|
|
1976
|
-
};
|
|
1977
|
-
output: string;
|
|
1978
|
-
outputFormat: "text";
|
|
1979
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
1980
|
-
} | {
|
|
1981
|
-
input: {
|
|
1982
|
-
query: {
|
|
1983
|
-
[x: string]: string | string[];
|
|
1984
|
-
profile?: string | undefined;
|
|
1985
|
-
channel?: string | undefined;
|
|
1986
|
-
};
|
|
1987
|
-
};
|
|
1988
|
-
output: "funnel claude — launch Claude Code\n\nusage:\n funnel claude launch the first channel from funnel.json, or the default profile\n funnel claude --channel <name> with funnel.json: select that channel; without: raw launch\n funnel claude -p <name> launch a named profile\n funnel claude --profile <name> (long form)\n funnel claude [...] any other argument is forwarded to the claude CLI\n\nresolution order:\n 1. --help print this help\n 2. --profile <name> named profile (ignores funnel.json)\n 3. ./funnel.json in the current directory + --channel selects (or first wins)\n 4. --channel <name> with no funnel.json → raw launch using an existing settings.json channel\n 5. 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 (selects from funnel.json, or raw-launches if no funnel.json)\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.";
|
|
1989
|
-
outputFormat: "text";
|
|
1990
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
1991
|
-
};
|
|
1992
|
-
};
|
|
1993
|
-
} & {
|
|
1994
|
-
"/channels": {
|
|
1995
|
-
$get: {
|
|
1996
|
-
input: {
|
|
1997
|
-
query: Record<string, never>;
|
|
1998
|
-
};
|
|
1999
|
-
output: string;
|
|
2000
|
-
outputFormat: "text";
|
|
2001
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2002
|
-
};
|
|
2003
|
-
};
|
|
2004
|
-
} & {
|
|
2005
|
-
"/channels/add": {
|
|
2006
|
-
$post: {
|
|
2007
|
-
input: {};
|
|
2008
|
-
output: string;
|
|
2009
|
-
outputFormat: "text";
|
|
2010
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2011
|
-
};
|
|
2012
|
-
};
|
|
2013
|
-
} & {
|
|
2014
|
-
"/channels/add/:channel": {
|
|
2015
|
-
$post: {
|
|
2016
|
-
input: {
|
|
2017
|
-
param: {
|
|
2018
|
-
channel: string;
|
|
2019
|
-
};
|
|
2020
|
-
} & {
|
|
2021
|
-
query: {
|
|
2022
|
-
delivery?: "fanout" | "exclusive" | undefined;
|
|
2023
|
-
};
|
|
2024
|
-
};
|
|
2025
|
-
output: string;
|
|
2026
|
-
outputFormat: "text";
|
|
2027
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2028
|
-
} | {
|
|
2029
|
-
input: {
|
|
2030
|
-
param: {
|
|
2031
|
-
channel: string;
|
|
2032
|
-
};
|
|
2033
|
-
} & {
|
|
2034
|
-
query: {
|
|
2035
|
-
delivery?: "fanout" | "exclusive" | undefined;
|
|
2036
|
-
};
|
|
2037
|
-
};
|
|
2038
|
-
output: `added channel "${string}" (id: ${string})`;
|
|
2039
|
-
outputFormat: "text";
|
|
2040
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2041
|
-
};
|
|
2042
|
-
};
|
|
2043
|
-
} & {
|
|
2044
|
-
"/channels/remove": {
|
|
2045
|
-
$post: {
|
|
2046
|
-
input: {};
|
|
2047
|
-
output: string;
|
|
2048
|
-
outputFormat: "text";
|
|
2049
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2050
|
-
};
|
|
2051
|
-
};
|
|
2052
|
-
} & {
|
|
2053
|
-
"/channels/remove/:channel": {
|
|
2054
|
-
$post: {
|
|
2055
|
-
input: {
|
|
2056
|
-
param: {
|
|
2057
|
-
channel: string;
|
|
2058
|
-
};
|
|
2059
|
-
} & {
|
|
2060
|
-
query: Record<string, never>;
|
|
2061
|
-
};
|
|
2062
|
-
output: string;
|
|
2063
|
-
outputFormat: "text";
|
|
2064
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2065
|
-
} | {
|
|
2066
|
-
input: {
|
|
2067
|
-
param: {
|
|
2068
|
-
channel: string;
|
|
2069
|
-
};
|
|
2070
|
-
} & {
|
|
2071
|
-
query: Record<string, never>;
|
|
2072
|
-
};
|
|
2073
|
-
output: `removed channel "${string}"`;
|
|
2074
|
-
outputFormat: "text";
|
|
2075
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2076
|
-
};
|
|
2077
|
-
};
|
|
2078
|
-
} & {
|
|
2079
|
-
"/channels/rename/:channel/:newName": {
|
|
2080
|
-
$post: {
|
|
2081
|
-
input: {
|
|
2082
|
-
param: {
|
|
2083
|
-
channel: string;
|
|
2084
|
-
newName: string;
|
|
2085
|
-
};
|
|
2086
|
-
} & {
|
|
2087
|
-
query: Record<string, never>;
|
|
2088
|
-
};
|
|
2089
|
-
output: string;
|
|
2090
|
-
outputFormat: "text";
|
|
2091
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2092
|
-
} | {
|
|
2093
|
-
input: {
|
|
2094
|
-
param: {
|
|
2095
|
-
channel: string;
|
|
2096
|
-
newName: string;
|
|
2097
|
-
};
|
|
2098
|
-
} & {
|
|
2099
|
-
query: Record<string, never>;
|
|
2100
|
-
};
|
|
2101
|
-
output: `renamed channel "${string}" to "${string}"`;
|
|
2102
|
-
outputFormat: "text";
|
|
2103
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2104
|
-
};
|
|
2105
|
-
};
|
|
2106
|
-
} & {
|
|
2107
|
-
"/channels/:channel/rename/:newName": {
|
|
2108
|
-
$post: {
|
|
2109
|
-
input: {
|
|
2110
|
-
param: {
|
|
2111
|
-
channel: string;
|
|
2112
|
-
newName: string;
|
|
2113
|
-
};
|
|
2114
|
-
} & {
|
|
2115
|
-
query: Record<string, never>;
|
|
2116
|
-
};
|
|
2117
|
-
output: string;
|
|
2118
|
-
outputFormat: "text";
|
|
2119
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2120
|
-
} | {
|
|
2121
|
-
input: {
|
|
2122
|
-
param: {
|
|
2123
|
-
channel: string;
|
|
2124
|
-
newName: string;
|
|
2125
|
-
};
|
|
2126
|
-
} & {
|
|
2127
|
-
query: Record<string, never>;
|
|
2128
|
-
};
|
|
2129
|
-
output: `renamed channel "${string}" to "${string}"`;
|
|
2130
|
-
outputFormat: "text";
|
|
2131
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2132
|
-
};
|
|
2133
|
-
};
|
|
2134
|
-
} & {
|
|
2135
|
-
"/channels/rename": {
|
|
2136
|
-
$post: {
|
|
2137
|
-
input: {};
|
|
2138
|
-
output: string;
|
|
2139
|
-
outputFormat: "text";
|
|
2140
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2141
|
-
};
|
|
2142
|
-
};
|
|
2143
|
-
} & {
|
|
2144
|
-
"/channels/:channel/rename": {
|
|
2145
|
-
$post: {
|
|
2146
|
-
input: {
|
|
2147
|
-
param: {
|
|
2148
|
-
channel: string;
|
|
2149
|
-
};
|
|
2150
|
-
};
|
|
2151
|
-
output: string;
|
|
2152
|
-
outputFormat: "text";
|
|
2153
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2154
|
-
};
|
|
2155
|
-
};
|
|
2156
|
-
} & {
|
|
2157
|
-
"/channels/:channel/set/delivery/:mode": {
|
|
2158
|
-
$post: {
|
|
2159
|
-
input: {
|
|
2160
|
-
param: {
|
|
2161
|
-
channel: string;
|
|
2162
|
-
mode: "fanout" | "exclusive";
|
|
2163
|
-
};
|
|
2164
|
-
};
|
|
2165
|
-
output: string;
|
|
2166
|
-
outputFormat: "text";
|
|
2167
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2168
|
-
} | {
|
|
2169
|
-
input: {
|
|
2170
|
-
param: {
|
|
2171
|
-
channel: string;
|
|
2172
|
-
mode: "fanout" | "exclusive";
|
|
2173
|
-
};
|
|
2174
|
-
};
|
|
2175
|
-
output: `channel "${string}" delivery set to fanout` | `channel "${string}" delivery set to exclusive`;
|
|
2176
|
-
outputFormat: "text";
|
|
2177
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2178
|
-
};
|
|
2179
|
-
};
|
|
2180
|
-
} & {
|
|
2181
|
-
"/channels/publish": {
|
|
2182
|
-
$post: {
|
|
2183
|
-
input: {};
|
|
2184
|
-
output: string;
|
|
2185
|
-
outputFormat: "text";
|
|
2186
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2187
|
-
};
|
|
2188
|
-
};
|
|
2189
|
-
} & {
|
|
2190
|
-
"/channels/:channel/publish": {
|
|
2191
|
-
$post: {
|
|
2192
|
-
input: {
|
|
2193
|
-
param: {
|
|
2194
|
-
channel: string;
|
|
2195
|
-
};
|
|
2196
|
-
} & {
|
|
2197
|
-
query: {
|
|
2198
|
-
[x: string]: string | string[];
|
|
2199
|
-
content: string | string[];
|
|
2200
|
-
connector?: string | undefined;
|
|
2201
|
-
};
|
|
2202
|
-
};
|
|
2203
|
-
output: string;
|
|
2204
|
-
outputFormat: "text";
|
|
2205
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2206
|
-
} | {
|
|
2207
|
-
input: {
|
|
2208
|
-
param: {
|
|
2209
|
-
channel: string;
|
|
2210
|
-
};
|
|
2211
|
-
} & {
|
|
2212
|
-
query: {
|
|
2213
|
-
[x: string]: string | string[];
|
|
2214
|
-
content: string | string[];
|
|
2215
|
-
connector?: string | undefined;
|
|
2216
|
-
};
|
|
2217
|
-
};
|
|
2218
|
-
output: `published (offset=${number})`;
|
|
2219
|
-
outputFormat: "text";
|
|
2220
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2221
|
-
};
|
|
2222
|
-
};
|
|
2223
|
-
} & {
|
|
2224
|
-
"/channels/:channel": {
|
|
2225
|
-
$get: {
|
|
2226
|
-
input: {
|
|
2227
|
-
param: {
|
|
2228
|
-
channel: string;
|
|
2229
|
-
};
|
|
2230
|
-
} & {
|
|
2231
|
-
query: Record<string, never>;
|
|
2232
|
-
};
|
|
2233
|
-
output: string;
|
|
2234
|
-
outputFormat: "text";
|
|
2235
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2236
|
-
};
|
|
2237
|
-
};
|
|
2238
|
-
} & {
|
|
2239
|
-
"/channels/:channel/connectors": {
|
|
2240
|
-
$get: {
|
|
2241
|
-
input: {
|
|
2242
|
-
param: {
|
|
2243
|
-
channel: string;
|
|
2244
|
-
};
|
|
2245
|
-
} & {
|
|
2246
|
-
query: Record<string, never>;
|
|
2247
|
-
};
|
|
2248
|
-
output: string;
|
|
2249
|
-
outputFormat: "text";
|
|
2250
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2251
|
-
};
|
|
2252
|
-
};
|
|
2253
|
-
} & {
|
|
2254
|
-
"/channels/:channel/connectors/add": {
|
|
2255
|
-
$post: {
|
|
2256
|
-
input: {
|
|
2257
|
-
param: {
|
|
2258
|
-
channel: string;
|
|
2259
|
-
};
|
|
2260
|
-
};
|
|
2261
|
-
output: string;
|
|
2262
|
-
outputFormat: "text";
|
|
2263
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2264
|
-
};
|
|
2265
|
-
};
|
|
2266
|
-
} & {
|
|
2267
|
-
"/channels/:channel/connectors/add/:connector": {
|
|
2268
|
-
$post: {
|
|
2269
|
-
input: {
|
|
2270
|
-
param: {
|
|
2271
|
-
channel: string;
|
|
2272
|
-
connector: string;
|
|
2273
|
-
};
|
|
2274
|
-
} & {
|
|
2275
|
-
query: {
|
|
2276
|
-
type: string | string[];
|
|
2277
|
-
"bot-token": string | string[];
|
|
2278
|
-
"app-token": string | string[];
|
|
2279
|
-
} | {
|
|
2280
|
-
type: string | string[];
|
|
2281
|
-
"poll-interval"?: string | string[] | undefined;
|
|
2282
|
-
} | {
|
|
2283
|
-
type: string | string[];
|
|
2284
|
-
"bot-token": string | string[];
|
|
2285
|
-
} | {
|
|
2286
|
-
type: string | string[];
|
|
2287
|
-
};
|
|
2288
|
-
};
|
|
2289
|
-
output: string;
|
|
2290
|
-
outputFormat: "text";
|
|
2291
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2292
|
-
} | {
|
|
2293
|
-
input: {
|
|
2294
|
-
param: {
|
|
2295
|
-
channel: string;
|
|
2296
|
-
connector: string;
|
|
2297
|
-
};
|
|
2298
|
-
} & {
|
|
2299
|
-
query: {
|
|
2300
|
-
type: string | string[];
|
|
2301
|
-
"bot-token": string | string[];
|
|
2302
|
-
"app-token": string | string[];
|
|
2303
|
-
} | {
|
|
2304
|
-
type: string | string[];
|
|
2305
|
-
"poll-interval"?: string | string[] | undefined;
|
|
2306
|
-
} | {
|
|
2307
|
-
type: string | string[];
|
|
2308
|
-
"bot-token": string | string[];
|
|
2309
|
-
} | {
|
|
2310
|
-
type: string | string[];
|
|
2311
|
-
};
|
|
2312
|
-
};
|
|
2313
|
-
output: `added slack connector "${string}" to channel "${string}"`;
|
|
2314
|
-
outputFormat: "text";
|
|
2315
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2316
|
-
} | {
|
|
2317
|
-
input: {
|
|
2318
|
-
param: {
|
|
2319
|
-
channel: string;
|
|
2320
|
-
connector: string;
|
|
2321
|
-
};
|
|
2322
|
-
} & {
|
|
2323
|
-
query: {
|
|
2324
|
-
type: string | string[];
|
|
2325
|
-
"bot-token": string | string[];
|
|
2326
|
-
"app-token": string | string[];
|
|
2327
|
-
} | {
|
|
2328
|
-
type: string | string[];
|
|
2329
|
-
"poll-interval"?: string | string[] | undefined;
|
|
2330
|
-
} | {
|
|
2331
|
-
type: string | string[];
|
|
2332
|
-
"bot-token": string | string[];
|
|
2333
|
-
} | {
|
|
2334
|
-
type: string | string[];
|
|
2335
|
-
};
|
|
2336
|
-
};
|
|
2337
|
-
output: `added gh connector "${string}" to channel "${string}"`;
|
|
2338
|
-
outputFormat: "text";
|
|
2339
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2340
|
-
} | {
|
|
2341
|
-
input: {
|
|
2342
|
-
param: {
|
|
2343
|
-
channel: string;
|
|
2344
|
-
connector: string;
|
|
2345
|
-
};
|
|
2346
|
-
} & {
|
|
2347
|
-
query: {
|
|
2348
|
-
type: string | string[];
|
|
2349
|
-
"bot-token": string | string[];
|
|
2350
|
-
"app-token": string | string[];
|
|
2351
|
-
} | {
|
|
2352
|
-
type: string | string[];
|
|
2353
|
-
"poll-interval"?: string | string[] | undefined;
|
|
2354
|
-
} | {
|
|
2355
|
-
type: string | string[];
|
|
2356
|
-
"bot-token": string | string[];
|
|
2357
|
-
} | {
|
|
2358
|
-
type: string | string[];
|
|
2359
|
-
};
|
|
2360
|
-
};
|
|
2361
|
-
output: `added discord connector "${string}" to channel "${string}"`;
|
|
2362
|
-
outputFormat: "text";
|
|
2363
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2364
|
-
} | {
|
|
2365
|
-
input: {
|
|
2366
|
-
param: {
|
|
2367
|
-
channel: string;
|
|
2368
|
-
connector: string;
|
|
2369
|
-
};
|
|
2370
|
-
} & {
|
|
2371
|
-
query: {
|
|
2372
|
-
type: string | string[];
|
|
2373
|
-
"bot-token": string | string[];
|
|
2374
|
-
"app-token": string | string[];
|
|
2375
|
-
} | {
|
|
2376
|
-
type: string | string[];
|
|
2377
|
-
"poll-interval"?: string | string[] | undefined;
|
|
2378
|
-
} | {
|
|
2379
|
-
type: string | string[];
|
|
2380
|
-
"bot-token": string | string[];
|
|
2381
|
-
} | {
|
|
2382
|
-
type: string | string[];
|
|
2383
|
-
};
|
|
2384
|
-
};
|
|
2385
|
-
output: `added schedule connector "${string}" to channel "${string}"`;
|
|
2386
|
-
outputFormat: "text";
|
|
2387
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2388
|
-
};
|
|
2389
|
-
};
|
|
2390
|
-
} & {
|
|
2391
|
-
"/channels/:channel/connectors/remove": {
|
|
2392
|
-
$post: {
|
|
2393
|
-
input: {
|
|
2394
|
-
param: {
|
|
2395
|
-
channel: string;
|
|
2396
|
-
};
|
|
2397
|
-
};
|
|
2398
|
-
output: string;
|
|
2399
|
-
outputFormat: "text";
|
|
2400
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2401
|
-
};
|
|
2402
|
-
};
|
|
2403
|
-
} & {
|
|
2404
|
-
"/channels/:channel/connectors/remove/:connector": {
|
|
2405
|
-
$post: {
|
|
2406
|
-
input: {
|
|
2407
|
-
param: {
|
|
2408
|
-
channel: string;
|
|
2409
|
-
connector: string;
|
|
2410
|
-
};
|
|
2411
|
-
} & {
|
|
2412
|
-
query: Record<string, never>;
|
|
2413
|
-
};
|
|
2414
|
-
output: string;
|
|
2415
|
-
outputFormat: "text";
|
|
2416
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2417
|
-
} | {
|
|
2418
|
-
input: {
|
|
2419
|
-
param: {
|
|
2420
|
-
channel: string;
|
|
2421
|
-
connector: string;
|
|
2422
|
-
};
|
|
2423
|
-
} & {
|
|
2424
|
-
query: Record<string, never>;
|
|
2425
|
-
};
|
|
2426
|
-
output: `removed connector "${string}" from channel "${string}"`;
|
|
2427
|
-
outputFormat: "text";
|
|
2428
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2429
|
-
};
|
|
2430
|
-
};
|
|
2431
|
-
} & {
|
|
2432
|
-
"/channels/:channel/connectors/set": {
|
|
2433
|
-
$post: {
|
|
2434
|
-
input: {
|
|
2435
|
-
param: {
|
|
2436
|
-
channel: string;
|
|
2437
|
-
};
|
|
2438
|
-
};
|
|
2439
|
-
output: string;
|
|
2440
|
-
outputFormat: "text";
|
|
2441
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2442
|
-
};
|
|
2443
|
-
};
|
|
2444
|
-
} & {
|
|
2445
|
-
"/channels/:channel/connectors/set/:connector": {
|
|
2446
|
-
$post: {
|
|
2447
|
-
input: {
|
|
2448
|
-
param: {
|
|
2449
|
-
channel: string;
|
|
2450
|
-
connector: string;
|
|
2451
|
-
};
|
|
2452
|
-
} & {
|
|
2453
|
-
query: {
|
|
2454
|
-
[x: string]: string | string[];
|
|
2455
|
-
"bot-token"?: string | undefined;
|
|
2456
|
-
"app-token"?: string | undefined;
|
|
2457
|
-
"poll-interval"?: string | string[] | undefined;
|
|
2458
|
-
};
|
|
2459
|
-
};
|
|
2460
|
-
output: string;
|
|
2461
|
-
outputFormat: "text";
|
|
2462
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2463
|
-
} | {
|
|
2464
|
-
input: {
|
|
2465
|
-
param: {
|
|
2466
|
-
channel: string;
|
|
2467
|
-
connector: string;
|
|
2468
|
-
};
|
|
2469
|
-
} & {
|
|
2470
|
-
query: {
|
|
2471
|
-
[x: string]: string | string[];
|
|
2472
|
-
"bot-token"?: string | undefined;
|
|
2473
|
-
"app-token"?: string | undefined;
|
|
2474
|
-
"poll-interval"?: string | string[] | undefined;
|
|
2475
|
-
};
|
|
2476
|
-
};
|
|
2477
|
-
output: `updated connector "${string}" in channel "${string}"`;
|
|
2478
|
-
outputFormat: "text";
|
|
2479
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2480
|
-
};
|
|
2481
|
-
};
|
|
2482
|
-
} & {
|
|
2483
|
-
"/channels/:channel/connectors/rename/:connector/:newName": {
|
|
2484
|
-
$post: {
|
|
2485
|
-
input: {
|
|
2486
|
-
param: {
|
|
2487
|
-
channel: string;
|
|
2488
|
-
connector: string;
|
|
2489
|
-
newName: string;
|
|
2490
|
-
};
|
|
2491
|
-
} & {
|
|
2492
|
-
query: Record<string, never>;
|
|
2493
|
-
};
|
|
2494
|
-
output: string;
|
|
2495
|
-
outputFormat: "text";
|
|
2496
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2497
|
-
} | {
|
|
2498
|
-
input: {
|
|
2499
|
-
param: {
|
|
2500
|
-
channel: string;
|
|
2501
|
-
connector: string;
|
|
2502
|
-
newName: string;
|
|
2503
|
-
};
|
|
2504
|
-
} & {
|
|
2505
|
-
query: Record<string, never>;
|
|
2506
|
-
};
|
|
2507
|
-
output: `renamed connector "${string}" to "${string}"`;
|
|
2508
|
-
outputFormat: "text";
|
|
2509
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2510
|
-
};
|
|
2511
|
-
};
|
|
2512
|
-
} & {
|
|
2513
|
-
"/channels/:channel/connectors/:connector/rename/:newName": {
|
|
2514
|
-
$post: {
|
|
2515
|
-
input: {
|
|
2516
|
-
param: {
|
|
2517
|
-
channel: string;
|
|
2518
|
-
connector: string;
|
|
2519
|
-
newName: string;
|
|
2520
|
-
};
|
|
2521
|
-
} & {
|
|
2522
|
-
query: Record<string, never>;
|
|
2523
|
-
};
|
|
2524
|
-
output: string;
|
|
2525
|
-
outputFormat: "text";
|
|
2526
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2527
|
-
} | {
|
|
2528
|
-
input: {
|
|
2529
|
-
param: {
|
|
2530
|
-
channel: string;
|
|
2531
|
-
connector: string;
|
|
2532
|
-
newName: string;
|
|
2533
|
-
};
|
|
2534
|
-
} & {
|
|
2535
|
-
query: Record<string, never>;
|
|
2536
|
-
};
|
|
2537
|
-
output: `renamed connector "${string}" to "${string}"`;
|
|
2538
|
-
outputFormat: "text";
|
|
2539
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2540
|
-
};
|
|
2541
|
-
};
|
|
2542
|
-
} & {
|
|
2543
|
-
"/channels/:channel/connectors/rename": {
|
|
2544
|
-
$post: {
|
|
2545
|
-
input: {
|
|
2546
|
-
param: {
|
|
2547
|
-
channel: string;
|
|
2548
|
-
};
|
|
2549
|
-
};
|
|
2550
|
-
output: string;
|
|
2551
|
-
outputFormat: "text";
|
|
2552
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2553
|
-
};
|
|
2554
|
-
};
|
|
2555
|
-
} & {
|
|
2556
|
-
"/channels/:channel/connectors/:connector/rename": {
|
|
2557
|
-
$post: {
|
|
2558
|
-
input: {
|
|
2559
|
-
param: {
|
|
2560
|
-
channel: string;
|
|
2561
|
-
} & {
|
|
2562
|
-
connector: string;
|
|
2563
|
-
};
|
|
2564
|
-
};
|
|
2565
|
-
output: string;
|
|
2566
|
-
outputFormat: "text";
|
|
2567
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2568
|
-
};
|
|
2569
|
-
};
|
|
2570
|
-
} & {
|
|
2571
|
-
"/channels/:channel/connectors/:connector/request": {
|
|
2572
|
-
$post: {
|
|
2573
|
-
input: {
|
|
2574
|
-
param: {
|
|
2575
|
-
channel: string;
|
|
2576
|
-
connector: string;
|
|
2577
|
-
};
|
|
2578
|
-
} & {
|
|
2579
|
-
query: {
|
|
2580
|
-
[x: string]: string | string[];
|
|
2581
|
-
method: string | string[];
|
|
2582
|
-
};
|
|
2583
|
-
};
|
|
2584
|
-
output: string;
|
|
2585
|
-
outputFormat: "text";
|
|
2586
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2587
|
-
};
|
|
2588
|
-
};
|
|
2589
|
-
} & {
|
|
2590
|
-
"/channels/:channel/connectors/:connector": {
|
|
2591
|
-
$get: {
|
|
2592
|
-
input: {
|
|
2593
|
-
param: {
|
|
2594
|
-
channel: string;
|
|
2595
|
-
connector: string;
|
|
2596
|
-
};
|
|
2597
|
-
} & {
|
|
2598
|
-
query: Record<string, never>;
|
|
2599
|
-
};
|
|
2600
|
-
output: string;
|
|
2601
|
-
outputFormat: "text";
|
|
2602
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2603
|
-
};
|
|
2604
|
-
};
|
|
2605
|
-
} & {
|
|
2606
|
-
"/channels/:channel/connectors/:connector/schedules": {
|
|
2607
|
-
$get: {
|
|
2608
|
-
input: {
|
|
2609
|
-
param: {
|
|
2610
|
-
channel: string;
|
|
2611
|
-
connector: string;
|
|
2612
|
-
};
|
|
2613
|
-
} & {
|
|
2614
|
-
query: Record<string, never>;
|
|
2615
|
-
};
|
|
2616
|
-
output: string;
|
|
2617
|
-
outputFormat: "text";
|
|
2618
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2619
|
-
};
|
|
2620
|
-
};
|
|
2621
|
-
} & {
|
|
2622
|
-
"/channels/:channel/connectors/:connector/schedules/add": {
|
|
2623
|
-
$post: {
|
|
2624
|
-
input: {
|
|
2625
|
-
param: {
|
|
2626
|
-
channel: string;
|
|
2627
|
-
} & {
|
|
2628
|
-
connector: string;
|
|
2629
|
-
};
|
|
2630
|
-
};
|
|
2631
|
-
output: string;
|
|
2632
|
-
outputFormat: "text";
|
|
2633
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2634
|
-
};
|
|
2635
|
-
};
|
|
2636
|
-
} & {
|
|
2637
|
-
"/channels/:channel/connectors/:connector/schedules/add/:id": {
|
|
2638
|
-
$post: {
|
|
2639
|
-
input: {
|
|
2640
|
-
param: {
|
|
2641
|
-
channel: string;
|
|
2642
|
-
connector: string;
|
|
2643
|
-
id: string;
|
|
2644
|
-
};
|
|
2645
|
-
} & {
|
|
2646
|
-
query: {
|
|
2647
|
-
cron: string | string[];
|
|
2648
|
-
prompt: string | string[];
|
|
2649
|
-
enabled?: string | string[] | undefined;
|
|
2650
|
-
"catchup-policy"?: "latest" | "all" | "skip" | undefined;
|
|
2651
|
-
};
|
|
2652
|
-
};
|
|
2653
|
-
output: string;
|
|
2654
|
-
outputFormat: "text";
|
|
2655
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2656
|
-
} | {
|
|
2657
|
-
input: {
|
|
2658
|
-
param: {
|
|
2659
|
-
channel: string;
|
|
2660
|
-
connector: string;
|
|
2661
|
-
id: string;
|
|
2662
|
-
};
|
|
2663
|
-
} & {
|
|
2664
|
-
query: {
|
|
2665
|
-
cron: string | string[];
|
|
2666
|
-
prompt: string | string[];
|
|
2667
|
-
enabled?: string | string[] | undefined;
|
|
2668
|
-
"catchup-policy"?: "latest" | "all" | "skip" | undefined;
|
|
2669
|
-
};
|
|
2670
|
-
};
|
|
2671
|
-
output: `added schedule entry "${string}"`;
|
|
2672
|
-
outputFormat: "text";
|
|
2673
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2674
|
-
};
|
|
2675
|
-
};
|
|
2676
|
-
} & {
|
|
2677
|
-
"/channels/:channel/connectors/:connector/schedules/remove": {
|
|
2678
|
-
$post: {
|
|
2679
|
-
input: {
|
|
2680
|
-
param: {
|
|
2681
|
-
channel: string;
|
|
2682
|
-
} & {
|
|
2683
|
-
connector: string;
|
|
2684
|
-
};
|
|
2685
|
-
};
|
|
2686
|
-
output: string;
|
|
2687
|
-
outputFormat: "text";
|
|
2688
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2689
|
-
};
|
|
2690
|
-
};
|
|
2691
|
-
} & {
|
|
2692
|
-
"/channels/:channel/connectors/:connector/schedules/remove/:id": {
|
|
2693
|
-
$post: {
|
|
2694
|
-
input: {
|
|
2695
|
-
param: {
|
|
2696
|
-
channel: string;
|
|
2697
|
-
connector: string;
|
|
2698
|
-
id: string;
|
|
2699
|
-
};
|
|
2700
|
-
} & {
|
|
2701
|
-
query: Record<string, never>;
|
|
2702
|
-
};
|
|
2703
|
-
output: string;
|
|
2704
|
-
outputFormat: "text";
|
|
2705
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2706
|
-
} | {
|
|
2707
|
-
input: {
|
|
2708
|
-
param: {
|
|
2709
|
-
channel: string;
|
|
2710
|
-
connector: string;
|
|
2711
|
-
id: string;
|
|
2712
|
-
};
|
|
2713
|
-
} & {
|
|
2714
|
-
query: Record<string, never>;
|
|
2715
|
-
};
|
|
2716
|
-
output: `removed schedule entry "${string}"`;
|
|
2717
|
-
outputFormat: "text";
|
|
2718
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2719
|
-
};
|
|
2720
|
-
};
|
|
2721
|
-
} & {
|
|
2722
|
-
"/profiles": {
|
|
2723
|
-
$get: {
|
|
2724
|
-
input: {
|
|
2725
|
-
query: Record<string, never>;
|
|
2726
|
-
};
|
|
2727
|
-
output: string;
|
|
2728
|
-
outputFormat: "text";
|
|
2729
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2730
|
-
};
|
|
2731
|
-
};
|
|
2732
|
-
} & {
|
|
2733
|
-
"/profiles/add": {
|
|
2734
|
-
$post: {
|
|
2735
|
-
input: {};
|
|
2736
|
-
output: string;
|
|
2737
|
-
outputFormat: "text";
|
|
2738
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2739
|
-
};
|
|
2740
|
-
};
|
|
2741
|
-
} & {
|
|
2742
|
-
"/profiles/add/:profile": {
|
|
2743
|
-
$post: {
|
|
2744
|
-
input: {
|
|
2745
|
-
param: {
|
|
2746
|
-
profile: string;
|
|
2747
|
-
};
|
|
2748
|
-
} & {
|
|
2749
|
-
query: {
|
|
2750
|
-
path: string;
|
|
2751
|
-
channel: string;
|
|
2752
|
-
agent?: string | undefined;
|
|
2753
|
-
options?: string | undefined;
|
|
2754
|
-
env?: string | undefined;
|
|
2755
|
-
resume?: string | undefined;
|
|
2756
|
-
"no-resume"?: string | undefined;
|
|
2757
|
-
};
|
|
2758
|
-
};
|
|
2759
|
-
output: string;
|
|
2760
|
-
outputFormat: "text";
|
|
2761
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2762
|
-
} | {
|
|
2763
|
-
input: {
|
|
2764
|
-
param: {
|
|
2765
|
-
profile: string;
|
|
2766
|
-
};
|
|
2767
|
-
} & {
|
|
2768
|
-
query: {
|
|
2769
|
-
path: string;
|
|
2770
|
-
channel: string;
|
|
2771
|
-
agent?: string | undefined;
|
|
2772
|
-
options?: string | undefined;
|
|
2773
|
-
env?: string | undefined;
|
|
2774
|
-
resume?: string | undefined;
|
|
2775
|
-
"no-resume"?: string | undefined;
|
|
2776
|
-
};
|
|
2777
|
-
};
|
|
2778
|
-
output: `added profile "${string}"`;
|
|
2779
|
-
outputFormat: "text";
|
|
2780
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2781
|
-
};
|
|
2782
|
-
};
|
|
2783
|
-
} & {
|
|
2784
|
-
"/profiles/set": {
|
|
2785
|
-
$post: {
|
|
2786
|
-
input: {};
|
|
2787
|
-
output: string;
|
|
2788
|
-
outputFormat: "text";
|
|
2789
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2790
|
-
};
|
|
2791
|
-
};
|
|
2792
|
-
} & {
|
|
2793
|
-
"/profiles/set/:profile": {
|
|
2794
|
-
$post: {
|
|
2795
|
-
input: {
|
|
2796
|
-
param: {
|
|
2797
|
-
profile: string;
|
|
2798
|
-
};
|
|
2799
|
-
} & {
|
|
2800
|
-
query: {
|
|
2801
|
-
path?: string | undefined;
|
|
2802
|
-
channel?: string | undefined;
|
|
2803
|
-
agent?: string | undefined;
|
|
2804
|
-
options?: string | undefined;
|
|
2805
|
-
env?: string | undefined;
|
|
2806
|
-
resume?: string | undefined;
|
|
2807
|
-
"no-resume"?: string | undefined;
|
|
2808
|
-
};
|
|
2809
|
-
};
|
|
2810
|
-
output: string;
|
|
2811
|
-
outputFormat: "text";
|
|
2812
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2813
|
-
} | {
|
|
2814
|
-
input: {
|
|
2815
|
-
param: {
|
|
2816
|
-
profile: string;
|
|
2817
|
-
};
|
|
2818
|
-
} & {
|
|
2819
|
-
query: {
|
|
2820
|
-
path?: string | undefined;
|
|
2821
|
-
channel?: string | undefined;
|
|
2822
|
-
agent?: string | undefined;
|
|
2823
|
-
options?: string | undefined;
|
|
2824
|
-
env?: string | undefined;
|
|
2825
|
-
resume?: string | undefined;
|
|
2826
|
-
"no-resume"?: string | undefined;
|
|
2827
|
-
};
|
|
2828
|
-
};
|
|
2829
|
-
output: `updated profile "${string}"`;
|
|
2830
|
-
outputFormat: "text";
|
|
2831
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2832
|
-
};
|
|
2833
|
-
};
|
|
2834
|
-
} & {
|
|
2835
|
-
"/profiles/remove": {
|
|
2836
|
-
$post: {
|
|
2837
|
-
input: {};
|
|
2838
|
-
output: string;
|
|
2839
|
-
outputFormat: "text";
|
|
2840
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2841
|
-
};
|
|
2842
|
-
};
|
|
2843
|
-
} & {
|
|
2844
|
-
"/profiles/remove/:profile": {
|
|
2845
|
-
$post: {
|
|
2846
|
-
input: {
|
|
2847
|
-
param: {
|
|
2848
|
-
profile: string;
|
|
2849
|
-
};
|
|
2850
|
-
} & {
|
|
2851
|
-
query: Record<string, never>;
|
|
2852
|
-
};
|
|
2853
|
-
output: string;
|
|
2854
|
-
outputFormat: "text";
|
|
2855
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2856
|
-
} | {
|
|
2857
|
-
input: {
|
|
2858
|
-
param: {
|
|
2859
|
-
profile: string;
|
|
2860
|
-
};
|
|
2861
|
-
} & {
|
|
2862
|
-
query: Record<string, never>;
|
|
2863
|
-
};
|
|
2864
|
-
output: `removed profile "${string}"`;
|
|
2865
|
-
outputFormat: "text";
|
|
2866
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2867
|
-
};
|
|
2868
|
-
};
|
|
2869
|
-
} & {
|
|
2870
|
-
"/profiles/rename/:profile/:newName": {
|
|
2871
|
-
$post: {
|
|
2872
|
-
input: {
|
|
2873
|
-
param: {
|
|
2874
|
-
profile: string;
|
|
2875
|
-
newName: string;
|
|
2876
|
-
};
|
|
2877
|
-
} & {
|
|
2878
|
-
query: Record<string, never>;
|
|
2879
|
-
};
|
|
2880
|
-
output: string;
|
|
2881
|
-
outputFormat: "text";
|
|
2882
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2883
|
-
} | {
|
|
2884
|
-
input: {
|
|
2885
|
-
param: {
|
|
2886
|
-
profile: string;
|
|
2887
|
-
newName: string;
|
|
2888
|
-
};
|
|
2889
|
-
} & {
|
|
2890
|
-
query: Record<string, never>;
|
|
2891
|
-
};
|
|
2892
|
-
output: `renamed profile "${string}" to "${string}"`;
|
|
2893
|
-
outputFormat: "text";
|
|
2894
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2895
|
-
};
|
|
2896
|
-
};
|
|
2897
|
-
} & {
|
|
2898
|
-
"/profiles/:profile/rename/:newName": {
|
|
2899
|
-
$post: {
|
|
2900
|
-
input: {
|
|
2901
|
-
param: {
|
|
2902
|
-
profile: string;
|
|
2903
|
-
newName: string;
|
|
2904
|
-
};
|
|
2905
|
-
} & {
|
|
2906
|
-
query: Record<string, never>;
|
|
2907
|
-
};
|
|
2908
|
-
output: string;
|
|
2909
|
-
outputFormat: "text";
|
|
2910
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2911
|
-
} | {
|
|
2912
|
-
input: {
|
|
2913
|
-
param: {
|
|
2914
|
-
profile: string;
|
|
2915
|
-
newName: string;
|
|
2916
|
-
};
|
|
2917
|
-
} & {
|
|
2918
|
-
query: Record<string, never>;
|
|
2919
|
-
};
|
|
2920
|
-
output: `renamed profile "${string}" to "${string}"`;
|
|
2921
|
-
outputFormat: "text";
|
|
2922
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2923
|
-
};
|
|
2924
|
-
};
|
|
2925
|
-
} & {
|
|
2926
|
-
"/profiles/rename": {
|
|
2927
|
-
$post: {
|
|
2928
|
-
input: {};
|
|
2929
|
-
output: string;
|
|
2930
|
-
outputFormat: "text";
|
|
2931
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2932
|
-
};
|
|
2933
|
-
};
|
|
2934
|
-
} & {
|
|
2935
|
-
"/profiles/:profile/rename": {
|
|
2936
|
-
$post: {
|
|
2937
|
-
input: {
|
|
2938
|
-
param: {
|
|
2939
|
-
profile: string;
|
|
2940
|
-
};
|
|
2941
|
-
};
|
|
2942
|
-
output: string;
|
|
2943
|
-
outputFormat: "text";
|
|
2944
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2945
|
-
};
|
|
2946
|
-
};
|
|
2947
|
-
} & {
|
|
2948
|
-
"/profiles/:profile/as-default": {
|
|
2949
|
-
$post: {
|
|
2950
|
-
input: {
|
|
2951
|
-
param: {
|
|
2952
|
-
profile: string;
|
|
2953
|
-
};
|
|
2954
|
-
} & {
|
|
2955
|
-
query: Record<string, never>;
|
|
2956
|
-
};
|
|
2957
|
-
output: string;
|
|
2958
|
-
outputFormat: "text";
|
|
2959
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2960
|
-
} | {
|
|
2961
|
-
input: {
|
|
2962
|
-
param: {
|
|
2963
|
-
profile: string;
|
|
2964
|
-
};
|
|
2965
|
-
} & {
|
|
2966
|
-
query: Record<string, never>;
|
|
2967
|
-
};
|
|
2968
|
-
output: `profile "${string}" is now the default`;
|
|
2969
|
-
outputFormat: "text";
|
|
2970
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2971
|
-
};
|
|
2972
|
-
};
|
|
2973
|
-
} & {
|
|
2974
|
-
"/profiles/:profile/run": {
|
|
2975
|
-
$get: {
|
|
2976
|
-
input: {
|
|
2977
|
-
param: {
|
|
2978
|
-
profile: string;
|
|
2979
|
-
};
|
|
2980
|
-
} & {
|
|
2981
|
-
query: {
|
|
2982
|
-
[x: string]: string | string[];
|
|
2983
|
-
};
|
|
2984
|
-
};
|
|
2985
|
-
output: string;
|
|
2986
|
-
outputFormat: "text";
|
|
2987
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2988
|
-
} | {
|
|
2989
|
-
input: {
|
|
2990
|
-
param: {
|
|
2991
|
-
profile: string;
|
|
2992
|
-
};
|
|
2993
|
-
} & {
|
|
2994
|
-
query: {
|
|
2995
|
-
[x: string]: string | string[];
|
|
2996
|
-
};
|
|
2997
|
-
};
|
|
2998
|
-
output: Promise<never>;
|
|
2999
|
-
outputFormat: "json";
|
|
3000
|
-
status: _$hono_utils_http_status0.StatusCode;
|
|
3001
|
-
};
|
|
3002
|
-
};
|
|
3003
|
-
} & {
|
|
3004
|
-
"/profiles/:profile": {
|
|
3005
|
-
$get: {
|
|
3006
|
-
input: {
|
|
3007
|
-
param: {
|
|
3008
|
-
profile: string;
|
|
3009
|
-
};
|
|
3010
|
-
} & {
|
|
3011
|
-
query: {
|
|
3012
|
-
[x: string]: string | string[];
|
|
3013
|
-
};
|
|
3014
|
-
};
|
|
3015
|
-
output: string;
|
|
3016
|
-
outputFormat: "text";
|
|
3017
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3018
|
-
} | {
|
|
3019
|
-
input: {
|
|
3020
|
-
param: {
|
|
3021
|
-
profile: string;
|
|
3022
|
-
};
|
|
3023
|
-
} & {
|
|
3024
|
-
query: {
|
|
3025
|
-
[x: string]: string | string[];
|
|
3026
|
-
};
|
|
3027
|
-
};
|
|
3028
|
-
output: Promise<never>;
|
|
3029
|
-
outputFormat: "json";
|
|
3030
|
-
status: _$hono_utils_http_status0.StatusCode;
|
|
3031
|
-
};
|
|
3032
|
-
};
|
|
3033
|
-
} & {
|
|
3034
|
-
"/gateway": {
|
|
3035
|
-
$get: {
|
|
3036
|
-
input: {};
|
|
3037
|
-
output: string;
|
|
3038
|
-
outputFormat: "text";
|
|
3039
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3040
|
-
} | {
|
|
3041
|
-
input: {};
|
|
3042
|
-
output: "funnel gateway: running (pid null) — health check failed" | `funnel gateway: running (pid ${number}) \u2014 health check failed`;
|
|
3043
|
-
outputFormat: "text";
|
|
3044
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3045
|
-
} | {
|
|
3046
|
-
input: {};
|
|
3047
|
-
output: `funnel gateway: running (pid null)
|
|
3048
|
-
port: ${number}
|
|
3049
|
-
clients: ${string}` | `funnel gateway: running (pid ${number})
|
|
3050
|
-
port: ${number}
|
|
3051
|
-
clients: ${string}`;
|
|
3052
|
-
outputFormat: "text";
|
|
3053
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3054
|
-
};
|
|
3055
|
-
};
|
|
3056
|
-
} & {
|
|
3057
|
-
"/gateway/status": {
|
|
3058
|
-
$get: {
|
|
3059
|
-
input: {};
|
|
3060
|
-
output: string;
|
|
3061
|
-
outputFormat: "text";
|
|
3062
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3063
|
-
} | {
|
|
3064
|
-
input: {};
|
|
3065
|
-
output: "funnel gateway: running (pid null) — health check failed" | `funnel gateway: running (pid ${number}) \u2014 health check failed`;
|
|
3066
|
-
outputFormat: "text";
|
|
3067
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3068
|
-
} | {
|
|
3069
|
-
input: {};
|
|
3070
|
-
output: `funnel gateway: running (pid null)
|
|
3071
|
-
port: ${number}
|
|
3072
|
-
clients: ${string}` | `funnel gateway: running (pid ${number})
|
|
3073
|
-
port: ${number}
|
|
3074
|
-
clients: ${string}`;
|
|
3075
|
-
outputFormat: "text";
|
|
3076
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3077
|
-
};
|
|
3078
|
-
};
|
|
3079
|
-
} & {
|
|
3080
|
-
"/gateway/start": {
|
|
3081
|
-
$get: {
|
|
3082
|
-
input: {
|
|
3083
|
-
query: {
|
|
3084
|
-
"no-caffeine"?: string | undefined;
|
|
3085
|
-
};
|
|
3086
|
-
};
|
|
3087
|
-
output: string;
|
|
3088
|
-
outputFormat: "text";
|
|
3089
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3090
|
-
} | {
|
|
3091
|
-
input: {
|
|
3092
|
-
query: {
|
|
3093
|
-
"no-caffeine"?: string | undefined;
|
|
3094
|
-
};
|
|
3095
|
-
};
|
|
3096
|
-
output: "funnel gateway: already running (pid null)" | `funnel gateway: already running (pid ${number})`;
|
|
3097
|
-
outputFormat: "text";
|
|
3098
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3099
|
-
} | {
|
|
3100
|
-
input: {
|
|
3101
|
-
query: {
|
|
3102
|
-
"no-caffeine"?: string | undefined;
|
|
3103
|
-
};
|
|
3104
|
-
};
|
|
3105
|
-
output: "funnel gateway: started";
|
|
3106
|
-
outputFormat: "text";
|
|
3107
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3108
|
-
};
|
|
3109
|
-
};
|
|
3110
|
-
} & {
|
|
3111
|
-
"/gateway/stop": {
|
|
3112
|
-
$get: {
|
|
3113
|
-
input: {
|
|
3114
|
-
query: Record<string, never>;
|
|
3115
|
-
};
|
|
3116
|
-
output: string;
|
|
3117
|
-
outputFormat: "text";
|
|
3118
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3119
|
-
} | {
|
|
3120
|
-
input: {
|
|
3121
|
-
query: Record<string, never>;
|
|
3122
|
-
};
|
|
3123
|
-
output: "funnel gateway: no running process";
|
|
3124
|
-
outputFormat: "text";
|
|
3125
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3126
|
-
} | {
|
|
3127
|
-
input: {
|
|
3128
|
-
query: Record<string, never>;
|
|
3129
|
-
};
|
|
3130
|
-
output: "funnel gateway: stopped";
|
|
3131
|
-
outputFormat: "text";
|
|
3132
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3133
|
-
};
|
|
3134
|
-
};
|
|
3135
|
-
} & {
|
|
3136
|
-
"/gateway/restart": {
|
|
3137
|
-
$get: {
|
|
3138
|
-
input: {
|
|
3139
|
-
query: {
|
|
3140
|
-
"no-caffeine"?: string | undefined;
|
|
3141
|
-
};
|
|
3142
|
-
};
|
|
3143
|
-
output: string;
|
|
3144
|
-
outputFormat: "text";
|
|
3145
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3146
|
-
};
|
|
3147
|
-
};
|
|
3148
|
-
} & {
|
|
3149
|
-
"/gateway/run": {
|
|
3150
|
-
$get: {
|
|
3151
|
-
input: {
|
|
3152
|
-
query: {
|
|
3153
|
-
"no-caffeine"?: string | undefined;
|
|
3154
|
-
};
|
|
3155
|
-
};
|
|
3156
|
-
output: string;
|
|
3157
|
-
outputFormat: "text";
|
|
3158
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3159
|
-
} | {
|
|
3160
|
-
input: {
|
|
3161
|
-
query: {
|
|
3162
|
-
"no-caffeine"?: string | undefined;
|
|
3163
|
-
};
|
|
3164
|
-
};
|
|
3165
|
-
output: Promise<never>;
|
|
3166
|
-
outputFormat: "json";
|
|
3167
|
-
status: _$hono_utils_http_status0.StatusCode;
|
|
3168
|
-
};
|
|
3169
|
-
};
|
|
3170
|
-
} & {
|
|
3171
|
-
"/gateway/logs": {
|
|
3172
|
-
$get: {
|
|
3173
|
-
input: {
|
|
3174
|
-
query: {
|
|
3175
|
-
n?: string | undefined;
|
|
3176
|
-
};
|
|
3177
|
-
};
|
|
3178
|
-
output: string;
|
|
3179
|
-
outputFormat: "text";
|
|
3180
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3181
|
-
} | {
|
|
3182
|
-
input: {
|
|
3183
|
-
query: {
|
|
3184
|
-
n?: string | undefined;
|
|
3185
|
-
};
|
|
3186
|
-
};
|
|
3187
|
-
output: "no logs";
|
|
3188
|
-
outputFormat: "text";
|
|
3189
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3190
|
-
};
|
|
3191
|
-
};
|
|
3192
|
-
} & {
|
|
3193
|
-
"/gateway/sql": {
|
|
3194
|
-
$get: {
|
|
3195
|
-
input: {
|
|
3196
|
-
query: {
|
|
3197
|
-
query?: string | undefined;
|
|
3198
|
-
};
|
|
3199
|
-
};
|
|
3200
|
-
output: string;
|
|
3201
|
-
outputFormat: "text";
|
|
3202
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3203
|
-
};
|
|
3204
|
-
};
|
|
3205
|
-
} & {
|
|
3206
|
-
"/gateway/listeners": {
|
|
3207
|
-
$get: {
|
|
3208
|
-
input: {
|
|
3209
|
-
query: Record<string, never>;
|
|
3210
|
-
};
|
|
3211
|
-
output: string;
|
|
3212
|
-
outputFormat: "text";
|
|
3213
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3214
|
-
} | {
|
|
3215
|
-
input: {
|
|
3216
|
-
query: Record<string, never>;
|
|
3217
|
-
};
|
|
3218
|
-
output: "funnel gateway: no running listeners";
|
|
3219
|
-
outputFormat: "text";
|
|
3220
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3221
|
-
} | {
|
|
3222
|
-
input: {
|
|
3223
|
-
query: Record<string, never>;
|
|
3224
|
-
};
|
|
3225
|
-
output: `funnel gateway: running listeners
|
|
3226
|
-
${string}`;
|
|
3227
|
-
outputFormat: "text";
|
|
3228
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3229
|
-
};
|
|
3230
|
-
};
|
|
3231
|
-
} & {
|
|
3232
|
-
"/schema": {
|
|
3233
|
-
$get: {
|
|
3234
|
-
input: {
|
|
3235
|
-
query: Record<string, never>;
|
|
3236
|
-
};
|
|
3237
|
-
output: string;
|
|
3238
|
-
outputFormat: "text";
|
|
3239
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3240
|
-
} | {
|
|
3241
|
-
input: {
|
|
3242
|
-
query: Record<string, never>;
|
|
3243
|
-
};
|
|
3244
|
-
output: `${string}
|
|
3245
|
-
`;
|
|
3246
|
-
outputFormat: "text";
|
|
3247
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3248
|
-
};
|
|
3249
|
-
};
|
|
3250
|
-
} & {
|
|
3251
|
-
"/status": {
|
|
3252
|
-
$get: {
|
|
3253
|
-
input: {
|
|
3254
|
-
query: Record<string, never>;
|
|
3255
|
-
};
|
|
3256
|
-
output: string;
|
|
3257
|
-
outputFormat: "text";
|
|
3258
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3259
|
-
};
|
|
3260
|
-
};
|
|
3261
|
-
} & {
|
|
3262
|
-
"/update": {
|
|
3263
|
-
$get: {
|
|
3264
|
-
input: {
|
|
3265
|
-
query: Record<string, never>;
|
|
3266
|
-
};
|
|
3267
|
-
output: string;
|
|
3268
|
-
outputFormat: "text";
|
|
3269
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3270
|
-
} | {
|
|
3271
|
-
input: {
|
|
3272
|
-
query: Record<string, never>;
|
|
3273
|
-
};
|
|
3274
|
-
output: "updated @interactive-inc/claude-funnel";
|
|
3275
|
-
outputFormat: "text";
|
|
3276
|
-
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3277
|
-
};
|
|
2095
|
+
* unmapped labels throw so the test surfaces unexpected prompts loudly.
|
|
2096
|
+
*/
|
|
2097
|
+
declare class MemoryFunnelTokenPrompter extends FunnelTokenPrompter {
|
|
2098
|
+
private readonly answers;
|
|
2099
|
+
readonly asked: string[];
|
|
2100
|
+
constructor(props?: Props$3);
|
|
2101
|
+
promptSecret(label: string): Promise<string>;
|
|
2102
|
+
}
|
|
2103
|
+
//#endregion
|
|
2104
|
+
//#region lib/gateway/sqlite-funnel-event-log.d.ts
|
|
2105
|
+
type Props$2 = {
|
|
2106
|
+
/** SQLite database file path. Created on first write. ":memory:" for tests. */path: string; /** Override for tests. Defaults to `Date.now`. */
|
|
2107
|
+
now?: () => number; /** Optional row cap. Pruned on every insert. */
|
|
2108
|
+
maxRows?: number; /** Optional age cap in ms. Pruned on every insert. */
|
|
2109
|
+
maxAgeMs?: number; /** Optional on-disk byte cap. Checked periodically; on overflow the oldest rows are dropped toward targetBytes and the file is VACUUMed. */
|
|
2110
|
+
maxBytes?: number; /** Shrink target when maxBytes is exceeded. Defaults to maxBytes/4. */
|
|
2111
|
+
targetBytes?: number;
|
|
2112
|
+
};
|
|
2113
|
+
/**
|
|
2114
|
+
* SQLite-backed `FunnelEventLog`. One indexed table holds every broadcaster
|
|
2115
|
+
* event with `channel_id` and `connector_id` as dedicated columns, so
|
|
2116
|
+
* per-channel and per-connector replay is an indexed range scan.
|
|
2117
|
+
*
|
|
2118
|
+
* Concurrency: `seq` is `INTEGER PRIMARY KEY`, so SQLite assigns it
|
|
2119
|
+
* atomically. The broadcaster owns its own offset counter at runtime
|
|
2120
|
+
* (seeded from `findMaxOffset()` at startup); each broadcaster event
|
|
2121
|
+
* flows in here via `record()` with that pre-assigned offset, which the
|
|
2122
|
+
* sink stores via `write()` — PK uniqueness catches double-emit bugs.
|
|
2123
|
+
*
|
|
2124
|
+
* System events (gateway lifecycle, channel connect/disconnect, etc.) do
|
|
2125
|
+
* NOT go through this store. They are diagnostic only and live in
|
|
2126
|
+
* `FunnelLogger`'s file so the seq space here stays exclusive to
|
|
2127
|
+
* broadcaster traffic. This is what makes the broadcaster's seq seeding
|
|
2128
|
+
* (`getMaxSeq()` at startup) correct without per-event coordination.
|
|
2129
|
+
*/
|
|
2130
|
+
declare class SqliteFunnelEventLog extends FunnelEventLog {
|
|
2131
|
+
private readonly sink;
|
|
2132
|
+
private readonly now;
|
|
2133
|
+
constructor(props: Props$2);
|
|
2134
|
+
/**
|
|
2135
|
+
* Persist a broadcaster-driven event with its assigned offset. Caller
|
|
2136
|
+
* (the gateway-server) supplies the offset from `broadcaster.broadcast()`
|
|
2137
|
+
* so this store and the broadcaster's in-memory ring stay aligned.
|
|
2138
|
+
*/
|
|
2139
|
+
record(record: FunnelEventRecord): void;
|
|
2140
|
+
/**
|
|
2141
|
+
* Returns events with offset > since. Filtering by channel/connector is
|
|
2142
|
+
* the broadcaster's responsibility (it knows the client's subscription),
|
|
2143
|
+
* so this returns the full slice and lets the caller filter.
|
|
2144
|
+
*/
|
|
2145
|
+
loadSince(since: number): ReplayableEvent[];
|
|
2146
|
+
/**
|
|
2147
|
+
* Returns events for one channel (and optionally one connector). Used
|
|
2148
|
+
* by the gateway logs CLI for scoped queries. Channel/connector filters
|
|
2149
|
+
* are indexed columns, so this is an indexed range scan.
|
|
2150
|
+
*/
|
|
2151
|
+
loadForChannel(props: {
|
|
2152
|
+
channelId: string;
|
|
2153
|
+
connectorId?: string;
|
|
2154
|
+
sinceSeq?: number;
|
|
2155
|
+
limit?: number;
|
|
2156
|
+
}): ReplayableEvent[];
|
|
2157
|
+
findMaxOffset(): number;
|
|
2158
|
+
clear(): void;
|
|
2159
|
+
close(): void;
|
|
2160
|
+
}
|
|
2161
|
+
//#endregion
|
|
2162
|
+
//#region lib/gateway/memory-funnel-event-log.d.ts
|
|
2163
|
+
/**
|
|
2164
|
+
* In-process `FunnelEventLog` backed by a plain array. Used by tests and by
|
|
2165
|
+
* embedders that do not need durability — replay works within the process
|
|
2166
|
+
* lifetime but is lost when the process exits. Unlike the SQLite log it does
|
|
2167
|
+
* not truncate content or prune, so it is not meant for unbounded production
|
|
2168
|
+
* traffic.
|
|
2169
|
+
*/
|
|
2170
|
+
declare class MemoryFunnelEventLog extends FunnelEventLog {
|
|
2171
|
+
private readonly events;
|
|
2172
|
+
constructor();
|
|
2173
|
+
record(record: FunnelEventRecord): void;
|
|
2174
|
+
loadSince(since: number): ReplayableEvent[];
|
|
2175
|
+
findMaxOffset(): number;
|
|
2176
|
+
clear(): void;
|
|
2177
|
+
close(): void;
|
|
2178
|
+
}
|
|
2179
|
+
//#endregion
|
|
2180
|
+
//#region lib/gateway/sqlite-connector-diagnostic-log.d.ts
|
|
2181
|
+
type Props$1 = {
|
|
2182
|
+
/** SQLite file for the raw (pre-filter) table. ":memory:" for tests. */rawPath: string; /** SQLite file for the processed (verdict) table. ":memory:" for tests. */
|
|
2183
|
+
processedPath: string; /** SQLite file for the connection (lifecycle) table. ":memory:" for tests. */
|
|
2184
|
+
connectionPath: string;
|
|
2185
|
+
now?: () => number; /** Row cap for the processed and connection tables. Pruned on every insert. */
|
|
2186
|
+
maxRows?: number;
|
|
2187
|
+
/**
|
|
2188
|
+
* Row cap for the raw table specifically. Raw rows can each hold up to
|
|
2189
|
+
* `RAW_PAYLOAD_CAP` bytes, so they want a tighter cap than the small
|
|
2190
|
+
* processed/connection verdict rows. Defaults to `maxRows` when unset.
|
|
2191
|
+
*/
|
|
2192
|
+
rawMaxRows?: number; /** Age cap in ms for all tables — bounds how long untouched payloads (with PII) live. Pruned on every insert. */
|
|
2193
|
+
maxAgeMs?: number; /** When set, `insert()` errors (disk full, WAL lock) are logged instead of silently dropped. */
|
|
2194
|
+
logger?: FunnelLogger;
|
|
2195
|
+
};
|
|
2196
|
+
/**
|
|
2197
|
+
* Default `ConnectorDiagnosticLog`: three independent `LeucoLoggerSqliteSink`s, one
|
|
2198
|
+
* per table (raw / processed / connection), in separate files. Each sink
|
|
2199
|
+
* indexes the columns its queries filter on — `event_id` / `connector_id` /
|
|
2200
|
+
* `channel_id` for raw, plus `outcome` for processed and `status` for
|
|
2201
|
+
* connection — so those lookups are indexed scans (`type` is a fixed column
|
|
2202
|
+
* the sink extracts separately, not an index, so filtering by it is a scan).
|
|
2203
|
+
*
|
|
2204
|
+
* The raw table offloads any payload over `RAW_PAYLOAD_CAP`: rather than
|
|
2205
|
+
* truncating mid-string (which yields unparseable JSON), it replaces the
|
|
2206
|
+
* body with a small JSON object that keeps the diagnostic essentials and
|
|
2207
|
+
* records the dropped size under `_funnel_oversized`. Every stored payload
|
|
2208
|
+
* therefore stays valid JSON.
|
|
2209
|
+
*/
|
|
2210
|
+
declare class SqliteConnectorDiagnosticLog extends ConnectorDiagnosticLog {
|
|
2211
|
+
private readonly raw;
|
|
2212
|
+
private readonly processed;
|
|
2213
|
+
private readonly connection;
|
|
2214
|
+
private readonly now;
|
|
2215
|
+
private readonly logger;
|
|
2216
|
+
constructor(props: Props$1);
|
|
2217
|
+
recordRaw(record: ConnectorRawRecord): void;
|
|
2218
|
+
recordProcessed(record: ConnectorProcessedRecord): void;
|
|
2219
|
+
recordConnection(record: ConnectorConnectionRecord): void;
|
|
2220
|
+
private report;
|
|
2221
|
+
queryRaw(query: ConnectorRawQuery): StoredRawEvent[];
|
|
2222
|
+
queryProcessed(query: ConnectorProcessedQuery): StoredProcessedEvent[];
|
|
2223
|
+
queryConnection(query: ConnectorConnectionQuery): StoredConnectionEvent[];
|
|
2224
|
+
clear(): void;
|
|
2225
|
+
close(): void;
|
|
2226
|
+
}
|
|
2227
|
+
//#endregion
|
|
2228
|
+
//#region lib/gateway/memory-connector-diagnostic-log.d.ts
|
|
2229
|
+
/**
|
|
2230
|
+
* In-process `ConnectorDiagnosticLog` backed by one array per table. Used by tests
|
|
2231
|
+
* and embedders that do not need durability. Like the SQLite log it keeps
|
|
2232
|
+
* `seq` per-table (each array's 1-based position) and returns the most recent
|
|
2233
|
+
* `limit` rows oldest-first; unlike it, it never prunes and never offloads
|
|
2234
|
+
* oversized payloads — it keeps whatever the caller hands it, which is fine
|
|
2235
|
+
* for the bounded volumes a test produces. Payload-validity is therefore a
|
|
2236
|
+
* SQLite-only guarantee; do not write a test that leans on this double
|
|
2237
|
+
* rejecting a malformed payload.
|
|
2238
|
+
*/
|
|
2239
|
+
declare class MemoryConnectorDiagnosticLog extends ConnectorDiagnosticLog {
|
|
2240
|
+
private readonly now;
|
|
2241
|
+
private readonly raws;
|
|
2242
|
+
private readonly processeds;
|
|
2243
|
+
private readonly connections;
|
|
2244
|
+
constructor(now?: () => number);
|
|
2245
|
+
recordRaw(record: ConnectorRawRecord): void;
|
|
2246
|
+
recordProcessed(record: ConnectorProcessedRecord): void;
|
|
2247
|
+
recordConnection(record: ConnectorConnectionRecord): void;
|
|
2248
|
+
queryRaw(query: ConnectorRawQuery): StoredRawEvent[];
|
|
2249
|
+
queryProcessed(query: ConnectorProcessedQuery): StoredProcessedEvent[];
|
|
2250
|
+
queryConnection(query: ConnectorConnectionQuery): StoredConnectionEvent[];
|
|
2251
|
+
clear(): void;
|
|
2252
|
+
close(): void;
|
|
2253
|
+
}
|
|
2254
|
+
//#endregion
|
|
2255
|
+
//#region lib/gateway/connector-diagnostic-sql-reader.d.ts
|
|
2256
|
+
type Props = {
|
|
2257
|
+
/** SQLite file holding the raw (pre-filter) table. */rawPath: string; /** SQLite file holding the processed (verdict) table. */
|
|
2258
|
+
processedPath: string; /** SQLite file holding the connection (lifecycle) table. */
|
|
2259
|
+
connectionPath: string;
|
|
2260
|
+
};
|
|
2261
|
+
type Row = Record<string, unknown>;
|
|
2262
|
+
/**
|
|
2263
|
+
* Read-only SQL surface over the three diagnostic tables, for Claude to query
|
|
2264
|
+
* the log with arbitrary `SELECT`s. It opens all files read-only and exposes
|
|
2265
|
+
* three views — `raw`, `processed`, `connection` — that hide the storage
|
|
2266
|
+
* details (the physical table is `leuco_log` and each row's columns live
|
|
2267
|
+
* inside a JSON `event` blob): the views surface the columns as plain fields,
|
|
2268
|
+
* with `payload` already pulled out of the nested JSON.
|
|
2269
|
+
*
|
|
2270
|
+
* The tables are separate files. `raw` and `processed` share an `event_id`,
|
|
2271
|
+
* so a `JOIN` answers "the event arrived, but what verdict did it get?";
|
|
2272
|
+
* `connection` answers the other half — "did the listener ever connect at
|
|
2273
|
+
* all?". Writes are impossible: the connection is read-only and `query`
|
|
2274
|
+
* rejects anything but a single `SELECT`.
|
|
2275
|
+
*/
|
|
2276
|
+
declare class ConnectorDiagnosticSqlReader {
|
|
2277
|
+
private readonly db;
|
|
2278
|
+
constructor(props: Props);
|
|
2279
|
+
/**
|
|
2280
|
+
* Run one read-only `SELECT` and return the rows. Returns an `Error` (rather
|
|
2281
|
+
* than throwing) for a non-SELECT statement or a SQL error, so the caller
|
|
2282
|
+
* can surface the message without a stack trace.
|
|
2283
|
+
*/
|
|
2284
|
+
query(sql: string, params?: (string | number | null)[]): Row[] | Error;
|
|
2285
|
+
close(): void;
|
|
2286
|
+
}
|
|
2287
|
+
//#endregion
|
|
2288
|
+
//#region lib/cli/factory.d.ts
|
|
2289
|
+
type Env = {
|
|
2290
|
+
Bindings: {
|
|
2291
|
+
funnel: Funnel;
|
|
3278
2292
|
};
|
|
3279
|
-
}
|
|
3280
|
-
|
|
3281
|
-
|
|
2293
|
+
};
|
|
2294
|
+
declare const factory: _$hono_factory0.Factory<Env, string>;
|
|
2295
|
+
//#endregion
|
|
2296
|
+
//#region lib/cli/router/to-request.d.ts
|
|
2297
|
+
declare const toRequest: (args: string[]) => {
|
|
2298
|
+
method: string;
|
|
2299
|
+
path: string;
|
|
2300
|
+
url: string;
|
|
2301
|
+
};
|
|
2302
|
+
//#endregion
|
|
2303
|
+
//#region lib/cli/router/query-to-cli-args.d.ts
|
|
2304
|
+
declare const queryToCliArgs: (url: string, reservedKeys?: string[]) => string[];
|
|
2305
|
+
//#endregion
|
|
2306
|
+
//#region lib/cli/routes/index.d.ts
|
|
2307
|
+
declare const routes: _$hono_hono_base0.HonoBase<Env, {
|
|
3282
2308
|
"/claude": {
|
|
3283
2309
|
$get: {
|
|
3284
2310
|
input: {
|
|
@@ -3308,18 +2334,38 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3308
2334
|
"/channels": {
|
|
3309
2335
|
$get: {
|
|
3310
2336
|
input: {
|
|
3311
|
-
query:
|
|
2337
|
+
query: {
|
|
2338
|
+
json?: "" | "true" | "false" | undefined;
|
|
2339
|
+
};
|
|
3312
2340
|
};
|
|
3313
2341
|
output: string;
|
|
3314
2342
|
outputFormat: "text";
|
|
3315
2343
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2344
|
+
} | {
|
|
2345
|
+
input: {
|
|
2346
|
+
query: {
|
|
2347
|
+
json?: "" | "true" | "false" | undefined;
|
|
2348
|
+
};
|
|
2349
|
+
};
|
|
2350
|
+
output: {
|
|
2351
|
+
id: string;
|
|
2352
|
+
name: string;
|
|
2353
|
+
delivery: "fanout" | "exclusive";
|
|
2354
|
+
connectors: {
|
|
2355
|
+
id: string;
|
|
2356
|
+
name: string;
|
|
2357
|
+
type: "schedule" | "slack" | "gh" | "discord";
|
|
2358
|
+
}[];
|
|
2359
|
+
}[];
|
|
2360
|
+
outputFormat: "json";
|
|
2361
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3316
2362
|
};
|
|
3317
2363
|
};
|
|
3318
2364
|
} & {
|
|
3319
2365
|
"/channels/add": {
|
|
3320
2366
|
$post: {
|
|
3321
2367
|
input: {};
|
|
3322
|
-
output:
|
|
2368
|
+
output: "funnel channels add — add a channel\n\nusage: funnel channels add <name> [--delivery fanout|exclusive]\n\noptions:\n --delivery routing mode (default fanout):\n fanout every connected client receives every event\n exclusive each event delivered to exactly one client (round-robin)";
|
|
3323
2369
|
outputFormat: "text";
|
|
3324
2370
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3325
2371
|
};
|
|
@@ -3358,7 +2404,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3358
2404
|
"/channels/remove": {
|
|
3359
2405
|
$post: {
|
|
3360
2406
|
input: {};
|
|
3361
|
-
output:
|
|
2407
|
+
output: "funnel channels remove — remove a channel\n\nusage: funnel channels remove <name>";
|
|
3362
2408
|
outputFormat: "text";
|
|
3363
2409
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3364
2410
|
};
|
|
@@ -3449,7 +2495,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3449
2495
|
"/channels/rename": {
|
|
3450
2496
|
$post: {
|
|
3451
2497
|
input: {};
|
|
3452
|
-
output:
|
|
2498
|
+
output: "funnel channels rename — rename a channel\n\nusage:\n funnel channels rename <old> <new>\n funnel channels <old> rename <new>";
|
|
3453
2499
|
outputFormat: "text";
|
|
3454
2500
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3455
2501
|
};
|
|
@@ -3462,7 +2508,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3462
2508
|
channel: string;
|
|
3463
2509
|
};
|
|
3464
2510
|
};
|
|
3465
|
-
output:
|
|
2511
|
+
output: "funnel channels rename — rename a channel\n\nusage:\n funnel channels rename <old> <new>\n funnel channels <old> rename <new>";
|
|
3466
2512
|
outputFormat: "text";
|
|
3467
2513
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3468
2514
|
};
|
|
@@ -3495,7 +2541,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3495
2541
|
"/channels/publish": {
|
|
3496
2542
|
$post: {
|
|
3497
2543
|
input: {};
|
|
3498
|
-
output:
|
|
2544
|
+
output: "funnel channels <channel> publish — push arbitrary content into a channel\n\nusage: funnel channels <channel> publish --content=\"<text>\" [--connector=<name>] [--meta-<key>=<value> ...]\n\noptions:\n --content Required. The event body delivered to subscribers.\n --connector Optional. Stamp the event with a connector name (resolved to id when found).\n --meta-<key> Optional. Repeatable. Added to meta. Example: --meta-source=cron";
|
|
3499
2545
|
outputFormat: "text";
|
|
3500
2546
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3501
2547
|
};
|
|
@@ -3534,6 +2580,53 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3534
2580
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3535
2581
|
};
|
|
3536
2582
|
};
|
|
2583
|
+
} & {
|
|
2584
|
+
"/channels/:channel/validate": {
|
|
2585
|
+
$get: {
|
|
2586
|
+
input: {
|
|
2587
|
+
param: {
|
|
2588
|
+
channel: string;
|
|
2589
|
+
};
|
|
2590
|
+
} & {
|
|
2591
|
+
query: {
|
|
2592
|
+
json?: "" | "true" | "false" | undefined;
|
|
2593
|
+
};
|
|
2594
|
+
};
|
|
2595
|
+
output: string;
|
|
2596
|
+
outputFormat: "text";
|
|
2597
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2598
|
+
} | {
|
|
2599
|
+
input: {
|
|
2600
|
+
param: {
|
|
2601
|
+
channel: string;
|
|
2602
|
+
};
|
|
2603
|
+
} & {
|
|
2604
|
+
query: {
|
|
2605
|
+
json?: "" | "true" | "false" | undefined;
|
|
2606
|
+
};
|
|
2607
|
+
};
|
|
2608
|
+
output: {
|
|
2609
|
+
channel: string;
|
|
2610
|
+
valid: boolean;
|
|
2611
|
+
issues: {
|
|
2612
|
+
connector: string;
|
|
2613
|
+
field: string;
|
|
2614
|
+
message: string;
|
|
2615
|
+
}[];
|
|
2616
|
+
};
|
|
2617
|
+
outputFormat: "json";
|
|
2618
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2619
|
+
};
|
|
2620
|
+
};
|
|
2621
|
+
} & {
|
|
2622
|
+
"/channels/validate": {
|
|
2623
|
+
$get: {
|
|
2624
|
+
input: {};
|
|
2625
|
+
output: "funnel channels <channel> validate — check connector configuration\n\nusage: funnel channels <channel> validate [--json]\n\noptions:\n --json output as JSON\n\nChecks that each connector has the required tokens and fields set.\nDoes not make any network calls — static config check only.\n\nexamples:\n funnel channels open-karte validate\n funnel channels open-karte validate --json";
|
|
2626
|
+
outputFormat: "text";
|
|
2627
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
2628
|
+
};
|
|
2629
|
+
};
|
|
3537
2630
|
} & {
|
|
3538
2631
|
"/channels/:channel": {
|
|
3539
2632
|
$get: {
|
|
@@ -3572,7 +2665,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3572
2665
|
channel: string;
|
|
3573
2666
|
};
|
|
3574
2667
|
};
|
|
3575
|
-
output:
|
|
2668
|
+
output: "funnel channels <channel> connectors add <connector> — add a connector to a channel\n\nusage:\n funnel channels <channel> connectors add <connector> --type=slack --bot-token=xoxb-... --app-token=xapp-...\n funnel channels <channel> connectors add <connector> --type=gh [--poll-interval=60]\n funnel channels <channel> connectors add <connector> --type=discord --bot-token=...\n funnel channels <channel> connectors add <connector> --type=schedule\n\nToken uniqueness is enforced across all channels.";
|
|
3576
2669
|
outputFormat: "text";
|
|
3577
2670
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3578
2671
|
};
|
|
@@ -3709,7 +2802,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3709
2802
|
channel: string;
|
|
3710
2803
|
};
|
|
3711
2804
|
};
|
|
3712
|
-
output:
|
|
2805
|
+
output: "funnel channels <channel> connectors remove <connector> — remove a connector\n\nusage: funnel channels <channel> connectors remove <connector>";
|
|
3713
2806
|
outputFormat: "text";
|
|
3714
2807
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3715
2808
|
};
|
|
@@ -3750,7 +2843,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3750
2843
|
channel: string;
|
|
3751
2844
|
};
|
|
3752
2845
|
};
|
|
3753
|
-
output:
|
|
2846
|
+
output: "funnel channels <channel> connectors set <connector> — update connector fields\n\nusage:\n funnel channels <ch> connectors set <conn> [--bot-token=...] [--app-token=...] # slack\n funnel channels <ch> connectors set <conn> [--bot-token=...] # discord\n funnel channels <ch> connectors set <conn> [--poll-interval=N] # gh";
|
|
3754
2847
|
outputFormat: "text";
|
|
3755
2848
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3756
2849
|
};
|
|
@@ -3861,7 +2954,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3861
2954
|
channel: string;
|
|
3862
2955
|
};
|
|
3863
2956
|
};
|
|
3864
|
-
output:
|
|
2957
|
+
output: "funnel channels <channel> connectors rename <connector> <new-name>\n\nusage: funnel channels <channel> connectors rename <connector> <new-name>";
|
|
3865
2958
|
outputFormat: "text";
|
|
3866
2959
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3867
2960
|
};
|
|
@@ -3876,7 +2969,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3876
2969
|
connector: string;
|
|
3877
2970
|
};
|
|
3878
2971
|
};
|
|
3879
|
-
output:
|
|
2972
|
+
output: "funnel channels <channel> connectors rename <connector> <new-name>\n\nusage: funnel channels <channel> connectors rename <connector> <new-name>";
|
|
3880
2973
|
outputFormat: "text";
|
|
3881
2974
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3882
2975
|
};
|
|
@@ -3942,7 +3035,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3942
3035
|
connector: string;
|
|
3943
3036
|
};
|
|
3944
3037
|
};
|
|
3945
|
-
output:
|
|
3038
|
+
output: "funnel channels <ch> connectors <conn> schedules add <id> — add a schedule entry\n\nusage: funnel channels <ch> connectors <conn> schedules add <id> --cron=\"*/5 * * * *\" --prompt=\"...\" [--enabled=true] [--catchup-policy=latest|all|skip]";
|
|
3946
3039
|
outputFormat: "text";
|
|
3947
3040
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3948
3041
|
};
|
|
@@ -3997,7 +3090,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
3997
3090
|
connector: string;
|
|
3998
3091
|
};
|
|
3999
3092
|
};
|
|
4000
|
-
output:
|
|
3093
|
+
output: "funnel channels <ch> connectors <conn> schedules remove <id>\n\nusage: funnel channels <ch> connectors <conn> schedules remove <id>";
|
|
4001
3094
|
outputFormat: "text";
|
|
4002
3095
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4003
3096
|
};
|
|
@@ -4047,7 +3140,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
4047
3140
|
"/profiles/add": {
|
|
4048
3141
|
$post: {
|
|
4049
3142
|
input: {};
|
|
4050
|
-
output: string;
|
|
3143
|
+
output: "funnel profiles add — add a profile\n\nusage: funnel profiles add <name> --path <path> --channel <channel-name> [recipe]\n\noptions:\n --path working directory passed to claude as cwd\n --channel channel name (resolved to channel id internally)\n --agent sub-agent name, prepended to the launch argv as --agent <name>\n --options extra launch argv as one whitespace-split string (e.g. \"--brief\")\n --env env vars layered under the process, as \"KEY=VAL,KEY2=VAL2\"\n --no-resume start a fresh claude session every launch (default resumes)\n\nThe launch recipe (--agent / --options / --env / --resume) lives on the\nprofile; the channel only declares transport (connectors / delivery).";
|
|
4051
3144
|
outputFormat: "text";
|
|
4052
3145
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4053
3146
|
};
|
|
@@ -4098,7 +3191,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
4098
3191
|
"/profiles/set": {
|
|
4099
3192
|
$post: {
|
|
4100
3193
|
input: {};
|
|
4101
|
-
output: string;
|
|
3194
|
+
output: "funnel profiles <name> set — update a profile\n\nusage: funnel profiles <name> set [--path <path>] [--channel <channel-name>] [recipe]\n\noptions:\n --path working directory passed to claude as cwd\n --channel channel name (resolved to channel id internally)\n --agent sub-agent name, prepended to the launch argv as --agent <name>\n --options extra launch argv as one whitespace-split string (e.g. \"--brief\")\n --env env vars layered under the process, as \"KEY=VAL,KEY2=VAL2\"\n --resume / --no-resume toggle claude session reuse\n\nOnly the flags you pass are changed; --agent and --options together replace\nthe profile's whole options list.";
|
|
4102
3195
|
outputFormat: "text";
|
|
4103
3196
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4104
3197
|
};
|
|
@@ -4149,7 +3242,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
4149
3242
|
"/profiles/remove": {
|
|
4150
3243
|
$post: {
|
|
4151
3244
|
input: {};
|
|
4152
|
-
output:
|
|
3245
|
+
output: "funnel profiles remove — remove a profile\n\nusage: funnel profiles remove <name>";
|
|
4153
3246
|
outputFormat: "text";
|
|
4154
3247
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4155
3248
|
};
|
|
@@ -4240,7 +3333,7 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
4240
3333
|
"/profiles/rename": {
|
|
4241
3334
|
$post: {
|
|
4242
3335
|
input: {};
|
|
4243
|
-
output:
|
|
3336
|
+
output: "funnel profiles rename — rename a profile\n\nusage:\n funnel profiles rename <old> <new>\n funnel profiles <old> rename <new>";
|
|
4244
3337
|
outputFormat: "text";
|
|
4245
3338
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4246
3339
|
};
|
|
@@ -4253,19 +3346,266 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
4253
3346
|
profile: string;
|
|
4254
3347
|
};
|
|
4255
3348
|
};
|
|
3349
|
+
output: "funnel profiles rename — rename a profile\n\nusage:\n funnel profiles rename <old> <new>\n funnel profiles <old> rename <new>";
|
|
3350
|
+
outputFormat: "text";
|
|
3351
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3352
|
+
};
|
|
3353
|
+
};
|
|
3354
|
+
} & {
|
|
3355
|
+
"/profiles/:profile/as-default": {
|
|
3356
|
+
$post: {
|
|
3357
|
+
input: {
|
|
3358
|
+
param: {
|
|
3359
|
+
profile: string;
|
|
3360
|
+
};
|
|
3361
|
+
} & {
|
|
3362
|
+
query: Record<string, never>;
|
|
3363
|
+
};
|
|
3364
|
+
output: string;
|
|
3365
|
+
outputFormat: "text";
|
|
3366
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3367
|
+
} | {
|
|
3368
|
+
input: {
|
|
3369
|
+
param: {
|
|
3370
|
+
profile: string;
|
|
3371
|
+
};
|
|
3372
|
+
} & {
|
|
3373
|
+
query: Record<string, never>;
|
|
3374
|
+
};
|
|
3375
|
+
output: `profile "${string}" is now the default`;
|
|
3376
|
+
outputFormat: "text";
|
|
3377
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3378
|
+
};
|
|
3379
|
+
};
|
|
3380
|
+
} & {
|
|
3381
|
+
"/profiles/:profile/run": {
|
|
3382
|
+
$get: {
|
|
3383
|
+
input: {
|
|
3384
|
+
param: {
|
|
3385
|
+
profile: string;
|
|
3386
|
+
};
|
|
3387
|
+
} & {
|
|
3388
|
+
query: {
|
|
3389
|
+
[x: string]: string | string[];
|
|
3390
|
+
};
|
|
3391
|
+
};
|
|
3392
|
+
output: string;
|
|
3393
|
+
outputFormat: "text";
|
|
3394
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3395
|
+
} | {
|
|
3396
|
+
input: {
|
|
3397
|
+
param: {
|
|
3398
|
+
profile: string;
|
|
3399
|
+
};
|
|
3400
|
+
} & {
|
|
3401
|
+
query: {
|
|
3402
|
+
[x: string]: string | string[];
|
|
3403
|
+
};
|
|
3404
|
+
};
|
|
3405
|
+
output: Promise<never>;
|
|
3406
|
+
outputFormat: "json";
|
|
3407
|
+
status: _$hono_utils_http_status0.StatusCode;
|
|
3408
|
+
};
|
|
3409
|
+
};
|
|
3410
|
+
} & {
|
|
3411
|
+
"/profiles/:profile": {
|
|
3412
|
+
$get: {
|
|
3413
|
+
input: {
|
|
3414
|
+
param: {
|
|
3415
|
+
profile: string;
|
|
3416
|
+
};
|
|
3417
|
+
} & {
|
|
3418
|
+
query: {
|
|
3419
|
+
[x: string]: string | string[];
|
|
3420
|
+
};
|
|
3421
|
+
};
|
|
3422
|
+
output: string;
|
|
3423
|
+
outputFormat: "text";
|
|
3424
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3425
|
+
} | {
|
|
3426
|
+
input: {
|
|
3427
|
+
param: {
|
|
3428
|
+
profile: string;
|
|
3429
|
+
};
|
|
3430
|
+
} & {
|
|
3431
|
+
query: {
|
|
3432
|
+
[x: string]: string | string[];
|
|
3433
|
+
};
|
|
3434
|
+
};
|
|
3435
|
+
output: Promise<never>;
|
|
3436
|
+
outputFormat: "json";
|
|
3437
|
+
status: _$hono_utils_http_status0.StatusCode;
|
|
3438
|
+
};
|
|
3439
|
+
};
|
|
3440
|
+
} & {
|
|
3441
|
+
"/gateway": {
|
|
3442
|
+
$get: {
|
|
3443
|
+
input: {};
|
|
3444
|
+
output: string;
|
|
3445
|
+
outputFormat: "text";
|
|
3446
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3447
|
+
};
|
|
3448
|
+
};
|
|
3449
|
+
} & {
|
|
3450
|
+
"/gateway/status": {
|
|
3451
|
+
$get: {
|
|
3452
|
+
input: {
|
|
3453
|
+
query: {
|
|
3454
|
+
json?: "" | "true" | "false" | undefined;
|
|
3455
|
+
};
|
|
3456
|
+
};
|
|
3457
|
+
output: string;
|
|
3458
|
+
outputFormat: "text";
|
|
3459
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3460
|
+
} | {
|
|
3461
|
+
input: {
|
|
3462
|
+
query: {
|
|
3463
|
+
json?: "" | "true" | "false" | undefined;
|
|
3464
|
+
};
|
|
3465
|
+
};
|
|
3466
|
+
output: {
|
|
3467
|
+
running: true;
|
|
3468
|
+
port: number;
|
|
3469
|
+
};
|
|
3470
|
+
outputFormat: "json";
|
|
3471
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3472
|
+
};
|
|
3473
|
+
};
|
|
3474
|
+
} & {
|
|
3475
|
+
"/gateway/start": {
|
|
3476
|
+
$get: {
|
|
3477
|
+
input: {
|
|
3478
|
+
query: {
|
|
3479
|
+
"no-caffeine"?: string | undefined;
|
|
3480
|
+
};
|
|
3481
|
+
};
|
|
3482
|
+
output: string;
|
|
3483
|
+
outputFormat: "text";
|
|
3484
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3485
|
+
} | {
|
|
3486
|
+
input: {
|
|
3487
|
+
query: {
|
|
3488
|
+
"no-caffeine"?: string | undefined;
|
|
3489
|
+
};
|
|
3490
|
+
};
|
|
3491
|
+
output: "funnel gateway: already running (pid null)" | `funnel gateway: already running (pid ${number})`;
|
|
3492
|
+
outputFormat: "text";
|
|
3493
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3494
|
+
} | {
|
|
3495
|
+
input: {
|
|
3496
|
+
query: {
|
|
3497
|
+
"no-caffeine"?: string | undefined;
|
|
3498
|
+
};
|
|
3499
|
+
};
|
|
3500
|
+
output: "funnel gateway: started";
|
|
3501
|
+
outputFormat: "text";
|
|
3502
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3503
|
+
};
|
|
3504
|
+
};
|
|
3505
|
+
} & {
|
|
3506
|
+
"/gateway/stop": {
|
|
3507
|
+
$get: {
|
|
3508
|
+
input: {
|
|
3509
|
+
query: Record<string, never>;
|
|
3510
|
+
};
|
|
3511
|
+
output: string;
|
|
3512
|
+
outputFormat: "text";
|
|
3513
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3514
|
+
} | {
|
|
3515
|
+
input: {
|
|
3516
|
+
query: Record<string, never>;
|
|
3517
|
+
};
|
|
3518
|
+
output: "funnel gateway: no running process";
|
|
3519
|
+
outputFormat: "text";
|
|
3520
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3521
|
+
} | {
|
|
3522
|
+
input: {
|
|
3523
|
+
query: Record<string, never>;
|
|
3524
|
+
};
|
|
3525
|
+
output: "funnel gateway: stopped";
|
|
3526
|
+
outputFormat: "text";
|
|
3527
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3528
|
+
};
|
|
3529
|
+
};
|
|
3530
|
+
} & {
|
|
3531
|
+
"/gateway/restart": {
|
|
3532
|
+
$get: {
|
|
3533
|
+
input: {
|
|
3534
|
+
query: {
|
|
3535
|
+
"no-caffeine"?: string | undefined;
|
|
3536
|
+
};
|
|
3537
|
+
};
|
|
3538
|
+
output: string;
|
|
3539
|
+
outputFormat: "text";
|
|
3540
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3541
|
+
};
|
|
3542
|
+
};
|
|
3543
|
+
} & {
|
|
3544
|
+
"/gateway/run": {
|
|
3545
|
+
$get: {
|
|
3546
|
+
input: {
|
|
3547
|
+
query: {
|
|
3548
|
+
"no-caffeine"?: string | undefined;
|
|
3549
|
+
};
|
|
3550
|
+
};
|
|
3551
|
+
output: string;
|
|
3552
|
+
outputFormat: "text";
|
|
3553
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3554
|
+
} | {
|
|
3555
|
+
input: {
|
|
3556
|
+
query: {
|
|
3557
|
+
"no-caffeine"?: string | undefined;
|
|
3558
|
+
};
|
|
3559
|
+
};
|
|
3560
|
+
output: Promise<never>;
|
|
3561
|
+
outputFormat: "json";
|
|
3562
|
+
status: _$hono_utils_http_status0.StatusCode;
|
|
3563
|
+
};
|
|
3564
|
+
};
|
|
3565
|
+
} & {
|
|
3566
|
+
"/gateway/logs": {
|
|
3567
|
+
$get: {
|
|
3568
|
+
input: {
|
|
3569
|
+
query: {
|
|
3570
|
+
n?: string | undefined;
|
|
3571
|
+
format?: "json" | "plain" | undefined;
|
|
3572
|
+
};
|
|
3573
|
+
};
|
|
3574
|
+
output: string;
|
|
3575
|
+
outputFormat: "text";
|
|
3576
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3577
|
+
} | {
|
|
3578
|
+
input: {
|
|
3579
|
+
query: {
|
|
3580
|
+
n?: string | undefined;
|
|
3581
|
+
format?: "json" | "plain" | undefined;
|
|
3582
|
+
};
|
|
3583
|
+
};
|
|
3584
|
+
output: "no logs";
|
|
3585
|
+
outputFormat: "text";
|
|
3586
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3587
|
+
};
|
|
3588
|
+
};
|
|
3589
|
+
} & {
|
|
3590
|
+
"/gateway/sql": {
|
|
3591
|
+
$get: {
|
|
3592
|
+
input: {
|
|
3593
|
+
query: {
|
|
3594
|
+
query?: string | undefined;
|
|
3595
|
+
preset?: string | undefined;
|
|
3596
|
+
channel?: string | undefined;
|
|
3597
|
+
limit?: string | undefined;
|
|
3598
|
+
};
|
|
3599
|
+
};
|
|
4256
3600
|
output: string;
|
|
4257
3601
|
outputFormat: "text";
|
|
4258
3602
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4259
3603
|
};
|
|
4260
3604
|
};
|
|
4261
3605
|
} & {
|
|
4262
|
-
"/
|
|
4263
|
-
$
|
|
3606
|
+
"/gateway/listeners": {
|
|
3607
|
+
$get: {
|
|
4264
3608
|
input: {
|
|
4265
|
-
param: {
|
|
4266
|
-
profile: string;
|
|
4267
|
-
};
|
|
4268
|
-
} & {
|
|
4269
3609
|
query: Record<string, never>;
|
|
4270
3610
|
};
|
|
4271
3611
|
output: string;
|
|
@@ -4273,27 +3613,30 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
4273
3613
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4274
3614
|
} | {
|
|
4275
3615
|
input: {
|
|
4276
|
-
param: {
|
|
4277
|
-
profile: string;
|
|
4278
|
-
};
|
|
4279
|
-
} & {
|
|
4280
3616
|
query: Record<string, never>;
|
|
4281
3617
|
};
|
|
4282
|
-
output:
|
|
3618
|
+
output: "funnel gateway: no running listeners";
|
|
3619
|
+
outputFormat: "text";
|
|
3620
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3621
|
+
} | {
|
|
3622
|
+
input: {
|
|
3623
|
+
query: Record<string, never>;
|
|
3624
|
+
};
|
|
3625
|
+
output: `funnel gateway: running listeners
|
|
3626
|
+
${string}`;
|
|
4283
3627
|
outputFormat: "text";
|
|
4284
3628
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4285
3629
|
};
|
|
4286
3630
|
};
|
|
4287
3631
|
} & {
|
|
4288
|
-
"/
|
|
3632
|
+
"/debug": {
|
|
4289
3633
|
$get: {
|
|
4290
3634
|
input: {
|
|
4291
|
-
param: {
|
|
4292
|
-
profile: string;
|
|
4293
|
-
};
|
|
4294
|
-
} & {
|
|
4295
3635
|
query: {
|
|
4296
|
-
|
|
3636
|
+
channel?: string | undefined;
|
|
3637
|
+
all?: "" | "true" | "false" | undefined;
|
|
3638
|
+
json?: "" | "true" | "false" | undefined;
|
|
3639
|
+
limit?: string | undefined;
|
|
4297
3640
|
};
|
|
4298
3641
|
};
|
|
4299
3642
|
output: string;
|
|
@@ -4301,101 +3644,246 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
4301
3644
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4302
3645
|
} | {
|
|
4303
3646
|
input: {
|
|
4304
|
-
param: {
|
|
4305
|
-
profile: string;
|
|
4306
|
-
};
|
|
4307
|
-
} & {
|
|
4308
3647
|
query: {
|
|
4309
|
-
|
|
3648
|
+
channel?: string | undefined;
|
|
3649
|
+
all?: "" | "true" | "false" | undefined;
|
|
3650
|
+
json?: "" | "true" | "false" | undefined;
|
|
3651
|
+
limit?: string | undefined;
|
|
4310
3652
|
};
|
|
4311
3653
|
};
|
|
4312
|
-
output:
|
|
3654
|
+
output: {
|
|
3655
|
+
error: string;
|
|
3656
|
+
nextAction: string;
|
|
3657
|
+
};
|
|
4313
3658
|
outputFormat: "json";
|
|
4314
|
-
status: _$hono_utils_http_status0.
|
|
4315
|
-
}
|
|
4316
|
-
};
|
|
4317
|
-
} & {
|
|
4318
|
-
"/profiles/:profile": {
|
|
4319
|
-
$get: {
|
|
3659
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3660
|
+
} | {
|
|
4320
3661
|
input: {
|
|
4321
|
-
param: {
|
|
4322
|
-
profile: string;
|
|
4323
|
-
};
|
|
4324
|
-
} & {
|
|
4325
3662
|
query: {
|
|
4326
|
-
|
|
4327
|
-
|
|
3663
|
+
channel?: string | undefined;
|
|
3664
|
+
all?: "" | "true" | "false" | undefined;
|
|
3665
|
+
json?: "" | "true" | "false" | undefined;
|
|
3666
|
+
limit?: string | undefined;
|
|
3667
|
+
};
|
|
3668
|
+
};
|
|
3669
|
+
output: {
|
|
3670
|
+
summary: {
|
|
3671
|
+
total: number;
|
|
3672
|
+
ok: number;
|
|
3673
|
+
warn: number;
|
|
3674
|
+
error: number;
|
|
3675
|
+
criticalChannels: string[];
|
|
3676
|
+
warnChannels: string[];
|
|
3677
|
+
suggestedActions: string[];
|
|
3678
|
+
};
|
|
3679
|
+
channels: {
|
|
3680
|
+
channel: string;
|
|
3681
|
+
gateway: {
|
|
3682
|
+
running: boolean;
|
|
3683
|
+
pid: number | null;
|
|
3684
|
+
port: number | null;
|
|
3685
|
+
uptimeMs: number | null;
|
|
3686
|
+
};
|
|
3687
|
+
listeners: {
|
|
3688
|
+
name: string;
|
|
3689
|
+
type: string;
|
|
3690
|
+
alive: boolean;
|
|
3691
|
+
events: number;
|
|
3692
|
+
errors: number;
|
|
3693
|
+
lastEventAt: string | null;
|
|
3694
|
+
}[];
|
|
3695
|
+
claudeClients: number;
|
|
3696
|
+
channelId: string;
|
|
3697
|
+
recentEvents: {
|
|
3698
|
+
seq: number | null;
|
|
3699
|
+
ts: number | null;
|
|
3700
|
+
type: string;
|
|
3701
|
+
outcome: string;
|
|
3702
|
+
eventId: string | null;
|
|
3703
|
+
payload: string | null;
|
|
3704
|
+
payloadParsed: {
|
|
3705
|
+
[x: string]: _$hono_utils_types0.JSONValue;
|
|
3706
|
+
} | null;
|
|
3707
|
+
preview: string | null;
|
|
3708
|
+
}[];
|
|
3709
|
+
connectionErrors: {
|
|
3710
|
+
seq: number | null;
|
|
3711
|
+
ts: number | null;
|
|
3712
|
+
type: string;
|
|
3713
|
+
status: string;
|
|
3714
|
+
detail: string | null;
|
|
3715
|
+
}[];
|
|
3716
|
+
diagnosis: {
|
|
3717
|
+
status: "ok" | "warn" | "error";
|
|
3718
|
+
message: string;
|
|
3719
|
+
nextActions: string[];
|
|
3720
|
+
rootCause: string | null;
|
|
3721
|
+
};
|
|
3722
|
+
}[];
|
|
4328
3723
|
};
|
|
4329
|
-
|
|
4330
|
-
outputFormat: "text";
|
|
3724
|
+
outputFormat: "json";
|
|
4331
3725
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4332
3726
|
} | {
|
|
4333
3727
|
input: {
|
|
4334
|
-
param: {
|
|
4335
|
-
profile: string;
|
|
4336
|
-
};
|
|
4337
|
-
} & {
|
|
4338
3728
|
query: {
|
|
4339
|
-
|
|
3729
|
+
channel?: string | undefined;
|
|
3730
|
+
all?: "" | "true" | "false" | undefined;
|
|
3731
|
+
json?: "" | "true" | "false" | undefined;
|
|
3732
|
+
limit?: string | undefined;
|
|
4340
3733
|
};
|
|
4341
3734
|
};
|
|
4342
|
-
output:
|
|
3735
|
+
output: {
|
|
3736
|
+
error: string;
|
|
3737
|
+
availableChannels: string[];
|
|
3738
|
+
};
|
|
4343
3739
|
outputFormat: "json";
|
|
4344
|
-
status: _$hono_utils_http_status0.StatusCode;
|
|
4345
|
-
};
|
|
4346
|
-
};
|
|
4347
|
-
} & {
|
|
4348
|
-
"/gateway": {
|
|
4349
|
-
$get: {
|
|
4350
|
-
input: {};
|
|
4351
|
-
output: string;
|
|
4352
|
-
outputFormat: "text";
|
|
4353
3740
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4354
3741
|
} | {
|
|
4355
|
-
input: {
|
|
4356
|
-
|
|
4357
|
-
|
|
3742
|
+
input: {
|
|
3743
|
+
query: {
|
|
3744
|
+
channel?: string | undefined;
|
|
3745
|
+
all?: "" | "true" | "false" | undefined;
|
|
3746
|
+
json?: "" | "true" | "false" | undefined;
|
|
3747
|
+
limit?: string | undefined;
|
|
3748
|
+
};
|
|
3749
|
+
};
|
|
3750
|
+
output: {
|
|
3751
|
+
error: string;
|
|
3752
|
+
channels: string[];
|
|
3753
|
+
hint: string;
|
|
3754
|
+
};
|
|
3755
|
+
outputFormat: "json";
|
|
4358
3756
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4359
3757
|
} | {
|
|
4360
|
-
input: {
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
3758
|
+
input: {
|
|
3759
|
+
query: {
|
|
3760
|
+
channel?: string | undefined;
|
|
3761
|
+
all?: "" | "true" | "false" | undefined;
|
|
3762
|
+
json?: "" | "true" | "false" | undefined;
|
|
3763
|
+
limit?: string | undefined;
|
|
3764
|
+
};
|
|
3765
|
+
};
|
|
3766
|
+
output: {
|
|
3767
|
+
channel: string;
|
|
3768
|
+
gateway: {
|
|
3769
|
+
running: boolean;
|
|
3770
|
+
pid: number | null;
|
|
3771
|
+
port: number | null;
|
|
3772
|
+
uptimeMs: number | null;
|
|
3773
|
+
};
|
|
3774
|
+
listeners: {
|
|
3775
|
+
name: string;
|
|
3776
|
+
type: string;
|
|
3777
|
+
alive: boolean;
|
|
3778
|
+
events: number;
|
|
3779
|
+
errors: number;
|
|
3780
|
+
lastEventAt: string | null;
|
|
3781
|
+
}[];
|
|
3782
|
+
claudeClients: number;
|
|
3783
|
+
channelId: string;
|
|
3784
|
+
recentEvents: {
|
|
3785
|
+
seq: number | null;
|
|
3786
|
+
ts: number | null;
|
|
3787
|
+
type: string;
|
|
3788
|
+
outcome: string;
|
|
3789
|
+
eventId: string | null;
|
|
3790
|
+
payload: string | null;
|
|
3791
|
+
payloadParsed: {
|
|
3792
|
+
[x: string]: _$hono_utils_types0.JSONValue;
|
|
3793
|
+
} | null;
|
|
3794
|
+
preview: string | null;
|
|
3795
|
+
}[];
|
|
3796
|
+
connectionErrors: {
|
|
3797
|
+
seq: number | null;
|
|
3798
|
+
ts: number | null;
|
|
3799
|
+
type: string;
|
|
3800
|
+
status: string;
|
|
3801
|
+
detail: string | null;
|
|
3802
|
+
}[];
|
|
3803
|
+
diagnosis: {
|
|
3804
|
+
status: "ok" | "warn" | "error";
|
|
3805
|
+
message: string;
|
|
3806
|
+
nextActions: string[];
|
|
3807
|
+
rootCause: string | null;
|
|
3808
|
+
};
|
|
3809
|
+
};
|
|
3810
|
+
outputFormat: "json";
|
|
4367
3811
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4368
3812
|
};
|
|
4369
3813
|
};
|
|
4370
3814
|
} & {
|
|
4371
|
-
"/
|
|
3815
|
+
"/debug/events": {
|
|
4372
3816
|
$get: {
|
|
4373
|
-
input: {
|
|
3817
|
+
input: {
|
|
3818
|
+
query: {
|
|
3819
|
+
channel?: string | undefined;
|
|
3820
|
+
limit?: string | undefined;
|
|
3821
|
+
json?: "" | "true" | "false" | undefined;
|
|
3822
|
+
};
|
|
3823
|
+
};
|
|
4374
3824
|
output: string;
|
|
4375
3825
|
outputFormat: "text";
|
|
4376
3826
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4377
3827
|
} | {
|
|
4378
|
-
input: {
|
|
4379
|
-
|
|
4380
|
-
|
|
3828
|
+
input: {
|
|
3829
|
+
query: {
|
|
3830
|
+
channel?: string | undefined;
|
|
3831
|
+
limit?: string | undefined;
|
|
3832
|
+
json?: "" | "true" | "false" | undefined;
|
|
3833
|
+
};
|
|
3834
|
+
};
|
|
3835
|
+
output: {
|
|
3836
|
+
error: string;
|
|
3837
|
+
availableChannels: string[];
|
|
3838
|
+
};
|
|
3839
|
+
outputFormat: "json";
|
|
4381
3840
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4382
3841
|
} | {
|
|
4383
|
-
input: {
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
3842
|
+
input: {
|
|
3843
|
+
query: {
|
|
3844
|
+
channel?: string | undefined;
|
|
3845
|
+
limit?: string | undefined;
|
|
3846
|
+
json?: "" | "true" | "false" | undefined;
|
|
3847
|
+
};
|
|
3848
|
+
};
|
|
3849
|
+
output: {
|
|
3850
|
+
error: string;
|
|
3851
|
+
channels: string[];
|
|
3852
|
+
};
|
|
3853
|
+
outputFormat: "json";
|
|
3854
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3855
|
+
} | {
|
|
3856
|
+
input: {
|
|
3857
|
+
query: {
|
|
3858
|
+
channel?: string | undefined;
|
|
3859
|
+
limit?: string | undefined;
|
|
3860
|
+
json?: "" | "true" | "false" | undefined;
|
|
3861
|
+
};
|
|
3862
|
+
};
|
|
3863
|
+
output: {
|
|
3864
|
+
seq: number | null;
|
|
3865
|
+
ts: number | null;
|
|
3866
|
+
type: string;
|
|
3867
|
+
outcome: string;
|
|
3868
|
+
eventId: string | null;
|
|
3869
|
+
payload: string | null;
|
|
3870
|
+
payloadParsed: {
|
|
3871
|
+
[x: string]: _$hono_utils_types0.JSONValue;
|
|
3872
|
+
} | null;
|
|
3873
|
+
preview: string | null;
|
|
3874
|
+
}[];
|
|
3875
|
+
outputFormat: "json";
|
|
4390
3876
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4391
3877
|
};
|
|
4392
3878
|
};
|
|
4393
3879
|
} & {
|
|
4394
|
-
"/
|
|
3880
|
+
"/debug/dropped": {
|
|
4395
3881
|
$get: {
|
|
4396
3882
|
input: {
|
|
4397
3883
|
query: {
|
|
4398
|
-
|
|
3884
|
+
channel?: string | undefined;
|
|
3885
|
+
limit?: string | undefined;
|
|
3886
|
+
json?: "" | "true" | "false" | undefined;
|
|
4399
3887
|
};
|
|
4400
3888
|
};
|
|
4401
3889
|
output: string;
|
|
@@ -4404,140 +3892,244 @@ declare const app: _$hono_hono_base0.HonoBase<Env, {
|
|
|
4404
3892
|
} | {
|
|
4405
3893
|
input: {
|
|
4406
3894
|
query: {
|
|
4407
|
-
|
|
3895
|
+
channel?: string | undefined;
|
|
3896
|
+
limit?: string | undefined;
|
|
3897
|
+
json?: "" | "true" | "false" | undefined;
|
|
3898
|
+
};
|
|
3899
|
+
};
|
|
3900
|
+
output: {
|
|
3901
|
+
seq: number | null;
|
|
3902
|
+
ts: number | null;
|
|
3903
|
+
type: string;
|
|
3904
|
+
outcome: string;
|
|
3905
|
+
eventId: string | null;
|
|
3906
|
+
payload: string | null;
|
|
3907
|
+
payloadParsed: {
|
|
3908
|
+
[x: string]: _$hono_utils_types0.JSONValue;
|
|
3909
|
+
} | null;
|
|
3910
|
+
preview: string | null;
|
|
3911
|
+
}[];
|
|
3912
|
+
outputFormat: "json";
|
|
3913
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3914
|
+
} | {
|
|
3915
|
+
input: {
|
|
3916
|
+
query: {
|
|
3917
|
+
channel?: string | undefined;
|
|
3918
|
+
limit?: string | undefined;
|
|
3919
|
+
json?: "" | "true" | "false" | undefined;
|
|
4408
3920
|
};
|
|
4409
3921
|
};
|
|
4410
|
-
output:
|
|
4411
|
-
|
|
3922
|
+
output: {
|
|
3923
|
+
error: string;
|
|
3924
|
+
availableChannels: string[];
|
|
3925
|
+
};
|
|
3926
|
+
outputFormat: "json";
|
|
4412
3927
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4413
3928
|
} | {
|
|
4414
3929
|
input: {
|
|
4415
3930
|
query: {
|
|
4416
|
-
|
|
3931
|
+
channel?: string | undefined;
|
|
3932
|
+
limit?: string | undefined;
|
|
3933
|
+
json?: "" | "true" | "false" | undefined;
|
|
4417
3934
|
};
|
|
4418
3935
|
};
|
|
4419
|
-
output:
|
|
4420
|
-
|
|
3936
|
+
output: {
|
|
3937
|
+
error: string;
|
|
3938
|
+
channels: string[];
|
|
3939
|
+
};
|
|
3940
|
+
outputFormat: "json";
|
|
4421
3941
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4422
3942
|
};
|
|
4423
3943
|
};
|
|
4424
3944
|
} & {
|
|
4425
|
-
"/
|
|
3945
|
+
"/debug/errors": {
|
|
4426
3946
|
$get: {
|
|
4427
3947
|
input: {
|
|
4428
|
-
query:
|
|
3948
|
+
query: {
|
|
3949
|
+
channel?: string | undefined;
|
|
3950
|
+
limit?: string | undefined;
|
|
3951
|
+
json?: "" | "true" | "false" | undefined;
|
|
3952
|
+
};
|
|
4429
3953
|
};
|
|
4430
3954
|
output: string;
|
|
4431
3955
|
outputFormat: "text";
|
|
4432
3956
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4433
3957
|
} | {
|
|
4434
3958
|
input: {
|
|
4435
|
-
query:
|
|
3959
|
+
query: {
|
|
3960
|
+
channel?: string | undefined;
|
|
3961
|
+
limit?: string | undefined;
|
|
3962
|
+
json?: "" | "true" | "false" | undefined;
|
|
3963
|
+
};
|
|
4436
3964
|
};
|
|
4437
|
-
output:
|
|
4438
|
-
|
|
3965
|
+
output: {
|
|
3966
|
+
error: string;
|
|
3967
|
+
availableChannels: string[];
|
|
3968
|
+
};
|
|
3969
|
+
outputFormat: "json";
|
|
4439
3970
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4440
3971
|
} | {
|
|
4441
3972
|
input: {
|
|
4442
|
-
query:
|
|
3973
|
+
query: {
|
|
3974
|
+
channel?: string | undefined;
|
|
3975
|
+
limit?: string | undefined;
|
|
3976
|
+
json?: "" | "true" | "false" | undefined;
|
|
3977
|
+
};
|
|
4443
3978
|
};
|
|
4444
|
-
output:
|
|
4445
|
-
|
|
3979
|
+
output: {
|
|
3980
|
+
error: string;
|
|
3981
|
+
channels: string[];
|
|
3982
|
+
};
|
|
3983
|
+
outputFormat: "json";
|
|
3984
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
3985
|
+
} | {
|
|
3986
|
+
input: {
|
|
3987
|
+
query: {
|
|
3988
|
+
channel?: string | undefined;
|
|
3989
|
+
limit?: string | undefined;
|
|
3990
|
+
json?: "" | "true" | "false" | undefined;
|
|
3991
|
+
};
|
|
3992
|
+
};
|
|
3993
|
+
output: {
|
|
3994
|
+
seq: number | null;
|
|
3995
|
+
ts: number | null;
|
|
3996
|
+
type: string;
|
|
3997
|
+
status: string;
|
|
3998
|
+
detail: string | null;
|
|
3999
|
+
}[];
|
|
4000
|
+
outputFormat: "json";
|
|
4446
4001
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4447
4002
|
};
|
|
4448
4003
|
};
|
|
4449
4004
|
} & {
|
|
4450
|
-
"/
|
|
4005
|
+
"/debug/replay": {
|
|
4451
4006
|
$get: {
|
|
4452
4007
|
input: {
|
|
4453
4008
|
query: {
|
|
4454
|
-
|
|
4009
|
+
channel?: string | undefined;
|
|
4010
|
+
seq?: string | undefined;
|
|
4011
|
+
json?: "" | "true" | "false" | undefined;
|
|
4455
4012
|
};
|
|
4456
4013
|
};
|
|
4457
4014
|
output: string;
|
|
4458
4015
|
outputFormat: "text";
|
|
4459
4016
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4460
|
-
}
|
|
4461
|
-
};
|
|
4462
|
-
} & {
|
|
4463
|
-
"/gateway/run": {
|
|
4464
|
-
$get: {
|
|
4017
|
+
} | {
|
|
4465
4018
|
input: {
|
|
4466
4019
|
query: {
|
|
4467
|
-
|
|
4020
|
+
channel?: string | undefined;
|
|
4021
|
+
seq?: string | undefined;
|
|
4022
|
+
json?: "" | "true" | "false" | undefined;
|
|
4468
4023
|
};
|
|
4469
4024
|
};
|
|
4470
|
-
output: string
|
|
4025
|
+
output: `error: ${string}`;
|
|
4471
4026
|
outputFormat: "text";
|
|
4472
4027
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4473
4028
|
} | {
|
|
4474
4029
|
input: {
|
|
4475
4030
|
query: {
|
|
4476
|
-
|
|
4031
|
+
channel?: string | undefined;
|
|
4032
|
+
seq?: string | undefined;
|
|
4033
|
+
json?: "" | "true" | "false" | undefined;
|
|
4477
4034
|
};
|
|
4478
4035
|
};
|
|
4479
|
-
output:
|
|
4480
|
-
outputFormat: "
|
|
4481
|
-
status: _$hono_utils_http_status0.
|
|
4482
|
-
}
|
|
4483
|
-
};
|
|
4484
|
-
} & {
|
|
4485
|
-
"/gateway/logs": {
|
|
4486
|
-
$get: {
|
|
4036
|
+
output: `channel not found: ${string}`;
|
|
4037
|
+
outputFormat: "text";
|
|
4038
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4039
|
+
} | {
|
|
4487
4040
|
input: {
|
|
4488
4041
|
query: {
|
|
4489
|
-
|
|
4042
|
+
channel?: string | undefined;
|
|
4043
|
+
seq?: string | undefined;
|
|
4044
|
+
json?: "" | "true" | "false" | undefined;
|
|
4490
4045
|
};
|
|
4491
4046
|
};
|
|
4492
|
-
output:
|
|
4047
|
+
output: "no diagnostic store yet (start the gateway first)";
|
|
4493
4048
|
outputFormat: "text";
|
|
4494
4049
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4495
4050
|
} | {
|
|
4496
4051
|
input: {
|
|
4497
4052
|
query: {
|
|
4498
|
-
|
|
4053
|
+
channel?: string | undefined;
|
|
4054
|
+
seq?: string | undefined;
|
|
4055
|
+
json?: "" | "true" | "false" | undefined;
|
|
4499
4056
|
};
|
|
4500
4057
|
};
|
|
4501
|
-
output:
|
|
4058
|
+
output: `multiple channels \u2014 specify one with --channel:
|
|
4059
|
+
${string}`;
|
|
4502
4060
|
outputFormat: "text";
|
|
4503
4061
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4504
|
-
}
|
|
4505
|
-
};
|
|
4506
|
-
} & {
|
|
4507
|
-
"/gateway/sql": {
|
|
4508
|
-
$get: {
|
|
4062
|
+
} | {
|
|
4509
4063
|
input: {
|
|
4510
4064
|
query: {
|
|
4511
|
-
|
|
4065
|
+
channel?: string | undefined;
|
|
4066
|
+
seq?: string | undefined;
|
|
4067
|
+
json?: "" | "true" | "false" | undefined;
|
|
4512
4068
|
};
|
|
4513
4069
|
};
|
|
4514
|
-
output:
|
|
4070
|
+
output: "no channels configured";
|
|
4515
4071
|
outputFormat: "text";
|
|
4516
4072
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4517
|
-
}
|
|
4518
|
-
};
|
|
4519
|
-
} & {
|
|
4520
|
-
"/gateway/listeners": {
|
|
4521
|
-
$get: {
|
|
4073
|
+
} | {
|
|
4522
4074
|
input: {
|
|
4523
|
-
query:
|
|
4075
|
+
query: {
|
|
4076
|
+
channel?: string | undefined;
|
|
4077
|
+
seq?: string | undefined;
|
|
4078
|
+
json?: "" | "true" | "false" | undefined;
|
|
4079
|
+
};
|
|
4524
4080
|
};
|
|
4525
|
-
output:
|
|
4081
|
+
output: {
|
|
4082
|
+
error: string;
|
|
4083
|
+
};
|
|
4084
|
+
outputFormat: "json";
|
|
4085
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4086
|
+
} | {
|
|
4087
|
+
input: {
|
|
4088
|
+
query: {
|
|
4089
|
+
channel?: string | undefined;
|
|
4090
|
+
seq?: string | undefined;
|
|
4091
|
+
json?: "" | "true" | "false" | undefined;
|
|
4092
|
+
};
|
|
4093
|
+
};
|
|
4094
|
+
output: "no matching event found";
|
|
4526
4095
|
outputFormat: "text";
|
|
4527
4096
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4528
4097
|
} | {
|
|
4529
4098
|
input: {
|
|
4530
|
-
query:
|
|
4099
|
+
query: {
|
|
4100
|
+
channel?: string | undefined;
|
|
4101
|
+
seq?: string | undefined;
|
|
4102
|
+
json?: "" | "true" | "false" | undefined;
|
|
4103
|
+
};
|
|
4531
4104
|
};
|
|
4532
|
-
output: "
|
|
4105
|
+
output: "event has no payload to replay";
|
|
4533
4106
|
outputFormat: "text";
|
|
4534
4107
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4535
4108
|
} | {
|
|
4536
4109
|
input: {
|
|
4537
|
-
query:
|
|
4110
|
+
query: {
|
|
4111
|
+
channel?: string | undefined;
|
|
4112
|
+
seq?: string | undefined;
|
|
4113
|
+
json?: "" | "true" | "false" | undefined;
|
|
4114
|
+
};
|
|
4538
4115
|
};
|
|
4539
|
-
output:
|
|
4540
|
-
|
|
4116
|
+
output: {
|
|
4117
|
+
replayed: true;
|
|
4118
|
+
seq: number | null;
|
|
4119
|
+
offset: number;
|
|
4120
|
+
preview: string | null;
|
|
4121
|
+
};
|
|
4122
|
+
outputFormat: "json";
|
|
4123
|
+
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4124
|
+
} | {
|
|
4125
|
+
input: {
|
|
4126
|
+
query: {
|
|
4127
|
+
channel?: string | undefined;
|
|
4128
|
+
seq?: string | undefined;
|
|
4129
|
+
json?: "" | "true" | "false" | undefined;
|
|
4130
|
+
};
|
|
4131
|
+
};
|
|
4132
|
+
output: `replayed seq=${number} \u2192 offset=${number}${string}` | `replayed seq=? \u2192 offset=${number}${string}`;
|
|
4541
4133
|
outputFormat: "text";
|
|
4542
4134
|
status: _$hono_utils_http_status0.ContentfulStatusCode;
|
|
4543
4135
|
};
|
|
@@ -4565,7 +4157,10 @@ ${string}`;
|
|
|
4565
4157
|
"/status": {
|
|
4566
4158
|
$get: {
|
|
4567
4159
|
input: {
|
|
4568
|
-
query:
|
|
4160
|
+
query: {
|
|
4161
|
+
watch?: "" | "true" | "false" | undefined;
|
|
4162
|
+
interval?: string | undefined;
|
|
4163
|
+
};
|
|
4569
4164
|
};
|
|
4570
4165
|
output: string;
|
|
4571
4166
|
outputFormat: "text";
|
|
@@ -4591,5 +4186,6 @@ ${string}`;
|
|
|
4591
4186
|
};
|
|
4592
4187
|
};
|
|
4593
4188
|
}, "/", "/update">;
|
|
4189
|
+
type CliApp = typeof routes;
|
|
4594
4190
|
//#endregion
|
|
4595
|
-
export { AliveStub, AttachOptions, BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, ChannelConfig, ChannelConnectorView, ChannelDeliveryMode, ChannelServerOptions, ChannelSpec, ConnectorConfig, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDiagnosticLog, ConnectorDiagnosticSqlReader, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, ConnectorSpec, ConnectorSyncOutcome, ConnectorType, DEFAULT_GATEWAY_PORT, DEFAULT_GATEWAY_TOKEN_PATH, DetachOptions, DiscordConnectorConfig, Env, FUNNEL_DIR, FUNNEL_MCP_ARGS, FUNNEL_MCP_COMMAND, FUNNEL_MCP_NAME, FileStat, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClaude, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLocalConfig, FunnelLocalConfigSync, FunnelLocalConfigWriter, FunnelLogger, FunnelMcp, FunnelProcessRunner, FunnelProfiles, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, FunnelTokenPrompter, type GatewayEmitInput, type GatewayRouteDeps, type Env$1 as GatewayServerEnv, GhConnectorConfig, LOCAL_CONFIG_FILENAME, LaunchOptions, ListListenersResult, ListenerEntry, ListenerOpResult, LocalConfig, LocalConfigSyncResult, LogEntry, MemoryConnectorDiagnosticLog, MemoryFunnelClock, MemoryFunnelEventLog, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryFunnelTokenPrompter, MemoryProcessCall, MemoryProcessHandler, MemoryProcessResponse, MemoryProcessSyncHandler, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NodeFunnelTokenPrompter, NoopFunnelLogger, NotifyFn, OnFunnelError, ProcessListStub, ProcessSnapshot, ProfileConfig, ProfileSpec, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, RunOptions, RunResult, SETTINGS_PATH, SETTINGS_VERSION, ScheduleCatchupPolicy, ScheduleConnectorConfig, ScheduleEntry, ScheduleListenerOptions, Settings, SlackConnectorConfig, SlackListenerOptions, SlackProcessed, SlackProcessedEmit, SlackProcessedSkip, SlackRawEvent, SlackSkipReason, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, StoredConnectionEvent, StoredProcessedEvent, StoredRawEvent, channelConfigSchema, channelDeliveryModeSchema, channelSpecSchema,
|
|
4191
|
+
export { AliveStub, AttachOptions, BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, ChannelConfig, ChannelConnectorView, ChannelDeliveryMode, ChannelServerOptions, ChannelSpec, type CliApp, ConnectorConfig, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDiagnosticLog, ConnectorDiagnosticSqlReader, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, ConnectorSpec, ConnectorSyncOutcome, ConnectorType, DEFAULT_GATEWAY_PORT, DEFAULT_GATEWAY_TOKEN_PATH, DetachOptions, DiscordConnectorConfig, Env, FUNNEL_DIR, FUNNEL_MCP_ARGS, FUNNEL_MCP_COMMAND, FUNNEL_MCP_NAME, FileStat, Funnel, FunnelBroadcaster, FunnelChannelPublisher, FunnelChannels, FunnelClaude, FunnelClock, FunnelConnectorFactory, FunnelConnectorListener, type FunnelDebugReport, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelFileSystem, FunnelGateway, FunnelGatewayServer, FunnelGatewayToken, FunnelIdGenerator, FunnelListenerSupervisor, FunnelListenersClient, FunnelLocalConfig, FunnelLocalConfigSync, FunnelLocalConfigWriter, FunnelLogger, FunnelMcp, FunnelProcessRunner, FunnelProfiles, FunnelSettingsReader, FunnelSettingsStore, FunnelSlackEventProcessor, FunnelTokenPrompter, type GatewayApp, type GatewayEmitInput, type GatewayRouteDeps, type Env$1 as GatewayServerEnv, GhConnectorConfig, LOCAL_CONFIG_FILENAME, LaunchOptions, ListListenersResult, ListenerEntry, ListenerOpResult, LocalConfig, LocalConfigSyncResult, LogEntry, MemoryConnectorDiagnosticLog, MemoryFunnelClock, MemoryFunnelEventLog, MemoryFunnelFileSystem, MemoryFunnelIdGenerator, MemoryFunnelLogger, MemoryFunnelProcessRunner, MemoryFunnelTokenPrompter, MemoryProcessCall, MemoryProcessHandler, MemoryProcessResponse, MemoryProcessSyncHandler, MockFunnelSettingsReader, NodeFunnelClock, NodeFunnelFileSystem, NodeFunnelIdGenerator, NodeFunnelLogger, NodeFunnelProcessRunner, NodeFunnelTokenPrompter, NoopFunnelLogger, NotifyFn, OnFunnelError, ProcessListStub, ProcessSnapshot, ProfileConfig, ProfileSpec, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, RunOptions, RunResult, SETTINGS_PATH, SETTINGS_VERSION, ScheduleCatchupPolicy, ScheduleConnectorConfig, ScheduleEntry, ScheduleListenerOptions, Settings, SlackConnectorConfig, SlackListenerOptions, SlackProcessed, SlackProcessedEmit, SlackProcessedSkip, SlackRawEvent, SlackSkipReason, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, StoredConnectionEvent, StoredProcessedEvent, StoredRawEvent, channelConfigSchema, channelDeliveryModeSchema, channelSpecSchema, routes as cliRoutes, connectorConfigSchema, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, connectorSpecSchema, createSettings, discordConnectorSchema, factory, funnelEventSchema, funnelJsonSchema, ghConnectorSchema, localConfigSchema, profileConfigSchema, profileSpecSchema, publishRequestSchema, publishResponseSchema, queryToCliArgs, resolveFunnelDir, resolveFunnelPort, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema, settingsSchema, slackConnectorSchema, startChannelServer, toRequest };
|