@leadbay/mcp 0.23.0 → 0.23.2
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/CHANGELOG.md +14 -0
- package/dist/bin.js +818 -30
- package/dist/http-server.js +701 -6
- package/dist/installer-electron.js +67 -22
- package/dist/installer-gui.js +66 -21
- package/package.json +1 -1
|
@@ -90,11 +90,11 @@ var init_install_claude_code = __esm({
|
|
|
90
90
|
// installer/install-json-config.ts
|
|
91
91
|
async function installInJsonConfig(configPath, token, region, includeWrite, telemetryEnabled, localBinPath) {
|
|
92
92
|
try {
|
|
93
|
-
const { readFileSync: readFileSync3, writeFileSync, existsSync:
|
|
93
|
+
const { readFileSync: readFileSync3, writeFileSync, existsSync: existsSync4, mkdirSync, statSync } = await import("fs");
|
|
94
94
|
const { dirname } = await import("path");
|
|
95
95
|
let parsed = {};
|
|
96
96
|
let preserved = {};
|
|
97
|
-
const existed =
|
|
97
|
+
const existed = existsSync4(configPath);
|
|
98
98
|
if (existed) {
|
|
99
99
|
const raw = readFileSync3(configPath, "utf8");
|
|
100
100
|
try {
|
|
@@ -144,8 +144,8 @@ function stripJsonMcpEntry(existing) {
|
|
|
144
144
|
}
|
|
145
145
|
async function uninstallFromJsonConfig(configPath) {
|
|
146
146
|
try {
|
|
147
|
-
const { existsSync:
|
|
148
|
-
if (!
|
|
147
|
+
const { existsSync: existsSync4, readFileSync: readFileSync3, writeFileSync } = await import("fs");
|
|
148
|
+
if (!existsSync4(configPath)) return { ok: true, message: "config not found \u2014 nothing to do" };
|
|
149
149
|
const existing = readFileSync3(configPath, "utf8");
|
|
150
150
|
const { content, changed } = stripJsonMcpEntry(existing);
|
|
151
151
|
if (!changed) return { ok: true, message: "leadbay entry not present" };
|
|
@@ -233,10 +233,10 @@ function stripShellExportBlock(existing) {
|
|
|
233
233
|
}
|
|
234
234
|
async function installInCodexConfig(configPath, includeWrite, telemetryEnabled, localBinPath) {
|
|
235
235
|
try {
|
|
236
|
-
const { readFileSync: readFileSync3, writeFileSync, existsSync:
|
|
236
|
+
const { readFileSync: readFileSync3, writeFileSync, existsSync: existsSync4, mkdirSync, statSync, renameSync, chmodSync } = await import("fs");
|
|
237
237
|
const { dirname } = await import("path");
|
|
238
238
|
let existing = "";
|
|
239
|
-
const existed =
|
|
239
|
+
const existed = existsSync4(configPath);
|
|
240
240
|
if (existed) {
|
|
241
241
|
existing = readFileSync3(configPath, "utf8");
|
|
242
242
|
} else {
|
|
@@ -282,15 +282,15 @@ async function appendShellExports(token, region, includeWrite, telemetryEnabled)
|
|
|
282
282
|
}
|
|
283
283
|
return { ok: true, message: "env exported with setx; restart Codex/terminal" };
|
|
284
284
|
}
|
|
285
|
-
const { existsSync:
|
|
285
|
+
const { existsSync: existsSync4, readFileSync: readFileSync3, writeFileSync, renameSync } = await import("fs");
|
|
286
286
|
const os = await import("os");
|
|
287
287
|
const home = os.homedir();
|
|
288
|
-
const preferred = [`${home}/.zshrc`, `${home}/.bashrc`].filter((path) =>
|
|
288
|
+
const preferred = [`${home}/.zshrc`, `${home}/.bashrc`].filter((path) => existsSync4(path));
|
|
289
289
|
const paths = preferred.length ? preferred : [`${home}/.profile`];
|
|
290
290
|
const block = buildShellExportBlock(token, region, includeWrite, telemetryEnabled);
|
|
291
291
|
const updated = [];
|
|
292
292
|
for (const path of paths) {
|
|
293
|
-
const existing =
|
|
293
|
+
const existing = existsSync4(path) ? readFileSync3(path, "utf8") : "";
|
|
294
294
|
const merged = mergeShellExportBlock(existing, block);
|
|
295
295
|
if (!merged.changed) continue;
|
|
296
296
|
const tmp = `${path}.leadbay.tmp`;
|
|
@@ -308,8 +308,8 @@ async function appendShellExports(token, region, includeWrite, telemetryEnabled)
|
|
|
308
308
|
}
|
|
309
309
|
async function uninstallFromCodexConfig(configPath) {
|
|
310
310
|
try {
|
|
311
|
-
const { existsSync:
|
|
312
|
-
if (!
|
|
311
|
+
const { existsSync: existsSync4, readFileSync: readFileSync3, writeFileSync } = await import("fs");
|
|
312
|
+
if (!existsSync4(configPath)) return { ok: true, message: "config not found \u2014 nothing to do" };
|
|
313
313
|
const existing = readFileSync3(configPath, "utf8");
|
|
314
314
|
const { content, changed } = stripCodexBlock(existing);
|
|
315
315
|
if (!changed) return { ok: true, message: "leadbay block not present" };
|
|
@@ -321,11 +321,11 @@ async function uninstallFromCodexConfig(configPath) {
|
|
|
321
321
|
}
|
|
322
322
|
async function uninstallShellExports() {
|
|
323
323
|
try {
|
|
324
|
-
const { existsSync:
|
|
324
|
+
const { existsSync: existsSync4, readFileSync: readFileSync3, writeFileSync, renameSync } = await import("fs");
|
|
325
325
|
const os = await import("os");
|
|
326
326
|
const home = os.homedir();
|
|
327
327
|
const candidates = [`${home}/.zshrc`, `${home}/.bashrc`, `${home}/.profile`].filter(
|
|
328
|
-
(p) =>
|
|
328
|
+
(p) => existsSync4(p)
|
|
329
329
|
);
|
|
330
330
|
const updated = [];
|
|
331
331
|
for (const p of candidates) {
|
|
@@ -354,17 +354,17 @@ var init_install_codex = __esm({
|
|
|
354
354
|
// installer/install-dxt.ts
|
|
355
355
|
async function removeDxtExtension(claudeSupportDir) {
|
|
356
356
|
try {
|
|
357
|
-
const { existsSync:
|
|
357
|
+
const { existsSync: existsSync4, readFileSync: readFileSync3, writeFileSync, rmSync } = await import("fs");
|
|
358
358
|
const { join: join2 } = await import("path");
|
|
359
359
|
const extensionDir = join2(claudeSupportDir, "Claude Extensions", DXT_EXTENSION_ID);
|
|
360
360
|
const registryPath = join2(claudeSupportDir, "extensions-installations.json");
|
|
361
361
|
let removedDir = false;
|
|
362
362
|
let removedEntry = false;
|
|
363
|
-
if (
|
|
363
|
+
if (existsSync4(extensionDir)) {
|
|
364
364
|
rmSync(extensionDir, { recursive: true, force: true });
|
|
365
365
|
removedDir = true;
|
|
366
366
|
}
|
|
367
|
-
if (
|
|
367
|
+
if (existsSync4(registryPath)) {
|
|
368
368
|
try {
|
|
369
369
|
const raw = readFileSync3(registryPath, "utf8");
|
|
370
370
|
const parsed = JSON.parse(raw);
|
|
@@ -550,7 +550,7 @@ import { createHash, randomBytes } from "crypto";
|
|
|
550
550
|
import { createServer } from "http";
|
|
551
551
|
import { request as httpsRequestRaw } from "https";
|
|
552
552
|
import { spawn as spawn3 } from "child_process";
|
|
553
|
-
import { readdirSync } from "fs";
|
|
553
|
+
import { readdirSync, existsSync as existsSync2 } from "fs";
|
|
554
554
|
async function inferRegionViaStargate(opts) {
|
|
555
555
|
const url = STARGATE_URLS[opts.staging ? "staging" : "prod"];
|
|
556
556
|
const res = await httpsCall("GET", url, { Accept: "application/json" });
|
|
@@ -837,7 +837,19 @@ function browserOpenCandidates(url) {
|
|
|
837
837
|
function browserLaunchEnv(debug) {
|
|
838
838
|
const env = { ...process.env };
|
|
839
839
|
if (process.platform !== "linux") return env;
|
|
840
|
-
|
|
840
|
+
let runtimeDir = env.XDG_RUNTIME_DIR;
|
|
841
|
+
if (!runtimeDir || !existsSync2(runtimeDir)) {
|
|
842
|
+
try {
|
|
843
|
+
const uid = process.getuid?.();
|
|
844
|
+
const candidate = uid !== void 0 ? `/run/user/${uid}` : void 0;
|
|
845
|
+
if (candidate && existsSync2(candidate)) {
|
|
846
|
+
runtimeDir = candidate;
|
|
847
|
+
env.XDG_RUNTIME_DIR = candidate;
|
|
848
|
+
debug?.(`browserLaunchEnv: injected XDG_RUNTIME_DIR=${candidate}`);
|
|
849
|
+
}
|
|
850
|
+
} catch {
|
|
851
|
+
}
|
|
852
|
+
}
|
|
841
853
|
if (!env.WAYLAND_DISPLAY && runtimeDir) {
|
|
842
854
|
try {
|
|
843
855
|
const sock = readdirSync(runtimeDir).find((f) => /^wayland-\d+$/.test(f));
|
|
@@ -848,6 +860,13 @@ function browserLaunchEnv(debug) {
|
|
|
848
860
|
} catch {
|
|
849
861
|
}
|
|
850
862
|
}
|
|
863
|
+
if (!env.DBUS_SESSION_BUS_ADDRESS && runtimeDir) {
|
|
864
|
+
const busPath = `${runtimeDir}/bus`;
|
|
865
|
+
if (existsSync2(busPath)) {
|
|
866
|
+
env.DBUS_SESSION_BUS_ADDRESS = `unix:path=${busPath}`;
|
|
867
|
+
debug?.(`browserLaunchEnv: injected DBUS_SESSION_BUS_ADDRESS=unix:path=${busPath}`);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
851
870
|
if (!env.DISPLAY) {
|
|
852
871
|
try {
|
|
853
872
|
const x = readdirSync("/tmp/.X11-unix").map((f) => f.match(/^X(\d+)$/)?.[1]).filter((n) => !!n).sort((a, b) => Number(a) - Number(b))[0];
|
|
@@ -857,6 +876,25 @@ function browserLaunchEnv(debug) {
|
|
|
857
876
|
}
|
|
858
877
|
debug?.(`browserLaunchEnv: injected DISPLAY=${env.DISPLAY}`);
|
|
859
878
|
}
|
|
879
|
+
if (!env.XAUTHORITY) {
|
|
880
|
+
try {
|
|
881
|
+
let xauth;
|
|
882
|
+
if (runtimeDir) {
|
|
883
|
+
const cookie = readdirSync(runtimeDir).find(
|
|
884
|
+
(f) => /^\.mutter-Xwaylandauth\./.test(f)
|
|
885
|
+
);
|
|
886
|
+
if (cookie) xauth = `${runtimeDir}/${cookie}`;
|
|
887
|
+
}
|
|
888
|
+
if (!xauth && env.HOME && existsSync2(`${env.HOME}/.Xauthority`)) {
|
|
889
|
+
xauth = `${env.HOME}/.Xauthority`;
|
|
890
|
+
}
|
|
891
|
+
if (xauth) {
|
|
892
|
+
env.XAUTHORITY = xauth;
|
|
893
|
+
debug?.(`browserLaunchEnv: injected XAUTHORITY=${xauth}`);
|
|
894
|
+
}
|
|
895
|
+
} catch {
|
|
896
|
+
}
|
|
897
|
+
}
|
|
860
898
|
return env;
|
|
861
899
|
}
|
|
862
900
|
async function openInBrowser(url, debug) {
|
|
@@ -1010,6 +1048,8 @@ var init_oauth = __esm({
|
|
|
1010
1048
|
var installer_gui_exports = {};
|
|
1011
1049
|
__export(installer_gui_exports, {
|
|
1012
1050
|
install: () => install,
|
|
1051
|
+
pageHtml: () => pageHtml,
|
|
1052
|
+
pageUninstallHtml: () => pageUninstallHtml,
|
|
1013
1053
|
sanitizeOutput: () => sanitizeOutput,
|
|
1014
1054
|
startInstallerGui: () => startInstallerGui,
|
|
1015
1055
|
startUninstallerGui: () => startUninstallerGui
|
|
@@ -1018,14 +1058,14 @@ import { createServer as createServer2 } from "http";
|
|
|
1018
1058
|
import { randomUUID } from "crypto";
|
|
1019
1059
|
import { resolve as resolvePath } from "path";
|
|
1020
1060
|
import { fileURLToPath } from "url";
|
|
1021
|
-
import { existsSync as
|
|
1061
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
1022
1062
|
async function isLeadbayConfigured(client) {
|
|
1023
1063
|
if (client.id === "claude-code") {
|
|
1024
1064
|
return await isLeadbayConfiguredInClaudeCode();
|
|
1025
1065
|
}
|
|
1026
1066
|
if (client.id === "codex") {
|
|
1027
1067
|
const configPath2 = client.detail;
|
|
1028
|
-
if (!
|
|
1068
|
+
if (!existsSync3(configPath2)) return false;
|
|
1029
1069
|
try {
|
|
1030
1070
|
return readFileSync2(configPath2, "utf8").includes("[mcp_servers.leadbay]");
|
|
1031
1071
|
} catch {
|
|
@@ -1034,7 +1074,7 @@ async function isLeadbayConfigured(client) {
|
|
|
1034
1074
|
}
|
|
1035
1075
|
if (client.id === "chatgpt-desktop") return false;
|
|
1036
1076
|
const configPath = client.configPath;
|
|
1037
|
-
if (!configPath || !
|
|
1077
|
+
if (!configPath || !existsSync3(configPath)) return false;
|
|
1038
1078
|
try {
|
|
1039
1079
|
const parsed = JSON.parse(readFileSync2(configPath, "utf8"));
|
|
1040
1080
|
return Boolean(parsed?.mcpServers?.leadbay);
|
|
@@ -1333,6 +1373,7 @@ function pageUninstallHtml() {
|
|
|
1333
1373
|
.result-note { font-size:12.5px; color:var(--muted); text-align:center; margin-top:-6px; }
|
|
1334
1374
|
@keyframes draw { to { stroke-dashoffset:0; } }
|
|
1335
1375
|
@keyframes pop { 0%{transform:scale(.5);opacity:0;} 60%{transform:scale(1.06);} 100%{transform:scale(1);opacity:1;} }
|
|
1376
|
+
.version { text-align:center; color:var(--muted); font-size:11px; margin:14px 0 0; letter-spacing:.02em; }
|
|
1336
1377
|
@media (max-width:520px) { .actions{flex-direction:column;} button{width:100%;} }
|
|
1337
1378
|
</style>
|
|
1338
1379
|
</head>
|
|
@@ -1364,6 +1405,7 @@ function pageUninstallHtml() {
|
|
|
1364
1405
|
<button class="danger" id="next">Remove selected</button>
|
|
1365
1406
|
</div>
|
|
1366
1407
|
</div>
|
|
1408
|
+
<p class="version">v${VERSION}</p>
|
|
1367
1409
|
</main>
|
|
1368
1410
|
<script>
|
|
1369
1411
|
const $ = (id) => document.getElementById(id);
|
|
@@ -1456,6 +1498,7 @@ function pageHtml() {
|
|
|
1456
1498
|
.result-note { font-size:12.5px; color:var(--muted); text-align:center; margin-top:-6px; }
|
|
1457
1499
|
@keyframes draw { to { stroke-dashoffset:0; } }
|
|
1458
1500
|
@keyframes pop { 0%{transform:scale(.5);opacity:0;} 60%{transform:scale(1.06);} 100%{transform:scale(1);opacity:1;} }
|
|
1501
|
+
.version { text-align:center; color:var(--muted); font-size:11px; margin:14px 0 0; letter-spacing:.02em; }
|
|
1459
1502
|
@media (max-width:520px) { .actions{flex-direction:column;} button{width:100%;} }
|
|
1460
1503
|
</style>
|
|
1461
1504
|
</head>
|
|
@@ -1487,6 +1530,7 @@ function pageHtml() {
|
|
|
1487
1530
|
<button class="primary" id="next">Sign in with Leadbay</button>
|
|
1488
1531
|
</div>
|
|
1489
1532
|
</div>
|
|
1533
|
+
<p class="version">v${VERSION}</p>
|
|
1490
1534
|
</main>
|
|
1491
1535
|
<script>
|
|
1492
1536
|
const $ = (id) => document.getElementById(id);
|
|
@@ -1664,7 +1708,7 @@ function startUninstallerGui(options = {}) {
|
|
|
1664
1708
|
return false;
|
|
1665
1709
|
}, "uninstaller");
|
|
1666
1710
|
}
|
|
1667
|
-
var PORT, sessions, OAUTH_BASE_URLS, LOCAL_BIN_PATH;
|
|
1711
|
+
var VERSION, PORT, sessions, OAUTH_BASE_URLS, LOCAL_BIN_PATH;
|
|
1668
1712
|
var init_installer_gui = __esm({
|
|
1669
1713
|
"installer/installer-gui.ts"() {
|
|
1670
1714
|
"use strict";
|
|
@@ -1674,6 +1718,7 @@ var init_installer_gui = __esm({
|
|
|
1674
1718
|
init_install_dxt();
|
|
1675
1719
|
init_install_shared();
|
|
1676
1720
|
init_oauth();
|
|
1721
|
+
VERSION = true ? "0.23.2" : "0.0.0-dev";
|
|
1677
1722
|
PORT = Number(process.env.LEADBAY_INSTALLER_PORT ?? 0);
|
|
1678
1723
|
sessions = /* @__PURE__ */ new Map();
|
|
1679
1724
|
OAUTH_BASE_URLS = {
|
package/dist/installer-gui.js
CHANGED
|
@@ -82,11 +82,11 @@ async function uninstallFromClaudeCode() {
|
|
|
82
82
|
// installer/install-json-config.ts
|
|
83
83
|
async function installInJsonConfig(configPath, token, region, includeWrite, telemetryEnabled, localBinPath) {
|
|
84
84
|
try {
|
|
85
|
-
const { readFileSync: readFileSync3, writeFileSync, existsSync:
|
|
85
|
+
const { readFileSync: readFileSync3, writeFileSync, existsSync: existsSync4, mkdirSync, statSync } = await import("fs");
|
|
86
86
|
const { dirname } = await import("path");
|
|
87
87
|
let parsed = {};
|
|
88
88
|
let preserved = {};
|
|
89
|
-
const existed =
|
|
89
|
+
const existed = existsSync4(configPath);
|
|
90
90
|
if (existed) {
|
|
91
91
|
const raw = readFileSync3(configPath, "utf8");
|
|
92
92
|
try {
|
|
@@ -136,8 +136,8 @@ function stripJsonMcpEntry(existing) {
|
|
|
136
136
|
}
|
|
137
137
|
async function uninstallFromJsonConfig(configPath) {
|
|
138
138
|
try {
|
|
139
|
-
const { existsSync:
|
|
140
|
-
if (!
|
|
139
|
+
const { existsSync: existsSync4, readFileSync: readFileSync3, writeFileSync } = await import("fs");
|
|
140
|
+
if (!existsSync4(configPath)) return { ok: true, message: "config not found \u2014 nothing to do" };
|
|
141
141
|
const existing = readFileSync3(configPath, "utf8");
|
|
142
142
|
const { content, changed } = stripJsonMcpEntry(existing);
|
|
143
143
|
if (!changed) return { ok: true, message: "leadbay entry not present" };
|
|
@@ -220,10 +220,10 @@ function stripShellExportBlock(existing) {
|
|
|
220
220
|
}
|
|
221
221
|
async function installInCodexConfig(configPath, includeWrite, telemetryEnabled, localBinPath) {
|
|
222
222
|
try {
|
|
223
|
-
const { readFileSync: readFileSync3, writeFileSync, existsSync:
|
|
223
|
+
const { readFileSync: readFileSync3, writeFileSync, existsSync: existsSync4, mkdirSync, statSync, renameSync, chmodSync } = await import("fs");
|
|
224
224
|
const { dirname } = await import("path");
|
|
225
225
|
let existing = "";
|
|
226
|
-
const existed =
|
|
226
|
+
const existed = existsSync4(configPath);
|
|
227
227
|
if (existed) {
|
|
228
228
|
existing = readFileSync3(configPath, "utf8");
|
|
229
229
|
} else {
|
|
@@ -269,15 +269,15 @@ async function appendShellExports(token, region, includeWrite, telemetryEnabled)
|
|
|
269
269
|
}
|
|
270
270
|
return { ok: true, message: "env exported with setx; restart Codex/terminal" };
|
|
271
271
|
}
|
|
272
|
-
const { existsSync:
|
|
272
|
+
const { existsSync: existsSync4, readFileSync: readFileSync3, writeFileSync, renameSync } = await import("fs");
|
|
273
273
|
const os = await import("os");
|
|
274
274
|
const home = os.homedir();
|
|
275
|
-
const preferred = [`${home}/.zshrc`, `${home}/.bashrc`].filter((path) =>
|
|
275
|
+
const preferred = [`${home}/.zshrc`, `${home}/.bashrc`].filter((path) => existsSync4(path));
|
|
276
276
|
const paths = preferred.length ? preferred : [`${home}/.profile`];
|
|
277
277
|
const block = buildShellExportBlock(token, region, includeWrite, telemetryEnabled);
|
|
278
278
|
const updated = [];
|
|
279
279
|
for (const path of paths) {
|
|
280
|
-
const existing =
|
|
280
|
+
const existing = existsSync4(path) ? readFileSync3(path, "utf8") : "";
|
|
281
281
|
const merged = mergeShellExportBlock(existing, block);
|
|
282
282
|
if (!merged.changed) continue;
|
|
283
283
|
const tmp = `${path}.leadbay.tmp`;
|
|
@@ -295,8 +295,8 @@ async function appendShellExports(token, region, includeWrite, telemetryEnabled)
|
|
|
295
295
|
}
|
|
296
296
|
async function uninstallFromCodexConfig(configPath) {
|
|
297
297
|
try {
|
|
298
|
-
const { existsSync:
|
|
299
|
-
if (!
|
|
298
|
+
const { existsSync: existsSync4, readFileSync: readFileSync3, writeFileSync } = await import("fs");
|
|
299
|
+
if (!existsSync4(configPath)) return { ok: true, message: "config not found \u2014 nothing to do" };
|
|
300
300
|
const existing = readFileSync3(configPath, "utf8");
|
|
301
301
|
const { content, changed } = stripCodexBlock(existing);
|
|
302
302
|
if (!changed) return { ok: true, message: "leadbay block not present" };
|
|
@@ -308,11 +308,11 @@ async function uninstallFromCodexConfig(configPath) {
|
|
|
308
308
|
}
|
|
309
309
|
async function uninstallShellExports() {
|
|
310
310
|
try {
|
|
311
|
-
const { existsSync:
|
|
311
|
+
const { existsSync: existsSync4, readFileSync: readFileSync3, writeFileSync, renameSync } = await import("fs");
|
|
312
312
|
const os = await import("os");
|
|
313
313
|
const home = os.homedir();
|
|
314
314
|
const candidates = [`${home}/.zshrc`, `${home}/.bashrc`, `${home}/.profile`].filter(
|
|
315
|
-
(p) =>
|
|
315
|
+
(p) => existsSync4(p)
|
|
316
316
|
);
|
|
317
317
|
const updated = [];
|
|
318
318
|
for (const p of candidates) {
|
|
@@ -337,17 +337,17 @@ async function uninstallShellExports() {
|
|
|
337
337
|
var DXT_EXTENSION_ID = "local.dxt.leadbay.leadbay";
|
|
338
338
|
async function removeDxtExtension(claudeSupportDir) {
|
|
339
339
|
try {
|
|
340
|
-
const { existsSync:
|
|
340
|
+
const { existsSync: existsSync4, readFileSync: readFileSync3, writeFileSync, rmSync } = await import("fs");
|
|
341
341
|
const { join: join2 } = await import("path");
|
|
342
342
|
const extensionDir = join2(claudeSupportDir, "Claude Extensions", DXT_EXTENSION_ID);
|
|
343
343
|
const registryPath = join2(claudeSupportDir, "extensions-installations.json");
|
|
344
344
|
let removedDir = false;
|
|
345
345
|
let removedEntry = false;
|
|
346
|
-
if (
|
|
346
|
+
if (existsSync4(extensionDir)) {
|
|
347
347
|
rmSync(extensionDir, { recursive: true, force: true });
|
|
348
348
|
removedDir = true;
|
|
349
349
|
}
|
|
350
|
-
if (
|
|
350
|
+
if (existsSync4(registryPath)) {
|
|
351
351
|
try {
|
|
352
352
|
const raw = readFileSync3(registryPath, "utf8");
|
|
353
353
|
const parsed = JSON.parse(raw);
|
|
@@ -374,7 +374,7 @@ async function removeDxtExtension(claudeSupportDir) {
|
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
// installer/installer-gui.ts
|
|
377
|
-
import { existsSync as
|
|
377
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
378
378
|
|
|
379
379
|
// installer/install-shared.ts
|
|
380
380
|
import { spawn as spawn2 } from "child_process";
|
|
@@ -523,7 +523,7 @@ import { createHash, randomBytes } from "crypto";
|
|
|
523
523
|
import { createServer } from "http";
|
|
524
524
|
import { request as httpsRequestRaw } from "https";
|
|
525
525
|
import { spawn as spawn3 } from "child_process";
|
|
526
|
-
import { readdirSync } from "fs";
|
|
526
|
+
import { readdirSync, existsSync as existsSync2 } from "fs";
|
|
527
527
|
var LEADBAY_LOOPBACK_PORTS = [51789, 51790, 51791, 51792];
|
|
528
528
|
var BrowserOpenFailedError = class extends Error {
|
|
529
529
|
authorizeUrl;
|
|
@@ -843,7 +843,19 @@ function browserOpenCandidates(url) {
|
|
|
843
843
|
function browserLaunchEnv(debug) {
|
|
844
844
|
const env = { ...process.env };
|
|
845
845
|
if (process.platform !== "linux") return env;
|
|
846
|
-
|
|
846
|
+
let runtimeDir = env.XDG_RUNTIME_DIR;
|
|
847
|
+
if (!runtimeDir || !existsSync2(runtimeDir)) {
|
|
848
|
+
try {
|
|
849
|
+
const uid = process.getuid?.();
|
|
850
|
+
const candidate = uid !== void 0 ? `/run/user/${uid}` : void 0;
|
|
851
|
+
if (candidate && existsSync2(candidate)) {
|
|
852
|
+
runtimeDir = candidate;
|
|
853
|
+
env.XDG_RUNTIME_DIR = candidate;
|
|
854
|
+
debug?.(`browserLaunchEnv: injected XDG_RUNTIME_DIR=${candidate}`);
|
|
855
|
+
}
|
|
856
|
+
} catch {
|
|
857
|
+
}
|
|
858
|
+
}
|
|
847
859
|
if (!env.WAYLAND_DISPLAY && runtimeDir) {
|
|
848
860
|
try {
|
|
849
861
|
const sock = readdirSync(runtimeDir).find((f) => /^wayland-\d+$/.test(f));
|
|
@@ -854,6 +866,13 @@ function browserLaunchEnv(debug) {
|
|
|
854
866
|
} catch {
|
|
855
867
|
}
|
|
856
868
|
}
|
|
869
|
+
if (!env.DBUS_SESSION_BUS_ADDRESS && runtimeDir) {
|
|
870
|
+
const busPath = `${runtimeDir}/bus`;
|
|
871
|
+
if (existsSync2(busPath)) {
|
|
872
|
+
env.DBUS_SESSION_BUS_ADDRESS = `unix:path=${busPath}`;
|
|
873
|
+
debug?.(`browserLaunchEnv: injected DBUS_SESSION_BUS_ADDRESS=unix:path=${busPath}`);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
857
876
|
if (!env.DISPLAY) {
|
|
858
877
|
try {
|
|
859
878
|
const x = readdirSync("/tmp/.X11-unix").map((f) => f.match(/^X(\d+)$/)?.[1]).filter((n) => !!n).sort((a, b) => Number(a) - Number(b))[0];
|
|
@@ -863,6 +882,25 @@ function browserLaunchEnv(debug) {
|
|
|
863
882
|
}
|
|
864
883
|
debug?.(`browserLaunchEnv: injected DISPLAY=${env.DISPLAY}`);
|
|
865
884
|
}
|
|
885
|
+
if (!env.XAUTHORITY) {
|
|
886
|
+
try {
|
|
887
|
+
let xauth;
|
|
888
|
+
if (runtimeDir) {
|
|
889
|
+
const cookie = readdirSync(runtimeDir).find(
|
|
890
|
+
(f) => /^\.mutter-Xwaylandauth\./.test(f)
|
|
891
|
+
);
|
|
892
|
+
if (cookie) xauth = `${runtimeDir}/${cookie}`;
|
|
893
|
+
}
|
|
894
|
+
if (!xauth && env.HOME && existsSync2(`${env.HOME}/.Xauthority`)) {
|
|
895
|
+
xauth = `${env.HOME}/.Xauthority`;
|
|
896
|
+
}
|
|
897
|
+
if (xauth) {
|
|
898
|
+
env.XAUTHORITY = xauth;
|
|
899
|
+
debug?.(`browserLaunchEnv: injected XAUTHORITY=${xauth}`);
|
|
900
|
+
}
|
|
901
|
+
} catch {
|
|
902
|
+
}
|
|
903
|
+
}
|
|
866
904
|
return env;
|
|
867
905
|
}
|
|
868
906
|
async function openInBrowser(url, debug) {
|
|
@@ -974,6 +1012,7 @@ async function oauthLogin(opts) {
|
|
|
974
1012
|
}
|
|
975
1013
|
|
|
976
1014
|
// installer/installer-gui.ts
|
|
1015
|
+
var VERSION = true ? "0.23.2" : "0.0.0-dev";
|
|
977
1016
|
var PORT = Number(process.env.LEADBAY_INSTALLER_PORT ?? 0);
|
|
978
1017
|
var sessions = /* @__PURE__ */ new Map();
|
|
979
1018
|
var OAUTH_BASE_URLS = {
|
|
@@ -988,7 +1027,7 @@ async function isLeadbayConfigured(client) {
|
|
|
988
1027
|
}
|
|
989
1028
|
if (client.id === "codex") {
|
|
990
1029
|
const configPath2 = client.detail;
|
|
991
|
-
if (!
|
|
1030
|
+
if (!existsSync3(configPath2)) return false;
|
|
992
1031
|
try {
|
|
993
1032
|
return readFileSync2(configPath2, "utf8").includes("[mcp_servers.leadbay]");
|
|
994
1033
|
} catch {
|
|
@@ -997,7 +1036,7 @@ async function isLeadbayConfigured(client) {
|
|
|
997
1036
|
}
|
|
998
1037
|
if (client.id === "chatgpt-desktop") return false;
|
|
999
1038
|
const configPath = client.configPath;
|
|
1000
|
-
if (!configPath || !
|
|
1039
|
+
if (!configPath || !existsSync3(configPath)) return false;
|
|
1001
1040
|
try {
|
|
1002
1041
|
const parsed = JSON.parse(readFileSync2(configPath, "utf8"));
|
|
1003
1042
|
return Boolean(parsed?.mcpServers?.leadbay);
|
|
@@ -1306,6 +1345,7 @@ function pageUninstallHtml() {
|
|
|
1306
1345
|
.result-note { font-size:12.5px; color:var(--muted); text-align:center; margin-top:-6px; }
|
|
1307
1346
|
@keyframes draw { to { stroke-dashoffset:0; } }
|
|
1308
1347
|
@keyframes pop { 0%{transform:scale(.5);opacity:0;} 60%{transform:scale(1.06);} 100%{transform:scale(1);opacity:1;} }
|
|
1348
|
+
.version { text-align:center; color:var(--muted); font-size:11px; margin:14px 0 0; letter-spacing:.02em; }
|
|
1309
1349
|
@media (max-width:520px) { .actions{flex-direction:column;} button{width:100%;} }
|
|
1310
1350
|
</style>
|
|
1311
1351
|
</head>
|
|
@@ -1337,6 +1377,7 @@ function pageUninstallHtml() {
|
|
|
1337
1377
|
<button class="danger" id="next">Remove selected</button>
|
|
1338
1378
|
</div>
|
|
1339
1379
|
</div>
|
|
1380
|
+
<p class="version">v${VERSION}</p>
|
|
1340
1381
|
</main>
|
|
1341
1382
|
<script>
|
|
1342
1383
|
const $ = (id) => document.getElementById(id);
|
|
@@ -1429,6 +1470,7 @@ function pageHtml() {
|
|
|
1429
1470
|
.result-note { font-size:12.5px; color:var(--muted); text-align:center; margin-top:-6px; }
|
|
1430
1471
|
@keyframes draw { to { stroke-dashoffset:0; } }
|
|
1431
1472
|
@keyframes pop { 0%{transform:scale(.5);opacity:0;} 60%{transform:scale(1.06);} 100%{transform:scale(1);opacity:1;} }
|
|
1473
|
+
.version { text-align:center; color:var(--muted); font-size:11px; margin:14px 0 0; letter-spacing:.02em; }
|
|
1432
1474
|
@media (max-width:520px) { .actions{flex-direction:column;} button{width:100%;} }
|
|
1433
1475
|
</style>
|
|
1434
1476
|
</head>
|
|
@@ -1460,6 +1502,7 @@ function pageHtml() {
|
|
|
1460
1502
|
<button class="primary" id="next">Sign in with Leadbay</button>
|
|
1461
1503
|
</div>
|
|
1462
1504
|
</div>
|
|
1505
|
+
<p class="version">v${VERSION}</p>
|
|
1463
1506
|
</main>
|
|
1464
1507
|
<script>
|
|
1465
1508
|
const $ = (id) => document.getElementById(id);
|
|
@@ -1639,6 +1682,8 @@ function startUninstallerGui(options = {}) {
|
|
|
1639
1682
|
}
|
|
1640
1683
|
export {
|
|
1641
1684
|
install,
|
|
1685
|
+
pageHtml,
|
|
1686
|
+
pageUninstallHtml,
|
|
1642
1687
|
sanitizeOutput,
|
|
1643
1688
|
startInstallerGui,
|
|
1644
1689
|
startUninstallerGui
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leadbay/mcp",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.2",
|
|
4
4
|
"mcpName": "io.github.leadbay/leadbay-mcp",
|
|
5
5
|
"description": "Model Context Protocol (MCP) server for Leadbay — AI lead discovery, qualification, and enrichment for Claude Desktop, Cursor, and Claude Code.",
|
|
6
6
|
"type": "module",
|