tunnelcake 0.1.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/public/assets/index-2FUaMbWY.js +64 -0
- package/dist/public/assets/index-B47yacxU.css +1 -0
- package/dist/public/favicon.svg +9 -0
- package/dist/public/index.html +25 -0
- package/dist/public/opengraph.jpg +0 -0
- package/dist/public/robots.txt +2 -0
- package/dist/server/index.mjs +58725 -0
- package/dist/server/index.mjs.map +7 -0
- package/dist/server/pino-file.mjs +4350 -0
- package/dist/server/pino-file.mjs.map +7 -0
- package/dist/server/pino-pretty.mjs +3312 -0
- package/dist/server/pino-pretty.mjs.map +7 -0
- package/dist/server/pino-worker.mjs +4706 -0
- package/dist/server/pino-worker.mjs.map +7 -0
- package/dist/server/thread-stream-worker.mjs +228 -0
- package/dist/server/thread-stream-worker.mjs.map +7 -0
- package/launch.mjs +134 -0
- package/package.json +24 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { createRequire as __bannerCrReq } from 'node:module';
|
|
2
|
+
import __bannerPath from 'node:path';
|
|
3
|
+
import __bannerUrl from 'node:url';
|
|
4
|
+
|
|
5
|
+
globalThis.require = __bannerCrReq(import.meta.url);
|
|
6
|
+
globalThis.__filename = __bannerUrl.fileURLToPath(import.meta.url);
|
|
7
|
+
globalThis.__dirname = __bannerPath.dirname(globalThis.__filename);
|
|
8
|
+
|
|
9
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
10
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
11
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
12
|
+
}) : x)(function(x) {
|
|
13
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
14
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
15
|
+
});
|
|
16
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
17
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// ../../node_modules/.pnpm/real-require@0.2.0/node_modules/real-require/src/index.js
|
|
21
|
+
var require_src = __commonJS({
|
|
22
|
+
"../../node_modules/.pnpm/real-require@0.2.0/node_modules/real-require/src/index.js"(exports, module) {
|
|
23
|
+
var realImport2 = new Function("modulePath", "return import(modulePath)");
|
|
24
|
+
function realRequire2(modulePath) {
|
|
25
|
+
if (typeof __non_webpack__require__ === "function") {
|
|
26
|
+
return __non_webpack__require__(modulePath);
|
|
27
|
+
}
|
|
28
|
+
return __require(modulePath);
|
|
29
|
+
}
|
|
30
|
+
module.exports = { realImport: realImport2, realRequire: realRequire2 };
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// ../../node_modules/.pnpm/thread-stream@3.1.0/node_modules/thread-stream/lib/indexes.js
|
|
35
|
+
var require_indexes = __commonJS({
|
|
36
|
+
"../../node_modules/.pnpm/thread-stream@3.1.0/node_modules/thread-stream/lib/indexes.js"(exports, module) {
|
|
37
|
+
"use strict";
|
|
38
|
+
var WRITE_INDEX2 = 4;
|
|
39
|
+
var READ_INDEX2 = 8;
|
|
40
|
+
module.exports = {
|
|
41
|
+
WRITE_INDEX: WRITE_INDEX2,
|
|
42
|
+
READ_INDEX: READ_INDEX2
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// ../../node_modules/.pnpm/thread-stream@3.1.0/node_modules/thread-stream/lib/wait.js
|
|
48
|
+
var require_wait = __commonJS({
|
|
49
|
+
"../../node_modules/.pnpm/thread-stream@3.1.0/node_modules/thread-stream/lib/wait.js"(exports, module) {
|
|
50
|
+
"use strict";
|
|
51
|
+
var MAX_TIMEOUT = 1e3;
|
|
52
|
+
function wait(state2, index, expected, timeout, done) {
|
|
53
|
+
const max = Date.now() + timeout;
|
|
54
|
+
let current = Atomics.load(state2, index);
|
|
55
|
+
if (current === expected) {
|
|
56
|
+
done(null, "ok");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
let prior = current;
|
|
60
|
+
const check = (backoff) => {
|
|
61
|
+
if (Date.now() > max) {
|
|
62
|
+
done(null, "timed-out");
|
|
63
|
+
} else {
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
prior = current;
|
|
66
|
+
current = Atomics.load(state2, index);
|
|
67
|
+
if (current === prior) {
|
|
68
|
+
check(backoff >= MAX_TIMEOUT ? MAX_TIMEOUT : backoff * 2);
|
|
69
|
+
} else {
|
|
70
|
+
if (current === expected) done(null, "ok");
|
|
71
|
+
else done(null, "not-equal");
|
|
72
|
+
}
|
|
73
|
+
}, backoff);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
check(1);
|
|
77
|
+
}
|
|
78
|
+
function waitDiff2(state2, index, expected, timeout, done) {
|
|
79
|
+
const max = Date.now() + timeout;
|
|
80
|
+
let current = Atomics.load(state2, index);
|
|
81
|
+
if (current !== expected) {
|
|
82
|
+
done(null, "ok");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const check = (backoff) => {
|
|
86
|
+
if (Date.now() > max) {
|
|
87
|
+
done(null, "timed-out");
|
|
88
|
+
} else {
|
|
89
|
+
setTimeout(() => {
|
|
90
|
+
current = Atomics.load(state2, index);
|
|
91
|
+
if (current !== expected) {
|
|
92
|
+
done(null, "ok");
|
|
93
|
+
} else {
|
|
94
|
+
check(backoff >= MAX_TIMEOUT ? MAX_TIMEOUT : backoff * 2);
|
|
95
|
+
}
|
|
96
|
+
}, backoff);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
check(1);
|
|
100
|
+
}
|
|
101
|
+
module.exports = { wait, waitDiff: waitDiff2 };
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// ../../node_modules/.pnpm/thread-stream@3.1.0/node_modules/thread-stream/lib/worker.js
|
|
106
|
+
var { realImport, realRequire } = require_src();
|
|
107
|
+
var { workerData, parentPort } = __require("worker_threads");
|
|
108
|
+
var { WRITE_INDEX, READ_INDEX } = require_indexes();
|
|
109
|
+
var { waitDiff } = require_wait();
|
|
110
|
+
var {
|
|
111
|
+
dataBuf,
|
|
112
|
+
filename,
|
|
113
|
+
stateBuf
|
|
114
|
+
} = workerData;
|
|
115
|
+
var destination;
|
|
116
|
+
var state = new Int32Array(stateBuf);
|
|
117
|
+
var data = Buffer.from(dataBuf);
|
|
118
|
+
async function start() {
|
|
119
|
+
let worker;
|
|
120
|
+
try {
|
|
121
|
+
if (filename.endsWith(".ts") || filename.endsWith(".cts")) {
|
|
122
|
+
if (!process[/* @__PURE__ */ Symbol.for("ts-node.register.instance")]) {
|
|
123
|
+
realRequire("ts-node/register");
|
|
124
|
+
} else if (process.env.TS_NODE_DEV) {
|
|
125
|
+
realRequire("ts-node-dev");
|
|
126
|
+
}
|
|
127
|
+
worker = realRequire(decodeURIComponent(filename.replace(process.platform === "win32" ? "file:///" : "file://", "")));
|
|
128
|
+
} else {
|
|
129
|
+
worker = await realImport(filename);
|
|
130
|
+
}
|
|
131
|
+
} catch (error) {
|
|
132
|
+
if ((error.code === "ENOTDIR" || error.code === "ERR_MODULE_NOT_FOUND") && filename.startsWith("file://")) {
|
|
133
|
+
worker = realRequire(decodeURIComponent(filename.replace("file://", "")));
|
|
134
|
+
} else if (error.code === void 0 || error.code === "ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING") {
|
|
135
|
+
try {
|
|
136
|
+
worker = realRequire(decodeURIComponent(filename.replace(process.platform === "win32" ? "file:///" : "file://", "")));
|
|
137
|
+
} catch {
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (typeof worker === "object") worker = worker.default;
|
|
145
|
+
if (typeof worker === "object") worker = worker.default;
|
|
146
|
+
destination = await worker(workerData.workerData);
|
|
147
|
+
destination.on("error", function(err) {
|
|
148
|
+
Atomics.store(state, WRITE_INDEX, -2);
|
|
149
|
+
Atomics.notify(state, WRITE_INDEX);
|
|
150
|
+
Atomics.store(state, READ_INDEX, -2);
|
|
151
|
+
Atomics.notify(state, READ_INDEX);
|
|
152
|
+
parentPort.postMessage({
|
|
153
|
+
code: "ERROR",
|
|
154
|
+
err
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
destination.on("close", function() {
|
|
158
|
+
const end = Atomics.load(state, WRITE_INDEX);
|
|
159
|
+
Atomics.store(state, READ_INDEX, end);
|
|
160
|
+
Atomics.notify(state, READ_INDEX);
|
|
161
|
+
setImmediate(() => {
|
|
162
|
+
process.exit(0);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
start().then(function() {
|
|
167
|
+
parentPort.postMessage({
|
|
168
|
+
code: "READY"
|
|
169
|
+
});
|
|
170
|
+
process.nextTick(run);
|
|
171
|
+
});
|
|
172
|
+
function run() {
|
|
173
|
+
const current = Atomics.load(state, READ_INDEX);
|
|
174
|
+
const end = Atomics.load(state, WRITE_INDEX);
|
|
175
|
+
if (end === current) {
|
|
176
|
+
if (end === data.length) {
|
|
177
|
+
waitDiff(state, READ_INDEX, end, Infinity, run);
|
|
178
|
+
} else {
|
|
179
|
+
waitDiff(state, WRITE_INDEX, end, Infinity, run);
|
|
180
|
+
}
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (end === -1) {
|
|
184
|
+
destination.end();
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const toWrite = data.toString("utf8", current, end);
|
|
188
|
+
const res = destination.write(toWrite);
|
|
189
|
+
if (res) {
|
|
190
|
+
Atomics.store(state, READ_INDEX, end);
|
|
191
|
+
Atomics.notify(state, READ_INDEX);
|
|
192
|
+
setImmediate(run);
|
|
193
|
+
} else {
|
|
194
|
+
destination.once("drain", function() {
|
|
195
|
+
Atomics.store(state, READ_INDEX, end);
|
|
196
|
+
Atomics.notify(state, READ_INDEX);
|
|
197
|
+
run();
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
process.on("unhandledRejection", function(err) {
|
|
202
|
+
parentPort.postMessage({
|
|
203
|
+
code: "ERROR",
|
|
204
|
+
err
|
|
205
|
+
});
|
|
206
|
+
process.exit(1);
|
|
207
|
+
});
|
|
208
|
+
process.on("uncaughtException", function(err) {
|
|
209
|
+
parentPort.postMessage({
|
|
210
|
+
code: "ERROR",
|
|
211
|
+
err
|
|
212
|
+
});
|
|
213
|
+
process.exit(1);
|
|
214
|
+
});
|
|
215
|
+
process.once("exit", (exitCode) => {
|
|
216
|
+
if (exitCode !== 0) {
|
|
217
|
+
process.exit(exitCode);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (destination?.writableNeedDrain && !destination?.writableEnded) {
|
|
221
|
+
parentPort.postMessage({
|
|
222
|
+
code: "WARNING",
|
|
223
|
+
err: new Error("ThreadStream: process exited before destination stream was drained. this may indicate that the destination stream try to write to a another missing stream")
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
process.exit(0);
|
|
227
|
+
});
|
|
228
|
+
//# sourceMappingURL=thread-stream-worker.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../node_modules/.pnpm/real-require@0.2.0/node_modules/real-require/src/index.js", "../../../node_modules/.pnpm/thread-stream@3.1.0/node_modules/thread-stream/lib/indexes.js", "../../../node_modules/.pnpm/thread-stream@3.1.0/node_modules/thread-stream/lib/wait.js", "../../../node_modules/.pnpm/thread-stream@3.1.0/node_modules/thread-stream/lib/worker.js"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable no-new-func, camelcase */\n/* globals __non_webpack__require__ */\n\nconst realImport = new Function('modulePath', 'return import(modulePath)')\n\nfunction realRequire(modulePath) {\n if (typeof __non_webpack__require__ === 'function') {\n return __non_webpack__require__(modulePath)\n }\n\n return require(modulePath)\n}\n\nmodule.exports = { realImport, realRequire }\n", "'use strict'\n\nconst WRITE_INDEX = 4\nconst READ_INDEX = 8\n\nmodule.exports = {\n WRITE_INDEX,\n READ_INDEX\n}\n", "'use strict'\n\nconst MAX_TIMEOUT = 1000\n\nfunction wait (state, index, expected, timeout, done) {\n const max = Date.now() + timeout\n let current = Atomics.load(state, index)\n if (current === expected) {\n done(null, 'ok')\n return\n }\n let prior = current\n const check = (backoff) => {\n if (Date.now() > max) {\n done(null, 'timed-out')\n } else {\n setTimeout(() => {\n prior = current\n current = Atomics.load(state, index)\n if (current === prior) {\n check(backoff >= MAX_TIMEOUT ? MAX_TIMEOUT : backoff * 2)\n } else {\n if (current === expected) done(null, 'ok')\n else done(null, 'not-equal')\n }\n }, backoff)\n }\n }\n check(1)\n}\n\n// let waitDiffCount = 0\nfunction waitDiff (state, index, expected, timeout, done) {\n // const id = waitDiffCount++\n // process._rawDebug(`>>> waitDiff ${id}`)\n const max = Date.now() + timeout\n let current = Atomics.load(state, index)\n if (current !== expected) {\n done(null, 'ok')\n return\n }\n const check = (backoff) => {\n // process._rawDebug(`${id} ${index} current ${current} expected ${expected}`)\n // process._rawDebug('' + backoff)\n if (Date.now() > max) {\n done(null, 'timed-out')\n } else {\n setTimeout(() => {\n current = Atomics.load(state, index)\n if (current !== expected) {\n done(null, 'ok')\n } else {\n check(backoff >= MAX_TIMEOUT ? MAX_TIMEOUT : backoff * 2)\n }\n }, backoff)\n }\n }\n check(1)\n}\n\nmodule.exports = { wait, waitDiff }\n", "'use strict'\n\nconst { realImport, realRequire } = require('real-require')\nconst { workerData, parentPort } = require('worker_threads')\nconst { WRITE_INDEX, READ_INDEX } = require('./indexes')\nconst { waitDiff } = require('./wait')\n\nconst {\n dataBuf,\n filename,\n stateBuf\n} = workerData\n\nlet destination\n\nconst state = new Int32Array(stateBuf)\nconst data = Buffer.from(dataBuf)\n\nasync function start () {\n let worker\n try {\n if (filename.endsWith('.ts') || filename.endsWith('.cts')) {\n // TODO: add support for the TSM modules loader ( https://github.com/lukeed/tsm ).\n if (!process[Symbol.for('ts-node.register.instance')]) {\n realRequire('ts-node/register')\n } else if (process.env.TS_NODE_DEV) {\n realRequire('ts-node-dev')\n }\n // TODO: Support ES imports once tsc, tap & ts-node provide better compatibility guarantees.\n // Remove extra forwardslash on Windows\n worker = realRequire(decodeURIComponent(filename.replace(process.platform === 'win32' ? 'file:///' : 'file://', '')))\n } else {\n worker = (await realImport(filename))\n }\n } catch (error) {\n // A yarn user that tries to start a ThreadStream for an external module\n // provides a filename pointing to a zip file.\n // eg. require.resolve('pino-elasticsearch') // returns /foo/pino-elasticsearch-npm-6.1.0-0c03079478-6915435172.zip/bar.js\n // The `import` will fail to try to load it.\n // This catch block executes the `require` fallback to load the module correctly.\n // In fact, yarn modifies the `require` function to manage the zipped path.\n // More details at https://github.com/pinojs/pino/pull/1113\n // The error codes may change based on the node.js version (ENOTDIR > 12, ERR_MODULE_NOT_FOUND <= 12 )\n if ((error.code === 'ENOTDIR' || error.code === 'ERR_MODULE_NOT_FOUND') &&\n filename.startsWith('file://')) {\n worker = realRequire(decodeURIComponent(filename.replace('file://', '')))\n } else if (error.code === undefined || error.code === 'ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING') {\n // When bundled with pkg, an undefined error is thrown when called with realImport\n // When bundled with pkg and using node v20, an ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING error is thrown when called with realImport\n // More info at: https://github.com/pinojs/thread-stream/issues/143\n try {\n worker = realRequire(decodeURIComponent(filename.replace(process.platform === 'win32' ? 'file:///' : 'file://', '')))\n } catch {\n throw error\n }\n } else {\n throw error\n }\n }\n\n // Depending on how the default export is performed, and on how the code is\n // transpiled, we may find cases of two nested \"default\" objects.\n // See https://github.com/pinojs/pino/issues/1243#issuecomment-982774762\n if (typeof worker === 'object') worker = worker.default\n if (typeof worker === 'object') worker = worker.default\n\n destination = await worker(workerData.workerData)\n\n destination.on('error', function (err) {\n Atomics.store(state, WRITE_INDEX, -2)\n Atomics.notify(state, WRITE_INDEX)\n\n Atomics.store(state, READ_INDEX, -2)\n Atomics.notify(state, READ_INDEX)\n\n parentPort.postMessage({\n code: 'ERROR',\n err\n })\n })\n\n destination.on('close', function () {\n // process._rawDebug('worker close emitted')\n const end = Atomics.load(state, WRITE_INDEX)\n Atomics.store(state, READ_INDEX, end)\n Atomics.notify(state, READ_INDEX)\n setImmediate(() => {\n process.exit(0)\n })\n })\n}\n\n// No .catch() handler,\n// in case there is an error it goes\n// to unhandledRejection\nstart().then(function () {\n parentPort.postMessage({\n code: 'READY'\n })\n\n process.nextTick(run)\n})\n\nfunction run () {\n const current = Atomics.load(state, READ_INDEX)\n const end = Atomics.load(state, WRITE_INDEX)\n\n // process._rawDebug(`pre state ${current} ${end}`)\n\n if (end === current) {\n if (end === data.length) {\n waitDiff(state, READ_INDEX, end, Infinity, run)\n } else {\n waitDiff(state, WRITE_INDEX, end, Infinity, run)\n }\n return\n }\n\n // process._rawDebug(`post state ${current} ${end}`)\n\n if (end === -1) {\n // process._rawDebug('end')\n destination.end()\n return\n }\n\n const toWrite = data.toString('utf8', current, end)\n // process._rawDebug('worker writing: ' + toWrite)\n\n const res = destination.write(toWrite)\n\n if (res) {\n Atomics.store(state, READ_INDEX, end)\n Atomics.notify(state, READ_INDEX)\n setImmediate(run)\n } else {\n destination.once('drain', function () {\n Atomics.store(state, READ_INDEX, end)\n Atomics.notify(state, READ_INDEX)\n run()\n })\n }\n}\n\nprocess.on('unhandledRejection', function (err) {\n parentPort.postMessage({\n code: 'ERROR',\n err\n })\n process.exit(1)\n})\n\nprocess.on('uncaughtException', function (err) {\n parentPort.postMessage({\n code: 'ERROR',\n err\n })\n process.exit(1)\n})\n\nprocess.once('exit', exitCode => {\n if (exitCode !== 0) {\n process.exit(exitCode)\n return\n }\n if (destination?.writableNeedDrain && !destination?.writableEnded) {\n parentPort.postMessage({\n code: 'WARNING',\n err: new Error('ThreadStream: process exited before destination stream was drained. this may indicate that the destination stream try to write to a another missing stream')\n })\n }\n\n process.exit(0)\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["realImport", "realRequire", "WRITE_INDEX", "READ_INDEX", "state", "waitDiff"]
|
|
7
|
+
}
|
package/launch.mjs
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Pure-Node launcher. No pnpm, no build step, no workspace assumptions.
|
|
3
|
+
//
|
|
4
|
+
// Two run modes, auto-detected:
|
|
5
|
+
// 1. Published npm package (`npx tunnelcake`): runs the prebuilt
|
|
6
|
+
// bundle shipped in ./dist (server + web), with @ngrok/ngrok resolved from
|
|
7
|
+
// this package's own dependencies.
|
|
8
|
+
// 2. Monorepo / `pnpm start`: runs the in-place artifact builds so dynamic
|
|
9
|
+
// deps (e.g. @ngrok/ngrok) resolve from the workspace.
|
|
10
|
+
import { spawn } from "node:child_process";
|
|
11
|
+
import { createServer } from "node:net";
|
|
12
|
+
import { existsSync } from "node:fs";
|
|
13
|
+
import { homedir, platform } from "node:os";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
|
|
17
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
|
|
19
|
+
const repoServer = path.resolve(
|
|
20
|
+
here,
|
|
21
|
+
"..",
|
|
22
|
+
"artifacts/api-server/dist/index.mjs",
|
|
23
|
+
);
|
|
24
|
+
const repoWeb = path.resolve(here, "..", "artifacts/mcp-manager/dist/public");
|
|
25
|
+
const bundledServer = path.join(here, "dist/server/index.mjs");
|
|
26
|
+
const bundledWeb = path.join(here, "dist/public");
|
|
27
|
+
|
|
28
|
+
function log(msg) {
|
|
29
|
+
process.stdout.write(`[tunnelcake] ${msg}\n`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let serverEntry;
|
|
33
|
+
let webDist;
|
|
34
|
+
if (existsSync(repoServer)) {
|
|
35
|
+
serverEntry = repoServer;
|
|
36
|
+
webDist = repoWeb;
|
|
37
|
+
} else if (existsSync(bundledServer)) {
|
|
38
|
+
serverEntry = bundledServer;
|
|
39
|
+
webDist = bundledWeb;
|
|
40
|
+
} else {
|
|
41
|
+
log(
|
|
42
|
+
"Could not find the built app. If running from source, run `pnpm install` then `pnpm start`.",
|
|
43
|
+
);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Ask the OS for a free loopback port by binding to port 0.
|
|
48
|
+
function findFreePort() {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const srv = createServer();
|
|
51
|
+
srv.on("error", reject);
|
|
52
|
+
srv.listen(0, "127.0.0.1", () => {
|
|
53
|
+
const { port } = srv.address();
|
|
54
|
+
srv.close(() => resolve(port));
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function waitForReady(url, timeoutMs = 30000) {
|
|
60
|
+
const start = Date.now();
|
|
61
|
+
while (Date.now() - start < timeoutMs) {
|
|
62
|
+
try {
|
|
63
|
+
const res = await fetch(url);
|
|
64
|
+
if (res.ok) return true;
|
|
65
|
+
} catch {
|
|
66
|
+
// not up yet
|
|
67
|
+
}
|
|
68
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function openBrowser(url) {
|
|
74
|
+
const os = platform();
|
|
75
|
+
const cmd = os === "darwin" ? "open" : os === "win32" ? "cmd" : "xdg-open";
|
|
76
|
+
const args = os === "win32" ? ["/c", "start", "", url] : [url];
|
|
77
|
+
try {
|
|
78
|
+
const child = spawn(cmd, args, { stdio: "ignore", detached: true });
|
|
79
|
+
child.on("error", () => {
|
|
80
|
+
/* headless / no browser — the URL is logged below */
|
|
81
|
+
});
|
|
82
|
+
child.unref();
|
|
83
|
+
} catch {
|
|
84
|
+
/* ignore */
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function main() {
|
|
89
|
+
const host = "127.0.0.1";
|
|
90
|
+
const port = process.env.PORT
|
|
91
|
+
? Number(process.env.PORT)
|
|
92
|
+
: await findFreePort();
|
|
93
|
+
const url = `http://${host}:${port}/`;
|
|
94
|
+
|
|
95
|
+
const child = spawn(
|
|
96
|
+
process.execPath,
|
|
97
|
+
["--enable-source-maps", "--no-warnings", serverEntry],
|
|
98
|
+
{
|
|
99
|
+
stdio: "inherit",
|
|
100
|
+
env: {
|
|
101
|
+
...process.env,
|
|
102
|
+
NODE_ENV: "production",
|
|
103
|
+
HOST: host,
|
|
104
|
+
PORT: String(port),
|
|
105
|
+
MCP_WEB_DIST: webDist,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const shutdown = () => {
|
|
111
|
+
if (!child.killed) child.kill("SIGTERM");
|
|
112
|
+
};
|
|
113
|
+
process.on("SIGINT", shutdown);
|
|
114
|
+
process.on("SIGTERM", shutdown);
|
|
115
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
116
|
+
|
|
117
|
+
const dataDir =
|
|
118
|
+
process.env.MCP_DATA_DIR ?? path.join(homedir(), ".tunnelcake");
|
|
119
|
+
log(`Data is stored in ${dataDir}`);
|
|
120
|
+
log(`Starting on ${url}`);
|
|
121
|
+
|
|
122
|
+
const ready = await waitForReady(`${url}api/healthz`);
|
|
123
|
+
if (ready) {
|
|
124
|
+
log("Ready — opening your browser.");
|
|
125
|
+
openBrowser(url);
|
|
126
|
+
} else {
|
|
127
|
+
log(`Server did not become ready in time. Open ${url} manually.`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
main().catch((err) => {
|
|
132
|
+
log(`Failed to start: ${err?.message ?? err}`);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tunnelcake",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Local-first manager for MCP stdio servers, exposed to ChatGPT via the OpenAI Secure MCP Tunnel or an ngrok SSE proxy.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"tunnelcake": "launch.mjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"launch.mjs",
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=24"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@ngrok/ngrok": "^1.7.0"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"bundle": "node ./build.mjs",
|
|
22
|
+
"prepack": "node ./build.mjs"
|
|
23
|
+
}
|
|
24
|
+
}
|