@interactive-inc/claude-funnel 0.21.1 → 0.22.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/dist/bin.js +436 -436
- package/dist/connectors/discord.d.ts +1 -1
- package/dist/connectors/discord.js +1 -1
- package/dist/connectors/gh.d.ts +2 -2
- package/dist/connectors/gh.js +1 -1
- package/dist/connectors/schedule.d.ts +1 -1
- package/dist/connectors/schedule.js +1 -1
- package/dist/connectors/slack.d.ts +1 -1
- package/dist/connectors/slack.js +1 -1
- package/dist/{discord-connector-schema-ygf5Df-2.js → discord-connector-schema-CR8RJ08_.js} +1 -1
- package/dist/gateway/daemon.js +194 -194
- package/dist/{gh-connector-schema-CD5HIkrd.js → gh-connector-schema-CAC24s0r.js} +148 -4
- package/dist/{gh-connector-schema-BNyTaASt.d.ts → gh-connector-schema-Cmi57jvL.d.ts} +16 -2
- package/dist/index.d.ts +25 -13
- package/dist/index.js +88 -85
- package/dist/{logger-CTlXs7z4.d.ts → logger-B3aXsVcX.d.ts} +1 -1
- package/dist/{node-logger-DQz_BGOD.js → node-logger-B97ZiGwj.js} +17 -4
- package/dist/{schedule-connector-schema-FxP7LPlx.js → schedule-connector-schema-BZpH6ZmR.js} +1 -1
- package/dist/{schedule-listener-BPodvbld.d.ts → schedule-listener-CBYF2bGZ.d.ts} +1 -1
- package/dist/{slack-connector-schema-BM9xshol.js → slack-connector-schema-B3jr-RTH.js} +1 -1
- package/dist/{slack-listener-CHj6uMY-.d.ts → slack-listener-tQH7cXU7.d.ts} +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { i as FunnelDiscordAdapter, n as FunnelDiscordListener, t as discordConnectorSchema } from "./discord-connector-schema-
|
|
2
|
-
import { n as
|
|
3
|
-
import { a as FunnelProcessRunner, i as NodeFunnelProcessRunner, n as FunnelGhListener, r as FunnelGhAdapter, t as ghConnectorSchema } from "./gh-connector-schema-
|
|
4
|
-
import { a as ScheduleStateStore, i as FunnelScheduleListener, n as scheduleConnectorSchema, o as NodeFunnelFileSystem, r as scheduleEntrySchema, s as FunnelFileSystem, t as scheduleCatchupPolicySchema } from "./schedule-connector-schema-
|
|
5
|
-
import { i as FunnelSlackAdapter, n as FunnelSlackListener, r as FunnelSlackEventProcessor, t as slackConnectorSchema } from "./slack-connector-schema-
|
|
1
|
+
import { i as FunnelDiscordAdapter, n as FunnelDiscordListener, t as discordConnectorSchema } from "./discord-connector-schema-CR8RJ08_.js";
|
|
2
|
+
import { i as FunnelConnectorListener, n as funnelTmpDir, r as FunnelLogger, t as NodeFunnelLogger } from "./node-logger-B97ZiGwj.js";
|
|
3
|
+
import { a as FunnelProcessRunner, i as NodeFunnelProcessRunner, n as FunnelGhListener, r as FunnelGhAdapter, t as ghConnectorSchema } from "./gh-connector-schema-CAC24s0r.js";
|
|
4
|
+
import { a as ScheduleStateStore, i as FunnelScheduleListener, n as scheduleConnectorSchema, o as NodeFunnelFileSystem, r as scheduleEntrySchema, s as FunnelFileSystem, t as scheduleCatchupPolicySchema } from "./schedule-connector-schema-BZpH6ZmR.js";
|
|
5
|
+
import { i as FunnelSlackAdapter, n as FunnelSlackListener, r as FunnelSlackEventProcessor, t as slackConnectorSchema } from "./slack-connector-schema-B3jr-RTH.js";
|
|
6
6
|
import { dirname, join, resolve } from "node:path";
|
|
7
7
|
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
8
|
-
import { z } from "zod";
|
|
9
8
|
import { homedir } from "node:os";
|
|
9
|
+
import { z } from "zod";
|
|
10
10
|
import { stderr, stdin } from "node:process";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
12
|
import { timingSafeEqual } from "node:crypto";
|
|
@@ -647,17 +647,7 @@ var FunnelClaude = class {
|
|
|
647
647
|
globalThis.process.once("exit", () => this.removePidFile(profileName));
|
|
648
648
|
}
|
|
649
649
|
isProcessAlive(pid) {
|
|
650
|
-
|
|
651
|
-
"ps",
|
|
652
|
-
"-p",
|
|
653
|
-
String(pid),
|
|
654
|
-
"-o",
|
|
655
|
-
"state="
|
|
656
|
-
]);
|
|
657
|
-
if (result.exitCode !== 0) return false;
|
|
658
|
-
const state = result.stdout.trim();
|
|
659
|
-
if (!state) return false;
|
|
660
|
-
return !state.startsWith("Z");
|
|
650
|
+
return this.process.isAlive(pid);
|
|
661
651
|
}
|
|
662
652
|
buildArgs(channelOptions, userArgs, cwd, sessionId) {
|
|
663
653
|
const result = [...channelOptions, ...userArgs];
|
|
@@ -1332,6 +1322,8 @@ var MemoryFunnelProcessRunner = class extends FunnelProcessRunner {
|
|
|
1332
1322
|
killed = [];
|
|
1333
1323
|
handler = () => empty;
|
|
1334
1324
|
syncHandler = () => empty;
|
|
1325
|
+
aliveStub = null;
|
|
1326
|
+
listStub = null;
|
|
1335
1327
|
on(handler) {
|
|
1336
1328
|
this.handler = handler;
|
|
1337
1329
|
return this;
|
|
@@ -1340,6 +1332,14 @@ var MemoryFunnelProcessRunner = class extends FunnelProcessRunner {
|
|
|
1340
1332
|
this.syncHandler = handler;
|
|
1341
1333
|
return this;
|
|
1342
1334
|
}
|
|
1335
|
+
onIsAlive(stub) {
|
|
1336
|
+
this.aliveStub = stub;
|
|
1337
|
+
return this;
|
|
1338
|
+
}
|
|
1339
|
+
onListProcessesContaining(stub) {
|
|
1340
|
+
this.listStub = stub;
|
|
1341
|
+
return this;
|
|
1342
|
+
}
|
|
1343
1343
|
async run(command, options = {}) {
|
|
1344
1344
|
this.calls.push({
|
|
1345
1345
|
kind: "run",
|
|
@@ -1391,6 +1391,24 @@ var MemoryFunnelProcessRunner = class extends FunnelProcessRunner {
|
|
|
1391
1391
|
signal
|
|
1392
1392
|
});
|
|
1393
1393
|
}
|
|
1394
|
+
isAlive(pid) {
|
|
1395
|
+
if (this.aliveStub) return this.aliveStub(pid);
|
|
1396
|
+
const result = this.syncHandler([
|
|
1397
|
+
"ps",
|
|
1398
|
+
"-p",
|
|
1399
|
+
String(pid),
|
|
1400
|
+
"-o",
|
|
1401
|
+
"state="
|
|
1402
|
+
]);
|
|
1403
|
+
if ((result.exitCode ?? 0) !== 0) return false;
|
|
1404
|
+
const state = (result.stdout ?? "").trim();
|
|
1405
|
+
if (!state) return false;
|
|
1406
|
+
return !state.startsWith("Z");
|
|
1407
|
+
}
|
|
1408
|
+
listProcessesContaining(marker) {
|
|
1409
|
+
if (this.listStub) return this.listStub(marker);
|
|
1410
|
+
return [];
|
|
1411
|
+
}
|
|
1394
1412
|
};
|
|
1395
1413
|
//#endregion
|
|
1396
1414
|
//#region lib/engine/profiles/profiles.ts
|
|
@@ -1749,7 +1767,6 @@ const resolveDaemonScript = () => {
|
|
|
1749
1767
|
//#endregion
|
|
1750
1768
|
//#region lib/gateway/gateway.ts
|
|
1751
1769
|
const DEFAULT_PORT$1 = 9742;
|
|
1752
|
-
const DEFAULT_TMP_DIR$1 = "/tmp/funnel";
|
|
1753
1770
|
const STARTUP_TIMEOUT_MS = 5e3;
|
|
1754
1771
|
const SIGTERM_TIMEOUT_MS = 2e3;
|
|
1755
1772
|
const POLL_INTERVAL_MS$1 = 100;
|
|
@@ -1771,7 +1788,6 @@ var FunnelGateway = class {
|
|
|
1771
1788
|
clock;
|
|
1772
1789
|
dir;
|
|
1773
1790
|
pidFile;
|
|
1774
|
-
logDir;
|
|
1775
1791
|
gatewayLog;
|
|
1776
1792
|
tmpDir;
|
|
1777
1793
|
port;
|
|
@@ -1781,9 +1797,8 @@ var FunnelGateway = class {
|
|
|
1781
1797
|
this.fs = deps.fs ?? defaultFs$1;
|
|
1782
1798
|
this.clock = deps.clock ?? defaultClock;
|
|
1783
1799
|
this.dir = deps.dir ?? FUNNEL_DIR;
|
|
1784
|
-
this.tmpDir = deps.tmpDir ??
|
|
1800
|
+
this.tmpDir = deps.tmpDir ?? funnelTmpDir();
|
|
1785
1801
|
this.pidFile = join(this.dir, "gateway.pid");
|
|
1786
|
-
this.logDir = join(this.tmpDir, "events");
|
|
1787
1802
|
this.gatewayLog = join(this.tmpDir, "gateway.log");
|
|
1788
1803
|
this.port = deps.port ?? DEFAULT_PORT$1;
|
|
1789
1804
|
this.sleep = deps.sleep ?? defaultSleep$1;
|
|
@@ -1808,11 +1823,10 @@ var FunnelGateway = class {
|
|
|
1808
1823
|
this.fs.mkdirSync(this.tmpDir, { recursive: true });
|
|
1809
1824
|
const gatewayScript = resolveDaemonScript();
|
|
1810
1825
|
const command = this.buildStartCommand(gatewayScript, options);
|
|
1811
|
-
this.process.detach(
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
]);
|
|
1826
|
+
this.process.detach(command, {
|
|
1827
|
+
stdoutFile: this.gatewayLog,
|
|
1828
|
+
stderrFile: this.gatewayLog
|
|
1829
|
+
});
|
|
1816
1830
|
const deadline = this.clock.millis() + STARTUP_TIMEOUT_MS;
|
|
1817
1831
|
while (this.clock.millis() < deadline) {
|
|
1818
1832
|
if (this.isRunning()) return true;
|
|
@@ -1821,7 +1835,19 @@ var FunnelGateway = class {
|
|
|
1821
1835
|
return this.isRunning();
|
|
1822
1836
|
}
|
|
1823
1837
|
buildStartCommand(gatewayScript, options = {}) {
|
|
1824
|
-
|
|
1838
|
+
const tag = `funnel-gateway[${this.dir}]`;
|
|
1839
|
+
if (options.caffeinate !== false && globalThis.process.platform === "darwin") return [
|
|
1840
|
+
"caffeinate",
|
|
1841
|
+
"-is",
|
|
1842
|
+
"bun",
|
|
1843
|
+
gatewayScript,
|
|
1844
|
+
tag
|
|
1845
|
+
];
|
|
1846
|
+
return [
|
|
1847
|
+
"bun",
|
|
1848
|
+
gatewayScript,
|
|
1849
|
+
tag
|
|
1850
|
+
];
|
|
1825
1851
|
}
|
|
1826
1852
|
async stop() {
|
|
1827
1853
|
const pid = this.readPid();
|
|
@@ -1873,9 +1899,6 @@ var FunnelGateway = class {
|
|
|
1873
1899
|
started
|
|
1874
1900
|
};
|
|
1875
1901
|
}
|
|
1876
|
-
getLogDir() {
|
|
1877
|
-
return this.logDir;
|
|
1878
|
-
}
|
|
1879
1902
|
getGatewayLog() {
|
|
1880
1903
|
return this.gatewayLog;
|
|
1881
1904
|
}
|
|
@@ -1897,17 +1920,7 @@ var FunnelGateway = class {
|
|
|
1897
1920
|
this.fs.unlink(this.pidFile);
|
|
1898
1921
|
}
|
|
1899
1922
|
isProcessAlive(pid) {
|
|
1900
|
-
|
|
1901
|
-
"ps",
|
|
1902
|
-
"-p",
|
|
1903
|
-
String(pid),
|
|
1904
|
-
"-o",
|
|
1905
|
-
"state="
|
|
1906
|
-
]);
|
|
1907
|
-
if (result.exitCode !== 0) return false;
|
|
1908
|
-
const state = result.stdout.trim();
|
|
1909
|
-
if (!state) return false;
|
|
1910
|
-
return !state.startsWith("Z");
|
|
1923
|
+
return this.process.isAlive(pid);
|
|
1911
1924
|
}
|
|
1912
1925
|
};
|
|
1913
1926
|
//#endregion
|
|
@@ -2728,36 +2741,24 @@ const titleFor = (dir) => `funnel-gateway[${dir}]`;
|
|
|
2728
2741
|
* which is the only situation that causes a real conflict (duplicate Slack
|
|
2729
2742
|
* Socket Mode connections with the same tokens). Daemons rooted at a
|
|
2730
2743
|
* different `~/.funnel/` are left alone — they hold different tokens and
|
|
2731
|
-
* speak to different Slack apps. The daemon advertises its dir via
|
|
2732
|
-
* `
|
|
2744
|
+
* speak to different Slack apps. The daemon advertises its dir via the
|
|
2745
|
+
* `funnel-gateway[<dir>]` marker appended to argv (also assigned to
|
|
2746
|
+
* `process.title` on POSIX). `FunnelProcessRunner.listProcessesContaining`
|
|
2747
|
+
* absorbs the POSIX/Windows enumeration difference behind the marker match.
|
|
2733
2748
|
*/
|
|
2734
2749
|
const killCompetingSlackGateways = async (props) => {
|
|
2735
2750
|
const runner = props.process ?? defaultProcess;
|
|
2736
2751
|
const logger = props.logger ?? defaultLogger$1;
|
|
2737
|
-
const result = await runner.run([
|
|
2738
|
-
"ps",
|
|
2739
|
-
"-e",
|
|
2740
|
-
"-o",
|
|
2741
|
-
"pid=,args="
|
|
2742
|
-
]);
|
|
2743
|
-
if (result.exitCode !== 0) return [];
|
|
2744
2752
|
const expectedTitle = titleFor(props.dir);
|
|
2753
|
+
const snapshots = runner.listProcessesContaining(expectedTitle);
|
|
2745
2754
|
const killed = [];
|
|
2746
|
-
for (const
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
if (!match) continue;
|
|
2751
|
-
const pid = Number(match[1]);
|
|
2752
|
-
const args = match[2];
|
|
2753
|
-
if (!Number.isInteger(pid) || pid <= 0) continue;
|
|
2754
|
-
if (pid === props.selfPid) continue;
|
|
2755
|
-
if (!args.includes(expectedTitle)) continue;
|
|
2756
|
-
runner.kill(pid, "SIGTERM");
|
|
2757
|
-
killed.push(pid);
|
|
2755
|
+
for (const snapshot of snapshots) {
|
|
2756
|
+
if (snapshot.pid === props.selfPid) continue;
|
|
2757
|
+
runner.kill(snapshot.pid, "SIGTERM");
|
|
2758
|
+
killed.push(snapshot.pid);
|
|
2758
2759
|
logger.info("killed competing Slack gateway process", {
|
|
2759
|
-
pid,
|
|
2760
|
-
args:
|
|
2760
|
+
pid: snapshot.pid,
|
|
2761
|
+
args: snapshot.command.slice(0, 160)
|
|
2761
2762
|
});
|
|
2762
2763
|
}
|
|
2763
2764
|
return killed;
|
|
@@ -2923,8 +2924,7 @@ const gatewayRoutes = factory$1.createApp().get("/health", ...healthHandler).get
|
|
|
2923
2924
|
//#endregion
|
|
2924
2925
|
//#region lib/gateway/gateway-server.ts
|
|
2925
2926
|
const DEFAULT_PORT = 9742;
|
|
2926
|
-
const
|
|
2927
|
-
const DB_FILENAME = "events.db";
|
|
2927
|
+
const defaultDbPath = () => join(funnelTmpDir(), "events.db");
|
|
2928
2928
|
const defaultLogger = new NodeFunnelLogger();
|
|
2929
2929
|
/**
|
|
2930
2930
|
* In-process gateway: runs `Bun.serve` (HTTP + WebSocket /ws), boots connector
|
|
@@ -2940,7 +2940,7 @@ var FunnelGatewayServer = class {
|
|
|
2940
2940
|
channels;
|
|
2941
2941
|
settings;
|
|
2942
2942
|
port;
|
|
2943
|
-
|
|
2943
|
+
dbPath;
|
|
2944
2944
|
process;
|
|
2945
2945
|
logger;
|
|
2946
2946
|
selfPid;
|
|
@@ -2958,7 +2958,7 @@ var FunnelGatewayServer = class {
|
|
|
2958
2958
|
this.channels = deps.channels;
|
|
2959
2959
|
this.settings = deps.settings;
|
|
2960
2960
|
this.port = deps.port ?? DEFAULT_PORT;
|
|
2961
|
-
this.
|
|
2961
|
+
this.dbPath = deps.dbPath ?? defaultDbPath();
|
|
2962
2962
|
this.process = deps.process;
|
|
2963
2963
|
this.logger = deps.logger ?? defaultLogger;
|
|
2964
2964
|
this.selfPid = deps.selfPid ?? globalThis.process.pid;
|
|
@@ -2968,9 +2968,10 @@ var FunnelGatewayServer = class {
|
|
|
2968
2968
|
this.extraRoutes = deps.extraRoutes ?? null;
|
|
2969
2969
|
const clock = deps.clock;
|
|
2970
2970
|
this.nowMs = clock ? () => clock.millis() : () => Date.now();
|
|
2971
|
-
|
|
2971
|
+
const dbDir = dirname(this.dbPath);
|
|
2972
|
+
if (!existsSync(dbDir)) mkdirSync(dbDir, { recursive: true });
|
|
2972
2973
|
this.eventStore = new FunnelEventStore({
|
|
2973
|
-
path:
|
|
2974
|
+
path: this.dbPath,
|
|
2974
2975
|
now: this.nowMs
|
|
2975
2976
|
});
|
|
2976
2977
|
this.broadcaster = new FunnelBroadcaster({
|
|
@@ -3174,7 +3175,7 @@ var FunnelGatewayServer = class {
|
|
|
3174
3175
|
channel: entry.channelName,
|
|
3175
3176
|
connector: entry.name
|
|
3176
3177
|
});
|
|
3177
|
-
this.logger.info(`event store: ${
|
|
3178
|
+
this.logger.info(`event store: ${this.dbPath}`);
|
|
3178
3179
|
this.logger.info("funnel gateway running");
|
|
3179
3180
|
}
|
|
3180
3181
|
/**
|
|
@@ -3361,7 +3362,6 @@ var FunnelListenersClient = class {
|
|
|
3361
3362
|
};
|
|
3362
3363
|
//#endregion
|
|
3363
3364
|
//#region lib/funnel.ts
|
|
3364
|
-
const DEFAULT_TMP_DIR = "/tmp/funnel";
|
|
3365
3365
|
const SANDBOX_DIR = "/sandbox/.funnel";
|
|
3366
3366
|
const SANDBOX_TMP_DIR = "/sandbox/tmp";
|
|
3367
3367
|
/**
|
|
@@ -3411,7 +3411,7 @@ var Funnel = class Funnel {
|
|
|
3411
3411
|
const dir = this.props.dir ?? FUNNEL_DIR;
|
|
3412
3412
|
return {
|
|
3413
3413
|
dir,
|
|
3414
|
-
tmpDir: this.props.tmpDir ??
|
|
3414
|
+
tmpDir: this.props.tmpDir ?? funnelTmpDir(),
|
|
3415
3415
|
settings: join(dir, "settings.json")
|
|
3416
3416
|
};
|
|
3417
3417
|
}
|
|
@@ -3591,7 +3591,7 @@ var Funnel = class Funnel {
|
|
|
3591
3591
|
channels: this.channels,
|
|
3592
3592
|
settings: this.store,
|
|
3593
3593
|
port: options.port,
|
|
3594
|
-
|
|
3594
|
+
dbPath: options.dbPath,
|
|
3595
3595
|
process: this.process,
|
|
3596
3596
|
clock: this.clock,
|
|
3597
3597
|
logger: this.logger,
|
|
@@ -4445,13 +4445,13 @@ usage: funnel gateway logs [-n <N>]
|
|
|
4445
4445
|
options:
|
|
4446
4446
|
-n <N> number of trailing lines to show (default: 20)
|
|
4447
4447
|
|
|
4448
|
-
Tails
|
|
4448
|
+
Tails ${join(funnelTmpDir(), "funnel.log")} (the daemon's diagnostic stream — gateway
|
|
4449
4449
|
lifecycle, channel connect/disconnect, listener boot). Exit with SIGINT.
|
|
4450
4450
|
Output is formatted as YAML.
|
|
4451
4451
|
|
|
4452
4452
|
Domain events fanned out to WebSocket clients live in the SQLite event
|
|
4453
|
-
store (
|
|
4454
|
-
WS endpoint or query the store directly.
|
|
4453
|
+
store (${join(funnelTmpDir(), "events.db")}); they are not shown here. Subscribe via
|
|
4454
|
+
the WS endpoint or query the store directly.
|
|
4455
4455
|
|
|
4456
4456
|
examples:
|
|
4457
4457
|
funnel gateway logs
|
|
@@ -4525,7 +4525,7 @@ const gatewayRestartHandler = factory.createHandlers(zValidator$1("query", z.obj
|
|
|
4525
4525
|
usage: funnel gateway restart [--no-caffeine]
|
|
4526
4526
|
|
|
4527
4527
|
Stops the running process then starts it again in background.
|
|
4528
|
-
On macOS wraps with caffeinate -
|
|
4528
|
+
On macOS wraps with caffeinate -is by default. Use --no-caffeine to disable.
|
|
4529
4529
|
|
|
4530
4530
|
examples:
|
|
4531
4531
|
funnel gateway restart
|
|
@@ -4544,7 +4544,7 @@ const gatewayRunHandler = factory.createHandlers(zValidator$1("query", z.object(
|
|
|
4544
4544
|
usage: funnel gateway run [--no-caffeine]
|
|
4545
4545
|
|
|
4546
4546
|
For developers. The process is tied to the current terminal and exits on SIGINT / SIGTERM.
|
|
4547
|
-
On macOS wraps with caffeinate -
|
|
4547
|
+
On macOS wraps with caffeinate -is by default. Use --no-caffeine to disable.
|
|
4548
4548
|
|
|
4549
4549
|
For normal usage prefer funnel gateway start.
|
|
4550
4550
|
|
|
@@ -4556,28 +4556,31 @@ examples:
|
|
|
4556
4556
|
const gatewayScript = resolveDaemonScript();
|
|
4557
4557
|
const command = query["no-caffeine"] !== "true" && process.platform === "darwin" ? [
|
|
4558
4558
|
"caffeinate",
|
|
4559
|
-
"-
|
|
4559
|
+
"-is",
|
|
4560
4560
|
"bun",
|
|
4561
4561
|
gatewayScript
|
|
4562
4562
|
] : ["bun", gatewayScript];
|
|
4563
4563
|
const exitCode = await funnel.process.attach(command);
|
|
4564
4564
|
process.exit(exitCode);
|
|
4565
4565
|
});
|
|
4566
|
-
|
|
4566
|
+
//#endregion
|
|
4567
|
+
//#region lib/cli/routes/gateway.start.ts
|
|
4568
|
+
const startHelp = `funnel gateway start — start the gateway in background
|
|
4567
4569
|
|
|
4568
4570
|
usage: funnel gateway start [--no-caffeine]
|
|
4569
4571
|
|
|
4570
|
-
|
|
4571
|
-
On macOS wraps the process with caffeinate -
|
|
4572
|
+
Spawned as a detached background process so it keeps running after the terminal is closed.
|
|
4573
|
+
On macOS wraps the process with caffeinate -is by default to prevent idle and system sleep.
|
|
4572
4574
|
Use --no-caffeine to disable caffeinate.
|
|
4573
4575
|
|
|
4574
4576
|
port: 9742 (override via FUNNEL_PORT)
|
|
4575
4577
|
pid: ~/.funnel/gateway.pid
|
|
4576
|
-
log:
|
|
4578
|
+
log: ${join(funnelTmpDir(), "gateway.log")}
|
|
4577
4579
|
|
|
4578
4580
|
examples:
|
|
4579
4581
|
funnel gateway start
|
|
4580
|
-
funnel gateway start --no-caffeine
|
|
4582
|
+
funnel gateway start --no-caffeine`;
|
|
4583
|
+
const gatewayStartHandler = factory.createHandlers(zValidator$1("query", z.object({ "no-caffeine": z.string().optional() }), startHelp), async (c) => {
|
|
4581
4584
|
const query = c.req.valid("query");
|
|
4582
4585
|
const funnel = c.var.funnel;
|
|
4583
4586
|
if (funnel.gateway.isRunning()) {
|
|
@@ -20,7 +20,7 @@ declare abstract class FunnelConnectorListener {
|
|
|
20
20
|
//#region lib/engine/logger/logger.d.ts
|
|
21
21
|
/**
|
|
22
22
|
* Structured logger with three levels and an optional log-file path.
|
|
23
|
-
* Defaults to NodeFunnelLogger (appends to
|
|
23
|
+
* Defaults to NodeFunnelLogger (appends to `<os.tmpdir()>/funnel/funnel.log`);
|
|
24
24
|
* MemoryFunnelLogger captures entries in memory and NoopFunnelLogger silences output.
|
|
25
25
|
*/
|
|
26
26
|
declare abstract class FunnelLogger {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { dirname, join } from "node:path";
|
|
2
2
|
import { appendFileSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
3
4
|
//#region lib/connectors/connector-listener.ts
|
|
4
5
|
/**
|
|
5
6
|
* Long-lived event source for one connector.
|
|
@@ -21,19 +22,31 @@ var FunnelConnectorListener = class {
|
|
|
21
22
|
//#region lib/engine/logger/logger.ts
|
|
22
23
|
/**
|
|
23
24
|
* Structured logger with three levels and an optional log-file path.
|
|
24
|
-
* Defaults to NodeFunnelLogger (appends to
|
|
25
|
+
* Defaults to NodeFunnelLogger (appends to `<os.tmpdir()>/funnel/funnel.log`);
|
|
25
26
|
* MemoryFunnelLogger captures entries in memory and NoopFunnelLogger silences output.
|
|
26
27
|
*/
|
|
27
28
|
var FunnelLogger = class {};
|
|
28
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
|
|
29
42
|
//#region lib/engine/logger/node-logger.ts
|
|
30
|
-
const
|
|
43
|
+
const defaultLogFile = () => join(funnelTmpDir(), "funnel.log");
|
|
31
44
|
var NodeFunnelLogger = class extends FunnelLogger {
|
|
32
45
|
file;
|
|
33
46
|
now;
|
|
34
47
|
constructor(props = {}) {
|
|
35
48
|
super();
|
|
36
|
-
this.file = props.file ??
|
|
49
|
+
this.file = props.file ?? defaultLogFile();
|
|
37
50
|
this.now = props.now ?? (() => /* @__PURE__ */ new Date());
|
|
38
51
|
Object.freeze(this);
|
|
39
52
|
}
|
|
@@ -58,4 +71,4 @@ var NodeFunnelLogger = class extends FunnelLogger {
|
|
|
58
71
|
}
|
|
59
72
|
};
|
|
60
73
|
//#endregion
|
|
61
|
-
export {
|
|
74
|
+
export { FunnelConnectorListener as i, funnelTmpDir as n, FunnelLogger as r, NodeFunnelLogger as t };
|
package/dist/{schedule-connector-schema-FxP7LPlx.js → schedule-connector-schema-BZpH6ZmR.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-B97ZiGwj.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";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "./logger-
|
|
1
|
+
import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "./logger-B3aXsVcX.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
|
|
4
4
|
//#region lib/connectors/schedule-connector-schema.d.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as FunnelConnectorAdapter } from "./connector-adapter-D5Utumgz.js";
|
|
2
|
-
import {
|
|
2
|
+
import { i as FunnelConnectorListener, t as NodeFunnelLogger } from "./node-logger-B97ZiGwj.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { WebClient } from "@slack/web-api";
|
|
5
5
|
import { App, LogLevel } from "@slack/bolt";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "./logger-
|
|
1
|
+
import { n as FunnelConnectorListener, r as NotifyFn, t as FunnelLogger } from "./logger-B3aXsVcX.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { App } from "@slack/bolt";
|
|
4
4
|
|
package/package.json
CHANGED