@interactive-inc/claude-funnel 0.59.1 → 0.60.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 +9 -3
- package/dist/bin.js +549 -487
- package/dist/channels-2g_BU1N0.d.ts +174 -0
- package/dist/claude.d.ts +9 -5
- package/dist/claude.js +54 -17
- package/dist/{diagnostic-log-Cb3v8P7p.d.ts → connector-descriptor-6SXJoszo.d.ts} +158 -2
- package/dist/connectors/discord.d.ts +30 -4
- package/dist/connectors/discord.js +2 -2
- package/dist/connectors/gh.d.ts +21 -5
- package/dist/connectors/gh.js +3 -3
- package/dist/connectors/schedule.d.ts +124 -2
- package/dist/connectors/schedule.js +3 -3
- package/dist/connectors/slack.d.ts +149 -5
- package/dist/connectors/slack.js +2 -2
- package/dist/{diagnostic-sql-reader-CzYgZpq2.js → diagnostic-sql-reader-C9zR-Csp.js} +5 -5
- package/dist/diagnostics.d.ts +1 -1
- package/dist/diagnostics.js +1 -1
- package/dist/{discord-listener-CKsZGTnH.js → discord-connector-BL36yvbL.js} +60 -37
- package/dist/docs.d.ts +1 -1
- package/dist/docs.js +1 -1
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.js +1 -1
- package/dist/error-message-of-Byi4y0Uf.js +9 -0
- package/dist/{file-process-guard-JhFpmHYo.d.ts → file-process-guard-DOlCr4GF.d.ts} +4 -5
- package/dist/{funnel-diagnostics-BpKYrMSu.js → funnel-diagnostics-CSiJmPlZ.js} +19 -2
- package/dist/{funnel-diagnostics-K-wON25Y.d.ts → funnel-diagnostics-DpXOsCty.d.ts} +3 -3
- package/dist/{funnel-docs-ng5K8w4j.js → funnel-docs-BxXZ9Ksx.js} +76 -3
- package/dist/{funnel-docs-DYBs1-H_.d.ts → funnel-docs-CNklHvbt.d.ts} +1 -1
- package/dist/{funnel-doctor-vxO96TCA.d.ts → funnel-doctor-CZf_0Luq.d.ts} +2 -2
- package/dist/{funnel-recovery-COExL9MD.d.ts → funnel-recovery-DnLrdWO9.d.ts} +1 -1
- package/dist/gateway/daemon.js +326 -266
- package/dist/gateway-base-url-Dy4Ykuoh.js +14 -0
- package/dist/gateway.d.ts +2 -2
- package/dist/gateway.js +2 -2
- package/dist/{gh-listener-B2I4s8qh.js → gh-connector-DpiixfQZ.js} +53 -5
- package/dist/gh-connector-schema-Rzwc1c1N.js +12 -0
- package/dist/http-client-oICicjuO.d.ts +18 -0
- package/dist/index-CgY8NdMz.d.ts +1057 -0
- package/dist/index.d.ts +1558 -17
- package/dist/index.js +374 -342
- package/dist/{local-config-json-schema-DE1zkMcb.js → local-config-json-schema-JyLqOQNX.js} +9 -5
- package/dist/local-config-sync-Dh1Croqe.d.ts +169 -0
- package/dist/local-config.d.ts +2 -2
- package/dist/local-config.js +2 -2
- package/dist/logger.js +1 -1
- package/dist/{memory-diagnostic-log-B9Us7X05.js → memory-diagnostic-log-CI60kNfB.js} +33 -18
- package/dist/{memory-token-prompter-CcShtF8B.d.ts → memory-token-prompter-B4sjyaAq.d.ts} +2 -2
- package/dist/{memory-token-prompter-C7vREzCL.js → memory-token-prompter-CZde7e6y.js} +1 -1
- package/dist/{node-file-system-BcrmWN9I.js → node-file-system-Blr8pAir.js} +1 -1
- package/dist/node-http-client-lowp60Oa.js +25 -0
- package/dist/{gh-connector-schema-ClPLSYD9.js → node-process-runner-DxTvycoK.js} +1 -12
- package/dist/{profiles-g2qGVOWv.d.ts → profiles-Cy5wXQ0L.d.ts} +3 -3
- package/dist/{profiles-MnXvYfZF.js → profiles-DSzTeKQw.js} +1 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/profiles.js +1 -1
- package/dist/recovery.d.ts +1 -1
- package/dist/recovery.js +1 -1
- package/dist/{schedule-listener-DP9Jhc6U.js → schedule-connector-L4uzg5M8.js} +109 -9
- package/dist/{settings-reader-DPwqOVUm.d.ts → settings-reader-BIFB_j2f.d.ts} +1 -1
- package/dist/settings-schema-D1xcOqRu.d.ts +78 -0
- package/dist/{gateway-base-url-DxVjjDoW.js → settings-store-CUKSeTXC.js} +27 -29
- package/dist/{slack-listener-C4wlZaOq.js → slack-connector-DQIFPdBF.js} +67 -12
- package/dist/slot-fields-CMoRpwuy.js +45 -0
- package/dist/{yaml-render-cZu6CxkE.js → yaml-render-qW34NlYz.js} +4 -4
- package/package.json +1 -1
- package/dist/connector-adapter-DGacCppE.d.ts +0 -25
- package/dist/discord-connector-schema-CQyfDkLD.d.ts +0 -39
- package/dist/gh-connector-schema-CZzwzvqY.d.ts +0 -14
- package/dist/index-D7mjirUL.d.ts +0 -3602
- package/dist/local-config-sync-BGPAS9Be.d.ts +0 -401
- package/dist/process-runner-DIm1cy95.d.ts +0 -52
- package/dist/resolve-connector-token-CczqG_Ig.js +0 -22
- package/dist/schedule-listener-DoMPjHZj.d.ts +0 -112
- package/dist/settings-schema-1hh11jnN.d.ts +0 -152
- package/dist/slack-listener-Dj9NFbAJ.d.ts +0 -136
- /package/dist/{connector-adapter-qwXLjQId.js → connector-adapter-DU9Rvyec.js} +0 -0
- /package/dist/{connector-listener-CpHBecCj.js → connector-listener-DR3aKOuK.js} +0 -0
- /package/dist/{file-system-PWKKU7lA.js → file-system-Wvzc2ePY.js} +0 -0
- /package/dist/{file-system-DxpnnUVb.d.ts → file-system-o51IsM0W.d.ts} +0 -0
- /package/dist/{funnel-doctor-CApCezTq.js → funnel-doctor-DiJCjHsg.js} +0 -0
- /package/dist/{funnel-log-sqlite-sink-B_5_4ybn.js → funnel-log-sqlite-sink-kqJbx2H7.js} +0 -0
- /package/dist/{funnel-recovery-D9CxD5Zs.js → funnel-recovery-BFdPjL6Z.js} +0 -0
- /package/dist/{logger-BP6SisKt.js → logger-B6iyNbxM.js} +0 -0
- /package/dist/{schedule-connector-schema-B_xO5z5B.js → schedule-connector-schema-CfyuMCMh.js} +0 -0
- /package/dist/{settings-reader-DPqrpV7s.js → settings-reader-CtQ-Ix8_.js} +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region lib/engine/settings/settings-schema.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Routing mode when multiple WS clients are subscribed to the same channel.
|
|
6
|
+
*
|
|
7
|
+
* - `fanout` (default): every connected client receives every event. Right when each
|
|
8
|
+
* subscriber has its own job (e.g., TUI mirrors, distinct Claude profiles each running
|
|
9
|
+
* their own pipeline against the same source).
|
|
10
|
+
* - `exclusive`: each event is delivered to exactly one connected client, picked
|
|
11
|
+
* round-robin per channel. Right when subscribers are interchangeable workers and you
|
|
12
|
+
* want each event handled once. Tap=all clients (TUI dashboard) always receive,
|
|
13
|
+
* regardless of mode, so they can passively observe.
|
|
14
|
+
*/
|
|
15
|
+
declare const channelDeliveryModeSchema: z.ZodEnum<{
|
|
16
|
+
fanout: "fanout";
|
|
17
|
+
exclusive: "exclusive";
|
|
18
|
+
}>;
|
|
19
|
+
type ChannelDeliveryMode = z.infer<typeof channelDeliveryModeSchema>;
|
|
20
|
+
declare const channelConfigSchema: z.ZodObject<{
|
|
21
|
+
id: z.ZodString;
|
|
22
|
+
name: z.ZodString;
|
|
23
|
+
delivery: z.ZodDefault<z.ZodEnum<{
|
|
24
|
+
fanout: "fanout";
|
|
25
|
+
exclusive: "exclusive";
|
|
26
|
+
}>>;
|
|
27
|
+
connectors: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
28
|
+
id: z.ZodString;
|
|
29
|
+
name: z.ZodString;
|
|
30
|
+
type: z.ZodString;
|
|
31
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
32
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
33
|
+
}, z.core.$loose>>>;
|
|
34
|
+
}, z.core.$strip>;
|
|
35
|
+
type ChannelConfig = z.infer<typeof channelConfigSchema>;
|
|
36
|
+
declare const profileConfigSchema: z.ZodObject<{
|
|
37
|
+
id: z.ZodString;
|
|
38
|
+
name: z.ZodString;
|
|
39
|
+
path: z.ZodString;
|
|
40
|
+
channelId: z.ZodString;
|
|
41
|
+
options: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
42
|
+
env: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
43
|
+
resume: z.ZodDefault<z.ZodBoolean>;
|
|
44
|
+
sessionId: z.ZodOptional<z.ZodString>;
|
|
45
|
+
}, z.core.$strip>;
|
|
46
|
+
type ProfileConfig = z.infer<typeof profileConfigSchema>;
|
|
47
|
+
declare const SETTINGS_VERSION = 1;
|
|
48
|
+
declare const settingsSchema: z.ZodObject<{
|
|
49
|
+
version: z.ZodDefault<z.ZodLiteral<1>>;
|
|
50
|
+
channels: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
51
|
+
id: z.ZodString;
|
|
52
|
+
name: z.ZodString;
|
|
53
|
+
delivery: z.ZodDefault<z.ZodEnum<{
|
|
54
|
+
fanout: "fanout";
|
|
55
|
+
exclusive: "exclusive";
|
|
56
|
+
}>>;
|
|
57
|
+
connectors: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
58
|
+
id: z.ZodString;
|
|
59
|
+
name: z.ZodString;
|
|
60
|
+
type: z.ZodString;
|
|
61
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
62
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
63
|
+
}, z.core.$loose>>>;
|
|
64
|
+
}, z.core.$strip>>>;
|
|
65
|
+
profiles: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
66
|
+
id: z.ZodString;
|
|
67
|
+
name: z.ZodString;
|
|
68
|
+
path: z.ZodString;
|
|
69
|
+
channelId: z.ZodString;
|
|
70
|
+
options: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
71
|
+
env: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
72
|
+
resume: z.ZodDefault<z.ZodBoolean>;
|
|
73
|
+
sessionId: z.ZodOptional<z.ZodString>;
|
|
74
|
+
}, z.core.$strip>>>;
|
|
75
|
+
}, z.core.$strip>;
|
|
76
|
+
type Settings = z.infer<typeof settingsSchema>;
|
|
77
|
+
//#endregion
|
|
78
|
+
export { Settings as a, profileConfigSchema as c, SETTINGS_VERSION as i, settingsSchema as l, ChannelDeliveryMode as n, channelConfigSchema as o, ProfileConfig as r, channelDeliveryModeSchema as s, ChannelConfig as t };
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import { t as
|
|
3
|
-
import { n as FunnelIdGenerator, t as FunnelSettingsReader } from "./settings-reader-DPqrpV7s.js";
|
|
4
|
-
import { t as discordConnectorSchema } from "./discord-connector-schema-B_N6IXLz.js";
|
|
5
|
-
import { n as scheduleConnectorSchema } from "./schedule-connector-schema-B_xO5z5B.js";
|
|
6
|
-
import { t as slackConnectorSchema } from "./slack-connector-schema-C1zEf4TG.js";
|
|
1
|
+
import { t as NodeFunnelFileSystem } from "./node-file-system-Blr8pAir.js";
|
|
2
|
+
import { n as FunnelIdGenerator, t as FunnelSettingsReader } from "./settings-reader-CtQ-Ix8_.js";
|
|
7
3
|
import { dirname, join } from "node:path";
|
|
8
|
-
import { z } from "zod";
|
|
9
4
|
import { homedir } from "node:os";
|
|
5
|
+
import { z } from "zod";
|
|
10
6
|
//#region lib/engine/id/node-id-generator.ts
|
|
11
7
|
var NodeFunnelIdGenerator = class extends FunnelIdGenerator {
|
|
12
8
|
generate() {
|
|
@@ -14,16 +10,31 @@ var NodeFunnelIdGenerator = class extends FunnelIdGenerator {
|
|
|
14
10
|
}
|
|
15
11
|
};
|
|
16
12
|
//#endregion
|
|
17
|
-
//#region lib/engine/connectors/connector-config
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
//#region lib/engine/connectors/base-connector-config.ts
|
|
14
|
+
/**
|
|
15
|
+
* Fields every connector config carries, regardless of type. The discriminated
|
|
16
|
+
* union of concrete connector configs no longer lives in core: each connector
|
|
17
|
+
* type owns its full schema inside its descriptor, and core handles connectors
|
|
18
|
+
* through this base shape plus the injected registry. `type` is an open string
|
|
19
|
+
* here on purpose — core does not enumerate the known connector types.
|
|
20
|
+
*/
|
|
21
|
+
const baseConnectorConfigSchema = z.object({
|
|
22
|
+
id: z.string(),
|
|
23
|
+
name: z.string(),
|
|
24
|
+
type: z.string(),
|
|
25
|
+
createdAt: z.string().datetime().optional(),
|
|
26
|
+
updatedAt: z.string().datetime().optional()
|
|
27
|
+
});
|
|
24
28
|
//#endregion
|
|
25
29
|
//#region lib/engine/settings/settings-schema.ts
|
|
26
30
|
/**
|
|
31
|
+
* Connectors are stored loosely here: settings validates only the common base
|
|
32
|
+
* fields and preserves every type-specific key verbatim (`.passthrough()`).
|
|
33
|
+
* Core does not enumerate connector types, so strict per-type validation happens
|
|
34
|
+
* at the registry/descriptor layer (CRUD time), not on every settings read.
|
|
35
|
+
*/
|
|
36
|
+
const storedConnectorSchema = baseConnectorConfigSchema.passthrough();
|
|
37
|
+
/**
|
|
27
38
|
* Routing mode when multiple WS clients are subscribed to the same channel.
|
|
28
39
|
*
|
|
29
40
|
* - `fanout` (default): every connected client receives every event. Right when each
|
|
@@ -39,7 +50,7 @@ const channelConfigSchema = z.object({
|
|
|
39
50
|
id: z.string(),
|
|
40
51
|
name: z.string(),
|
|
41
52
|
delivery: channelDeliveryModeSchema.default("fanout"),
|
|
42
|
-
connectors: z.array(
|
|
53
|
+
connectors: z.array(storedConnectorSchema).default([])
|
|
43
54
|
});
|
|
44
55
|
const profileConfigSchema = z.object({
|
|
45
56
|
/** Stable identity (uuid). The primary key everything internal resolves to;
|
|
@@ -183,17 +194,4 @@ var FunnelSettingsStore = class extends FunnelSettingsReader {
|
|
|
183
194
|
}
|
|
184
195
|
};
|
|
185
196
|
//#endregion
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* The HTTP base URL of a gateway daemon on the loopback interface. The daemon
|
|
189
|
-
* always binds 127.0.0.1 for its management API (only the WS `/ws` endpoint is
|
|
190
|
-
* ever exposed off-box), so every in-process HTTP client — publisher, listeners
|
|
191
|
-
* client, MCP channel server — talks to it here. Centralizing the construction
|
|
192
|
-
* keeps the host/port shape in one place instead of re-spelling
|
|
193
|
-
* `http://127.0.0.1:${port}` at each call site.
|
|
194
|
-
*/
|
|
195
|
-
function gatewayLoopbackUrl(port) {
|
|
196
|
-
return `http://127.0.0.1:${port}`;
|
|
197
|
-
}
|
|
198
|
-
//#endregion
|
|
199
|
-
export { SETTINGS_PATH as a, SETTINGS_VERSION as c, profileConfigSchema as d, settingsSchema as f, FunnelSettingsStore as i, channelConfigSchema as l, NodeFunnelIdGenerator as m, DEFAULT_GATEWAY_PORT as n, resolveFunnelDir as o, connectorConfigSchema as p, FUNNEL_DIR as r, resolveFunnelPort as s, gatewayLoopbackUrl as t, channelDeliveryModeSchema as u };
|
|
197
|
+
export { resolveFunnelDir as a, channelConfigSchema as c, settingsSchema as d, baseConnectorConfigSchema as f, SETTINGS_PATH as i, channelDeliveryModeSchema as l, FUNNEL_DIR as n, resolveFunnelPort as o, NodeFunnelIdGenerator as p, FunnelSettingsStore as r, SETTINGS_VERSION as s, DEFAULT_GATEWAY_PORT as t, profileConfigSchema as u };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import { t as
|
|
3
|
-
import { t as FunnelConnectorListener } from "./connector-listener-
|
|
1
|
+
import { t as slackConnectorSchema } from "./slack-connector-schema-C1zEf4TG.js";
|
|
2
|
+
import { t as FunnelConnectorAdapter } from "./connector-adapter-DU9Rvyec.js";
|
|
3
|
+
import { t as FunnelConnectorListener } from "./connector-listener-DR3aKOuK.js";
|
|
4
|
+
import { t as errorMessageOf } from "./error-message-of-Byi4y0Uf.js";
|
|
5
|
+
import { n as resolveConnectorToken, t as slotFields } from "./slot-fields-CMoRpwuy.js";
|
|
4
6
|
import { z } from "zod";
|
|
5
7
|
import { WebClient } from "@slack/web-api";
|
|
6
8
|
import { App, LogLevel, SocketModeReceiver } from "@slack/bolt";
|
|
@@ -316,7 +318,7 @@ var FunnelSlackListener = class extends FunnelConnectorListener {
|
|
|
316
318
|
try {
|
|
317
319
|
authResult = await app.client.auth.test({ token: botToken });
|
|
318
320
|
} catch (error) {
|
|
319
|
-
this.recordConnection("auth-failed",
|
|
321
|
+
this.recordConnection("auth-failed", errorMessageOf(error));
|
|
320
322
|
throw error;
|
|
321
323
|
}
|
|
322
324
|
const processor = new FunnelSlackEventProcessor({
|
|
@@ -361,7 +363,7 @@ var FunnelSlackListener = class extends FunnelConnectorListener {
|
|
|
361
363
|
} catch {}
|
|
362
364
|
});
|
|
363
365
|
app.error(async (error) => {
|
|
364
|
-
const message =
|
|
366
|
+
const message = errorMessageOf(error);
|
|
365
367
|
this.recordConnection("error", message);
|
|
366
368
|
this.logger?.error("Slack error", { error: message });
|
|
367
369
|
});
|
|
@@ -369,7 +371,7 @@ var FunnelSlackListener = class extends FunnelConnectorListener {
|
|
|
369
371
|
try {
|
|
370
372
|
await app.start();
|
|
371
373
|
} catch (error) {
|
|
372
|
-
this.recordConnection("error",
|
|
374
|
+
this.recordConnection("error", errorMessageOf(error));
|
|
373
375
|
throw error;
|
|
374
376
|
}
|
|
375
377
|
this.app = app;
|
|
@@ -382,8 +384,8 @@ var FunnelSlackListener = class extends FunnelConnectorListener {
|
|
|
382
384
|
await this.app.stop();
|
|
383
385
|
this.recordConnection("disconnected", "");
|
|
384
386
|
} catch (error) {
|
|
385
|
-
this.recordConnection("error",
|
|
386
|
-
this.logger?.error("Slack stop error", { error:
|
|
387
|
+
this.recordConnection("error", errorMessageOf(error));
|
|
388
|
+
this.logger?.error("Slack stop error", { error: errorMessageOf(error) });
|
|
387
389
|
} finally {
|
|
388
390
|
this.app = null;
|
|
389
391
|
this.connected = false;
|
|
@@ -422,8 +424,61 @@ var FunnelSlackListener = class extends FunnelConnectorListener {
|
|
|
422
424
|
});
|
|
423
425
|
}
|
|
424
426
|
};
|
|
425
|
-
const messageOf = (error) => {
|
|
426
|
-
return error instanceof Error ? error.message : String(error);
|
|
427
|
-
};
|
|
428
427
|
//#endregion
|
|
429
|
-
|
|
428
|
+
//#region lib/engine/connectors/slack-connector.ts
|
|
429
|
+
/**
|
|
430
|
+
* Slack connector descriptor. Pass `slackConnector()` to
|
|
431
|
+
* `new Funnel({ connectors: [...] })` to enable the type. Host launch hooks are
|
|
432
|
+
* closed over here, so they need no Funnel-level option plumbing.
|
|
433
|
+
*/
|
|
434
|
+
const slackConnector = (options = {}) => ({
|
|
435
|
+
type: "slack",
|
|
436
|
+
toolExposed: true,
|
|
437
|
+
createListener(config, deps) {
|
|
438
|
+
return new FunnelSlackListener({
|
|
439
|
+
config: slackConnectorSchema.parse(config),
|
|
440
|
+
channelId: deps.channelId,
|
|
441
|
+
logger: deps.logger,
|
|
442
|
+
diagnosticLog: deps.diagnosticLog,
|
|
443
|
+
onAppCreated: options.onAppCreated,
|
|
444
|
+
preprocessEvent: options.preprocessEvent
|
|
445
|
+
});
|
|
446
|
+
},
|
|
447
|
+
createAdapter(config) {
|
|
448
|
+
return new FunnelSlackAdapter({ config: slackConnectorSchema.parse(config) });
|
|
449
|
+
},
|
|
450
|
+
secretTokens(config) {
|
|
451
|
+
const parsed = slackConnectorSchema.parse(config);
|
|
452
|
+
return [parsed.botToken, parsed.appToken].filter((token) => token !== void 0);
|
|
453
|
+
},
|
|
454
|
+
buildConfig(input, context) {
|
|
455
|
+
return slackConnectorSchema.parse({
|
|
456
|
+
id: context.id,
|
|
457
|
+
type: "slack",
|
|
458
|
+
name: input.name,
|
|
459
|
+
...typeof input.botToken === "string" ? { botToken: input.botToken } : {},
|
|
460
|
+
...typeof input.appToken === "string" ? { appToken: input.appToken } : {},
|
|
461
|
+
...typeof input.botTokenEnv === "string" ? { botTokenEnv: input.botTokenEnv } : {},
|
|
462
|
+
...typeof input.appTokenEnv === "string" ? { appTokenEnv: input.appTokenEnv } : {},
|
|
463
|
+
minify: typeof input.minify === "boolean" ? input.minify : true,
|
|
464
|
+
createdAt: context.now,
|
|
465
|
+
updatedAt: context.now
|
|
466
|
+
});
|
|
467
|
+
},
|
|
468
|
+
applyUpdate(config, fields, context) {
|
|
469
|
+
const current = slackConnectorSchema.parse(config);
|
|
470
|
+
return slackConnectorSchema.parse({
|
|
471
|
+
id: current.id,
|
|
472
|
+
name: current.name,
|
|
473
|
+
type: "slack",
|
|
474
|
+
minify: current.minify,
|
|
475
|
+
createdAt: current.createdAt,
|
|
476
|
+
updatedAt: context.now,
|
|
477
|
+
...slotFields("botToken", "botTokenEnv", fields, current),
|
|
478
|
+
...slotFields("appToken", "appTokenEnv", fields, current)
|
|
479
|
+
});
|
|
480
|
+
},
|
|
481
|
+
operations: {}
|
|
482
|
+
});
|
|
483
|
+
//#endregion
|
|
484
|
+
export { FunnelSlackAdapter as i, FunnelSlackListener as n, FunnelSlackEventProcessor as r, slackConnector as t };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region lib/engine/connectors/resolve-connector-token.ts
|
|
2
|
+
/**
|
|
3
|
+
* Resolves a connector token from either a literal value or the name of an env
|
|
4
|
+
* var. A connector config carries one or the other per slot (see
|
|
5
|
+
* slack-connector-schema): literals are inlined into settings.json, references
|
|
6
|
+
* keep the secret in `process.env` and out of settings.json.
|
|
7
|
+
*
|
|
8
|
+
* Errors loudly when neither yields a value — a misconfigured connector should
|
|
9
|
+
* fail at listener start, not connect with an empty token and silently never
|
|
10
|
+
* receive events.
|
|
11
|
+
*/
|
|
12
|
+
const resolveConnectorToken = (props) => {
|
|
13
|
+
if (props.literal !== void 0 && props.literal !== "") return props.literal;
|
|
14
|
+
if (props.envVar !== void 0 && props.envVar !== "") {
|
|
15
|
+
const fromEnv = props.env[props.envVar];
|
|
16
|
+
if (fromEnv !== void 0 && fromEnv !== "") return fromEnv;
|
|
17
|
+
throw new Error(`${props.label} references env var "${props.envVar}" but it is not set in the environment`);
|
|
18
|
+
}
|
|
19
|
+
throw new Error(`${props.label} has neither a literal token nor an env var reference`);
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region lib/engine/connectors/slot-fields.ts
|
|
23
|
+
/**
|
|
24
|
+
* Resolves one token slot (e.g. botToken/botTokenEnv) for a connector update.
|
|
25
|
+
* The literal and the env-ref form are mutually exclusive: if `fields` supplies
|
|
26
|
+
* either, that form wins and the other key is omitted entirely; if it supplies
|
|
27
|
+
* neither, the connector's current slot is carried over unchanged. Returns a
|
|
28
|
+
* partial object spread into the rebuilt connector, so an omitted key is truly
|
|
29
|
+
* absent rather than set to undefined — switching a slot from literal to ref
|
|
30
|
+
* drops the stale literal instead of leaving both behind.
|
|
31
|
+
*/
|
|
32
|
+
const slotFields = (literalKey, envKey, fields, current) => {
|
|
33
|
+
const literal = fields[literalKey];
|
|
34
|
+
if (typeof literal === "string") return { [literalKey]: literal };
|
|
35
|
+
const envVar = fields[envKey];
|
|
36
|
+
if (typeof envVar === "string") return { [envKey]: envVar };
|
|
37
|
+
const result = {};
|
|
38
|
+
const currentLiteral = current[literalKey];
|
|
39
|
+
const currentEnv = current[envKey];
|
|
40
|
+
if (typeof currentLiteral === "string") result[literalKey] = currentLiteral;
|
|
41
|
+
if (typeof currentEnv === "string") result[envKey] = currentEnv;
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
export { resolveConnectorToken as n, slotFields as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
3
|
-
import {
|
|
1
|
+
import { t as NodeFunnelFileSystem } from "./node-file-system-Blr8pAir.js";
|
|
2
|
+
import { t as NodeFunnelProcessRunner } from "./node-process-runner-DxTvycoK.js";
|
|
3
|
+
import { n as FUNNEL_DIR, o as resolveFunnelPort, p as NodeFunnelIdGenerator } from "./settings-store-CUKSeTXC.js";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { stringify } from "yaml";
|
|
6
6
|
//#region lib/engine/claude/claude.ts
|
|
@@ -280,7 +280,7 @@ var FunnelMcp = class {
|
|
|
280
280
|
}
|
|
281
281
|
};
|
|
282
282
|
//#endregion
|
|
283
|
-
//#region lib/
|
|
283
|
+
//#region lib/engine/yaml/yaml-render.ts
|
|
284
284
|
/**
|
|
285
285
|
* Render any value as a valid YAML document for CLI output.
|
|
286
286
|
*
|
package/package.json
CHANGED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
//#region lib/engine/connectors/connector-adapter.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* A JSON-serializable value. Connector call bodies are sent to external APIs as
|
|
4
|
-
* JSON, so the body must be representable as JSON — `JsonValue` says exactly
|
|
5
|
-
* that, replacing a bare `unknown` that let non-serializable values (functions,
|
|
6
|
-
* symbols, class instances) slip through to `JSON.stringify`.
|
|
7
|
-
*/
|
|
8
|
-
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
9
|
-
[key: string]: JsonValue;
|
|
10
|
-
};
|
|
11
|
-
type CallInput = {
|
|
12
|
-
method: string;
|
|
13
|
-
path: string; /** JSON request body. Omit for GET-like calls. */
|
|
14
|
-
body?: JsonValue;
|
|
15
|
-
};
|
|
16
|
-
declare abstract class FunnelConnectorAdapter {
|
|
17
|
-
/**
|
|
18
|
-
* Dispatches one Claude → external call. The response is the external API's
|
|
19
|
-
* raw payload, typed `unknown` because its shape is the provider's concern —
|
|
20
|
-
* the caller (Claude, via MCP) interprets it.
|
|
21
|
-
*/
|
|
22
|
-
abstract call(input: CallInput): Promise<unknown>;
|
|
23
|
-
}
|
|
24
|
-
//#endregion
|
|
25
|
-
export { FunnelConnectorAdapter as n, JsonValue as r, CallInput as t };
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
//#region lib/engine/http/http-client.d.ts
|
|
4
|
-
type HttpRequest = {
|
|
5
|
-
method: string;
|
|
6
|
-
url: string;
|
|
7
|
-
headers?: Record<string, string>;
|
|
8
|
-
body?: string;
|
|
9
|
-
};
|
|
10
|
-
type HttpResponse = {
|
|
11
|
-
status: number;
|
|
12
|
-
ok: boolean;
|
|
13
|
-
text(): Promise<string>;
|
|
14
|
-
json(): Promise<unknown>;
|
|
15
|
-
};
|
|
16
|
-
declare abstract class FunnelHttpClient {
|
|
17
|
-
abstract fetch(request: HttpRequest): Promise<HttpResponse>;
|
|
18
|
-
}
|
|
19
|
-
//#endregion
|
|
20
|
-
//#region lib/engine/connectors/discord-connector-schema.d.ts
|
|
21
|
-
/**
|
|
22
|
-
* Like slack, a discord connector holds either a literal `botToken` or a
|
|
23
|
-
* `botTokenEnv` reference resolved from `process.env` at listener start. The
|
|
24
|
-
* reference form keeps the secret out of settings.json, but is only set through
|
|
25
|
-
* the engine API (`new Funnel(...)`); funnel.json and the `fnl` CLI produce
|
|
26
|
-
* literals.
|
|
27
|
-
*/
|
|
28
|
-
declare const discordConnectorSchema: z.ZodObject<{
|
|
29
|
-
id: z.ZodString;
|
|
30
|
-
name: z.ZodString;
|
|
31
|
-
type: z.ZodLiteral<"discord">;
|
|
32
|
-
botToken: z.ZodOptional<z.ZodString>;
|
|
33
|
-
botTokenEnv: z.ZodOptional<z.ZodString>;
|
|
34
|
-
createdAt: z.ZodOptional<z.ZodString>;
|
|
35
|
-
updatedAt: z.ZodOptional<z.ZodString>;
|
|
36
|
-
}, z.core.$strip>;
|
|
37
|
-
type DiscordConnectorConfig = z.infer<typeof discordConnectorSchema>;
|
|
38
|
-
//#endregion
|
|
39
|
-
export { HttpResponse as a, HttpRequest as i, discordConnectorSchema as n, FunnelHttpClient as r, DiscordConnectorConfig as t };
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
//#region lib/engine/connectors/gh-connector-schema.d.ts
|
|
4
|
-
declare const ghConnectorSchema: z.ZodObject<{
|
|
5
|
-
id: z.ZodString;
|
|
6
|
-
name: z.ZodString;
|
|
7
|
-
type: z.ZodLiteral<"gh">;
|
|
8
|
-
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
9
|
-
createdAt: z.ZodOptional<z.ZodString>;
|
|
10
|
-
updatedAt: z.ZodOptional<z.ZodString>;
|
|
11
|
-
}, z.core.$strip>;
|
|
12
|
-
type GhConnectorConfig = z.infer<typeof ghConnectorSchema>;
|
|
13
|
-
//#endregion
|
|
14
|
-
export { ghConnectorSchema as n, GhConnectorConfig as t };
|