@interactive-inc/claude-funnel 0.25.2 → 0.26.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.
@@ -0,0 +1,27 @@
1
+ //#region lib/connectors/connector-listener.ts
2
+ /**
3
+ * Long-lived event source for one connector.
4
+ *
5
+ * `start()` opens the underlying connection (Slack Socket Mode, Discord
6
+ * Gateway, GH polling, schedule tick) and pushes events through `notify`.
7
+ * `stop()` releases the resources so the supervisor can recreate the listener
8
+ * with new config without restarting the whole gateway. `isAlive()` lets the
9
+ * supervisor periodically health-check and auto-restart dead listeners; the
10
+ * default optimistic implementation is fine for poll/tick-based listeners
11
+ * that self-heal.
12
+ */
13
+ var FunnelConnectorListener = class {
14
+ isAlive() {
15
+ return true;
16
+ }
17
+ };
18
+ //#endregion
19
+ //#region lib/engine/logger/logger.ts
20
+ /**
21
+ * Structured logger with three levels and an optional log-file path.
22
+ * Defaults to NodeFunnelLogger (appends to `<os.tmpdir()>/funnel/funnel.log`);
23
+ * MemoryFunnelLogger captures entries in memory and NoopFunnelLogger silences output.
24
+ */
25
+ var FunnelLogger = class {};
26
+ //#endregion
27
+ export { FunnelConnectorListener as n, FunnelLogger as t };
@@ -1,4 +1,4 @@
1
- import { i as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-B97ZiGwj.js";
1
+ import { n as FunnelConnectorListener } from "./logger-D1A3_JXV.js";
2
2
  import { dirname } from "node:path";
3
3
  import { appendFileSync, chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { z } from "zod";
@@ -153,7 +153,6 @@ var ScheduleStateStore = class {
153
153
  };
154
154
  //#endregion
155
155
  //#region lib/connectors/schedule-listener.ts
156
- const defaultLogger = new NodeFunnelLogger();
157
156
  const MAX_CATCHUP_MINUTES = 1440;
158
157
  var FunnelScheduleListener = class extends FunnelConnectorListener {
159
158
  config;
@@ -167,7 +166,7 @@ var FunnelScheduleListener = class extends FunnelConnectorListener {
167
166
  super();
168
167
  this.config = deps.config;
169
168
  this.lastFiredStore = deps.lastFiredStore;
170
- this.logger = deps.logger ?? defaultLogger;
169
+ this.logger = deps.logger;
171
170
  this.now = deps.now ?? (() => /* @__PURE__ */ new Date());
172
171
  this.onFired = deps.onFired ?? null;
173
172
  }
@@ -248,7 +247,7 @@ var FunnelScheduleListener = class extends FunnelConnectorListener {
248
247
  if (this.onFired) try {
249
248
  await this.onFired(entry, firedAt);
250
249
  } catch (error) {
251
- this.logger.error("schedule onFired callback failed", {
250
+ this.logger?.error("schedule onFired callback failed", {
252
251
  connector: this.config.name,
253
252
  id: entry.id,
254
253
  error: error instanceof Error ? error.message : String(error)
@@ -290,7 +289,7 @@ var FunnelScheduleListener = class extends FunnelConnectorListener {
290
289
  return matches;
291
290
  }
292
291
  logInvalidCron(entry, error) {
293
- this.logger.error("invalid cron expression in schedule", {
292
+ this.logger?.error("invalid cron expression in schedule", {
294
293
  connector: this.config.name,
295
294
  id: entry.id,
296
295
  cron: entry.cron,
@@ -1,5 +1,5 @@
1
1
  import { t as FunnelConnectorAdapter } from "./connector-adapter-D5Utumgz.js";
2
- import { i as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-B97ZiGwj.js";
2
+ import { n as FunnelConnectorListener } from "./logger-D1A3_JXV.js";
3
3
  import { z } from "zod";
4
4
  import { WebClient } from "@slack/web-api";
5
5
  import { App, LogLevel } from "@slack/bolt";
@@ -192,7 +192,6 @@ var FunnelSlackEventProcessor = class {
192
192
  //#endregion
193
193
  //#region lib/connectors/slack-listener.ts
194
194
  const middlewareArgsSchema = z.object({ event: z.record(z.string(), z.unknown()).optional() });
195
- const defaultLogger = new NodeFunnelLogger();
196
195
  var FunnelSlackListener = class extends FunnelConnectorListener {
197
196
  config;
198
197
  logger;
@@ -202,7 +201,7 @@ var FunnelSlackListener = class extends FunnelConnectorListener {
202
201
  constructor(deps) {
203
202
  super();
204
203
  this.config = deps.config;
205
- this.logger = deps.logger ?? defaultLogger;
204
+ this.logger = deps.logger;
206
205
  this.onAppCreated = deps.onAppCreated ?? null;
207
206
  this.preprocessEvent = deps.preprocessEvent ?? null;
208
207
  }
@@ -242,7 +241,7 @@ var FunnelSlackListener = class extends FunnelConnectorListener {
242
241
  } catch {}
243
242
  });
244
243
  app.error(async (error) => {
245
- this.logger.error("Slack error", { error: error instanceof Error ? error.message : String(error) });
244
+ this.logger?.error("Slack error", { error: error instanceof Error ? error.message : String(error) });
246
245
  });
247
246
  if (this.onAppCreated) await this.onAppCreated(app);
248
247
  await app.start();
@@ -253,7 +252,7 @@ var FunnelSlackListener = class extends FunnelConnectorListener {
253
252
  try {
254
253
  await this.app.stop();
255
254
  } catch (error) {
256
- this.logger.error("Slack stop error", { error: error instanceof Error ? error.message : String(error) });
255
+ this.logger?.error("Slack stop error", { error: error instanceof Error ? error.message : String(error) });
257
256
  } finally {
258
257
  this.app = null;
259
258
  }
@@ -139,9 +139,6 @@
139
139
  "items": {
140
140
  "type": "object",
141
141
  "properties": {
142
- "name": {
143
- "type": "string"
144
- },
145
142
  "channel": {
146
143
  "type": "string"
147
144
  },
@@ -165,7 +162,6 @@
165
162
  }
166
163
  },
167
164
  "required": [
168
- "name",
169
165
  "channel"
170
166
  ],
171
167
  "additionalProperties": false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interactive-inc/claude-funnel",
3
- "version": "0.25.2",
3
+ "version": "0.26.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",
@@ -85,8 +85,7 @@
85
85
  "@types/bun": "^1.3.14",
86
86
  "@types/react": "^19.2.14",
87
87
  "@typescript/native-preview": "^7.0.0-dev.20260516.1",
88
- "vite-plus": "^0.1.21",
89
- "vitest": "^4.1.6"
88
+ "vite-plus": "^0.1.21"
90
89
  },
91
90
  "engines": {
92
91
  "bun": ">=1.3.0"
@@ -1,74 +0,0 @@
1
- import { dirname, join } from "node:path";
2
- import { appendFileSync, mkdirSync } from "node:fs";
3
- import { tmpdir } from "node:os";
4
- //#region lib/connectors/connector-listener.ts
5
- /**
6
- * Long-lived event source for one connector.
7
- *
8
- * `start()` opens the underlying connection (Slack Socket Mode, Discord
9
- * Gateway, GH polling, schedule tick) and pushes events through `notify`.
10
- * `stop()` releases the resources so the supervisor can recreate the listener
11
- * with new config without restarting the whole gateway. `isAlive()` lets the
12
- * supervisor periodically health-check and auto-restart dead listeners; the
13
- * default optimistic implementation is fine for poll/tick-based listeners
14
- * that self-heal.
15
- */
16
- var FunnelConnectorListener = class {
17
- isAlive() {
18
- return true;
19
- }
20
- };
21
- //#endregion
22
- //#region lib/engine/logger/logger.ts
23
- /**
24
- * Structured logger with three levels and an optional log-file path.
25
- * Defaults to NodeFunnelLogger (appends to `<os.tmpdir()>/funnel/funnel.log`);
26
- * MemoryFunnelLogger captures entries in memory and NoopFunnelLogger silences output.
27
- */
28
- var FunnelLogger = class {};
29
- //#endregion
30
- //#region lib/engine/settings/tmp-dir.ts
31
- /**
32
- * Resolves the funnel temp/log root for the current OS. Defaults to
33
- * `<os.tmpdir()>/funnel` so Windows lands under `%TEMP%\funnel` and POSIX
34
- * lands under `/tmp/funnel`. Callers may override via `FUNNEL_TMP_DIR`.
35
- */
36
- function funnelTmpDir() {
37
- const override = process.env.FUNNEL_TMP_DIR;
38
- if (override && override.length > 0) return override;
39
- return join(tmpdir(), "funnel");
40
- }
41
- //#endregion
42
- //#region lib/engine/logger/node-logger.ts
43
- const defaultLogFile = () => join(funnelTmpDir(), "funnel.log");
44
- var NodeFunnelLogger = class extends FunnelLogger {
45
- file;
46
- now;
47
- constructor(props = {}) {
48
- super();
49
- this.file = props.file ?? defaultLogFile();
50
- this.now = props.now ?? (() => /* @__PURE__ */ new Date());
51
- Object.freeze(this);
52
- }
53
- info(message, meta) {
54
- this.write("info", message, meta);
55
- }
56
- warn(message, meta) {
57
- this.write("warn", message, meta);
58
- }
59
- error(message, meta) {
60
- this.write("error", message, meta);
61
- }
62
- write(level, message, meta) {
63
- mkdirSync(dirname(this.file), { recursive: true });
64
- const entry = {
65
- time: this.now().toISOString(),
66
- level,
67
- message,
68
- ...meta ? { meta } : {}
69
- };
70
- appendFileSync(this.file, `${JSON.stringify(entry)}\n`);
71
- }
72
- };
73
- //#endregion
74
- export { FunnelConnectorListener as i, funnelTmpDir as n, FunnelLogger as r, NodeFunnelLogger as t };