@interactive-inc/claude-funnel 0.53.0 → 0.56.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 +3 -3
- package/dist/bin.js +1229 -486
- package/dist/claude.d.ts +22 -5
- package/dist/claude.js +455 -168
- package/dist/{connector-adapter-CePYBTgW.d.ts → connector-adapter-1PxjN-Uk.d.ts} +1 -1
- package/dist/{connector-adapter-D5Utumgz.js → connector-adapter-qwXLjQId.js} +1 -1
- package/dist/{connector-listener-DU54DN-f.js → connector-listener-CpHBecCj.js} +1 -1
- package/dist/connectors/discord.d.ts +6 -6
- package/dist/connectors/discord.js +2 -2
- package/dist/connectors/gh.d.ts +6 -6
- package/dist/connectors/gh.js +2 -2
- package/dist/connectors/schedule.d.ts +12 -2
- package/dist/connectors/schedule.js +2 -2
- package/dist/connectors/slack.d.ts +3 -3
- package/dist/connectors/slack.js +2 -2
- package/dist/{connector-diagnostic-log-yTOojKUR.d.ts → diagnostic-log-Bxe7Bbvw.d.ts} +2 -2
- package/dist/diagnostic-sql-reader-CzYgZpq2.js +83 -0
- package/dist/diagnostics.d.ts +2 -0
- package/dist/diagnostics.js +2 -0
- package/dist/{discord-connector-schema-CBDyGdOI.js → discord-connector-schema-B_N6IXLz.js} +1 -1
- package/dist/{discord-connector-schema-R0Uu-3ns.d.ts → discord-connector-schema-CPgcZkXh.d.ts} +1 -1
- package/dist/{discord-listener-_jSE3HsQ.js → discord-listener-C0MoKdQO.js} +6 -6
- package/dist/docs.d.ts +2 -0
- package/dist/docs.js +2 -0
- package/dist/doctor.d.ts +2 -0
- package/dist/doctor.js +2 -0
- package/dist/{file-process-guard-DMeLB6Zd.d.ts → file-process-guard-DI1742H5.d.ts} +5 -4
- package/dist/funnel-diagnostics-BpKYrMSu.js +300 -0
- package/dist/funnel-diagnostics-qWy5tPSq.d.ts +176 -0
- package/dist/funnel-docs-dXPokzr5.d.ts +18 -0
- package/dist/funnel-docs-ng5K8w4j.js +653 -0
- package/dist/funnel-doctor-BF3Rdgk0.d.ts +34 -0
- package/dist/funnel-doctor-CApCezTq.js +82 -0
- package/dist/funnel-recovery-BUBsu7WX.d.ts +101 -0
- package/dist/funnel-recovery-D9CxD5Zs.js +134 -0
- package/dist/gateway/daemon.js +838 -252
- package/dist/{gateway-base-url-ssk_He5G.js → gateway-base-url-6foMXfFf.js} +5 -5
- package/dist/gateway.d.ts +2 -2
- package/dist/gateway.js +2 -2
- package/dist/{gh-connector-schema-eoTtHbY6.d.ts → gh-connector-schema-CU1ojfIF.d.ts} +1 -1
- package/dist/{gh-connector-schema-o3Q1-ojL.js → gh-connector-schema-DUcZgN2Q.js} +1 -1
- package/dist/{gh-listener-DH-fClQm.js → gh-listener-Dsx6AmhH.js} +5 -5
- package/dist/{index-DF5VmCPJ.d.ts → index-CrngHrne.d.ts} +104 -607
- package/dist/index.d.ts +16 -11
- package/dist/index.js +509 -973
- package/dist/{local-config-json-schema-D8i-BogY.js → local-config-json-schema-DE1zkMcb.js} +12 -8
- package/dist/{local-config-sync-Cq39mT6p.d.ts → local-config-sync-B8b04LrZ.d.ts} +21 -16
- package/dist/local-config.d.ts +2 -2
- package/dist/local-config.js +2 -2
- package/dist/{memory-connector-diagnostic-log-COUWCsT_.js → memory-diagnostic-log-BbFVqDzz.js} +30 -95
- package/dist/{memory-token-prompter-CKV7VBM5.d.ts → memory-token-prompter-Lo3YRDzq.d.ts} +4 -4
- package/dist/{memory-token-prompter-Q7Snwsv2.js → memory-token-prompter-vBXxY20-.js} +2 -2
- package/dist/{profiles-f0mNmEyP.d.ts → profiles-EHTeCOqB.d.ts} +3 -2
- package/dist/profiles.d.ts +1 -1
- package/dist/profiles.js +1 -1
- package/dist/recovery.d.ts +2 -0
- package/dist/recovery.js +2 -0
- package/dist/{resolve-connector-token-BHmZLRrV.js → resolve-connector-token-CczqG_Ig.js} +1 -1
- package/dist/{schedule-connector-schema-iCI61gzU.js → schedule-connector-schema-B_xO5z5B.js} +1 -1
- package/dist/{schedule-listener-CUyUFFR1.d.ts → schedule-listener-DKh0hnkK.d.ts} +5 -5
- package/dist/{schedule-listener-ePAjians.js → schedule-listener-DP9Jhc6U.js} +14 -4
- package/dist/settings-reader-CBrgz01o.d.ts +18 -0
- package/dist/{settings-reader-BSU6JyvM.d.ts → settings-schema-zhnMIa8I.d.ts} +1 -16
- package/dist/{slack-connector-schema-BCNWluHM.js → slack-connector-schema-C1zEf4TG.js} +1 -1
- package/dist/{slack-listener-Bv5xI9gC.d.ts → slack-listener-COQA8wAZ.d.ts} +4 -4
- package/dist/{slack-listener-ClQuHhEF.js → slack-listener-DUKPcpJH.js} +7 -7
- package/dist/{mcp-QeNCBhOD.js → yaml-render-OhUN-qkS.js} +52 -34
- package/package.json +21 -1
- /package/dist/{file-system-BeOKXjlV.d.ts → file-system-Wub9Nto4.d.ts} +0 -0
- /package/dist/{process-runner-DfniuWVU.d.ts → process-runner-D5I_jhYQ.d.ts} +0 -0
- /package/dist/{profiles-wMRnjSid.js → profiles-MnXvYfZF.js} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { t as FunnelConnectorAdapter } from "./connector-adapter-
|
|
2
|
-
import { t as resolveConnectorToken } from "./resolve-connector-token-
|
|
3
|
-
import { t as FunnelConnectorListener } from "./connector-listener-
|
|
1
|
+
import { t as FunnelConnectorAdapter } from "./connector-adapter-qwXLjQId.js";
|
|
2
|
+
import { t as resolveConnectorToken } from "./resolve-connector-token-CczqG_Ig.js";
|
|
3
|
+
import { t as FunnelConnectorListener } from "./connector-listener-CpHBecCj.js";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { WebClient } from "@slack/web-api";
|
|
6
6
|
import { App, LogLevel } from "@slack/bolt";
|
|
7
|
-
//#region lib/connectors/slack-adapter.ts
|
|
7
|
+
//#region lib/engine/connectors/slack-adapter.ts
|
|
8
8
|
const toRecord = (value) => {
|
|
9
9
|
const result = {};
|
|
10
10
|
for (const [key, val] of Object.entries(value)) result[key] = val;
|
|
@@ -53,7 +53,7 @@ var FunnelSlackAdapter = class extends FunnelConnectorAdapter {
|
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
55
|
//#endregion
|
|
56
|
-
//#region lib/connectors/minify-slack-event.ts
|
|
56
|
+
//#region lib/engine/connectors/minify-slack-event.ts
|
|
57
57
|
const TOP_LEVEL_KEYS = [
|
|
58
58
|
"type",
|
|
59
59
|
"subtype",
|
|
@@ -137,7 +137,7 @@ const minifySlackEvent = (event) => {
|
|
|
137
137
|
return minified;
|
|
138
138
|
};
|
|
139
139
|
//#endregion
|
|
140
|
-
//#region lib/connectors/slack-event-processor.ts
|
|
140
|
+
//#region lib/engine/connectors/slack-event-processor.ts
|
|
141
141
|
const ALLOWED_EVENTS = new Set(["message", "app_mention"]);
|
|
142
142
|
const ALLOWED_SUBTYPES = new Set([
|
|
143
143
|
void 0,
|
|
@@ -212,7 +212,7 @@ var FunnelSlackEventProcessor = class {
|
|
|
212
212
|
}
|
|
213
213
|
};
|
|
214
214
|
//#endregion
|
|
215
|
-
//#region lib/connectors/slack-listener.ts
|
|
215
|
+
//#region lib/engine/connectors/slack-listener.ts
|
|
216
216
|
const middlewareArgsSchema = z.object({ event: z.record(z.string(), z.unknown()).optional() });
|
|
217
217
|
var FunnelSlackListener = class extends FunnelConnectorListener {
|
|
218
218
|
config;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { n as NodeFunnelProcessRunner } from "./gh-connector-schema-
|
|
1
|
+
import { n as NodeFunnelProcessRunner } from "./gh-connector-schema-DUcZgN2Q.js";
|
|
2
2
|
import { t as NodeFunnelFileSystem } from "./node-file-system-BcrmWN9I.js";
|
|
3
|
-
import { m as NodeFunnelIdGenerator, r as FUNNEL_DIR, s as resolveFunnelPort } from "./gateway-base-url-
|
|
3
|
+
import { m as NodeFunnelIdGenerator, r as FUNNEL_DIR, s as resolveFunnelPort } from "./gateway-base-url-6foMXfFf.js";
|
|
4
4
|
import { join } from "node:path";
|
|
5
|
-
import {
|
|
5
|
+
import { stringify } from "yaml";
|
|
6
6
|
//#region lib/engine/claude/claude.ts
|
|
7
7
|
const defaultProcess$1 = new NodeFunnelProcessRunner();
|
|
8
8
|
const defaultIdGenerator = new NodeFunnelIdGenerator();
|
|
@@ -167,16 +167,20 @@ var FileProcessGuard = class {
|
|
|
167
167
|
const FUNNEL_MCP_COMMAND = "bun";
|
|
168
168
|
const FUNNEL_MCP_ARGS = ["funnel", "mcp"];
|
|
169
169
|
const FUNNEL_MCP_NAME = "funnel";
|
|
170
|
-
const mcpEntrySchema = z.object({
|
|
171
|
-
command: z.string().optional(),
|
|
172
|
-
args: z.array(z.string()).optional()
|
|
173
|
-
});
|
|
174
|
-
const mcpConfigSchema = z.object({ mcpServers: z.record(z.string(), mcpEntrySchema).optional() });
|
|
175
170
|
const defaultFs = new NodeFunnelFileSystem();
|
|
171
|
+
const isRecord = (value) => {
|
|
172
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
173
|
+
};
|
|
176
174
|
/**
|
|
177
175
|
* Installs/uninstalls the funnel MCP entry into a target repository's
|
|
178
176
|
* `.mcp.json`. Detects an existing entry by command match so renaming is
|
|
179
177
|
* preserved across re-installs.
|
|
178
|
+
*
|
|
179
|
+
* The raw JSON object is mutated and written back untouched apart from the
|
|
180
|
+
* funnel entry — third-party server fields (`type`, `url`, `env`, `headers`, …)
|
|
181
|
+
* and unrelated top-level keys are preserved verbatim. Never round-trip the
|
|
182
|
+
* file through a narrowing schema: that silently strips every key it does not
|
|
183
|
+
* declare, corrupting other MCP servers.
|
|
180
184
|
*/
|
|
181
185
|
var FunnelMcp = class {
|
|
182
186
|
fs;
|
|
@@ -187,46 +191,40 @@ var FunnelMcp = class {
|
|
|
187
191
|
install(repoPath) {
|
|
188
192
|
if (!this.fs.existsSync(repoPath)) throw new Error(`repository does not exist: ${repoPath}`);
|
|
189
193
|
const config = this.readConfig(repoPath);
|
|
190
|
-
const
|
|
194
|
+
const existing = config.mcpServers;
|
|
195
|
+
const servers = isRecord(existing) ? existing : {};
|
|
191
196
|
const targetName = this.findServerName(servers) ?? "funnel";
|
|
192
197
|
servers[targetName] = {
|
|
193
198
|
command: "bun",
|
|
194
199
|
args: FUNNEL_MCP_ARGS
|
|
195
200
|
};
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
mcpServers: servers
|
|
199
|
-
});
|
|
201
|
+
config.mcpServers = servers;
|
|
202
|
+
this.writeConfig(repoPath, config);
|
|
200
203
|
}
|
|
201
204
|
uninstall(repoPath) {
|
|
202
205
|
if (!this.fs.existsSync(repoPath)) return;
|
|
203
206
|
const config = this.readConfig(repoPath);
|
|
204
|
-
const servers = config.mcpServers
|
|
207
|
+
const servers = config.mcpServers;
|
|
208
|
+
if (!isRecord(servers)) return;
|
|
205
209
|
const name = this.findServerName(servers);
|
|
206
210
|
if (!name) return;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
this.writeConfig(repoPath, {
|
|
210
|
-
...config,
|
|
211
|
-
mcpServers: next
|
|
212
|
-
});
|
|
211
|
+
delete servers[name];
|
|
212
|
+
this.writeConfig(repoPath, config);
|
|
213
213
|
}
|
|
214
214
|
findInstalledName(cwd) {
|
|
215
|
-
const
|
|
216
|
-
return this.findServerName(
|
|
215
|
+
const servers = this.readConfig(cwd).mcpServers;
|
|
216
|
+
return isRecord(servers) ? this.findServerName(servers) : null;
|
|
217
217
|
}
|
|
218
218
|
findServerName(servers) {
|
|
219
|
-
for (const entry of Object.entries(servers))
|
|
220
|
-
const name = entry[0];
|
|
221
|
-
const value = entry[1];
|
|
222
|
-
if (this.isFunnelEntry(value)) return name;
|
|
223
|
-
}
|
|
219
|
+
for (const entry of Object.entries(servers)) if (this.isFunnelEntry(entry[1])) return entry[0];
|
|
224
220
|
return null;
|
|
225
221
|
}
|
|
226
222
|
isFunnelEntry(value) {
|
|
227
|
-
if (!value) return false;
|
|
228
|
-
|
|
229
|
-
|
|
223
|
+
if (!isRecord(value)) return false;
|
|
224
|
+
const command = value.command;
|
|
225
|
+
const args = value.args;
|
|
226
|
+
if (command === "bun" && Array.isArray(args) && args[0] === "funnel") return true;
|
|
227
|
+
if (command === "funnel") return true;
|
|
230
228
|
return false;
|
|
231
229
|
}
|
|
232
230
|
readConfig(repoPath) {
|
|
@@ -240,9 +238,8 @@ var FunnelMcp = class {
|
|
|
240
238
|
} catch (error) {
|
|
241
239
|
throw new Error(`invalid .mcp.json (${mcpPath}): ${error instanceof Error ? error.message : String(error)}`);
|
|
242
240
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return result.data;
|
|
241
|
+
if (!isRecord(parsed)) throw new Error(`invalid .mcp.json (${mcpPath}): expected a JSON object`);
|
|
242
|
+
return parsed;
|
|
246
243
|
}
|
|
247
244
|
writeConfig(repoPath, config) {
|
|
248
245
|
const mcpPath = join(repoPath, ".mcp.json");
|
|
@@ -250,4 +247,25 @@ var FunnelMcp = class {
|
|
|
250
247
|
}
|
|
251
248
|
};
|
|
252
249
|
//#endregion
|
|
253
|
-
|
|
250
|
+
//#region lib/cli/yaml-render.ts
|
|
251
|
+
/**
|
|
252
|
+
* Render any value as a valid YAML document for CLI output.
|
|
253
|
+
*
|
|
254
|
+
* The CLI never emits JSON: text and YAML are the two surfaces, and YAML
|
|
255
|
+
* subsumes both since plain strings round-trip as themselves. This keeps
|
|
256
|
+
* Claude's job simple — every command's output is parseable the same way.
|
|
257
|
+
*
|
|
258
|
+
* Numbers, booleans, null, and primitive arrays stringify trivially. For
|
|
259
|
+
* objects we use blocks (indent + dash) rather than flow (`{...}`), since
|
|
260
|
+
* indentation is what Claude actually reads.
|
|
261
|
+
*/
|
|
262
|
+
const renderYaml = (value) => {
|
|
263
|
+
if (typeof value === "string") return value;
|
|
264
|
+
return stringify(value, {
|
|
265
|
+
indent: 2,
|
|
266
|
+
lineWidth: 0,
|
|
267
|
+
defaultStringType: "PLAIN"
|
|
268
|
+
});
|
|
269
|
+
};
|
|
270
|
+
//#endregion
|
|
271
|
+
export { FunnelMcp as a, FUNNEL_MCP_NAME as i, FUNNEL_MCP_ARGS as n, FileProcessGuard as o, FUNNEL_MCP_COMMAND as r, FunnelClaude as s, renderYaml as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interactive-inc/claude-funnel",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.56.0",
|
|
4
4
|
"description": "Hub CLI that routes external events (Slack / GitHub / Discord) to Claude Code agents through subscription channels over MCP.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -62,6 +62,26 @@
|
|
|
62
62
|
"import": "./dist/local-config.js",
|
|
63
63
|
"default": "./dist/local-config.js"
|
|
64
64
|
},
|
|
65
|
+
"./diagnostics": {
|
|
66
|
+
"types": "./dist/diagnostics.d.ts",
|
|
67
|
+
"import": "./dist/diagnostics.js",
|
|
68
|
+
"default": "./dist/diagnostics.js"
|
|
69
|
+
},
|
|
70
|
+
"./recovery": {
|
|
71
|
+
"types": "./dist/recovery.d.ts",
|
|
72
|
+
"import": "./dist/recovery.js",
|
|
73
|
+
"default": "./dist/recovery.js"
|
|
74
|
+
},
|
|
75
|
+
"./doctor": {
|
|
76
|
+
"types": "./dist/doctor.d.ts",
|
|
77
|
+
"import": "./dist/doctor.js",
|
|
78
|
+
"default": "./dist/doctor.js"
|
|
79
|
+
},
|
|
80
|
+
"./docs": {
|
|
81
|
+
"types": "./dist/docs.d.ts",
|
|
82
|
+
"import": "./dist/docs.js",
|
|
83
|
+
"default": "./dist/docs.js"
|
|
84
|
+
},
|
|
65
85
|
"./connectors/slack": {
|
|
66
86
|
"types": "./dist/connectors/slack.d.ts",
|
|
67
87
|
"import": "./dist/connectors/slack.js",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|