@interactive-inc/claude-funnel 0.59.0 → 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 +524 -449
- 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-B3IFCj_G.d.ts → file-process-guard-DOlCr4GF.d.ts} +5 -6
- 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 +282 -209
- 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-Dsx6AmhH.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 +383 -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-5LzwJ_F7.js → memory-diagnostic-log-CI60kNfB.js} +33 -18
- package/dist/{memory-token-prompter-BlFwK9k7.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-DUcZgN2Q.js → node-process-runner-DxTvycoK.js} +35 -13
- 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-6foMXfFf.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-C9Hhjk-0.js → yaml-render-qW34NlYz.js} +43 -10
- 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-Conbxl5O.d.ts +0 -3595
- package/dist/local-config-sync--f739oCJ.d.ts +0 -401
- package/dist/process-runner-Cx5O_fTf.d.ts +0 -49
- 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
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { t as discordConnectorSchema } from "./discord-connector-schema-B_N6IXLz.js";
|
|
2
|
+
import { t as ghConnectorSchema } from "./gh-connector-schema-Rzwc1c1N.js";
|
|
3
|
+
import { t as slackConnectorSchema } from "./slack-connector-schema-C1zEf4TG.js";
|
|
1
4
|
import { join } from "node:path";
|
|
2
5
|
import { z } from "zod";
|
|
3
6
|
import { stderr, stdin } from "node:process";
|
|
@@ -296,16 +299,17 @@ var FunnelLocalConfigSync = class {
|
|
|
296
299
|
const existing = this.channels.getConnector(channelName, spec.name);
|
|
297
300
|
if (existing && existing.type !== "gh") throw new Error(`connector "${spec.name}" exists in channel "${channelName}" with type "${existing.type}", funnel.json declares "gh"`);
|
|
298
301
|
if (existing && existing.type === "gh") {
|
|
299
|
-
|
|
302
|
+
const gh = ghConnectorSchema.parse(existing);
|
|
303
|
+
if (spec.pollInterval !== void 0 && gh.pollInterval !== spec.pollInterval) {
|
|
300
304
|
this.channels.updateGhConnector(channelName, spec.name, { pollInterval: spec.pollInterval });
|
|
301
305
|
return {
|
|
302
|
-
id:
|
|
306
|
+
id: gh.id,
|
|
303
307
|
name: spec.name,
|
|
304
308
|
changed: true
|
|
305
309
|
};
|
|
306
310
|
}
|
|
307
311
|
return {
|
|
308
|
-
id:
|
|
312
|
+
id: gh.id,
|
|
309
313
|
name: spec.name,
|
|
310
314
|
changed: false
|
|
311
315
|
};
|
|
@@ -341,13 +345,13 @@ var FunnelLocalConfigSync = class {
|
|
|
341
345
|
const existing = this.channels.getConnector(channelName, connectorName);
|
|
342
346
|
if (!existing) return null;
|
|
343
347
|
if (existing.type !== "slack") throw new Error(`connector "${connectorName}" exists in channel "${channelName}" with type "${existing.type}", funnel.json declares "slack"`);
|
|
344
|
-
return existing;
|
|
348
|
+
return slackConnectorSchema.parse(existing);
|
|
345
349
|
}
|
|
346
350
|
findExistingDiscord(channelName, connectorName) {
|
|
347
351
|
const existing = this.channels.getConnector(channelName, connectorName);
|
|
348
352
|
if (!existing) return null;
|
|
349
353
|
if (existing.type !== "discord") throw new Error(`connector "${connectorName}" exists in channel "${channelName}" with type "${existing.type}", funnel.json declares "discord"`);
|
|
350
|
-
return existing;
|
|
354
|
+
return discordConnectorSchema.parse(existing);
|
|
351
355
|
}
|
|
352
356
|
removeExtras(channelName, touched) {
|
|
353
357
|
const channel = this.channels.get(channelName);
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { n as FunnelFileSystem } from "./file-system-o51IsM0W.js";
|
|
2
|
+
import { r as FunnelChannels } from "./channels-2g_BU1N0.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region lib/services/local-config/local-config-schema.d.ts
|
|
6
|
+
declare const connectorSpecSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
7
|
+
type: z.ZodLiteral<"slack">;
|
|
8
|
+
name: z.ZodString;
|
|
9
|
+
minify: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
11
|
+
type: z.ZodLiteral<"discord">;
|
|
12
|
+
name: z.ZodString;
|
|
13
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
14
|
+
type: z.ZodLiteral<"gh">;
|
|
15
|
+
name: z.ZodString;
|
|
16
|
+
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
18
|
+
type: z.ZodLiteral<"schedule">;
|
|
19
|
+
name: z.ZodString;
|
|
20
|
+
}, z.core.$strip>], "type">;
|
|
21
|
+
type ConnectorSpec = z.infer<typeof connectorSpecSchema>;
|
|
22
|
+
declare const channelSpecSchema: z.ZodObject<{
|
|
23
|
+
name: z.ZodString;
|
|
24
|
+
connectors: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
25
|
+
type: z.ZodLiteral<"slack">;
|
|
26
|
+
name: z.ZodString;
|
|
27
|
+
minify: z.ZodOptional<z.ZodBoolean>;
|
|
28
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
29
|
+
type: z.ZodLiteral<"discord">;
|
|
30
|
+
name: z.ZodString;
|
|
31
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
32
|
+
type: z.ZodLiteral<"gh">;
|
|
33
|
+
name: z.ZodString;
|
|
34
|
+
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
36
|
+
type: z.ZodLiteral<"schedule">;
|
|
37
|
+
name: z.ZodString;
|
|
38
|
+
}, z.core.$strip>], "type">>>;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
type ChannelSpec = z.infer<typeof channelSpecSchema>;
|
|
41
|
+
declare const profileSpecSchema: z.ZodObject<{
|
|
42
|
+
name: z.ZodString;
|
|
43
|
+
channel: z.ZodString;
|
|
44
|
+
options: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
45
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
46
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
type ProfileSpec = z.infer<typeof profileSpecSchema>;
|
|
49
|
+
declare const localConfigSchema: z.ZodObject<{
|
|
50
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
51
|
+
id: z.ZodOptional<z.ZodString>;
|
|
52
|
+
channels: z.ZodArray<z.ZodObject<{
|
|
53
|
+
name: z.ZodString;
|
|
54
|
+
connectors: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
55
|
+
type: z.ZodLiteral<"slack">;
|
|
56
|
+
name: z.ZodString;
|
|
57
|
+
minify: z.ZodOptional<z.ZodBoolean>;
|
|
58
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
59
|
+
type: z.ZodLiteral<"discord">;
|
|
60
|
+
name: z.ZodString;
|
|
61
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
62
|
+
type: z.ZodLiteral<"gh">;
|
|
63
|
+
name: z.ZodString;
|
|
64
|
+
pollInterval: z.ZodOptional<z.ZodNumber>;
|
|
65
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
66
|
+
type: z.ZodLiteral<"schedule">;
|
|
67
|
+
name: z.ZodString;
|
|
68
|
+
}, z.core.$strip>], "type">>>;
|
|
69
|
+
}, z.core.$strip>>;
|
|
70
|
+
profiles: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
71
|
+
name: z.ZodString;
|
|
72
|
+
channel: z.ZodString;
|
|
73
|
+
options: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
74
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
75
|
+
resume: z.ZodOptional<z.ZodBoolean>;
|
|
76
|
+
}, z.core.$strip>>>;
|
|
77
|
+
}, z.core.$strip>;
|
|
78
|
+
type LocalConfig = z.infer<typeof localConfigSchema>;
|
|
79
|
+
declare const LOCAL_CONFIG_FILENAME = "funnel.json";
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region lib/services/local-config/local-config.d.ts
|
|
82
|
+
type Deps$1 = {
|
|
83
|
+
fs: FunnelFileSystem;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Reads `funnel.json` from a directory. Returns `null` when the file is
|
|
87
|
+
* absent so callers can fall through to other resolution paths (default
|
|
88
|
+
* profile, help). Throws on present-but-invalid files so misconfiguration
|
|
89
|
+
* surfaces loudly instead of silently launching the wrong channel.
|
|
90
|
+
*/
|
|
91
|
+
declare class FunnelLocalConfig {
|
|
92
|
+
private readonly fs;
|
|
93
|
+
constructor(deps: Deps$1);
|
|
94
|
+
read(cwd: string): LocalConfig | null;
|
|
95
|
+
private assertProfilesValid;
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region lib/engine/token-prompter/token-prompter.d.ts
|
|
99
|
+
/**
|
|
100
|
+
* Asks the user for a secret value on stdin. Used as a last resort when a
|
|
101
|
+
* funnel.json token field is absent and not present in `~/.funnel`. The Node
|
|
102
|
+
* implementation refuses to prompt when stdin is not a TTY so non-interactive
|
|
103
|
+
* launches (CI, agent spawning agent, daemons) fail fast instead of hanging.
|
|
104
|
+
*/
|
|
105
|
+
declare abstract class FunnelTokenPrompter {
|
|
106
|
+
abstract promptSecret(label: string): Promise<string>;
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region lib/services/local-config/local-config-sync.d.ts
|
|
110
|
+
type Deps = {
|
|
111
|
+
channels: FunnelChannels;
|
|
112
|
+
prompter: FunnelTokenPrompter;
|
|
113
|
+
};
|
|
114
|
+
type ConnectorSyncOutcome = {
|
|
115
|
+
name: string;
|
|
116
|
+
changed: boolean;
|
|
117
|
+
};
|
|
118
|
+
type LocalConfigSyncResult = {
|
|
119
|
+
touched: ConnectorSyncOutcome[];
|
|
120
|
+
removed: string[];
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Reconciles a single funnel.json channel spec with `~/.funnel/settings.json`.
|
|
124
|
+
* The spec is the source of truth for the channel it declares:
|
|
125
|
+
*
|
|
126
|
+
* - missing channel → created
|
|
127
|
+
* - declared connector matched by name → tokens reconciled
|
|
128
|
+
* - declared connector with no name match → added (prompting for its tokens)
|
|
129
|
+
* - any connector left in the channel that the spec did not touch → removed
|
|
130
|
+
*
|
|
131
|
+
* Connectors are matched by NAME only — there is no rename-by-token path. A spec
|
|
132
|
+
* that renames a connector (same token, new name) is reconciled as "add the new
|
|
133
|
+
* name, remove the old one". Because the collision check runs at add time while
|
|
134
|
+
* the old connector is still present, re-using its token at the new name throws
|
|
135
|
+
* a token-collision error; remove the old connector via the CLI first.
|
|
136
|
+
*
|
|
137
|
+
* Removal only fires when the channel spec has a `connectors` field. An
|
|
138
|
+
* absent field means "do not manage connectors from here" and leaves
|
|
139
|
+
* everything in `~/.funnel` alone. Other channels in funnel.json (not
|
|
140
|
+
* passed to this call) are untouched.
|
|
141
|
+
*
|
|
142
|
+
* Returns the per-connector change set so callers (e.g. the claude launcher)
|
|
143
|
+
* can drive listener hot-reload on the gateway after settings are written.
|
|
144
|
+
*/
|
|
145
|
+
declare class FunnelLocalConfigSync {
|
|
146
|
+
private readonly channels;
|
|
147
|
+
private readonly prompter;
|
|
148
|
+
constructor(deps: Deps);
|
|
149
|
+
ensure(channel: ChannelSpec): Promise<LocalConfigSyncResult>;
|
|
150
|
+
private ensureConnector;
|
|
151
|
+
private ensureSlack;
|
|
152
|
+
private ensureDiscord;
|
|
153
|
+
private ensureGh;
|
|
154
|
+
private ensureSchedule;
|
|
155
|
+
private findExistingSlack;
|
|
156
|
+
private findExistingDiscord;
|
|
157
|
+
private removeExtras;
|
|
158
|
+
/**
|
|
159
|
+
* Decides how a single token slot is stored in settings.json. funnel.json
|
|
160
|
+
* never carries tokens, so the only sources are a value already in
|
|
161
|
+
* settings.json (carried over verbatim, whichever form it was — literal or an
|
|
162
|
+
* `env`-var reference set via the CLI) or, on first sync, a TTY prompt for a
|
|
163
|
+
* literal (throws when stdin is not a TTY). Either way the secret lands in the
|
|
164
|
+
* repo-scoped settings, never in the repo itself.
|
|
165
|
+
*/
|
|
166
|
+
private resolveSlot;
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
export { FunnelLocalConfig as a, LOCAL_CONFIG_FILENAME as c, channelSpecSchema as d, connectorSpecSchema as f, FunnelTokenPrompter as i, LocalConfig as l, profileSpecSchema as m, FunnelLocalConfigSync as n, ChannelSpec as o, localConfigSchema as p, LocalConfigSyncResult as r, ConnectorSpec as s, ConnectorSyncOutcome as t, ProfileSpec as u };
|
package/dist/local-config.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as funnelJsonSchema, n as NodeFunnelTokenPrompter, r as FunnelLocalConfigWriter, t as MemoryFunnelTokenPrompter } from "./memory-token-prompter-
|
|
1
|
+
import { a as FunnelLocalConfig, c as LOCAL_CONFIG_FILENAME, d as channelSpecSchema, f as connectorSpecSchema, i as FunnelTokenPrompter, l as LocalConfig, m as profileSpecSchema, n as FunnelLocalConfigSync, o as ChannelSpec, p as localConfigSchema, r as LocalConfigSyncResult, s as ConnectorSpec, t as ConnectorSyncOutcome, u as ProfileSpec } from "./local-config-sync-Dh1Croqe.js";
|
|
2
|
+
import { i as funnelJsonSchema, n as NodeFunnelTokenPrompter, r as FunnelLocalConfigWriter, t as MemoryFunnelTokenPrompter } from "./memory-token-prompter-B4sjyaAq.js";
|
|
3
3
|
export { ChannelSpec, ConnectorSpec, ConnectorSyncOutcome, FunnelLocalConfig, FunnelLocalConfigSync, FunnelLocalConfigWriter, FunnelTokenPrompter, LOCAL_CONFIG_FILENAME, LocalConfig, LocalConfigSyncResult, MemoryFunnelTokenPrompter, NodeFunnelTokenPrompter, ProfileSpec, channelSpecSchema, connectorSpecSchema, funnelJsonSchema, localConfigSchema, profileSpecSchema };
|
package/dist/local-config.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as FunnelLocalConfig, c as connectorSpecSchema, i as FunnelTokenPrompter, l as localConfigSchema, n as NodeFunnelTokenPrompter, o as LOCAL_CONFIG_FILENAME, r as FunnelLocalConfigSync, s as channelSpecSchema, t as funnelJsonSchema, u as profileSpecSchema } from "./local-config-json-schema-
|
|
2
|
-
import { n as FunnelLocalConfigWriter, t as MemoryFunnelTokenPrompter } from "./memory-token-prompter-
|
|
1
|
+
import { a as FunnelLocalConfig, c as connectorSpecSchema, i as FunnelTokenPrompter, l as localConfigSchema, n as NodeFunnelTokenPrompter, o as LOCAL_CONFIG_FILENAME, r as FunnelLocalConfigSync, s as channelSpecSchema, t as funnelJsonSchema, u as profileSpecSchema } from "./local-config-json-schema-JyLqOQNX.js";
|
|
2
|
+
import { n as FunnelLocalConfigWriter, t as MemoryFunnelTokenPrompter } from "./memory-token-prompter-CZde7e6y.js";
|
|
3
3
|
export { FunnelLocalConfig, FunnelLocalConfigSync, FunnelLocalConfigWriter, FunnelTokenPrompter, LOCAL_CONFIG_FILENAME, MemoryFunnelTokenPrompter, NodeFunnelTokenPrompter, channelSpecSchema, connectorSpecSchema, funnelJsonSchema, localConfigSchema, profileSpecSchema };
|
package/dist/logger.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as FunnelLogSqliteSink } from "./funnel-log-sqlite-sink-
|
|
1
|
+
import { t as FunnelLogSqliteSink } from "./funnel-log-sqlite-sink-kqJbx2H7.js";
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
3
|
import { appendFileSync, existsSync, mkdirSync, renameSync, statSync, unlinkSync } from "node:fs";
|
|
4
4
|
//#region lib/logger/funnel-log.ts
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as NodeFunnelFileSystem } from "./node-file-system-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { t as
|
|
1
|
+
import { t as gatewayLoopbackUrl } from "./gateway-base-url-Dy4Ykuoh.js";
|
|
2
|
+
import { t as NodeFunnelFileSystem } from "./node-file-system-Blr8pAir.js";
|
|
3
|
+
import { t as NodeFunnelProcessRunner } from "./node-process-runner-DxTvycoK.js";
|
|
4
|
+
import { n as FUNNEL_DIR, o as resolveFunnelPort } from "./settings-store-CUKSeTXC.js";
|
|
5
|
+
import { t as ConnectorDiagnosticSqlReader } from "./diagnostic-sql-reader-C9zR-Csp.js";
|
|
6
|
+
import { t as FunnelLogSqliteSink } from "./funnel-log-sqlite-sink-kqJbx2H7.js";
|
|
6
7
|
import { dirname, join } from "node:path";
|
|
7
8
|
import { chmodSync, existsSync, mkdirSync } from "node:fs";
|
|
8
|
-
import { z } from "zod";
|
|
9
9
|
import { homedir, tmpdir } from "node:os";
|
|
10
|
+
import { z } from "zod";
|
|
10
11
|
import { timingSafeEqual } from "node:crypto";
|
|
11
12
|
import { createFactory } from "hono/factory";
|
|
12
13
|
import { HTTPException } from "hono/http-exception";
|
|
@@ -1163,8 +1164,8 @@ const defaultOnError = () => {};
|
|
|
1163
1164
|
*/
|
|
1164
1165
|
var FunnelGatewayServer = class {
|
|
1165
1166
|
channels;
|
|
1166
|
-
|
|
1167
|
-
|
|
1167
|
+
configuredPort;
|
|
1168
|
+
configuredHostname;
|
|
1168
1169
|
dbPath;
|
|
1169
1170
|
process;
|
|
1170
1171
|
logger;
|
|
@@ -1183,8 +1184,8 @@ var FunnelGatewayServer = class {
|
|
|
1183
1184
|
server = null;
|
|
1184
1185
|
constructor(deps) {
|
|
1185
1186
|
this.channels = deps.channels;
|
|
1186
|
-
this.
|
|
1187
|
-
this.
|
|
1187
|
+
this.configuredPort = deps.port ?? resolveFunnelPort();
|
|
1188
|
+
this.configuredHostname = deps.hostname ?? DEFAULT_HOST;
|
|
1188
1189
|
this.dbPath = deps.dbPath ?? defaultDbPath();
|
|
1189
1190
|
this.process = deps.process;
|
|
1190
1191
|
this.logger = deps.logger;
|
|
@@ -1229,15 +1230,26 @@ var FunnelGatewayServer = class {
|
|
|
1229
1230
|
now: this.nowMs
|
|
1230
1231
|
});
|
|
1231
1232
|
}
|
|
1233
|
+
/**
|
|
1234
|
+
* The resolved listen port: the live Bun server's port once started (so
|
|
1235
|
+
* `port: 0` auto-assignment is visible), the configured value before that.
|
|
1236
|
+
*/
|
|
1237
|
+
get port() {
|
|
1238
|
+
return this.server?.port ?? this.configuredPort;
|
|
1239
|
+
}
|
|
1240
|
+
/** The bind address: the live Bun server's hostname once started, the configured value before that. */
|
|
1241
|
+
get hostname() {
|
|
1242
|
+
return this.server?.hostname ?? this.configuredHostname;
|
|
1243
|
+
}
|
|
1232
1244
|
async start() {
|
|
1233
|
-
if (this.server) return
|
|
1234
|
-
if (!this.token && !LOOPBACK_HOSTS.has(this.
|
|
1245
|
+
if (this.server) return;
|
|
1246
|
+
if (!this.token && !LOOPBACK_HOSTS.has(this.configuredHostname) && !this.allowInsecureHost) throw new Error(`refusing to start gateway: hostname "${this.configuredHostname}" is reachable off-box but no token is set. Set a token, bind to loopback (127.0.0.1), or pass allowInsecureHost: true.`);
|
|
1235
1247
|
const app = this.buildApp();
|
|
1236
1248
|
await this.killCompetingSlackIfNeeded();
|
|
1237
1249
|
this.startedAt = this.nowMs();
|
|
1238
1250
|
this.server = Bun.serve({
|
|
1239
|
-
port: this.
|
|
1240
|
-
hostname: this.
|
|
1251
|
+
port: this.configuredPort,
|
|
1252
|
+
hostname: this.configuredHostname,
|
|
1241
1253
|
development: false,
|
|
1242
1254
|
fetch: (request, server) => this.handleFetch(request, server, app),
|
|
1243
1255
|
websocket: {
|
|
@@ -1248,7 +1260,6 @@ var FunnelGatewayServer = class {
|
|
|
1248
1260
|
});
|
|
1249
1261
|
this.logServerStarted();
|
|
1250
1262
|
await this.bootListeners();
|
|
1251
|
-
return this.server;
|
|
1252
1263
|
}
|
|
1253
1264
|
async stop() {
|
|
1254
1265
|
await this.supervisor.stopAll();
|
|
@@ -1424,6 +1435,10 @@ var FunnelGatewayServer = class {
|
|
|
1424
1435
|
* when they resolve. Used by both the connector-listener path (via the
|
|
1425
1436
|
* supervisor's `notify` callback) and the public `/channels/:channel/publish`
|
|
1426
1437
|
* route. Returns the assigned event offset.
|
|
1438
|
+
*
|
|
1439
|
+
* Public SDK surface for hosts running this gateway in-process — the no-HTTP
|
|
1440
|
+
* sibling of `funnel.publisher.publish()`, which targets a daemon instead
|
|
1441
|
+
* (see fnl docs programmable-api).
|
|
1427
1442
|
*/
|
|
1428
1443
|
emit(input) {
|
|
1429
1444
|
const channelId = this.lookupChannelId(input.channel);
|
|
@@ -1571,7 +1586,7 @@ var MemoryFunnelEventLog = class extends FunnelEventLog {
|
|
|
1571
1586
|
close() {}
|
|
1572
1587
|
};
|
|
1573
1588
|
//#endregion
|
|
1574
|
-
//#region lib/
|
|
1589
|
+
//#region lib/engine/diagnostic-log/diagnostic-log.ts
|
|
1575
1590
|
/**
|
|
1576
1591
|
* Points in the listener's connection lifecycle. The single source of truth
|
|
1577
1592
|
* for the value set: the `status` column schema, the `ConnectorConnectionStatus`
|
|
@@ -1662,7 +1677,7 @@ const connectorConnectionEventSchema = z.object({
|
|
|
1662
1677
|
*/
|
|
1663
1678
|
var ConnectorDiagnosticLog = class {};
|
|
1664
1679
|
//#endregion
|
|
1665
|
-
//#region lib/
|
|
1680
|
+
//#region lib/engine/diagnostic-log/sqlite-diagnostic-log.ts
|
|
1666
1681
|
/**
|
|
1667
1682
|
* Cap on a raw payload kept verbatim. The point of the raw table is to see
|
|
1668
1683
|
* what Slack/Discord actually sent, and a typical event is a few KB — so 256
|
|
@@ -1918,7 +1933,7 @@ const headFields = (payload) => {
|
|
|
1918
1933
|
}
|
|
1919
1934
|
};
|
|
1920
1935
|
//#endregion
|
|
1921
|
-
//#region lib/
|
|
1936
|
+
//#region lib/engine/diagnostic-log/memory-diagnostic-log.ts
|
|
1922
1937
|
/**
|
|
1923
1938
|
* In-process `ConnectorDiagnosticLog` backed by one array per table. Used by tests
|
|
1924
1939
|
* and embedders that do not need durability. Like the SQLite log it keeps
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as FunnelFileSystem } from "./file-system-
|
|
2
|
-
import { i as FunnelTokenPrompter } from "./local-config-sync
|
|
1
|
+
import { n as FunnelFileSystem } from "./file-system-o51IsM0W.js";
|
|
2
|
+
import { i as FunnelTokenPrompter } from "./local-config-sync-Dh1Croqe.js";
|
|
3
3
|
|
|
4
4
|
//#region lib/services/local-config/local-config-json-schema.d.ts
|
|
5
5
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as FunnelTokenPrompter, o as LOCAL_CONFIG_FILENAME } from "./local-config-json-schema-
|
|
1
|
+
import { i as FunnelTokenPrompter, o as LOCAL_CONFIG_FILENAME } from "./local-config-json-schema-JyLqOQNX.js";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
//#region lib/services/local-config/local-config-writer.ts
|
|
4
4
|
const isRecord = (value) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as FunnelFileSystem } from "./file-system-
|
|
1
|
+
import { t as FunnelFileSystem } from "./file-system-Wvzc2ePY.js";
|
|
2
2
|
import { appendFileSync, chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
3
|
//#region lib/engine/fs/node-file-system.ts
|
|
4
4
|
const SECRET_MODE = 384;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region lib/engine/http/http-client.ts
|
|
2
|
+
var FunnelHttpClient = class {};
|
|
3
|
+
//#endregion
|
|
4
|
+
//#region lib/engine/http/node-http-client.ts
|
|
5
|
+
var NodeFunnelHttpClient = class extends FunnelHttpClient {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
Object.freeze(this);
|
|
9
|
+
}
|
|
10
|
+
async fetch(request) {
|
|
11
|
+
const res = await globalThis.fetch(request.url, {
|
|
12
|
+
method: request.method,
|
|
13
|
+
headers: request.headers,
|
|
14
|
+
body: request.body
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
status: res.status,
|
|
18
|
+
ok: res.ok,
|
|
19
|
+
text: () => res.text(),
|
|
20
|
+
json: () => res.json()
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { FunnelHttpClient as n, NodeFunnelHttpClient as t };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { openSync } from "node:fs";
|
|
2
|
-
import { z } from "zod";
|
|
3
2
|
//#region lib/engine/process/process-runner.ts
|
|
4
3
|
/**
|
|
5
4
|
* Process boundary covering one-shot runs, sync runs, foreground attach, and
|
|
@@ -10,7 +9,9 @@ import { z } from "zod";
|
|
|
10
9
|
* callers do not branch on `process.platform`. `isAlive` checks whether a PID
|
|
11
10
|
* names a live (non-zombie) process; `listProcessesContaining` enumerates
|
|
12
11
|
* processes whose command line includes `marker`, used for funnel-gateway tag
|
|
13
|
-
* matching across daemons that share a home dir.
|
|
12
|
+
* matching across daemons that share a home dir. `getStartTime` returns a
|
|
13
|
+
* stable string identifying when a PID was started, used to detect PID reuse
|
|
14
|
+
* after the original process died abnormally (no exit hook fired).
|
|
14
15
|
*/
|
|
15
16
|
var FunnelProcessRunner = class {};
|
|
16
17
|
//#endregion
|
|
@@ -145,6 +146,11 @@ var NodeFunnelProcessRunner = class extends FunnelProcessRunner {
|
|
|
145
146
|
if (isWindows()) return this.listProcessesContainingWindows(marker);
|
|
146
147
|
return this.listProcessesContainingPosix(marker);
|
|
147
148
|
}
|
|
149
|
+
getStartTime(pid) {
|
|
150
|
+
if (!Number.isInteger(pid) || pid <= 0) return null;
|
|
151
|
+
if (isWindows()) return this.getStartTimeWindows(pid);
|
|
152
|
+
return this.getStartTimePosix(pid);
|
|
153
|
+
}
|
|
148
154
|
isAlivePosix(pid) {
|
|
149
155
|
const result = this.runSync([
|
|
150
156
|
"ps",
|
|
@@ -195,6 +201,32 @@ var NodeFunnelProcessRunner = class extends FunnelProcessRunner {
|
|
|
195
201
|
}
|
|
196
202
|
return snapshots;
|
|
197
203
|
}
|
|
204
|
+
getStartTimePosix(pid) {
|
|
205
|
+
const result = this.runSync([
|
|
206
|
+
"ps",
|
|
207
|
+
"-p",
|
|
208
|
+
String(pid),
|
|
209
|
+
"-o",
|
|
210
|
+
"lstart="
|
|
211
|
+
]);
|
|
212
|
+
if (result.exitCode !== 0) return null;
|
|
213
|
+
const value = result.stdout.trim();
|
|
214
|
+
if (!value) return null;
|
|
215
|
+
return value;
|
|
216
|
+
}
|
|
217
|
+
getStartTimeWindows(pid) {
|
|
218
|
+
const script = `Get-CimInstance Win32_Process -Filter "ProcessId=${pid}" | Select-Object -ExpandProperty CreationDate | ForEach-Object { $_.ToString("o") }`;
|
|
219
|
+
const result = this.runSync([
|
|
220
|
+
"powershell",
|
|
221
|
+
"-NoProfile",
|
|
222
|
+
"-Command",
|
|
223
|
+
script
|
|
224
|
+
]);
|
|
225
|
+
if (result.exitCode !== 0) return null;
|
|
226
|
+
const value = result.stdout.trim();
|
|
227
|
+
if (!value) return null;
|
|
228
|
+
return value;
|
|
229
|
+
}
|
|
198
230
|
listProcessesContainingWindows(marker) {
|
|
199
231
|
const result = this.runSync([
|
|
200
232
|
"powershell",
|
|
@@ -223,14 +255,4 @@ var NodeFunnelProcessRunner = class extends FunnelProcessRunner {
|
|
|
223
255
|
}
|
|
224
256
|
};
|
|
225
257
|
//#endregion
|
|
226
|
-
|
|
227
|
-
const ghConnectorSchema = z.object({
|
|
228
|
-
id: z.string(),
|
|
229
|
-
name: z.string(),
|
|
230
|
-
type: z.literal("gh"),
|
|
231
|
-
pollInterval: z.number().int().positive().optional(),
|
|
232
|
-
createdAt: z.string().datetime().optional(),
|
|
233
|
-
updatedAt: z.string().datetime().optional()
|
|
234
|
-
});
|
|
235
|
-
//#endregion
|
|
236
|
-
export { NodeFunnelProcessRunner as n, FunnelProcessRunner as r, ghConnectorSchema as t };
|
|
258
|
+
export { FunnelProcessRunner as n, NodeFunnelProcessRunner as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { r as ProfileConfig } from "./settings-schema-
|
|
2
|
-
import { n as FunnelIdGenerator, t as FunnelSettingsReader } from "./settings-reader-
|
|
3
|
-
import { n as FunnelFileSystem } from "./file-system-
|
|
1
|
+
import { r as ProfileConfig } from "./settings-schema-D1xcOqRu.js";
|
|
2
|
+
import { n as FunnelIdGenerator, t as FunnelSettingsReader } from "./settings-reader-BIFB_j2f.js";
|
|
3
|
+
import { n as FunnelFileSystem } from "./file-system-o51IsM0W.js";
|
|
4
4
|
|
|
5
5
|
//#region lib/engine/profiles/profiles.d.ts
|
|
6
6
|
type Deps = {
|
package/dist/profiles.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as FunnelProfiles } from "./profiles-
|
|
1
|
+
import { t as FunnelProfiles } from "./profiles-Cy5wXQ0L.js";
|
|
2
2
|
export { FunnelProfiles };
|
package/dist/profiles.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as FunnelProfiles } from "./profiles-
|
|
1
|
+
import { t as FunnelProfiles } from "./profiles-DSzTeKQw.js";
|
|
2
2
|
export { FunnelProfiles };
|
package/dist/recovery.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as RecoveryListenerControl, i as RecoveryGatewayControl, n as RecoveryAction, o as RecoveryResult, r as RecoveryChannelSource, t as FunnelRecovery } from "./funnel-recovery-
|
|
1
|
+
import { a as RecoveryListenerControl, i as RecoveryGatewayControl, n as RecoveryAction, o as RecoveryResult, r as RecoveryChannelSource, t as FunnelRecovery } from "./funnel-recovery-DnLrdWO9.js";
|
|
2
2
|
export { FunnelRecovery, RecoveryAction, RecoveryChannelSource, RecoveryGatewayControl, RecoveryListenerControl, RecoveryResult };
|
package/dist/recovery.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as FunnelRecovery } from "./funnel-recovery-
|
|
1
|
+
import { t as FunnelRecovery } from "./funnel-recovery-BFdPjL6Z.js";
|
|
2
2
|
export { FunnelRecovery };
|