@interactive-inc/claude-funnel 0.60.1 → 0.64.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 +2 -2
- package/dist/bin.js +428 -761
- package/dist/{channels-2g_BU1N0.d.ts → channels-CRGb6B5_.d.ts} +17 -16
- package/dist/claude.d.ts +5 -7
- package/dist/claude.js +143 -36
- package/dist/{connector-descriptor-6SXJoszo.d.ts → connector-descriptor-BFIhyTfa.d.ts} +49 -10
- package/dist/connector-diagnostics-recorder-COtNEmUp.js +42 -0
- package/dist/connectors/discord.d.ts +31 -37
- package/dist/connectors/discord.js +3 -3
- package/dist/connectors/gh.d.ts +37 -33
- package/dist/connectors/gh.js +3 -3
- package/dist/connectors/schedule.d.ts +9 -57
- package/dist/connectors/schedule.js +3 -3
- package/dist/connectors/slack.d.ts +106 -132
- package/dist/connectors/slack.js +4 -3
- package/dist/diagnostics.d.ts +1 -1
- package/dist/diagnostics.js +1 -1
- package/dist/discord-connector-DIFkYBbi.js +250 -0
- package/dist/discord-connector-schema-D-bOVAKt.d.ts +22 -0
- package/dist/docs.js +1 -1
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.js +1 -1
- package/dist/{file-process-guard-C_PLxfUX.d.ts → file-process-guard-tVcgckH6.d.ts} +6 -6
- package/dist/{file-system-o51IsM0W.d.ts → file-system-VhwwXZbm.d.ts} +8 -0
- package/dist/flume-source-listener-BNyAII7N.d.ts +133 -0
- package/dist/{funnel-diagnostics-CSiJmPlZ.js → funnel-diagnostics-Cvk6Sk4x.js} +193 -43
- package/dist/{funnel-diagnostics-DpXOsCty.d.ts → funnel-diagnostics-b9ar0Ing.d.ts} +67 -5
- package/dist/{funnel-docs-BxXZ9Ksx.js → funnel-docs-C-ge0MuB.js} +42 -6
- package/dist/{funnel-doctor-CZf_0Luq.d.ts → funnel-doctor-CnRQi4kM.d.ts} +2 -2
- package/dist/{funnel-doctor-DiJCjHsg.js → funnel-doctor-XrI2GBH8.js} +1 -1
- package/dist/funnel-error-0t1MK1R6.js +75 -0
- package/dist/{funnel-recovery-DnLrdWO9.d.ts → funnel-recovery-CMhY8Jfk.d.ts} +1 -1
- package/dist/gateway/daemon.js +167 -527
- package/dist/gateway.d.ts +3 -3
- package/dist/gateway.js +3 -3
- package/dist/gh-connector-BUGCOEWS.js +187 -0
- package/dist/{gh-connector-schema-Rzwc1c1N.js → gh-connector-schema-CAqIhzGr.js} +7 -0
- package/dist/gh-connector-schema-DWQaB6gX.d.ts +16 -0
- package/dist/{index-CgY8NdMz.d.ts → index-Ds6sHhA-.d.ts} +37 -19
- package/dist/index.d.ts +182 -22
- package/dist/index.js +363 -173
- package/dist/{local-config-json-schema-JyLqOQNX.js → local-config-json-schema-DexV8vX3.js} +24 -4
- package/dist/local-config.d.ts +39 -2
- package/dist/local-config.js +53 -2
- package/dist/logger.js +1 -1
- package/dist/loopback-fetch-CVNuN3YZ.js +40 -0
- package/dist/{local-config-sync-Dh1Croqe.d.ts → memory-token-prompter-BoV8Hf-n.d.ts} +30 -3
- package/dist/node-file-system-BOXIHW_Q.js +174 -0
- package/dist/{profiles-DSzTeKQw.js → profiles-ZHLONml4.js} +49 -49
- package/dist/{profiles-Cy5wXQ0L.d.ts → profiles-cVZQkM69.d.ts} +3 -3
- 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/resolve-connector-token-DxDG9mhf.js +22 -0
- package/dist/{schedule-connector-L4uzg5M8.js → schedule-connector-9k3gOIgl.js} +54 -55
- package/dist/schedule-connector-schema-Z0RXLgPI.d.ts +49 -0
- package/dist/settings-reader-BNxjsxCB.d.ts +27 -0
- package/dist/{settings-store-CUKSeTXC.js → settings-store-C2QdOH-t.js} +23 -4
- package/dist/slack-connector-CxpWagbT.js +388 -0
- package/dist/slack-event-processor-BhCf5Wiy.d.ts +95 -0
- package/dist/slack-event-processor-xFDG3US0.js +176 -0
- package/dist/slot-fields-D-pvMgTK.js +249 -0
- package/dist/{memory-diagnostic-log-CI60kNfB.js → sqlite-diagnostic-log-DOTPW-tG.js} +373 -249
- package/dist/{yaml-render-93pX7EF7.js → yaml-render--J1_3BSA.js} +25 -21
- package/package.json +2 -4
- package/dist/discord-connector-BL36yvbL.js +0 -250
- package/dist/gateway-base-url-Dy4Ykuoh.js +0 -14
- package/dist/gh-connector-DpiixfQZ.js +0 -226
- package/dist/http-client-oICicjuO.d.ts +0 -18
- package/dist/memory-token-prompter-B4sjyaAq.d.ts +0 -57
- package/dist/memory-token-prompter-CZde7e6y.js +0 -61
- package/dist/node-file-system-Blr8pAir.js +0 -48
- package/dist/settings-reader-BIFB_j2f.d.ts +0 -18
- package/dist/slack-connector-DQIFPdBF.js +0 -484
- package/dist/slot-fields-CMoRpwuy.js +0 -45
- /package/dist/{connector-adapter-DU9Rvyec.js → connector-adapter-Dvs8N7ew.js} +0 -0
- /package/dist/{connector-listener-DR3aKOuK.js → connector-listener-mPGZYa8e.js} +0 -0
- /package/dist/{diagnostic-sql-reader-C9zR-Csp.js → diagnostic-sql-reader-oXZnWFf_.js} +0 -0
- /package/dist/{discord-connector-schema-B_N6IXLz.js → discord-connector-schema-B4YpWpR3.js} +0 -0
- /package/dist/{error-message-of-Byi4y0Uf.js → error-message-of-ColuYmAk.js} +0 -0
- /package/dist/{funnel-log-sqlite-sink-kqJbx2H7.js → funnel-log-sqlite-sink-DLYkY0pZ.js} +0 -0
- /package/dist/{funnel-recovery-BFdPjL6Z.js → funnel-recovery-DKnEutUS.js} +0 -0
- /package/dist/{node-http-client-lowp60Oa.js → node-http-client-u00atiKx.js} +0 -0
- /package/dist/{schedule-connector-schema-CfyuMCMh.js → schedule-connector-schema-DKEPZnVv.js} +0 -0
- /package/dist/{settings-reader-CtQ-Ix8_.js → settings-reader-9FcX3qS1.js} +0 -0
- /package/dist/{settings-schema-D1xcOqRu.d.ts → settings-schema-BL_c2Udm.d.ts} +0 -0
- /package/dist/{slack-connector-schema-C1zEf4TG.js → slack-connector-schema-Dem8to4P.js} +0 -0
package/dist/gateway.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as
|
|
2
|
-
import { A as FunnelBroadcaster, C as funnelEventSchema, D as
|
|
3
|
-
export { BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, ChannelWsUrlInput, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDiagnosticLog, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelGatewayServer, FunnelGatewayToken,
|
|
1
|
+
import { A as connectorRawEventSchema, C as ConnectorRawQuery, D as StoredRawEvent, E as StoredProcessedEvent, O as connectorConnectionEventSchema, S as ConnectorRawEvent, T as StoredConnectionEvent, _ as ConnectorDiagnosticLog, b as ConnectorProcessedRecord, f as CONNECTOR_CONNECTION_STATUSES, g as ConnectorConnectionStatus, h as ConnectorConnectionRecord, k as connectorProcessedEventSchema, m as ConnectorConnectionQuery, p as ConnectorConnectionEvent, v as ConnectorProcessedEvent, w as ConnectorRawRecord, x as ConnectorQuery, y as ConnectorProcessedQuery } from "./connector-descriptor-BFIhyTfa.js";
|
|
2
|
+
import { A as FunnelBroadcaster, C as funnelEventSchema, D as FunnelListenerRegistry, E as GatewayRouteDeps, O as BroadcastEvent, S as FunnelEventRecord, T as GatewayEmitInput, _ as channelWsUrl, a as SqliteFunnelEventLog, b as FunnelEvent, c as PublishResponse, d as publishResponseSchema, f as DEFAULT_GATEWAY_TOKEN_PATH, g as channelWsProtocols, h as ChannelWsUrlInput, i as MemoryFunnelEventLog, j as ReplayableEvent, k as BroadcastSubscriber, l as PublishResult, m as gatewayLoopbackUrl, n as MemoryConnectorDiagnosticLog, o as FunnelChannelPublisher, p as FunnelGatewayToken, r as SqliteConnectorDiagnosticLog, s as PublishRequest, t as GatewayApp, u as publishRequestSchema, v as FunnelGatewayServer, w as Env, x as FunnelEventLog, y as GatewayEventStore } from "./index-Ds6sHhA-.js";
|
|
3
|
+
export { BroadcastEvent, BroadcastSubscriber, CONNECTOR_CONNECTION_STATUSES, ChannelWsUrlInput, ConnectorConnectionEvent, ConnectorConnectionQuery, ConnectorConnectionRecord, ConnectorConnectionStatus, ConnectorDiagnosticLog, ConnectorProcessedEvent, ConnectorProcessedQuery, ConnectorProcessedRecord, ConnectorQuery, ConnectorRawEvent, ConnectorRawQuery, ConnectorRawRecord, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEvent, FunnelEventLog, FunnelEventRecord, FunnelGatewayServer, FunnelGatewayToken, FunnelListenerRegistry, type GatewayApp, type GatewayEmitInput, GatewayEventStore, type GatewayRouteDeps, type Env as GatewayServerEnv, MemoryConnectorDiagnosticLog, MemoryFunnelEventLog, PublishRequest, PublishResponse, PublishResult, ReplayableEvent, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, StoredConnectionEvent, StoredProcessedEvent, StoredRawEvent, channelWsProtocols, channelWsUrl, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, funnelEventSchema, gatewayLoopbackUrl, publishRequestSchema, publishResponseSchema };
|
package/dist/gateway.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { S as
|
|
3
|
-
export { CONNECTOR_CONNECTION_STATUSES, ConnectorDiagnosticLog, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEventLog, FunnelGatewayServer, FunnelGatewayToken,
|
|
1
|
+
import { n as gatewayLoopbackUrl } from "./loopback-fetch-CVNuN3YZ.js";
|
|
2
|
+
import { S as connectorRawEventSchema, _ as MemoryConnectorDiagnosticLog, a as DEFAULT_GATEWAY_TOKEN_PATH, b as connectorConnectionEventSchema, c as FunnelListenerRegistry, d as funnelEventSchema, f as FunnelBroadcaster, g as publishResponseSchema, h as publishRequestSchema, i as channelWsUrl, l as SqliteFunnelEventLog, m as FunnelChannelPublisher, n as MemoryFunnelEventLog, o as FunnelGatewayToken, r as channelWsProtocols, s as FunnelGatewayServer, t as SqliteConnectorDiagnosticLog, u as FunnelEventLog, v as CONNECTOR_CONNECTION_STATUSES, x as connectorProcessedEventSchema, y as ConnectorDiagnosticLog } from "./sqlite-diagnostic-log-DOTPW-tG.js";
|
|
3
|
+
export { CONNECTOR_CONNECTION_STATUSES, ConnectorDiagnosticLog, DEFAULT_GATEWAY_TOKEN_PATH, FunnelBroadcaster, FunnelChannelPublisher, FunnelEventLog, FunnelGatewayServer, FunnelGatewayToken, FunnelListenerRegistry, MemoryConnectorDiagnosticLog, MemoryFunnelEventLog, SqliteConnectorDiagnosticLog, SqliteFunnelEventLog, channelWsProtocols, channelWsUrl, connectorConnectionEventSchema, connectorProcessedEventSchema, connectorRawEventSchema, funnelEventSchema, gatewayLoopbackUrl, publishRequestSchema, publishResponseSchema };
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { t as NodeFunnelProcessRunner } from "./node-process-runner-DxTvycoK.js";
|
|
2
|
+
import { t as errorMessageOf } from "./error-message-of-ColuYmAk.js";
|
|
3
|
+
import { t as ghConnectorSchema } from "./gh-connector-schema-CAqIhzGr.js";
|
|
4
|
+
import { t as FunnelConnectorAdapter } from "./connector-adapter-Dvs8N7ew.js";
|
|
5
|
+
import { i as resolveFlumeDeps, n as FunnelFlumeSourceListener, r as flumeLogHandler, t as slotFields } from "./slot-fields-D-pvMgTK.js";
|
|
6
|
+
import { FlumeGitHubSource } from "@interactive-inc/flume/github";
|
|
7
|
+
//#region lib/engine/connectors/gh-adapter.ts
|
|
8
|
+
const defaultProcess$1 = new NodeFunnelProcessRunner();
|
|
9
|
+
var FunnelGhAdapter = class extends FunnelConnectorAdapter {
|
|
10
|
+
process;
|
|
11
|
+
constructor(deps = {}) {
|
|
12
|
+
super();
|
|
13
|
+
this.process = deps.process ?? defaultProcess$1;
|
|
14
|
+
Object.freeze(this);
|
|
15
|
+
}
|
|
16
|
+
async call(input) {
|
|
17
|
+
const args = ["api", input.path];
|
|
18
|
+
if (input.method && input.method.toLowerCase() !== "get") args.push("-X", input.method.toUpperCase());
|
|
19
|
+
const hasBody = input.body && typeof input.body === "object" && Object.keys(input.body).length > 0;
|
|
20
|
+
if (hasBody) args.push("--input", "-");
|
|
21
|
+
const result = await this.process.run(["gh", ...args], { input: hasBody ? JSON.stringify(input.body) : void 0 });
|
|
22
|
+
if (result.exitCode !== 0) throw new Error(`gh api failed: ${result.stderr.trim() || result.stdout.trim()}`);
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(result.stdout);
|
|
25
|
+
} catch {
|
|
26
|
+
return result.stdout;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region lib/engine/connectors/gh-flume-listener.ts
|
|
32
|
+
const defaultProcess = new NodeFunnelProcessRunner();
|
|
33
|
+
/**
|
|
34
|
+
* GitHub listener backed by `@interactive-inc/flume`'s `FlumeGitHubSource`
|
|
35
|
+
* (raw REST polling of `/notifications` + Zod).
|
|
36
|
+
*
|
|
37
|
+
* Token resolution order mirrors the other connectors' literal-or-env-ref
|
|
38
|
+
* slot, with a `gh auth token` fallback as the convenience path:
|
|
39
|
+
*
|
|
40
|
+
* 1. `config.token` (literal)
|
|
41
|
+
* 2. `config.tokenEnv` (env var name → value)
|
|
42
|
+
* 3. `gh auth token` (reuses the `gh` CLI's authenticated session)
|
|
43
|
+
*
|
|
44
|
+
* The adapter still uses `gh api` for outbound calls, so when the fallback
|
|
45
|
+
* is in use the auth model is unchanged end-to-end.
|
|
46
|
+
*/
|
|
47
|
+
var FunnelFlumeGhListener = class extends FunnelFlumeSourceListener {
|
|
48
|
+
config;
|
|
49
|
+
env;
|
|
50
|
+
process;
|
|
51
|
+
flumeDeps;
|
|
52
|
+
signal;
|
|
53
|
+
constructor(deps) {
|
|
54
|
+
super({
|
|
55
|
+
type: "gh",
|
|
56
|
+
connectorId: deps.config.id,
|
|
57
|
+
channelId: deps.channelId ?? null,
|
|
58
|
+
logger: deps.logger,
|
|
59
|
+
diagnosticLog: deps.diagnosticLog
|
|
60
|
+
});
|
|
61
|
+
this.config = deps.config;
|
|
62
|
+
this.env = deps.env ?? process.env;
|
|
63
|
+
this.process = deps.process ?? defaultProcess;
|
|
64
|
+
this.flumeDeps = deps.flumeDeps ?? {};
|
|
65
|
+
this.signal = deps.signal;
|
|
66
|
+
}
|
|
67
|
+
async start(notify) {
|
|
68
|
+
this.diagnostics.recordConnection("started", "");
|
|
69
|
+
let token;
|
|
70
|
+
try {
|
|
71
|
+
token = await this.resolveToken();
|
|
72
|
+
} catch (error) {
|
|
73
|
+
this.diagnostics.recordConnection("auth-failed", errorMessageOf(error));
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
const source = new FlumeGitHubSource({
|
|
77
|
+
token,
|
|
78
|
+
pollInterval: this.config.pollInterval ?? 60
|
|
79
|
+
});
|
|
80
|
+
await this.runStart({
|
|
81
|
+
source,
|
|
82
|
+
onLog: flumeLogHandler(this.logger),
|
|
83
|
+
deps: resolveFlumeDeps(this.flumeDeps),
|
|
84
|
+
signal: this.signal,
|
|
85
|
+
onEvent: (event) => {
|
|
86
|
+
if (event.source !== "github") return Promise.resolve();
|
|
87
|
+
return this.handleEvent(event, notify);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async resolveToken() {
|
|
92
|
+
if (this.config.token) return this.config.token;
|
|
93
|
+
if (this.config.tokenEnv) {
|
|
94
|
+
const fromEnv = this.env[this.config.tokenEnv];
|
|
95
|
+
if (typeof fromEnv === "string" && fromEnv !== "") return fromEnv;
|
|
96
|
+
throw new Error(`${this.config.name}.token references env var "${this.config.tokenEnv}" but it is not set`);
|
|
97
|
+
}
|
|
98
|
+
const result = await this.process.run([
|
|
99
|
+
"gh",
|
|
100
|
+
"auth",
|
|
101
|
+
"token"
|
|
102
|
+
]);
|
|
103
|
+
if (result.exitCode !== 0) throw new Error(`gh auth token failed: ${result.stderr.trim() || result.stdout.trim()}`);
|
|
104
|
+
return result.stdout.trim();
|
|
105
|
+
}
|
|
106
|
+
async handleEvent(event, notify) {
|
|
107
|
+
const eventId = event.data.id;
|
|
108
|
+
const rawJson = JSON.stringify(event.data);
|
|
109
|
+
this.diagnostics.recordRaw(eventId, rawJson);
|
|
110
|
+
const meta = {
|
|
111
|
+
...event.meta,
|
|
112
|
+
event_type: "gh",
|
|
113
|
+
subject_url: event.data.subject.url ?? "",
|
|
114
|
+
updated_at: event.data.updated_at
|
|
115
|
+
};
|
|
116
|
+
await this.deliver(notify, eventId, rawJson, meta);
|
|
117
|
+
}
|
|
118
|
+
async deliver(notify, eventId, content, meta) {
|
|
119
|
+
try {
|
|
120
|
+
await notify(content, meta);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
this.diagnostics.recordProcessed(eventId, "emitted:delivery-failed", content);
|
|
123
|
+
this.logger?.error("gh notify error", { error: errorMessageOf(error) });
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
this.diagnostics.recordProcessed(eventId, "emitted", content);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region lib/engine/connectors/gh-connector.ts
|
|
131
|
+
/**
|
|
132
|
+
* GitHub connector descriptor. Pass `ghConnector()` to
|
|
133
|
+
* `new Funnel({ connectors: [...] })` to enable the type.
|
|
134
|
+
*
|
|
135
|
+
* The listener is backed by `@interactive-inc/flume`'s `FlumeGitHubSource`
|
|
136
|
+
* (raw REST polling + Zod), authenticating with a token resolved from the
|
|
137
|
+
* environment or `gh auth token`. The adapter still uses `gh api` for
|
|
138
|
+
* outbound calls, so the auth model is unchanged end-to-end.
|
|
139
|
+
*/
|
|
140
|
+
const ghConnector = () => ({
|
|
141
|
+
type: "gh",
|
|
142
|
+
toolExposed: true,
|
|
143
|
+
createListener(config, deps) {
|
|
144
|
+
return new FunnelFlumeGhListener({
|
|
145
|
+
config: ghConnectorSchema.parse(config),
|
|
146
|
+
channelId: deps.channelId,
|
|
147
|
+
process: deps.process,
|
|
148
|
+
logger: deps.logger,
|
|
149
|
+
diagnosticLog: deps.diagnosticLog,
|
|
150
|
+
signal: deps.signal
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
createAdapter(config, deps) {
|
|
154
|
+
ghConnectorSchema.parse(config);
|
|
155
|
+
return new FunnelGhAdapter({ process: deps.process });
|
|
156
|
+
},
|
|
157
|
+
secretTokens(config) {
|
|
158
|
+
return [ghConnectorSchema.parse(config).token].filter((token) => token !== void 0);
|
|
159
|
+
},
|
|
160
|
+
buildConfig(input, context) {
|
|
161
|
+
return ghConnectorSchema.parse({
|
|
162
|
+
id: context.id,
|
|
163
|
+
type: "gh",
|
|
164
|
+
name: input.name,
|
|
165
|
+
...typeof input.pollInterval === "number" ? { pollInterval: input.pollInterval } : {},
|
|
166
|
+
...typeof input.token === "string" ? { token: input.token } : {},
|
|
167
|
+
...typeof input.tokenEnv === "string" ? { tokenEnv: input.tokenEnv } : {},
|
|
168
|
+
createdAt: context.now,
|
|
169
|
+
updatedAt: context.now
|
|
170
|
+
});
|
|
171
|
+
},
|
|
172
|
+
applyUpdate(config, fields, context) {
|
|
173
|
+
const current = ghConnectorSchema.parse(config);
|
|
174
|
+
return ghConnectorSchema.parse({
|
|
175
|
+
id: current.id,
|
|
176
|
+
name: current.name,
|
|
177
|
+
type: "gh",
|
|
178
|
+
pollInterval: typeof fields.pollInterval === "number" ? fields.pollInterval : current.pollInterval,
|
|
179
|
+
createdAt: current.createdAt,
|
|
180
|
+
updatedAt: context.now,
|
|
181
|
+
...slotFields("token", "tokenEnv", fields, current)
|
|
182
|
+
});
|
|
183
|
+
},
|
|
184
|
+
operations: {}
|
|
185
|
+
});
|
|
186
|
+
//#endregion
|
|
187
|
+
export { FunnelFlumeGhListener as n, FunnelGhAdapter as r, ghConnector as t };
|
|
@@ -5,6 +5,13 @@ const ghConnectorSchema = z.object({
|
|
|
5
5
|
name: z.string(),
|
|
6
6
|
type: z.literal("gh"),
|
|
7
7
|
pollInterval: z.number().int().positive().optional(),
|
|
8
|
+
/**
|
|
9
|
+
* Explicit PAT/OAuth token. When neither this nor `tokenEnv` is set, the
|
|
10
|
+
* listener falls back to `gh auth token`, reusing the `gh` CLI's session.
|
|
11
|
+
*/
|
|
12
|
+
token: z.string().optional(),
|
|
13
|
+
/** Name of an env var to read the token from at start time. */
|
|
14
|
+
tokenEnv: z.string().optional(),
|
|
8
15
|
createdAt: z.string().datetime().optional(),
|
|
9
16
|
updatedAt: z.string().datetime().optional()
|
|
10
17
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
token: z.ZodOptional<z.ZodString>;
|
|
10
|
+
tokenEnv: z.ZodOptional<z.ZodString>;
|
|
11
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
12
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
type GhConnectorConfig = z.infer<typeof ghConnectorSchema>;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { ghConnectorSchema as n, GhConnectorConfig as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { B as
|
|
2
|
-
import { n as FunnelFileSystem } from "./file-system-
|
|
3
|
-
import {
|
|
1
|
+
import { B as FunnelProcessRunner, C as ConnectorRawQuery, D as StoredRawEvent, E as StoredProcessedEvent, I as BaseConnectorConfig, T as StoredConnectionEvent, W as FunnelLogger, _ as ConnectorDiagnosticLog, b as ConnectorProcessedRecord, c as FunnelClock, h as ConnectorConnectionRecord, j as FunnelConnectorListener, m as ConnectorConnectionQuery, w as ConnectorRawRecord, y as ConnectorProcessedQuery } from "./connector-descriptor-BFIhyTfa.js";
|
|
2
|
+
import { n as FunnelFileSystem } from "./file-system-VhwwXZbm.js";
|
|
3
|
+
import { n as ChannelConnectorView, r as FunnelChannels } from "./channels-CRGb6B5_.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { Hono } from "hono";
|
|
6
6
|
import { ServerWebSocket } from "bun";
|
|
@@ -142,7 +142,7 @@ declare class FunnelBroadcaster {
|
|
|
142
142
|
seedLatestOffset(offset: number): void;
|
|
143
143
|
}
|
|
144
144
|
//#endregion
|
|
145
|
-
//#region lib/gateway/listener-
|
|
145
|
+
//#region lib/gateway/listener-registry.d.ts
|
|
146
146
|
type ConnectorRegistry = {
|
|
147
147
|
listAllConnectors(): ChannelConnectorView[];
|
|
148
148
|
createListener(channelName: string, connectorName: string): {
|
|
@@ -151,10 +151,10 @@ type ConnectorRegistry = {
|
|
|
151
151
|
listener: FunnelConnectorListener;
|
|
152
152
|
} | null;
|
|
153
153
|
};
|
|
154
|
-
type
|
|
154
|
+
type ListenerRegistryNotify = (channelName: string, connectorName: string, content: string, meta?: Record<string, string>) => Promise<void>;
|
|
155
155
|
type Deps$3 = {
|
|
156
156
|
channels: ConnectorRegistry;
|
|
157
|
-
notify:
|
|
157
|
+
notify: ListenerRegistryNotify;
|
|
158
158
|
logger?: FunnelLogger; /** Host hook for surfacing listener lifecycle exceptions. Defaults to no-op. */
|
|
159
159
|
onError?: OnFunnelError;
|
|
160
160
|
healthCheckIntervalMs?: number;
|
|
@@ -189,13 +189,14 @@ type ListenerEntryStatus = {
|
|
|
189
189
|
* dead listeners with exponential backoff (1s, 2s, 4s, ... capped). Resets
|
|
190
190
|
* the backoff counter on successful restart.
|
|
191
191
|
*/
|
|
192
|
-
declare class
|
|
192
|
+
declare class FunnelListenerRegistry {
|
|
193
193
|
private readonly channels;
|
|
194
194
|
private readonly notify;
|
|
195
195
|
private readonly logger;
|
|
196
196
|
private readonly onError;
|
|
197
197
|
private readonly running;
|
|
198
198
|
private readonly failureCounts;
|
|
199
|
+
private readonly starting;
|
|
199
200
|
private readonly stats;
|
|
200
201
|
private readonly healthCheckIntervalMs;
|
|
201
202
|
private readonly maxBackoffMs;
|
|
@@ -213,14 +214,18 @@ declare class FunnelListenerSupervisor {
|
|
|
213
214
|
start(channelName: string, connectorName: string): Promise<{
|
|
214
215
|
ok: boolean;
|
|
215
216
|
reason?: string;
|
|
217
|
+
retriable?: boolean;
|
|
216
218
|
}>;
|
|
219
|
+
private startLocked;
|
|
217
220
|
stop(channelName: string, connectorName: string): Promise<{
|
|
218
221
|
ok: boolean;
|
|
219
222
|
reason?: string;
|
|
223
|
+
retriable?: boolean;
|
|
220
224
|
}>;
|
|
221
225
|
restart(channelName: string, connectorName: string): Promise<{
|
|
222
226
|
ok: boolean;
|
|
223
227
|
reason?: string;
|
|
228
|
+
retriable?: boolean;
|
|
224
229
|
}>;
|
|
225
230
|
startAll(): Promise<void>;
|
|
226
231
|
stopAll(): Promise<void>;
|
|
@@ -232,6 +237,7 @@ declare class FunnelListenerSupervisor {
|
|
|
232
237
|
/** Run one health-check pass synchronously. Test-only seam. */
|
|
233
238
|
runHealthCheckForTest(): Promise<void>;
|
|
234
239
|
private runHealthCheck;
|
|
240
|
+
private attemptRetry;
|
|
235
241
|
private recoverDead;
|
|
236
242
|
}
|
|
237
243
|
//#endregion
|
|
@@ -248,7 +254,7 @@ type GatewayRouteDeps = {
|
|
|
248
254
|
* daemon answering on a shared port belongs to the expected repo/scope. */
|
|
249
255
|
dir: string;
|
|
250
256
|
broadcaster: FunnelBroadcaster;
|
|
251
|
-
|
|
257
|
+
registry: FunnelListenerRegistry;
|
|
252
258
|
channels: FunnelChannels;
|
|
253
259
|
uptimeMs: () => number;
|
|
254
260
|
emit: (input: GatewayEmitInput) => {
|
|
@@ -357,7 +363,7 @@ type Deps$2 = GatewayEventStore & {
|
|
|
357
363
|
};
|
|
358
364
|
/**
|
|
359
365
|
* In-process gateway: runs `Bun.serve` (HTTP + WebSocket /ws), boots connector
|
|
360
|
-
* listeners through `
|
|
366
|
+
* listeners through `FunnelListenerRegistry`, fans events out via
|
|
361
367
|
* `FunnelBroadcaster`, and persists them via a `FunnelEventLog` (SQLite by default).
|
|
362
368
|
* System events (gateway lifecycle, connect/disconnect) flow to `FunnelLogger`
|
|
363
369
|
* instead — keeping the SQLite seq space exclusive to broadcaster traffic so
|
|
@@ -380,11 +386,13 @@ declare class FunnelGatewayServer {
|
|
|
380
386
|
private readonly allowInsecureHost;
|
|
381
387
|
private readonly broadcaster;
|
|
382
388
|
private readonly eventLog;
|
|
383
|
-
private readonly
|
|
389
|
+
private readonly registry;
|
|
384
390
|
private readonly nowMs;
|
|
385
391
|
private readonly extraRoutes;
|
|
392
|
+
private readonly ownsEventLog;
|
|
386
393
|
private startedAt;
|
|
387
394
|
private server;
|
|
395
|
+
private disposed;
|
|
388
396
|
constructor(deps: Deps$2);
|
|
389
397
|
/**
|
|
390
398
|
* The resolved listen port: the live Bun server's port once started (so
|
|
@@ -403,7 +411,7 @@ declare class FunnelGatewayServer {
|
|
|
403
411
|
}[];
|
|
404
412
|
};
|
|
405
413
|
getBroadcaster(): FunnelBroadcaster;
|
|
406
|
-
|
|
414
|
+
getRegistry(): FunnelListenerRegistry;
|
|
407
415
|
getEventLog(): FunnelEventLog;
|
|
408
416
|
/**
|
|
409
417
|
* Register an in-process observer for every broadcast event. Fires after
|
|
@@ -517,12 +525,12 @@ declare class FunnelGatewayToken {
|
|
|
517
525
|
constructor(deps?: Deps$1);
|
|
518
526
|
read(): string | null;
|
|
519
527
|
/**
|
|
520
|
-
* Returns the existing token or, if missing, generates one and writes it
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
528
|
+
* Returns the existing token or, if missing, generates one and writes it
|
|
529
|
+
* with mode 0600. Read+write runs inside an exclusive lock so two
|
|
530
|
+
* concurrent `ensure()` calls (a daemon spawn racing a CLI helper that
|
|
531
|
+
* reads the token before the gateway PID lock is acquired) cannot each
|
|
532
|
+
* persist a different token and leave one side authenticating against a
|
|
533
|
+
* value the other never sees.
|
|
526
534
|
*/
|
|
527
535
|
ensure(): string;
|
|
528
536
|
getPath(): string;
|
|
@@ -582,7 +590,13 @@ declare class FunnelChannelPublisher {
|
|
|
582
590
|
type Props$1 = {
|
|
583
591
|
/** SQLite database file path. Created on first write. ":memory:" for tests. */path: string; /** Override for tests. Defaults to `Date.now`. */
|
|
584
592
|
now?: () => number; /** Surfaces a failed persist (PK collision, disk-full, locked WAL). Silent if absent. */
|
|
585
|
-
logger?: FunnelLogger;
|
|
593
|
+
logger?: FunnelLogger;
|
|
594
|
+
/**
|
|
595
|
+
* Host-supplied error sink. Routed alongside the logger when a write
|
|
596
|
+
* fails, so Sentry / Datadog / a custom alert pipeline sees the durable
|
|
597
|
+
* replay loss too — not just the local log file. Silent if absent.
|
|
598
|
+
*/
|
|
599
|
+
onError?: OnFunnelError; /** Optional row cap. Pruned on every insert. */
|
|
586
600
|
maxRows?: number; /** Optional age cap in ms. Pruned on every insert. */
|
|
587
601
|
maxAgeMs?: number; /** Optional on-disk byte cap. Checked periodically; on overflow the oldest rows are dropped toward targetBytes and the file is VACUUMed. */
|
|
588
602
|
maxBytes?: number; /** Shrink target when maxBytes is exceeded. Defaults to maxBytes/4. */
|
|
@@ -609,6 +623,7 @@ declare class SqliteFunnelEventLog extends FunnelEventLog {
|
|
|
609
623
|
private readonly sink;
|
|
610
624
|
private readonly now;
|
|
611
625
|
private readonly logger;
|
|
626
|
+
private readonly onError;
|
|
612
627
|
constructor(props: Props$1);
|
|
613
628
|
/**
|
|
614
629
|
* Persist a broadcaster-driven event with its assigned offset. Caller
|
|
@@ -896,6 +911,7 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
896
911
|
output: {
|
|
897
912
|
ok: boolean;
|
|
898
913
|
reason?: string | undefined;
|
|
914
|
+
retriable?: boolean | undefined;
|
|
899
915
|
};
|
|
900
916
|
outputFormat: "json";
|
|
901
917
|
status: 200 | 400;
|
|
@@ -926,6 +942,7 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
926
942
|
output: {
|
|
927
943
|
ok: boolean;
|
|
928
944
|
reason?: string | undefined;
|
|
945
|
+
retriable?: boolean | undefined;
|
|
929
946
|
};
|
|
930
947
|
outputFormat: "json";
|
|
931
948
|
status: 200 | 400;
|
|
@@ -956,6 +973,7 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
956
973
|
output: {
|
|
957
974
|
ok: boolean;
|
|
958
975
|
reason?: string | undefined;
|
|
976
|
+
retriable?: boolean | undefined;
|
|
959
977
|
};
|
|
960
978
|
outputFormat: "json";
|
|
961
979
|
status: 200 | 400;
|
|
@@ -1054,4 +1072,4 @@ declare function buildGatewayRoutes(): _$hono_hono_base0.HonoBase<Env, {
|
|
|
1054
1072
|
};
|
|
1055
1073
|
}, "/", "/channels/:channel/publish">;
|
|
1056
1074
|
//#endregion
|
|
1057
|
-
export { FunnelBroadcaster as A, funnelEventSchema as C,
|
|
1075
|
+
export { FunnelBroadcaster as A, funnelEventSchema as C, FunnelListenerRegistry as D, GatewayRouteDeps as E, OnFunnelError as M, BroadcastEvent as O, FunnelEventRecord as S, GatewayEmitInput as T, channelWsUrl as _, SqliteFunnelEventLog as a, FunnelEvent as b, PublishResponse as c, publishResponseSchema as d, DEFAULT_GATEWAY_TOKEN_PATH as f, channelWsProtocols as g, ChannelWsUrlInput as h, MemoryFunnelEventLog as i, ReplayableEvent as j, BroadcastSubscriber as k, PublishResult as l, gatewayLoopbackUrl as m, MemoryConnectorDiagnosticLog as n, FunnelChannelPublisher as o, FunnelGatewayToken as p, SqliteConnectorDiagnosticLog as r, PublishRequest as s, GatewayApp as t, publishRequestSchema as u, FunnelGatewayServer as v, Env as w, FunnelEventLog as x, GatewayEventStore as y };
|