@interactive-inc/claude-funnel 0.8.1 → 0.10.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 +179 -80
- package/dist/bin.js +724 -656
- package/dist/connector-adapter-CXB-q_XC.d.ts +11 -0
- package/dist/connector-adapter-D5Utumgz.js +4 -0
- package/dist/connectors/discord.d.ts +76 -0
- package/dist/connectors/discord.js +2 -0
- package/dist/connectors/gh.d.ts +38 -0
- package/dist/connectors/gh.js +2 -0
- package/dist/connectors/schedule.d.ts +53 -0
- package/dist/connectors/schedule.js +2 -0
- package/dist/connectors/slack.d.ts +62 -0
- package/dist/connectors/slack.js +2 -0
- package/dist/discord-connector-schema-Dww2I4zH.d.ts +14 -0
- package/dist/discord-connector-schema-ygf5Df-2.js +173 -0
- package/dist/file-system-Co60LrmR.d.ts +74 -0
- package/dist/gateway/daemon.js +233 -183
- package/dist/gh-connector-schema-2ml29MBC.js +218 -0
- package/dist/gh-connector-schema-BZFAS-p-.d.ts +45 -0
- package/dist/index.d.ts +3888 -36
- package/dist/index.js +6206 -3485
- package/dist/logger-CTlXs7z4.d.ts +33 -0
- package/dist/node-logger-DQz_BGOD.js +61 -0
- package/dist/schedule-connector-schema-CkuIQ0JQ.js +325 -0
- package/dist/slack-connector-schema-Cd22WiHB.js +153 -0
- package/dist/slack-connector-schema-D7zAHN8k.d.ts +15 -0
- package/lib/bin.ts +1 -76
- package/lib/cli/index.ts +85 -0
- package/lib/cli/router/to-request.ts +1 -0
- package/lib/cli/routes/channels.$channel.publish.ts +52 -0
- package/lib/cli/routes/claude.ts +1 -0
- package/lib/cli/routes/index.ts +35 -18
- package/lib/cli/routes/profiles.add.$profile.ts +5 -2
- package/lib/cli/routes/profiles.set.$profile.ts +10 -11
- package/lib/connectors/discord.ts +4 -0
- package/lib/connectors/gh.ts +3 -0
- package/lib/connectors/schedule.ts +4 -0
- package/lib/connectors/slack.ts +4 -0
- package/lib/engine/claude/claude.ts +6 -0
- package/lib/engine/mcp/channel-server.ts +34 -115
- package/lib/engine/mcp/channel-subscriber.ts +82 -0
- package/lib/engine/mcp/read-channel-connectors.ts +34 -0
- package/lib/engine/mcp/read-gateway-token.ts +16 -0
- package/lib/engine/mcp/usage-hint-for-type.ts +15 -0
- package/lib/engine/settings/settings-schema.ts +2 -0
- package/lib/funnel.ts +162 -55
- package/lib/gateway/broadcaster.ts +1 -1
- package/lib/gateway/channel-publisher.ts +67 -0
- package/lib/gateway/gateway-server.ts +28 -16
- package/lib/gateway/publish-schema.ts +27 -0
- package/lib/gateway/routes/channels.publish.ts +44 -0
- package/lib/gateway/routes/index.ts +2 -0
- package/lib/gateway/routes/route-deps.ts +8 -0
- package/lib/index.ts +15 -0
- package/package.json +34 -23
- package/dist/cli/factory.d.ts +0 -7
- package/dist/cli/router/query-to-cli-args.d.ts +0 -1
- package/dist/cli/router/to-request.d.ts +0 -5
- package/dist/cli/router/validator.d.ts +0 -5
- package/dist/cli/routes/channels.$channel.connectors.$connector.d.ts +0 -42
- package/dist/cli/routes/channels.$channel.connectors.$connector.rename.$newName.d.ts +0 -46
- package/dist/cli/routes/channels.$channel.connectors.$connector.request.d.ts +0 -54
- package/dist/cli/routes/channels.$channel.connectors.$connector.schedules.add.$id.d.ts +0 -66
- package/dist/cli/routes/channels.$channel.connectors.$connector.schedules.d.ts +0 -42
- package/dist/cli/routes/channels.$channel.connectors.$connector.schedules.remove.$id.d.ts +0 -46
- package/dist/cli/routes/channels.$channel.connectors.add.$connector.d.ts +0 -90
- package/dist/cli/routes/channels.$channel.connectors.d.ts +0 -38
- package/dist/cli/routes/channels.$channel.connectors.remove.$connector.d.ts +0 -42
- package/dist/cli/routes/channels.$channel.connectors.set.$connector.d.ts +0 -62
- package/dist/cli/routes/channels.$channel.d.ts +0 -38
- package/dist/cli/routes/channels.$channel.rename.$newName.d.ts +0 -42
- package/dist/cli/routes/channels.$channel.set.delivery.$mode.d.ts +0 -28
- package/dist/cli/routes/channels.add.$channel.d.ts +0 -46
- package/dist/cli/routes/channels.d.ts +0 -16
- package/dist/cli/routes/channels.remove.$channel.d.ts +0 -38
- package/dist/cli/routes/claude.d.ts +0 -32
- package/dist/cli/routes/gateway.d.ts +0 -20
- package/dist/cli/routes/gateway.listeners.d.ts +0 -17
- package/dist/cli/routes/gateway.logs.d.ts +0 -24
- package/dist/cli/routes/gateway.restart.d.ts +0 -24
- package/dist/cli/routes/gateway.run.d.ts +0 -24
- package/dist/cli/routes/gateway.start.d.ts +0 -24
- package/dist/cli/routes/gateway.status.d.ts +0 -13
- package/dist/cli/routes/gateway.stop.d.ts +0 -16
- package/dist/cli/routes/index.d.ts +0 -1222
- package/dist/cli/routes/profiles.$profile.as-default.d.ts +0 -38
- package/dist/cli/routes/profiles.$profile.rename.$newName.d.ts +0 -42
- package/dist/cli/routes/profiles.$profile.run.d.ts +0 -46
- package/dist/cli/routes/profiles.add.$profile.d.ts +0 -54
- package/dist/cli/routes/profiles.d.ts +0 -16
- package/dist/cli/routes/profiles.remove.$profile.d.ts +0 -38
- package/dist/cli/routes/profiles.set.$profile.d.ts +0 -54
- package/dist/cli/routes/status.d.ts +0 -16
- package/dist/cli/routes/update.d.ts +0 -16
- package/dist/connectors/connector-adapter.d.ts +0 -8
- package/dist/connectors/connector-config-schema.d.ts +0 -43
- package/dist/connectors/connector-factory.d.ts +0 -32
- package/dist/connectors/connector-listener.d.ts +0 -17
- package/dist/connectors/discord-adapter.d.ts +0 -14
- package/dist/connectors/discord-connector-schema.d.ts +0 -10
- package/dist/connectors/discord-event-processor.d.ts +0 -26
- package/dist/connectors/discord-listener.d.ts +0 -17
- package/dist/connectors/gh-adapter.d.ts +0 -11
- package/dist/connectors/gh-connector-schema.d.ts +0 -10
- package/dist/connectors/gh-listener.d.ts +0 -26
- package/dist/connectors/match-cron.d.ts +0 -1
- package/dist/connectors/schedule-connector-schema.d.ts +0 -45
- package/dist/connectors/schedule-listener.d.ts +0 -30
- package/dist/connectors/schedule-state-store.d.ts +0 -19
- package/dist/connectors/slack-adapter.d.ts +0 -15
- package/dist/connectors/slack-connector-schema.d.ts +0 -11
- package/dist/connectors/slack-event-processor.d.ts +0 -27
- package/dist/connectors/slack-listener.d.ts +0 -17
- package/dist/engine/channels/channels.d.ts +0 -106
- package/dist/engine/claude/claude.d.ts +0 -49
- package/dist/engine/claude/gateway-controller.d.ts +0 -6
- package/dist/engine/fs/file-system.d.ts +0 -24
- package/dist/engine/fs/memory-file-system.d.ts +0 -31
- package/dist/engine/fs/node-file-system.d.ts +0 -15
- package/dist/engine/http/http-client.d.ts +0 -15
- package/dist/engine/http/memory-http-client.d.ts +0 -12
- package/dist/engine/http/node-http-client.d.ts +0 -5
- package/dist/engine/id/id-generator.d.ts +0 -7
- package/dist/engine/id/memory-id-generator.d.ts +0 -11
- package/dist/engine/id/node-id-generator.d.ts +0 -4
- package/dist/engine/logger/logger.d.ts +0 -11
- package/dist/engine/logger/memory-logger.d.ts +0 -14
- package/dist/engine/logger/node-logger.d.ts +0 -15
- package/dist/engine/logger/noop-logger.d.ts +0 -7
- package/dist/engine/mcp/channel-server.d.ts +0 -1
- package/dist/engine/mcp/mcp.d.ts +0 -22
- package/dist/engine/process/memory-process-runner.d.ts +0 -43
- package/dist/engine/process/node-process-runner.d.ts +0 -9
- package/dist/engine/process/process-runner.d.ts +0 -29
- package/dist/engine/profiles/profile-channel-checker.d.ts +0 -7
- package/dist/engine/profiles/profiles.d.ts +0 -31
- package/dist/engine/settings/mock-settings-reader.d.ts +0 -9
- package/dist/engine/settings/settings-reader.d.ts +0 -5
- package/dist/engine/settings/settings-schema.d.ts +0 -132
- package/dist/engine/settings/settings-store.d.ts +0 -18
- package/dist/engine/time/clock.d.ts +0 -9
- package/dist/engine/time/memory-clock.d.ts +0 -12
- package/dist/engine/time/node-clock.d.ts +0 -4
- package/dist/funnel.d.ts +0 -95
- package/dist/gateway/auth-middleware.d.ts +0 -14
- package/dist/gateway/broadcaster.d.ts +0 -122
- package/dist/gateway/daemon.d.ts +0 -2
- package/dist/gateway/factory.d.ts +0 -7
- package/dist/gateway/funnel-event-store.d.ts +0 -81
- package/dist/gateway/gateway-server.d.ts +0 -94
- package/dist/gateway/gateway-token.d.ts +0 -33
- package/dist/gateway/gateway.d.ts +0 -58
- package/dist/gateway/kill-competing-slack-gateways.d.ts +0 -9
- package/dist/gateway/listener-supervisor.d.ts +0 -85
- package/dist/gateway/listeners-client.d.ts +0 -53
- package/dist/gateway/resolve-daemon-script.d.ts +0 -11
- package/dist/gateway/routes/channels.connectors.call.d.ts +0 -41
- package/dist/gateway/routes/health.d.ts +0 -17
- package/dist/gateway/routes/index.d.ts +0 -209
- package/dist/gateway/routes/listeners.list.d.ts +0 -14
- package/dist/gateway/routes/listeners.restart.d.ts +0 -34
- package/dist/gateway/routes/listeners.start.d.ts +0 -34
- package/dist/gateway/routes/listeners.stop.d.ts +0 -34
- package/dist/gateway/routes/route-deps.d.ts +0 -10
- package/dist/gateway/routes/status.d.ts +0 -30
- package/dist/gateway/routes/validator.d.ts +0 -19
- package/dist/logger/leuco-human-file-writer.d.ts +0 -33
- package/dist/logger/leuco-human-logger.d.ts +0 -46
- package/dist/logger/leuco-human-record.d.ts +0 -15
- package/dist/logger/leuco-human-stdout-writer.d.ts +0 -20
- package/dist/logger/leuco-human-writer.d.ts +0 -13
- package/dist/logger/leuco-logger-memory-sink.d.ts +0 -33
- package/dist/logger/leuco-logger-record.d.ts +0 -13
- package/dist/logger/leuco-logger-sink.d.ts +0 -34
- package/dist/logger/leuco-logger-sqlite-sink.d.ts +0 -102
- package/dist/logger/leuco-logger.d.ts +0 -56
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region lib/connectors/connector-adapter.d.ts
|
|
2
|
+
type CallInput = {
|
|
3
|
+
method: string;
|
|
4
|
+
path: string;
|
|
5
|
+
body?: unknown;
|
|
6
|
+
};
|
|
7
|
+
declare abstract class FunnelConnectorAdapter {
|
|
8
|
+
abstract call(input: CallInput): Promise<unknown>;
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { FunnelConnectorAdapter as n, CallInput as t };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { n as FunnelConnectorAdapter, t as CallInput } from "../connector-adapter-CXB-q_XC.js";
|
|
2
|
+
import { n as discordConnectorSchema, t as DiscordConnectorConfig } from "../discord-connector-schema-Dww2I4zH.js";
|
|
3
|
+
import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "../logger-CTlXs7z4.js";
|
|
4
|
+
|
|
5
|
+
//#region lib/engine/http/http-client.d.ts
|
|
6
|
+
type HttpRequest = {
|
|
7
|
+
method: string;
|
|
8
|
+
url: string;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
body?: string;
|
|
11
|
+
};
|
|
12
|
+
type HttpResponse = {
|
|
13
|
+
status: number;
|
|
14
|
+
ok: boolean;
|
|
15
|
+
text(): Promise<string>;
|
|
16
|
+
json(): Promise<unknown>;
|
|
17
|
+
};
|
|
18
|
+
declare abstract class FunnelHttpClient {
|
|
19
|
+
abstract fetch(request: HttpRequest): Promise<HttpResponse>;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region lib/connectors/discord-adapter.d.ts
|
|
23
|
+
type Deps$1 = {
|
|
24
|
+
config: DiscordConnectorConfig;
|
|
25
|
+
http?: FunnelHttpClient;
|
|
26
|
+
};
|
|
27
|
+
declare class FunnelDiscordAdapter extends FunnelConnectorAdapter {
|
|
28
|
+
private readonly token;
|
|
29
|
+
private readonly http;
|
|
30
|
+
constructor(deps: Deps$1);
|
|
31
|
+
call(input: CallInput): Promise<unknown>;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region lib/connectors/discord-event-processor.d.ts
|
|
35
|
+
type DiscordInboundMessage = {
|
|
36
|
+
authorId: string;
|
|
37
|
+
authorIsBot: boolean;
|
|
38
|
+
channelId: string;
|
|
39
|
+
guildId: string | null;
|
|
40
|
+
mentionedUserIds: string[];
|
|
41
|
+
raw: unknown;
|
|
42
|
+
};
|
|
43
|
+
type DiscordProcessedSkip = {
|
|
44
|
+
skip: true;
|
|
45
|
+
};
|
|
46
|
+
type DiscordProcessedEmit = {
|
|
47
|
+
skip: false;
|
|
48
|
+
content: string;
|
|
49
|
+
meta: Record<string, string>;
|
|
50
|
+
};
|
|
51
|
+
type DiscordProcessed = DiscordProcessedSkip | DiscordProcessedEmit;
|
|
52
|
+
type Props = {
|
|
53
|
+
ownUserId: string;
|
|
54
|
+
};
|
|
55
|
+
declare class FunnelDiscordEventProcessor {
|
|
56
|
+
private readonly ownUserId;
|
|
57
|
+
constructor(props: Props);
|
|
58
|
+
process(message: DiscordInboundMessage): DiscordProcessed;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region lib/connectors/discord-listener.d.ts
|
|
62
|
+
type Deps = {
|
|
63
|
+
config: DiscordConnectorConfig;
|
|
64
|
+
logger?: FunnelLogger;
|
|
65
|
+
};
|
|
66
|
+
declare class FunnelDiscordListener extends FunnelConnectorListener {
|
|
67
|
+
private readonly config;
|
|
68
|
+
private readonly logger;
|
|
69
|
+
private client;
|
|
70
|
+
constructor(deps: Deps);
|
|
71
|
+
start(notify: NotifyFn): Promise<void>;
|
|
72
|
+
stop(): Promise<void>;
|
|
73
|
+
isAlive(): boolean;
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
export { DiscordConnectorConfig, DiscordInboundMessage, DiscordProcessed, DiscordProcessedEmit, DiscordProcessedSkip, FunnelDiscordAdapter, FunnelDiscordEventProcessor, FunnelDiscordListener, discordConnectorSchema };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { i as FunnelDiscordAdapter, n as FunnelDiscordListener, r as FunnelDiscordEventProcessor, t as discordConnectorSchema } from "../discord-connector-schema-ygf5Df-2.js";
|
|
2
|
+
export { FunnelDiscordAdapter, FunnelDiscordEventProcessor, FunnelDiscordListener, discordConnectorSchema };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { n as FunnelConnectorAdapter, t as CallInput } from "../connector-adapter-CXB-q_XC.js";
|
|
2
|
+
import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "../logger-CTlXs7z4.js";
|
|
3
|
+
import { a as FunnelProcessRunner, n as ghConnectorSchema, t as GhConnectorConfig } from "../gh-connector-schema-BZFAS-p-.js";
|
|
4
|
+
|
|
5
|
+
//#region lib/connectors/gh-adapter.d.ts
|
|
6
|
+
type Deps$1 = {
|
|
7
|
+
process?: FunnelProcessRunner;
|
|
8
|
+
};
|
|
9
|
+
declare class FunnelGhAdapter extends FunnelConnectorAdapter {
|
|
10
|
+
private readonly process;
|
|
11
|
+
constructor(deps?: Deps$1);
|
|
12
|
+
call(input: CallInput): Promise<unknown>;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region lib/connectors/gh-listener.d.ts
|
|
16
|
+
type Deps = {
|
|
17
|
+
config: GhConnectorConfig;
|
|
18
|
+
process?: FunnelProcessRunner;
|
|
19
|
+
logger?: FunnelLogger;
|
|
20
|
+
now?: () => Date;
|
|
21
|
+
};
|
|
22
|
+
declare class FunnelGhListener extends FunnelConnectorListener {
|
|
23
|
+
private readonly config;
|
|
24
|
+
private readonly process;
|
|
25
|
+
private readonly logger;
|
|
26
|
+
private readonly now;
|
|
27
|
+
private readonly seen;
|
|
28
|
+
private bootstrapped;
|
|
29
|
+
private since;
|
|
30
|
+
private timer;
|
|
31
|
+
constructor(deps: Deps);
|
|
32
|
+
start(notify: NotifyFn): Promise<void>;
|
|
33
|
+
stop(): Promise<void>;
|
|
34
|
+
isAlive(): boolean;
|
|
35
|
+
pollOnce(notify: NotifyFn): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { FunnelGhAdapter, FunnelGhListener, GhConnectorConfig, ghConnectorSchema };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "../logger-CTlXs7z4.js";
|
|
2
|
+
import { a as ScheduleEntry, c as scheduleEntrySchema, i as ScheduleConnectorConfig, n as FunnelFileSystem, o as scheduleCatchupPolicySchema, r as ScheduleCatchupPolicy, s as scheduleConnectorSchema } from "../file-system-Co60LrmR.js";
|
|
3
|
+
|
|
4
|
+
//#region lib/connectors/match-cron.d.ts
|
|
5
|
+
declare const matchCron: (expr: string, date: Date) => boolean;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region lib/connectors/schedule-state-store.d.ts
|
|
8
|
+
type Deps$1 = {
|
|
9
|
+
path: string;
|
|
10
|
+
fs?: FunnelFileSystem;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Per-connector lastFiredAt persistence for the schedule listener. The path is
|
|
14
|
+
* passed in by FunnelConnectorFactory so this store does not know about the
|
|
15
|
+
* funnel directory layout (`channels/<id>/connectors/<id>/state.json` lives
|
|
16
|
+
* outside this class).
|
|
17
|
+
*/
|
|
18
|
+
declare class ScheduleStateStore {
|
|
19
|
+
private readonly path;
|
|
20
|
+
private readonly fs;
|
|
21
|
+
constructor(deps: Deps$1);
|
|
22
|
+
load(): Map<string, Date>;
|
|
23
|
+
save(state: Map<string, Date>): void;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region lib/connectors/schedule-listener.d.ts
|
|
27
|
+
type Deps = {
|
|
28
|
+
config: ScheduleConnectorConfig;
|
|
29
|
+
lastFiredStore: ScheduleStateStore;
|
|
30
|
+
logger?: FunnelLogger;
|
|
31
|
+
now?: () => Date;
|
|
32
|
+
};
|
|
33
|
+
declare class FunnelScheduleListener extends FunnelConnectorListener {
|
|
34
|
+
private readonly config;
|
|
35
|
+
private readonly lastFiredStore;
|
|
36
|
+
private readonly logger;
|
|
37
|
+
private readonly now;
|
|
38
|
+
private timer;
|
|
39
|
+
private stopped;
|
|
40
|
+
constructor(deps: Deps);
|
|
41
|
+
start(notify: NotifyFn): Promise<void>;
|
|
42
|
+
stop(): Promise<void>;
|
|
43
|
+
isAlive(): boolean;
|
|
44
|
+
tick(notify: NotifyFn): Promise<void>;
|
|
45
|
+
private fireEntry;
|
|
46
|
+
private notifyOne;
|
|
47
|
+
private findMostRecentMatch;
|
|
48
|
+
private findAllMatches;
|
|
49
|
+
private logInvalidCron;
|
|
50
|
+
private truncateToMinute;
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { FunnelScheduleListener, ScheduleCatchupPolicy, ScheduleConnectorConfig, ScheduleEntry, ScheduleStateStore, matchCron, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as ScheduleStateStore, c as matchCron, i as FunnelScheduleListener, n as scheduleConnectorSchema, r as scheduleEntrySchema, t as scheduleCatchupPolicySchema } from "../schedule-connector-schema-CkuIQ0JQ.js";
|
|
2
|
+
export { FunnelScheduleListener, ScheduleStateStore, matchCron, scheduleCatchupPolicySchema, scheduleConnectorSchema, scheduleEntrySchema };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { n as FunnelConnectorAdapter, t as CallInput } from "../connector-adapter-CXB-q_XC.js";
|
|
2
|
+
import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "../logger-CTlXs7z4.js";
|
|
3
|
+
import { n as slackConnectorSchema, t as SlackConnectorConfig } from "../slack-connector-schema-D7zAHN8k.js";
|
|
4
|
+
|
|
5
|
+
//#region lib/connectors/slack-adapter.d.ts
|
|
6
|
+
type SlackWebClientLike = {
|
|
7
|
+
apiCall: (method: string, options?: Record<string, unknown>) => Promise<unknown>;
|
|
8
|
+
};
|
|
9
|
+
type Deps$1 = {
|
|
10
|
+
config: SlackConnectorConfig;
|
|
11
|
+
client?: SlackWebClientLike;
|
|
12
|
+
};
|
|
13
|
+
declare class FunnelSlackAdapter extends FunnelConnectorAdapter {
|
|
14
|
+
private readonly client;
|
|
15
|
+
constructor(deps: Deps$1);
|
|
16
|
+
call(input: CallInput): Promise<unknown>;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region lib/connectors/slack-event-processor.d.ts
|
|
20
|
+
type SlackRawEvent = Record<string, unknown>;
|
|
21
|
+
type SlackProcessedSkip = {
|
|
22
|
+
skip: true;
|
|
23
|
+
};
|
|
24
|
+
type SlackProcessedEmit = {
|
|
25
|
+
skip: false;
|
|
26
|
+
content: string;
|
|
27
|
+
meta: Record<string, string>;
|
|
28
|
+
shouldReact: boolean;
|
|
29
|
+
channel: string;
|
|
30
|
+
timestamp: string;
|
|
31
|
+
};
|
|
32
|
+
type SlackProcessed = SlackProcessedSkip | SlackProcessedEmit;
|
|
33
|
+
type Props = {
|
|
34
|
+
ownBotUserId: string;
|
|
35
|
+
ownBotId: string;
|
|
36
|
+
now?: () => number;
|
|
37
|
+
};
|
|
38
|
+
declare class FunnelSlackEventProcessor {
|
|
39
|
+
private readonly ownBotUserId;
|
|
40
|
+
private readonly ownBotId;
|
|
41
|
+
private readonly now;
|
|
42
|
+
private readonly dedup;
|
|
43
|
+
constructor(props: Props);
|
|
44
|
+
process(event: SlackRawEvent): SlackProcessed;
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region lib/connectors/slack-listener.d.ts
|
|
48
|
+
type Deps = {
|
|
49
|
+
config: SlackConnectorConfig;
|
|
50
|
+
logger?: FunnelLogger;
|
|
51
|
+
};
|
|
52
|
+
declare class FunnelSlackListener extends FunnelConnectorListener {
|
|
53
|
+
private readonly config;
|
|
54
|
+
private readonly logger;
|
|
55
|
+
private app;
|
|
56
|
+
constructor(deps: Deps);
|
|
57
|
+
start(notify: NotifyFn): Promise<void>;
|
|
58
|
+
stop(): Promise<void>;
|
|
59
|
+
isAlive(): boolean;
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { FunnelSlackAdapter, FunnelSlackEventProcessor, FunnelSlackListener, SlackConnectorConfig, SlackProcessed, SlackProcessedEmit, SlackProcessedSkip, SlackRawEvent, SlackWebClientLike, slackConnectorSchema };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region lib/connectors/discord-connector-schema.d.ts
|
|
4
|
+
declare const discordConnectorSchema: z.ZodObject<{
|
|
5
|
+
id: z.ZodString;
|
|
6
|
+
name: z.ZodString;
|
|
7
|
+
type: z.ZodLiteral<"discord">;
|
|
8
|
+
botToken: z.ZodString;
|
|
9
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
10
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
type DiscordConnectorConfig = z.infer<typeof discordConnectorSchema>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { discordConnectorSchema as n, DiscordConnectorConfig as t };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { t as FunnelConnectorAdapter } from "./connector-adapter-D5Utumgz.js";
|
|
2
|
+
import { r as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-DQz_BGOD.js";
|
|
3
|
+
import { Client, GatewayIntentBits, Partials } from "discord.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
//#region lib/engine/http/http-client.ts
|
|
6
|
+
var FunnelHttpClient = class {};
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region lib/engine/http/node-http-client.ts
|
|
9
|
+
var NodeFunnelHttpClient = class extends FunnelHttpClient {
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
Object.freeze(this);
|
|
13
|
+
}
|
|
14
|
+
async fetch(request) {
|
|
15
|
+
const res = await globalThis.fetch(request.url, {
|
|
16
|
+
method: request.method,
|
|
17
|
+
headers: request.headers,
|
|
18
|
+
body: request.body
|
|
19
|
+
});
|
|
20
|
+
return {
|
|
21
|
+
status: res.status,
|
|
22
|
+
ok: res.ok,
|
|
23
|
+
text: () => res.text(),
|
|
24
|
+
json: () => res.json()
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region lib/connectors/discord-adapter.ts
|
|
30
|
+
const DISCORD_API_BASE = "https://discord.com/api/v10";
|
|
31
|
+
const defaultHttp = new NodeFunnelHttpClient();
|
|
32
|
+
var FunnelDiscordAdapter = class extends FunnelConnectorAdapter {
|
|
33
|
+
token;
|
|
34
|
+
http;
|
|
35
|
+
constructor(deps) {
|
|
36
|
+
super();
|
|
37
|
+
this.token = deps.config.botToken;
|
|
38
|
+
this.http = deps.http ?? defaultHttp;
|
|
39
|
+
Object.freeze(this);
|
|
40
|
+
}
|
|
41
|
+
async call(input) {
|
|
42
|
+
const method = (input.method || "GET").toUpperCase();
|
|
43
|
+
const path = input.path.startsWith("/") ? input.path : `/${input.path}`;
|
|
44
|
+
const body = input.body;
|
|
45
|
+
const hasBody = body !== null && typeof body === "object" && method !== "GET" && Object.keys(body).length > 0;
|
|
46
|
+
const res = await this.http.fetch({
|
|
47
|
+
method,
|
|
48
|
+
url: `${DISCORD_API_BASE}${path}`,
|
|
49
|
+
headers: {
|
|
50
|
+
Authorization: `Bot ${this.token}`,
|
|
51
|
+
"Content-Type": "application/json"
|
|
52
|
+
},
|
|
53
|
+
body: hasBody ? JSON.stringify(input.body) : void 0
|
|
54
|
+
});
|
|
55
|
+
if (!res.ok) throw new Error(`Discord API failed (${res.status}): ${await res.text()}`);
|
|
56
|
+
if (res.status === 204) return null;
|
|
57
|
+
return await res.json();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region lib/connectors/discord-event-processor.ts
|
|
62
|
+
var FunnelDiscordEventProcessor = class {
|
|
63
|
+
ownUserId;
|
|
64
|
+
constructor(props) {
|
|
65
|
+
this.ownUserId = props.ownUserId;
|
|
66
|
+
}
|
|
67
|
+
process(message) {
|
|
68
|
+
if (message.authorIsBot) return { skip: true };
|
|
69
|
+
const mentioned = this.ownUserId ? message.mentionedUserIds.includes(this.ownUserId) : false;
|
|
70
|
+
return {
|
|
71
|
+
skip: false,
|
|
72
|
+
content: JSON.stringify(message.raw),
|
|
73
|
+
meta: {
|
|
74
|
+
event_type: "discord",
|
|
75
|
+
channel_id: message.channelId,
|
|
76
|
+
user_id: message.authorId,
|
|
77
|
+
mentioned: String(mentioned),
|
|
78
|
+
guild_id: message.guildId ?? ""
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region lib/connectors/discord-listener.ts
|
|
85
|
+
const defaultLogger = new NodeFunnelLogger();
|
|
86
|
+
var FunnelDiscordListener = class extends FunnelConnectorListener {
|
|
87
|
+
config;
|
|
88
|
+
logger;
|
|
89
|
+
client = null;
|
|
90
|
+
constructor(deps) {
|
|
91
|
+
super();
|
|
92
|
+
this.config = deps.config;
|
|
93
|
+
this.logger = deps.logger ?? defaultLogger;
|
|
94
|
+
}
|
|
95
|
+
async start(notify) {
|
|
96
|
+
const client = new Client({
|
|
97
|
+
intents: [
|
|
98
|
+
GatewayIntentBits.Guilds,
|
|
99
|
+
GatewayIntentBits.GuildMessages,
|
|
100
|
+
GatewayIntentBits.MessageContent,
|
|
101
|
+
GatewayIntentBits.DirectMessages
|
|
102
|
+
],
|
|
103
|
+
partials: [Partials.Channel]
|
|
104
|
+
});
|
|
105
|
+
client.on("messageCreate", async (message) => {
|
|
106
|
+
const ownUserId = client.user?.id ?? "";
|
|
107
|
+
const mentionedUserIds = [...message.mentions.users.keys()];
|
|
108
|
+
this.logger.info("discord messageCreate", {
|
|
109
|
+
author: message.author.id,
|
|
110
|
+
authorIsBot: String(message.author.bot),
|
|
111
|
+
channelId: message.channelId,
|
|
112
|
+
guildId: message.guildId ?? "",
|
|
113
|
+
mentions: mentionedUserIds.join(","),
|
|
114
|
+
ownUserId,
|
|
115
|
+
mentioned: String(mentionedUserIds.includes(ownUserId))
|
|
116
|
+
});
|
|
117
|
+
const result = new FunnelDiscordEventProcessor({ ownUserId }).process({
|
|
118
|
+
authorId: message.author.id,
|
|
119
|
+
authorIsBot: message.author.bot,
|
|
120
|
+
channelId: message.channelId,
|
|
121
|
+
guildId: message.guildId,
|
|
122
|
+
mentionedUserIds,
|
|
123
|
+
raw: message.toJSON()
|
|
124
|
+
});
|
|
125
|
+
if (result.skip) {
|
|
126
|
+
this.logger.info("discord skip", { reason: "bot author" });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
await notify(result.content, result.meta);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
this.logger.error("discord notify error", { error: error instanceof Error ? error.message : String(error) });
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
client.on("ready", (readyClient) => {
|
|
136
|
+
this.logger.info("discord ready", {
|
|
137
|
+
userId: readyClient.user.id,
|
|
138
|
+
tag: readyClient.user.tag,
|
|
139
|
+
guilds: String(readyClient.guilds.cache.size)
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
client.on("error", (error) => {
|
|
143
|
+
this.logger.error("discord client error", { error: error instanceof Error ? error.message : String(error) });
|
|
144
|
+
});
|
|
145
|
+
await client.login(this.config.botToken);
|
|
146
|
+
this.client = client;
|
|
147
|
+
}
|
|
148
|
+
async stop() {
|
|
149
|
+
if (!this.client) return;
|
|
150
|
+
try {
|
|
151
|
+
await this.client.destroy();
|
|
152
|
+
} catch (error) {
|
|
153
|
+
this.logger.error("discord stop error", { error: error instanceof Error ? error.message : String(error) });
|
|
154
|
+
} finally {
|
|
155
|
+
this.client = null;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
isAlive() {
|
|
159
|
+
return this.client !== null;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
//#endregion
|
|
163
|
+
//#region lib/connectors/discord-connector-schema.ts
|
|
164
|
+
const discordConnectorSchema = z.object({
|
|
165
|
+
id: z.string(),
|
|
166
|
+
name: z.string(),
|
|
167
|
+
type: z.literal("discord"),
|
|
168
|
+
botToken: z.string().min(10),
|
|
169
|
+
createdAt: z.string().datetime().optional(),
|
|
170
|
+
updatedAt: z.string().datetime().optional()
|
|
171
|
+
});
|
|
172
|
+
//#endregion
|
|
173
|
+
export { FunnelDiscordAdapter as i, FunnelDiscordListener as n, FunnelDiscordEventProcessor as r, discordConnectorSchema as t };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region lib/connectors/schedule-connector-schema.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Catch-up behavior when the daemon was down past one or more matching minutes.
|
|
6
|
+
*
|
|
7
|
+
* - `latest`: fire once with the most recent missed match (default; preserves prior behavior).
|
|
8
|
+
* - `all`: fire once per missed minute, oldest first (capped at 24 h).
|
|
9
|
+
* - `skip`: never fire missed matches; only fire when the current minute matches.
|
|
10
|
+
*/
|
|
11
|
+
declare const scheduleCatchupPolicySchema: z.ZodEnum<{
|
|
12
|
+
latest: "latest";
|
|
13
|
+
all: "all";
|
|
14
|
+
skip: "skip";
|
|
15
|
+
}>;
|
|
16
|
+
type ScheduleCatchupPolicy = z.infer<typeof scheduleCatchupPolicySchema>;
|
|
17
|
+
declare const scheduleEntrySchema: z.ZodObject<{
|
|
18
|
+
id: z.ZodString;
|
|
19
|
+
cron: z.ZodString;
|
|
20
|
+
prompt: z.ZodString;
|
|
21
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
22
|
+
catchupPolicy: z.ZodDefault<z.ZodEnum<{
|
|
23
|
+
latest: "latest";
|
|
24
|
+
all: "all";
|
|
25
|
+
skip: "skip";
|
|
26
|
+
}>>;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
type ScheduleEntry = z.infer<typeof scheduleEntrySchema>;
|
|
29
|
+
declare const scheduleConnectorSchema: z.ZodObject<{
|
|
30
|
+
id: z.ZodString;
|
|
31
|
+
name: z.ZodString;
|
|
32
|
+
type: z.ZodLiteral<"schedule">;
|
|
33
|
+
entries: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
34
|
+
id: z.ZodString;
|
|
35
|
+
cron: z.ZodString;
|
|
36
|
+
prompt: z.ZodString;
|
|
37
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
38
|
+
catchupPolicy: z.ZodDefault<z.ZodEnum<{
|
|
39
|
+
latest: "latest";
|
|
40
|
+
all: "all";
|
|
41
|
+
skip: "skip";
|
|
42
|
+
}>>;
|
|
43
|
+
}, z.core.$strip>>>;
|
|
44
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
45
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
type ScheduleConnectorConfig = z.infer<typeof scheduleConnectorSchema>;
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region lib/engine/fs/file-system.d.ts
|
|
50
|
+
type FileStat = {
|
|
51
|
+
mtimeMs: number; /** POSIX mode bits (e.g. 0o600). `null` when the underlying FS does not expose mode. */
|
|
52
|
+
mode: number | null;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Filesystem boundary used everywhere funnel reads or writes.
|
|
56
|
+
* Default is NodeFunnelFileSystem (real `node:fs`); MemoryFunnelFileSystem
|
|
57
|
+
* provides a sandbox for tests and embedded use.
|
|
58
|
+
*/
|
|
59
|
+
declare abstract class FunnelFileSystem {
|
|
60
|
+
abstract existsSync(path: string): boolean;
|
|
61
|
+
abstract readFileSync(path: string): string;
|
|
62
|
+
abstract writeFileSync(path: string, data: string): void;
|
|
63
|
+
/** Write `data` and ensure the resulting file is owner-only (0600). Use for tokens and any file that may contain secrets. */
|
|
64
|
+
abstract writeSecretFileSync(path: string, data: string): void;
|
|
65
|
+
abstract appendFileSync(path: string, data: string): void;
|
|
66
|
+
abstract unlink(path: string): void;
|
|
67
|
+
abstract mkdirSync(path: string, options?: {
|
|
68
|
+
recursive?: boolean;
|
|
69
|
+
}): void;
|
|
70
|
+
abstract readdirSync(path: string): string[];
|
|
71
|
+
abstract statSync(path: string): FileStat;
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { ScheduleEntry as a, scheduleEntrySchema as c, ScheduleConnectorConfig as i, FunnelFileSystem as n, scheduleCatchupPolicySchema as o, ScheduleCatchupPolicy as r, scheduleConnectorSchema as s, FileStat as t };
|