@mcpcloud/cli 0.4.0-next-20260611161108 → 0.4.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/index.js +289 -214
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4151,9 +4151,83 @@ async function confirmUnset(bindingName, serverId) {
|
|
|
4151
4151
|
return ch === "y";
|
|
4152
4152
|
}
|
|
4153
4153
|
|
|
4154
|
+
// src/commands/servers-export.ts
|
|
4155
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
4156
|
+
import { dirname as dirname2, isAbsolute, join as join4, resolve as resolve2 } from "node:path";
|
|
4157
|
+
function formatBytes(bytes) {
|
|
4158
|
+
if (bytes < 1024)
|
|
4159
|
+
return `${bytes} B`;
|
|
4160
|
+
if (bytes < 1024 * 1024)
|
|
4161
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
4162
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
4163
|
+
}
|
|
4164
|
+
function assertSafeRelativePath(path) {
|
|
4165
|
+
if (isAbsolute(path) || path.split(/[\\/]/).includes("..")) {
|
|
4166
|
+
throw new Error(`Refusing to write unsafe bundle path: ${path}`);
|
|
4167
|
+
}
|
|
4168
|
+
}
|
|
4169
|
+
async function downloadTar(downloadPath) {
|
|
4170
|
+
requireApiKey();
|
|
4171
|
+
const url = new URL(downloadPath, getBaseUrl());
|
|
4172
|
+
const res = await fetch(url.toString(), {
|
|
4173
|
+
headers: { Authorization: `Bearer ${getApiKey()}` }
|
|
4174
|
+
});
|
|
4175
|
+
if (!res.ok) {
|
|
4176
|
+
throw new Error(`Bundle download failed (${res.status}).`);
|
|
4177
|
+
}
|
|
4178
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
4179
|
+
}
|
|
4180
|
+
function registerServerExportCommands(servers) {
|
|
4181
|
+
servers.command("export <serverId>").description("Export a self-host bundle (Dockerfile + node entry + config) for a server").option("--org <organizationId>", "Organization ID").requiredOption("--project <projectId>", "Project ID").option("--output <dir>", "Write the bundle files to a directory (default: ./<slug>)").option("--tar [file]", "Download the bundle as a single .tar instead").addHelpText("after", [
|
|
4182
|
+
"",
|
|
4183
|
+
"Examples:",
|
|
4184
|
+
" # Write the bundle into a directory and run it:",
|
|
4185
|
+
" $ mcp servers export srv_123 --project prj_123 --output ./my-server",
|
|
4186
|
+
" $ cd ./my-server && docker compose up --build",
|
|
4187
|
+
"",
|
|
4188
|
+
" # Download a single .tar:",
|
|
4189
|
+
" $ mcp servers export srv_123 --project prj_123 --tar my-server.tar"
|
|
4190
|
+
].join(`
|
|
4191
|
+
`)).action(runAction(async (serverId, opts) => {
|
|
4192
|
+
const organizationId = await resolveOrgId(opts.org);
|
|
4193
|
+
const result = await api.post("/api/v1/server/self-host-export", { organizationId, projectId: opts.project, serverId });
|
|
4194
|
+
const summary = {
|
|
4195
|
+
artifactId: result.artifactId,
|
|
4196
|
+
downloadPath: result.downloadPath,
|
|
4197
|
+
fileCount: result.fileCount,
|
|
4198
|
+
byteSize: result.byteSize,
|
|
4199
|
+
server: result.server
|
|
4200
|
+
};
|
|
4201
|
+
if (opts.tar !== undefined) {
|
|
4202
|
+
const tarPath = resolve2(typeof opts.tar === "string" ? opts.tar : `${result.server.slug}.tar`);
|
|
4203
|
+
writeFileSync2(tarPath, await downloadTar(result.downloadPath));
|
|
4204
|
+
if (isJsonMode()) {
|
|
4205
|
+
printJson({ ...summary, output: tarPath });
|
|
4206
|
+
return;
|
|
4207
|
+
}
|
|
4208
|
+
printSuccess(`Downloaded self-host bundle (${result.fileCount} files, ${formatBytes(result.byteSize)}) to ${tarPath}.`);
|
|
4209
|
+
printKeyValue({ Unpack: `tar xf ${tarPath} && docker compose up --build` });
|
|
4210
|
+
return;
|
|
4211
|
+
}
|
|
4212
|
+
const dir = resolve2(opts.output ?? `./${result.server.slug}`);
|
|
4213
|
+
for (const file of result.files) {
|
|
4214
|
+
assertSafeRelativePath(file.path);
|
|
4215
|
+
const full = join4(dir, file.path);
|
|
4216
|
+
mkdirSync3(dirname2(full), { recursive: true });
|
|
4217
|
+
writeFileSync2(full, file.content);
|
|
4218
|
+
}
|
|
4219
|
+
if (isJsonMode()) {
|
|
4220
|
+
printJson({ ...summary, output: dir });
|
|
4221
|
+
return;
|
|
4222
|
+
}
|
|
4223
|
+
printSuccess(`Exported ${result.fileCount} files (${formatBytes(result.byteSize)}) to ${dir}.`);
|
|
4224
|
+
printKeyValue({ "Run it": `cd ${dir} && docker compose up --build` });
|
|
4225
|
+
}));
|
|
4226
|
+
}
|
|
4227
|
+
|
|
4154
4228
|
// src/commands/servers-lifecycle.ts
|
|
4155
4229
|
import { existsSync as existsSync5 } from "node:fs";
|
|
4156
|
-
import { isAbsolute, resolve as
|
|
4230
|
+
import { isAbsolute as isAbsolute2, resolve as resolve3 } from "node:path";
|
|
4157
4231
|
|
|
4158
4232
|
// src/lib/dev/spec-watcher.ts
|
|
4159
4233
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -4162,7 +4236,7 @@ import {
|
|
|
4162
4236
|
readFileSync as readFileSync4,
|
|
4163
4237
|
watch as fsWatch
|
|
4164
4238
|
} from "node:fs";
|
|
4165
|
-
import { dirname as
|
|
4239
|
+
import { dirname as dirname3 } from "node:path";
|
|
4166
4240
|
async function regenerateDevBundle(args) {
|
|
4167
4241
|
try {
|
|
4168
4242
|
const response = await api.post("/api/v1/server/dev-bundle", {
|
|
@@ -4221,7 +4295,7 @@ function watchSpecFile(options) {
|
|
|
4221
4295
|
let lastHash = null;
|
|
4222
4296
|
let pendingTimer = null;
|
|
4223
4297
|
let closed = false;
|
|
4224
|
-
const dir =
|
|
4298
|
+
const dir = dirname3(options.specPath);
|
|
4225
4299
|
const baseName = options.specPath.slice(dir.length + 1);
|
|
4226
4300
|
const fire = () => {
|
|
4227
4301
|
if (closed)
|
|
@@ -4398,7 +4472,7 @@ function registerServerLifecycleCommands(servers) {
|
|
|
4398
4472
|
].join(`
|
|
4399
4473
|
`)).action(runAction(async (serverId, opts) => {
|
|
4400
4474
|
const cwd = process.cwd();
|
|
4401
|
-
const specPath =
|
|
4475
|
+
const specPath = isAbsolute2(opts.spec) ? opts.spec : resolve3(cwd, opts.spec);
|
|
4402
4476
|
if (!existsSync5(specPath)) {
|
|
4403
4477
|
throw new Error(`Spec file not found: ${specPath}`);
|
|
4404
4478
|
}
|
|
@@ -4904,6 +4978,7 @@ function registerServerTestCommands(servers) {
|
|
|
4904
4978
|
function registerServerCommands(program2) {
|
|
4905
4979
|
const servers = program2.command("servers").description("Manage MCP servers");
|
|
4906
4980
|
registerServerEnvCommands(servers);
|
|
4981
|
+
registerServerExportCommands(servers);
|
|
4907
4982
|
registerServerLifecycleCommands(servers);
|
|
4908
4983
|
registerServerMutationCommands(servers);
|
|
4909
4984
|
registerServerTestCommands(servers);
|
|
@@ -5093,35 +5168,35 @@ import { relative } from "node:path";
|
|
|
5093
5168
|
// src/lib/dev/handlers-sync.ts
|
|
5094
5169
|
import {
|
|
5095
5170
|
existsSync as existsSync8,
|
|
5096
|
-
mkdirSync as
|
|
5171
|
+
mkdirSync as mkdirSync6,
|
|
5097
5172
|
readFileSync as readFileSync7,
|
|
5098
5173
|
statSync,
|
|
5099
|
-
writeFileSync as
|
|
5174
|
+
writeFileSync as writeFileSync5
|
|
5100
5175
|
} from "node:fs";
|
|
5101
5176
|
import { createHash as createHash3 } from "node:crypto";
|
|
5102
|
-
import { dirname as
|
|
5177
|
+
import { dirname as dirname4, join as join7 } from "node:path";
|
|
5103
5178
|
|
|
5104
5179
|
// src/lib/dev/state.ts
|
|
5105
|
-
import { existsSync as existsSync6, mkdirSync as
|
|
5106
|
-
import { join as
|
|
5180
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
5181
|
+
import { join as join5, resolve as resolve4 } from "node:path";
|
|
5107
5182
|
function devRoot(cwd) {
|
|
5108
|
-
return
|
|
5183
|
+
return join5(cwd, ".mcpcloud");
|
|
5109
5184
|
}
|
|
5110
5185
|
function stateFile(cwd) {
|
|
5111
|
-
return
|
|
5186
|
+
return join5(devRoot(cwd), "state.json");
|
|
5112
5187
|
}
|
|
5113
5188
|
function serverDir(cwd) {
|
|
5114
|
-
return
|
|
5189
|
+
return join5(devRoot(cwd), "server");
|
|
5115
5190
|
}
|
|
5116
5191
|
function gitCloneDir(cwd, owner, name) {
|
|
5117
5192
|
const safe = `${owner}__${name}`.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
5118
|
-
return
|
|
5193
|
+
return join5(devRoot(cwd), "git", safe);
|
|
5119
5194
|
}
|
|
5120
5195
|
function envFile(cwd) {
|
|
5121
|
-
return
|
|
5196
|
+
return join5(devRoot(cwd), "env.json");
|
|
5122
5197
|
}
|
|
5123
5198
|
function backupsDir(cwd) {
|
|
5124
|
-
return
|
|
5199
|
+
return join5(devRoot(cwd), "agent-backups");
|
|
5125
5200
|
}
|
|
5126
5201
|
function readState(cwd) {
|
|
5127
5202
|
const path = stateFile(cwd);
|
|
@@ -5142,18 +5217,18 @@ function readState(cwd) {
|
|
|
5142
5217
|
}
|
|
5143
5218
|
function writeState(cwd, state) {
|
|
5144
5219
|
if (!existsSync6(devRoot(cwd))) {
|
|
5145
|
-
|
|
5220
|
+
mkdirSync4(devRoot(cwd), { recursive: true });
|
|
5146
5221
|
}
|
|
5147
|
-
|
|
5222
|
+
writeFileSync3(stateFile(cwd), JSON.stringify(state, null, 2), "utf-8");
|
|
5148
5223
|
}
|
|
5149
5224
|
function ensureGitignore(cwd) {
|
|
5150
|
-
const ignoreFile =
|
|
5225
|
+
const ignoreFile = join5(devRoot(cwd), ".gitignore");
|
|
5151
5226
|
if (existsSync6(ignoreFile))
|
|
5152
5227
|
return;
|
|
5153
5228
|
if (!existsSync6(devRoot(cwd))) {
|
|
5154
|
-
|
|
5229
|
+
mkdirSync4(devRoot(cwd), { recursive: true });
|
|
5155
5230
|
}
|
|
5156
|
-
|
|
5231
|
+
writeFileSync3(ignoreFile, [
|
|
5157
5232
|
"# generated by `mcp dev`",
|
|
5158
5233
|
"server/",
|
|
5159
5234
|
"git/",
|
|
@@ -5168,13 +5243,13 @@ function ensureGitignore(cwd) {
|
|
|
5168
5243
|
// src/lib/dev/tools-sync.ts
|
|
5169
5244
|
import {
|
|
5170
5245
|
existsSync as existsSync7,
|
|
5171
|
-
mkdirSync as
|
|
5246
|
+
mkdirSync as mkdirSync5,
|
|
5172
5247
|
readFileSync as readFileSync6,
|
|
5173
5248
|
readdirSync,
|
|
5174
5249
|
rmSync,
|
|
5175
|
-
writeFileSync as
|
|
5250
|
+
writeFileSync as writeFileSync4
|
|
5176
5251
|
} from "node:fs";
|
|
5177
|
-
import { join as
|
|
5252
|
+
import { join as join6 } from "node:path";
|
|
5178
5253
|
var TOOLS_DIR_NAME = "tools";
|
|
5179
5254
|
var RISK_CLASSES = [
|
|
5180
5255
|
"read",
|
|
@@ -5183,10 +5258,10 @@ var RISK_CLASSES = [
|
|
|
5183
5258
|
"external_effect"
|
|
5184
5259
|
];
|
|
5185
5260
|
function toolsDir(devRootDir) {
|
|
5186
|
-
return
|
|
5261
|
+
return join6(devRootDir, TOOLS_DIR_NAME);
|
|
5187
5262
|
}
|
|
5188
5263
|
function serverToolsDir(devRootDir, serverId) {
|
|
5189
|
-
return
|
|
5264
|
+
return join6(toolsDir(devRootDir), serverId);
|
|
5190
5265
|
}
|
|
5191
5266
|
function escapeFrontmatterScalar(raw) {
|
|
5192
5267
|
if (raw === "")
|
|
@@ -5376,7 +5451,7 @@ function arraysEqual(a, b) {
|
|
|
5376
5451
|
}
|
|
5377
5452
|
var STATE_FILE = ".tools-state.json";
|
|
5378
5453
|
function toolsStateFile(devRootDir, serverId) {
|
|
5379
|
-
return
|
|
5454
|
+
return join6(serverToolsDir(devRootDir, serverId), STATE_FILE);
|
|
5380
5455
|
}
|
|
5381
5456
|
function readToolsState(devRootDir, serverId) {
|
|
5382
5457
|
const file = toolsStateFile(devRootDir, serverId);
|
|
@@ -5398,8 +5473,8 @@ function readToolsState(devRootDir, serverId) {
|
|
|
5398
5473
|
function writeToolsState(devRootDir, state) {
|
|
5399
5474
|
const dir = serverToolsDir(devRootDir, state.serverId);
|
|
5400
5475
|
if (!existsSync7(dir))
|
|
5401
|
-
|
|
5402
|
-
|
|
5476
|
+
mkdirSync5(dir, { recursive: true });
|
|
5477
|
+
writeFileSync4(toolsStateFile(devRootDir, state.serverId), JSON.stringify(state, null, 2), "utf-8");
|
|
5403
5478
|
}
|
|
5404
5479
|
function hashLocalView(view) {
|
|
5405
5480
|
return JSON.stringify({
|
|
@@ -5412,13 +5487,13 @@ function hashLocalView(view) {
|
|
|
5412
5487
|
function materializeTools(args) {
|
|
5413
5488
|
const dir = serverToolsDir(args.devRootDir, args.serverId);
|
|
5414
5489
|
if (!existsSync7(dir))
|
|
5415
|
-
|
|
5490
|
+
mkdirSync5(dir, { recursive: true });
|
|
5416
5491
|
const kept = new Set;
|
|
5417
5492
|
let filesWritten = 0;
|
|
5418
5493
|
for (const tool of args.tools) {
|
|
5419
5494
|
const filename = `${tool.name}.md`;
|
|
5420
5495
|
kept.add(filename);
|
|
5421
|
-
|
|
5496
|
+
writeFileSync4(join6(dir, filename), renderToolMarkdown(tool), "utf-8");
|
|
5422
5497
|
filesWritten += 1;
|
|
5423
5498
|
}
|
|
5424
5499
|
let filesRemoved = 0;
|
|
@@ -5430,7 +5505,7 @@ function materializeTools(args) {
|
|
|
5430
5505
|
if (kept.has(entry))
|
|
5431
5506
|
continue;
|
|
5432
5507
|
try {
|
|
5433
|
-
rmSync(
|
|
5508
|
+
rmSync(join6(dir, entry), { force: true });
|
|
5434
5509
|
filesRemoved += 1;
|
|
5435
5510
|
} catch {}
|
|
5436
5511
|
}
|
|
@@ -5456,7 +5531,7 @@ function materializeTools(args) {
|
|
|
5456
5531
|
return { filesWritten, filesRemoved };
|
|
5457
5532
|
}
|
|
5458
5533
|
function readLocalTool(devRootDir, serverId, toolName) {
|
|
5459
|
-
const filePath =
|
|
5534
|
+
const filePath = join6(serverToolsDir(devRootDir, serverId), `${toolName}.md`);
|
|
5460
5535
|
if (!existsSync7(filePath))
|
|
5461
5536
|
return null;
|
|
5462
5537
|
const state = readToolsState(devRootDir, serverId);
|
|
@@ -5493,7 +5568,7 @@ async function pushLocalToolEdit(args) {
|
|
|
5493
5568
|
};
|
|
5494
5569
|
}
|
|
5495
5570
|
if (!local) {
|
|
5496
|
-
const filePath =
|
|
5571
|
+
const filePath = join6(serverToolsDir(args.devRootDir, args.serverId), `${args.toolName}.md`);
|
|
5497
5572
|
if (!existsSync7(filePath))
|
|
5498
5573
|
return { kind: "missing-file" };
|
|
5499
5574
|
return { kind: "unknown-tool" };
|
|
@@ -5577,7 +5652,7 @@ function toKebabSlug(value) {
|
|
|
5577
5652
|
return value.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase() || "generated-mcp-server";
|
|
5578
5653
|
}
|
|
5579
5654
|
function serverBundleHandlersDir(devRootDir) {
|
|
5580
|
-
return
|
|
5655
|
+
return join7(devRootDir, "server", "src", "tools");
|
|
5581
5656
|
}
|
|
5582
5657
|
function handlerSlugFromWatcherPath(rel) {
|
|
5583
5658
|
if (!rel)
|
|
@@ -5606,7 +5681,7 @@ function hashSource(source) {
|
|
|
5606
5681
|
}
|
|
5607
5682
|
var lastPushedHash = new Map;
|
|
5608
5683
|
async function pushLocalHandlerEdit(args) {
|
|
5609
|
-
const filePath =
|
|
5684
|
+
const filePath = join7(serverBundleHandlersDir(args.devRootDir), `${args.slug}.ts`);
|
|
5610
5685
|
if (!existsSync8(filePath)) {
|
|
5611
5686
|
return { kind: "missing-file" };
|
|
5612
5687
|
}
|
|
@@ -5758,9 +5833,9 @@ async function resetCloudHandler(args) {
|
|
|
5758
5833
|
}
|
|
5759
5834
|
}
|
|
5760
5835
|
function writeLocalHandlerFromCloud(args) {
|
|
5761
|
-
const filePath =
|
|
5762
|
-
|
|
5763
|
-
|
|
5836
|
+
const filePath = join7(serverBundleHandlersDir(args.devRootDir), `${args.slug}.ts`);
|
|
5837
|
+
mkdirSync6(dirname4(filePath), { recursive: true });
|
|
5838
|
+
writeFileSync5(filePath, args.content, "utf-8");
|
|
5764
5839
|
lastPushedHash.set(filePath, hashSource(args.content));
|
|
5765
5840
|
return filePath;
|
|
5766
5841
|
}
|
|
@@ -5769,7 +5844,7 @@ function handlerSlugFromToolName(toolName) {
|
|
|
5769
5844
|
}
|
|
5770
5845
|
var RECENT_EDIT_WINDOW_MS = 5 * 60 * 1000;
|
|
5771
5846
|
function inspectLocalHandler(args) {
|
|
5772
|
-
const filePath =
|
|
5847
|
+
const filePath = join7(serverBundleHandlersDir(args.devRootDir), `${args.slug}.ts`);
|
|
5773
5848
|
if (!existsSync8(filePath))
|
|
5774
5849
|
return { kind: "no-local-file" };
|
|
5775
5850
|
const cached2 = lastPushedHash.get(filePath);
|
|
@@ -6071,13 +6146,13 @@ function renderBool(value) {
|
|
|
6071
6146
|
|
|
6072
6147
|
// src/commands/tools-edit.ts
|
|
6073
6148
|
import { existsSync as existsSync11 } from "node:fs";
|
|
6074
|
-
import { join as
|
|
6149
|
+
import { join as join9, relative as relative2 } from "node:path";
|
|
6075
6150
|
|
|
6076
6151
|
// src/lib/editor-shell.ts
|
|
6077
6152
|
import { spawn as spawn2 } from "node:child_process";
|
|
6078
6153
|
import { existsSync as existsSync10, readFileSync as readFileSync9 } from "node:fs";
|
|
6079
6154
|
import { platform as platform2 } from "node:os";
|
|
6080
|
-
import { delimiter, join as
|
|
6155
|
+
import { delimiter, join as join8 } from "node:path";
|
|
6081
6156
|
var DEFAULT_FALLBACKS = ["vi"];
|
|
6082
6157
|
function isExecutableFile(path) {
|
|
6083
6158
|
try {
|
|
@@ -6098,7 +6173,7 @@ function findOnPath(command) {
|
|
|
6098
6173
|
if (!dir)
|
|
6099
6174
|
continue;
|
|
6100
6175
|
for (const ext of exts) {
|
|
6101
|
-
const candidate =
|
|
6176
|
+
const candidate = join8(dir, command + ext);
|
|
6102
6177
|
if (isExecutableFile(candidate))
|
|
6103
6178
|
return candidate;
|
|
6104
6179
|
}
|
|
@@ -6119,10 +6194,10 @@ function resolveEditorCommand(args) {
|
|
|
6119
6194
|
return { command: DEFAULT_FALLBACKS[0], source: "fallback" };
|
|
6120
6195
|
}
|
|
6121
6196
|
function defaultRun(cmd, args) {
|
|
6122
|
-
return new Promise((
|
|
6197
|
+
return new Promise((resolve5, reject) => {
|
|
6123
6198
|
const child = spawn2(cmd, args, { stdio: "inherit" });
|
|
6124
6199
|
child.on("error", (err) => reject(err));
|
|
6125
|
-
child.on("exit", (code) =>
|
|
6200
|
+
child.on("exit", (code) => resolve5(code ?? 0));
|
|
6126
6201
|
});
|
|
6127
6202
|
}
|
|
6128
6203
|
async function runEditor(args) {
|
|
@@ -6134,8 +6209,8 @@ async function runEditor(args) {
|
|
|
6134
6209
|
};
|
|
6135
6210
|
}
|
|
6136
6211
|
const { command } = resolveEditorCommand({ command: args.command });
|
|
6137
|
-
const
|
|
6138
|
-
const resolved =
|
|
6212
|
+
const resolve5 = args.resolveCommand ?? findOnPath;
|
|
6213
|
+
const resolved = resolve5(command);
|
|
6139
6214
|
if (!resolved) {
|
|
6140
6215
|
return {
|
|
6141
6216
|
ok: false,
|
|
@@ -6194,7 +6269,7 @@ async function runToolsEdit(args) {
|
|
|
6194
6269
|
if (!ctx)
|
|
6195
6270
|
return;
|
|
6196
6271
|
const cwd = process.cwd();
|
|
6197
|
-
const filePath =
|
|
6272
|
+
const filePath = join9(serverToolsDir(devRoot(cwd), ctx.serverId), `${args.toolName}.md`);
|
|
6198
6273
|
if (!existsSync11(filePath)) {
|
|
6199
6274
|
printError(`Tool file not found: ${relative2(cwd, filePath)}`);
|
|
6200
6275
|
printInfo(` ${c.dim("Run")} ${c.bold(`mcp tools pull ${args.toolName}`)} ${c.dim("first to materialize it, or check the name is spelled correctly.")}`);
|
|
@@ -7536,13 +7611,13 @@ function registerSkillTestCommands(skills) {
|
|
|
7536
7611
|
|
|
7537
7612
|
// src/commands/skills.ts
|
|
7538
7613
|
async function runClaudeMcpAdd(connectionName, mcpUrl) {
|
|
7539
|
-
return new Promise((
|
|
7614
|
+
return new Promise((resolve5) => {
|
|
7540
7615
|
const child = spawn3("claude", ["mcp", "add", "--transport", "http", connectionName, mcpUrl], {
|
|
7541
7616
|
stdio: "inherit",
|
|
7542
7617
|
shell: false
|
|
7543
7618
|
});
|
|
7544
|
-
child.on("error", () =>
|
|
7545
|
-
child.on("exit", (code) =>
|
|
7619
|
+
child.on("error", () => resolve5(127));
|
|
7620
|
+
child.on("exit", (code) => resolve5(code ?? 1));
|
|
7546
7621
|
});
|
|
7547
7622
|
}
|
|
7548
7623
|
function registerSkillCommands(program2) {
|
|
@@ -7859,9 +7934,9 @@ function registerApiKeyCommands(program2) {
|
|
|
7859
7934
|
|
|
7860
7935
|
// src/commands/config.ts
|
|
7861
7936
|
import { homedir as homedir2 } from "node:os";
|
|
7862
|
-
import { join as
|
|
7937
|
+
import { join as join10 } from "node:path";
|
|
7863
7938
|
function configFilePath() {
|
|
7864
|
-
return
|
|
7939
|
+
return join10(homedir2(), ".mcpcloud", "config.json");
|
|
7865
7940
|
}
|
|
7866
7941
|
function previewKey2(key) {
|
|
7867
7942
|
if (!key)
|
|
@@ -8103,11 +8178,11 @@ function registerConfigCommands(program2) {
|
|
|
8103
8178
|
|
|
8104
8179
|
// src/commands/dev.ts
|
|
8105
8180
|
import { existsSync as existsSync32 } from "node:fs";
|
|
8106
|
-
import { isAbsolute as
|
|
8181
|
+
import { isAbsolute as isAbsolute3, relative as relative7, resolve as resolve7 } from "node:path";
|
|
8107
8182
|
|
|
8108
8183
|
// src/lib/mcp-invoke.ts
|
|
8109
8184
|
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
|
|
8110
|
-
import { resolve as
|
|
8185
|
+
import { resolve as resolve5 } from "node:path";
|
|
8111
8186
|
var DEFAULT_TIMEOUT_MS3 = 60000;
|
|
8112
8187
|
var invokeRequestId = 1;
|
|
8113
8188
|
async function invokeMcpTool(args) {
|
|
@@ -8244,7 +8319,7 @@ async function parseToolArguments(opts) {
|
|
|
8244
8319
|
const reader = opts.readStdin ?? defaultStdinReader;
|
|
8245
8320
|
source = await reader();
|
|
8246
8321
|
} else if (raw.startsWith("@")) {
|
|
8247
|
-
const filePath =
|
|
8322
|
+
const filePath = resolve5(opts.cwd ?? process.cwd(), raw.slice(1));
|
|
8248
8323
|
if (!existsSync12(filePath)) {
|
|
8249
8324
|
return { ok: false, reason: "file-not-found", path: filePath };
|
|
8250
8325
|
}
|
|
@@ -8325,29 +8400,29 @@ function truncateJsonPreview(value) {
|
|
|
8325
8400
|
// src/lib/dev/sessions.ts
|
|
8326
8401
|
import {
|
|
8327
8402
|
existsSync as existsSync13,
|
|
8328
|
-
mkdirSync as
|
|
8403
|
+
mkdirSync as mkdirSync7,
|
|
8329
8404
|
readFileSync as readFileSync11,
|
|
8330
8405
|
readdirSync as readdirSync2,
|
|
8331
8406
|
unlinkSync,
|
|
8332
|
-
writeFileSync as
|
|
8407
|
+
writeFileSync as writeFileSync6
|
|
8333
8408
|
} from "node:fs";
|
|
8334
8409
|
import { homedir as homedir3 } from "node:os";
|
|
8335
|
-
import { join as
|
|
8410
|
+
import { join as join11 } from "node:path";
|
|
8336
8411
|
var SESSIONS_DIR_NAME = "dev-sessions";
|
|
8337
8412
|
function sessionsDir() {
|
|
8338
|
-
return
|
|
8413
|
+
return join11(homedir3(), ".mcpcloud", SESSIONS_DIR_NAME);
|
|
8339
8414
|
}
|
|
8340
8415
|
function sessionFile(pid) {
|
|
8341
|
-
return
|
|
8416
|
+
return join11(sessionsDir(), `${pid}.json`);
|
|
8342
8417
|
}
|
|
8343
8418
|
function ensureDir() {
|
|
8344
8419
|
const dir = sessionsDir();
|
|
8345
8420
|
if (!existsSync13(dir))
|
|
8346
|
-
|
|
8421
|
+
mkdirSync7(dir, { recursive: true, mode: 448 });
|
|
8347
8422
|
}
|
|
8348
8423
|
function recordSession(record) {
|
|
8349
8424
|
ensureDir();
|
|
8350
|
-
|
|
8425
|
+
writeFileSync6(sessionFile(record.pid), JSON.stringify(record, null, 2), {
|
|
8351
8426
|
encoding: "utf-8",
|
|
8352
8427
|
mode: 384
|
|
8353
8428
|
});
|
|
@@ -8368,7 +8443,7 @@ function listSessions() {
|
|
|
8368
8443
|
for (const entry of readdirSync2(dir)) {
|
|
8369
8444
|
if (!entry.endsWith(".json"))
|
|
8370
8445
|
continue;
|
|
8371
|
-
const path =
|
|
8446
|
+
const path = join11(dir, entry);
|
|
8372
8447
|
try {
|
|
8373
8448
|
const parsed = JSON.parse(readFileSync11(path, "utf-8"));
|
|
8374
8449
|
if (typeof parsed.pid !== "number") {
|
|
@@ -8563,27 +8638,27 @@ function invokeResultToJson(result) {
|
|
|
8563
8638
|
import {
|
|
8564
8639
|
appendFileSync as appendFileSync2,
|
|
8565
8640
|
existsSync as existsSync14,
|
|
8566
|
-
mkdirSync as
|
|
8641
|
+
mkdirSync as mkdirSync8,
|
|
8567
8642
|
readFileSync as readFileSync12,
|
|
8568
8643
|
readdirSync as readdirSync3,
|
|
8569
8644
|
renameSync,
|
|
8570
8645
|
statSync as statSync2
|
|
8571
8646
|
} from "node:fs";
|
|
8572
|
-
import { join as
|
|
8647
|
+
import { join as join12 } from "node:path";
|
|
8573
8648
|
var INSPECTOR_DIRNAME = "inspector";
|
|
8574
8649
|
var ACTIVE_FILE = "calls.ndjson";
|
|
8575
8650
|
var ROTATED_PREFIX = "calls.";
|
|
8576
8651
|
var ROTATED_SUFFIX = ".ndjson";
|
|
8577
8652
|
var ROTATION_LIMIT_BYTES = 50 * 1024 * 1024;
|
|
8578
8653
|
function inspectorDir(cwd) {
|
|
8579
|
-
return
|
|
8654
|
+
return join12(devRoot(cwd), INSPECTOR_DIRNAME);
|
|
8580
8655
|
}
|
|
8581
8656
|
function ensureInspectorDir(dir) {
|
|
8582
8657
|
if (!existsSync14(dir))
|
|
8583
|
-
|
|
8658
|
+
mkdirSync8(dir, { recursive: true });
|
|
8584
8659
|
}
|
|
8585
8660
|
function activeFilePath(dir) {
|
|
8586
|
-
return
|
|
8661
|
+
return join12(dir, ACTIVE_FILE);
|
|
8587
8662
|
}
|
|
8588
8663
|
function isRotatedName(name) {
|
|
8589
8664
|
return name !== ACTIVE_FILE && name.startsWith(ROTATED_PREFIX) && name.endsWith(ROTATED_SUFFIX);
|
|
@@ -8593,7 +8668,7 @@ function listRotatedFiles(dir) {
|
|
|
8593
8668
|
return [];
|
|
8594
8669
|
const rotated = readdirSync3(dir).filter(isRotatedName);
|
|
8595
8670
|
rotated.sort();
|
|
8596
|
-
return rotated.map((n) =>
|
|
8671
|
+
return rotated.map((n) => join12(dir, n));
|
|
8597
8672
|
}
|
|
8598
8673
|
function parseLines(text) {
|
|
8599
8674
|
if (!text)
|
|
@@ -8818,7 +8893,7 @@ import {
|
|
|
8818
8893
|
closeSync,
|
|
8819
8894
|
statSync as statSync3
|
|
8820
8895
|
} from "node:fs";
|
|
8821
|
-
import { join as
|
|
8896
|
+
import { join as join13 } from "node:path";
|
|
8822
8897
|
var DEFAULT_INTERVAL_MS = 250;
|
|
8823
8898
|
var MAX_READ_CHUNK = 64 * 1024;
|
|
8824
8899
|
function registerDevTailCommand(dev) {
|
|
@@ -8827,7 +8902,7 @@ function registerDevTailCommand(dev) {
|
|
|
8827
8902
|
async function runDevTail(opts) {
|
|
8828
8903
|
const cwd = process.cwd();
|
|
8829
8904
|
const dir = inspectorDir(cwd);
|
|
8830
|
-
const activePath =
|
|
8905
|
+
const activePath = join13(dir, ACTIVE_FILE);
|
|
8831
8906
|
const intervalMs = parseInterval(opts.intervalMs);
|
|
8832
8907
|
if (!existsSync15(dir)) {
|
|
8833
8908
|
printInfo(`No inspector history yet at ${dir}. Run \`mcp dev\` to start capturing.`);
|
|
@@ -8935,7 +9010,7 @@ function emitLines(text, filter) {
|
|
|
8935
9010
|
}
|
|
8936
9011
|
}
|
|
8937
9012
|
function sleep(ms) {
|
|
8938
|
-
return new Promise((
|
|
9013
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
8939
9014
|
}
|
|
8940
9015
|
|
|
8941
9016
|
// ../../node_modules/.bun/@clack+core@1.3.1/node_modules/@clack/core/dist/index.mjs
|
|
@@ -10222,12 +10297,12 @@ async function runInteractiveBootstrap() {
|
|
|
10222
10297
|
// src/lib/dev/bundle-sync.ts
|
|
10223
10298
|
import {
|
|
10224
10299
|
existsSync as existsSync16,
|
|
10225
|
-
mkdirSync as
|
|
10300
|
+
mkdirSync as mkdirSync9,
|
|
10226
10301
|
readFileSync as readFileSync13,
|
|
10227
10302
|
rmSync as rmSync2,
|
|
10228
|
-
writeFileSync as
|
|
10303
|
+
writeFileSync as writeFileSync7
|
|
10229
10304
|
} from "node:fs";
|
|
10230
|
-
import { dirname as
|
|
10305
|
+
import { dirname as dirname5, join as join14 } from "node:path";
|
|
10231
10306
|
async function resolveServerProject(args) {
|
|
10232
10307
|
const data = await api.get("/api/v1/server", {
|
|
10233
10308
|
organizationId: args.organizationId,
|
|
@@ -10284,7 +10359,7 @@ async function fetchBundle(args) {
|
|
|
10284
10359
|
}
|
|
10285
10360
|
function materializeBundle(destDir, bundle, options = {}) {
|
|
10286
10361
|
if (!existsSync16(destDir)) {
|
|
10287
|
-
|
|
10362
|
+
mkdirSync9(destDir, { recursive: true });
|
|
10288
10363
|
}
|
|
10289
10364
|
const preserve = options.preservePaths;
|
|
10290
10365
|
const kept = new Set;
|
|
@@ -10299,9 +10374,9 @@ function materializeBundle(destDir, bundle, options = {}) {
|
|
|
10299
10374
|
preservedCount += 1;
|
|
10300
10375
|
continue;
|
|
10301
10376
|
}
|
|
10302
|
-
const target =
|
|
10303
|
-
|
|
10304
|
-
|
|
10377
|
+
const target = join14(destDir, safePath);
|
|
10378
|
+
mkdirSync9(dirname5(target), { recursive: true });
|
|
10379
|
+
writeFileSync7(target, file.content, "utf-8");
|
|
10305
10380
|
writtenCount += 1;
|
|
10306
10381
|
}
|
|
10307
10382
|
let removed = 0;
|
|
@@ -10329,7 +10404,7 @@ function pruneStaleFiles(rootDir, currentDir, kept) {
|
|
|
10329
10404
|
const { relative: relative6 } = __require("node:path");
|
|
10330
10405
|
let removed = 0;
|
|
10331
10406
|
for (const entry of readdirSync4(currentDir)) {
|
|
10332
|
-
const abs =
|
|
10407
|
+
const abs = join14(currentDir, entry);
|
|
10333
10408
|
const stat = statSync4(abs);
|
|
10334
10409
|
if (stat.isDirectory()) {
|
|
10335
10410
|
removed += pruneStaleFiles(rootDir, abs, kept);
|
|
@@ -10396,7 +10471,7 @@ function startGitPullPoll(args) {
|
|
|
10396
10471
|
// src/lib/dev/editor.ts
|
|
10397
10472
|
import { spawn as spawn4 } from "node:child_process";
|
|
10398
10473
|
import { existsSync as existsSync17, statSync as statSync4 } from "node:fs";
|
|
10399
|
-
import { delimiter as delimiter2, join as
|
|
10474
|
+
import { delimiter as delimiter2, join as join15 } from "node:path";
|
|
10400
10475
|
import { platform as platform3 } from "node:os";
|
|
10401
10476
|
var TARGET_LABEL = {
|
|
10402
10477
|
tools: "tool metadata",
|
|
@@ -10432,7 +10507,7 @@ function findOnPath2(command) {
|
|
|
10432
10507
|
if (!dir)
|
|
10433
10508
|
continue;
|
|
10434
10509
|
for (const ext of exts) {
|
|
10435
|
-
const candidate =
|
|
10510
|
+
const candidate = join15(dir, command + ext);
|
|
10436
10511
|
if (existsSync17(candidate) && isExecutable(candidate))
|
|
10437
10512
|
return candidate;
|
|
10438
10513
|
}
|
|
@@ -10714,7 +10789,7 @@ function parseOpenChoice(raw) {
|
|
|
10714
10789
|
|
|
10715
10790
|
// src/lib/dev/file-watcher.ts
|
|
10716
10791
|
import { existsSync as existsSync18, statSync as statSync5, watch as fsWatch2 } from "node:fs";
|
|
10717
|
-
import { join as
|
|
10792
|
+
import { join as join16 } from "node:path";
|
|
10718
10793
|
var DEFAULT_IGNORE = ["node_modules", ".git", "_mcpsh_host.mjs"];
|
|
10719
10794
|
function watchDir(options) {
|
|
10720
10795
|
if (!existsSync18(options.rootDir)) {
|
|
@@ -10753,7 +10828,7 @@ function watchDir(options) {
|
|
|
10753
10828
|
for (const entry of readdirSync4(options.rootDir)) {
|
|
10754
10829
|
if (ignore.has(entry))
|
|
10755
10830
|
continue;
|
|
10756
|
-
const sub =
|
|
10831
|
+
const sub = join16(options.rootDir, entry);
|
|
10757
10832
|
try {
|
|
10758
10833
|
const stat = statSync5(sub);
|
|
10759
10834
|
if (!stat.isDirectory())
|
|
@@ -11020,7 +11095,7 @@ async function handleOne2(args) {
|
|
|
11020
11095
|
// src/lib/dev/local-runtime.ts
|
|
11021
11096
|
import { spawn as spawn5 } from "node:child_process";
|
|
11022
11097
|
import { existsSync as existsSync21 } from "node:fs";
|
|
11023
|
-
import { join as
|
|
11098
|
+
import { join as join17 } from "node:path";
|
|
11024
11099
|
function detectRuntime(preferred = "auto") {
|
|
11025
11100
|
if (preferred === "bun" || preferred === "node")
|
|
11026
11101
|
return preferred;
|
|
@@ -11057,52 +11132,52 @@ function startRuntime(options) {
|
|
|
11057
11132
|
if (child.exitCode !== null)
|
|
11058
11133
|
return;
|
|
11059
11134
|
child.kill("SIGTERM");
|
|
11060
|
-
await new Promise((
|
|
11135
|
+
await new Promise((resolve6) => {
|
|
11061
11136
|
const timer = setTimeout(() => {
|
|
11062
11137
|
if (child.exitCode === null)
|
|
11063
11138
|
child.kill("SIGKILL");
|
|
11064
|
-
|
|
11139
|
+
resolve6();
|
|
11065
11140
|
}, 3000);
|
|
11066
11141
|
child.once("exit", () => {
|
|
11067
11142
|
clearTimeout(timer);
|
|
11068
|
-
|
|
11143
|
+
resolve6();
|
|
11069
11144
|
});
|
|
11070
11145
|
});
|
|
11071
11146
|
}
|
|
11072
11147
|
};
|
|
11073
11148
|
}
|
|
11074
11149
|
async function installDependencies(options) {
|
|
11075
|
-
const pkgPath =
|
|
11150
|
+
const pkgPath = join17(options.serverDir, "package.json");
|
|
11076
11151
|
if (!existsSync21(pkgPath))
|
|
11077
11152
|
return { ran: false, exitCode: null };
|
|
11078
|
-
const nodeModules =
|
|
11153
|
+
const nodeModules = join17(options.serverDir, "node_modules");
|
|
11079
11154
|
if (options.skipIfPresent !== false && existsSync21(nodeModules)) {
|
|
11080
11155
|
return { ran: false, exitCode: 0 };
|
|
11081
11156
|
}
|
|
11082
11157
|
options.onStep?.("Installing dependencies (bun install)…");
|
|
11083
|
-
return await new Promise((
|
|
11158
|
+
return await new Promise((resolve6) => {
|
|
11084
11159
|
const child = spawn5("bun", ["install", "--silent"], {
|
|
11085
11160
|
cwd: options.serverDir,
|
|
11086
11161
|
stdio: "inherit"
|
|
11087
11162
|
});
|
|
11088
|
-
child.on("error", () =>
|
|
11089
|
-
child.on("exit", (code) =>
|
|
11163
|
+
child.on("error", () => resolve6({ ran: true, exitCode: 127 }));
|
|
11164
|
+
child.on("exit", (code) => resolve6({ ran: true, exitCode: code }));
|
|
11090
11165
|
});
|
|
11091
11166
|
}
|
|
11092
11167
|
|
|
11093
11168
|
// src/lib/dev/prepare.ts
|
|
11094
|
-
import { existsSync as existsSync25, writeFileSync as
|
|
11095
|
-
import { join as
|
|
11169
|
+
import { existsSync as existsSync25, writeFileSync as writeFileSync11 } from "node:fs";
|
|
11170
|
+
import { join as join21, relative as relative6 } from "node:path";
|
|
11096
11171
|
|
|
11097
11172
|
// src/lib/dev/git-clone.ts
|
|
11098
11173
|
import { spawnSync } from "node:child_process";
|
|
11099
11174
|
import {
|
|
11100
11175
|
existsSync as existsSync22,
|
|
11101
|
-
mkdirSync as
|
|
11176
|
+
mkdirSync as mkdirSync10,
|
|
11102
11177
|
readFileSync as readFileSync14,
|
|
11103
|
-
writeFileSync as
|
|
11178
|
+
writeFileSync as writeFileSync8
|
|
11104
11179
|
} from "node:fs";
|
|
11105
|
-
import { dirname as
|
|
11180
|
+
import { dirname as dirname6, join as join18 } from "node:path";
|
|
11106
11181
|
|
|
11107
11182
|
class GitNotAvailableError extends Error {
|
|
11108
11183
|
constructor() {
|
|
@@ -11175,21 +11250,21 @@ function isGitAvailable() {
|
|
|
11175
11250
|
}
|
|
11176
11251
|
}
|
|
11177
11252
|
function applyLocalExcludes(repoDir) {
|
|
11178
|
-
const excludePath =
|
|
11253
|
+
const excludePath = join18(repoDir, ".git", "info", "exclude");
|
|
11179
11254
|
const existing = existsSync22(excludePath) ? readFileSync14(excludePath, "utf-8") : "";
|
|
11180
11255
|
const next = mergeLocalExcludes(existing);
|
|
11181
11256
|
if (next === null)
|
|
11182
11257
|
return;
|
|
11183
|
-
if (!existsSync22(
|
|
11184
|
-
|
|
11258
|
+
if (!existsSync22(dirname6(excludePath))) {
|
|
11259
|
+
mkdirSync10(dirname6(excludePath), { recursive: true });
|
|
11185
11260
|
}
|
|
11186
|
-
|
|
11261
|
+
writeFileSync8(excludePath, next, "utf-8");
|
|
11187
11262
|
}
|
|
11188
11263
|
function ensureClone(opts) {
|
|
11189
11264
|
if (!isGitAvailable()) {
|
|
11190
11265
|
throw new GitNotAvailableError;
|
|
11191
11266
|
}
|
|
11192
|
-
if (existsSync22(
|
|
11267
|
+
if (existsSync22(join18(opts.repoDir, ".git"))) {
|
|
11193
11268
|
opts.onStep?.("Refreshing existing clone (git fetch)…");
|
|
11194
11269
|
runGit(gitFetchArgs(opts.branch), opts.repoDir);
|
|
11195
11270
|
applyLocalExcludes(opts.repoDir);
|
|
@@ -11205,12 +11280,12 @@ function ensureClone(opts) {
|
|
|
11205
11280
|
}
|
|
11206
11281
|
|
|
11207
11282
|
// src/lib/dev/host-runtime.ts
|
|
11208
|
-
import { existsSync as existsSync24, mkdirSync as
|
|
11209
|
-
import { dirname as
|
|
11283
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync12, writeFileSync as writeFileSync10 } from "node:fs";
|
|
11284
|
+
import { dirname as dirname7, join as join20 } from "node:path";
|
|
11210
11285
|
|
|
11211
11286
|
// src/lib/dev/inspector-module.ts
|
|
11212
|
-
import { existsSync as existsSync23, mkdirSync as
|
|
11213
|
-
import { join as
|
|
11287
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync11, writeFileSync as writeFileSync9 } from "node:fs";
|
|
11288
|
+
import { join as join19 } from "node:path";
|
|
11214
11289
|
|
|
11215
11290
|
// src/lib/dev/inspector-assets.ts
|
|
11216
11291
|
var INSPECTOR_HTML = `<!doctype html>
|
|
@@ -26346,9 +26421,9 @@ function buildInspectorModule() {
|
|
|
26346
26421
|
}
|
|
26347
26422
|
function writeInspectorModule(serverDir2) {
|
|
26348
26423
|
if (!existsSync23(serverDir2))
|
|
26349
|
-
|
|
26350
|
-
const target =
|
|
26351
|
-
|
|
26424
|
+
mkdirSync11(serverDir2, { recursive: true });
|
|
26425
|
+
const target = join19(serverDir2, INSPECTOR_FILE_NAME);
|
|
26426
|
+
writeFileSync9(target, buildInspectorModule(), "utf-8");
|
|
26352
26427
|
return target;
|
|
26353
26428
|
}
|
|
26354
26429
|
|
|
@@ -26528,10 +26603,10 @@ function buildHostScript(options) {
|
|
|
26528
26603
|
}
|
|
26529
26604
|
function writeHostScript(serverDir2, options) {
|
|
26530
26605
|
if (!existsSync24(serverDir2))
|
|
26531
|
-
|
|
26532
|
-
const target =
|
|
26533
|
-
|
|
26534
|
-
|
|
26606
|
+
mkdirSync12(serverDir2, { recursive: true });
|
|
26607
|
+
const target = join20(serverDir2, HOST_FILE_NAME);
|
|
26608
|
+
mkdirSync12(dirname7(target), { recursive: true });
|
|
26609
|
+
writeFileSync10(target, buildHostScript(options), "utf-8");
|
|
26535
26610
|
if (options.inspector) {
|
|
26536
26611
|
writeInspectorModule(serverDir2);
|
|
26537
26612
|
}
|
|
@@ -26560,7 +26635,7 @@ async function prepareDev(opts) {
|
|
|
26560
26635
|
projectId = projectId ?? gitLink.projectId;
|
|
26561
26636
|
serverName = `${gitLink.owner}/${gitLink.name}`;
|
|
26562
26637
|
repoDir = gitCloneDir(cwd, gitLink.owner, gitLink.name);
|
|
26563
|
-
dest = gitLink.pathPrefix ?
|
|
26638
|
+
dest = gitLink.pathPrefix ? join21(repoDir, gitLink.pathPrefix) : repoDir;
|
|
26564
26639
|
printStep(`Git-linked server — cloning ${gitLink.owner}/${gitLink.name}@${gitLink.branch}…`);
|
|
26565
26640
|
try {
|
|
26566
26641
|
const result = ensureClone({
|
|
@@ -26581,7 +26656,7 @@ async function prepareDev(opts) {
|
|
|
26581
26656
|
process.exit(1);
|
|
26582
26657
|
}
|
|
26583
26658
|
if (!existsSync25(env)) {
|
|
26584
|
-
|
|
26659
|
+
writeFileSync11(env, `{}
|
|
26585
26660
|
`, "utf-8");
|
|
26586
26661
|
printInfo(` → seeded ${relative6(cwd, env)} (empty; fill secrets here)`);
|
|
26587
26662
|
}
|
|
@@ -26606,7 +26681,7 @@ async function prepareDev(opts) {
|
|
|
26606
26681
|
const result = materializeBundle(dest, bundle, { prune: true });
|
|
26607
26682
|
printInfo(` → wrote ${result.filesWritten} files (pruned ${result.filesRemoved})`);
|
|
26608
26683
|
if (!existsSync25(env)) {
|
|
26609
|
-
|
|
26684
|
+
writeFileSync11(env, `{}
|
|
26610
26685
|
`, "utf-8");
|
|
26611
26686
|
printInfo(` → seeded ${relative6(cwd, env)} (empty; fill secrets here)`);
|
|
26612
26687
|
}
|
|
@@ -26632,7 +26707,7 @@ async function prepareDev(opts) {
|
|
|
26632
26707
|
process.exit(1);
|
|
26633
26708
|
}
|
|
26634
26709
|
}
|
|
26635
|
-
const entryRel = ENTRY_CANDIDATES.find((c2) => existsSync25(
|
|
26710
|
+
const entryRel = ENTRY_CANDIDATES.find((c2) => existsSync25(join21(dest, c2)));
|
|
26636
26711
|
if (!entryRel) {
|
|
26637
26712
|
printError("Could not locate an entry file (expected src/worker.ts).");
|
|
26638
26713
|
process.exit(1);
|
|
@@ -26790,13 +26865,13 @@ function createBurstGuard() {
|
|
|
26790
26865
|
}
|
|
26791
26866
|
|
|
26792
26867
|
// src/lib/dev/agent-connectors/claude-code.ts
|
|
26793
|
-
import { existsSync as existsSync27, unlinkSync as unlinkSync2, writeFileSync as
|
|
26868
|
+
import { existsSync as existsSync27, unlinkSync as unlinkSync2, writeFileSync as writeFileSync13 } from "node:fs";
|
|
26794
26869
|
import { homedir as homedir4 } from "node:os";
|
|
26795
|
-
import { join as
|
|
26870
|
+
import { join as join23 } from "node:path";
|
|
26796
26871
|
|
|
26797
26872
|
// src/lib/dev/agent-connectors/json-config-utils.ts
|
|
26798
|
-
import { existsSync as existsSync26, mkdirSync as
|
|
26799
|
-
import { dirname as
|
|
26873
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync13, readFileSync as readFileSync15, writeFileSync as writeFileSync12 } from "node:fs";
|
|
26874
|
+
import { dirname as dirname8, join as join22, basename } from "node:path";
|
|
26800
26875
|
function readJsonFile(path) {
|
|
26801
26876
|
if (!existsSync26(path))
|
|
26802
26877
|
return { ok: true, value: {} };
|
|
@@ -26814,9 +26889,9 @@ function readJsonFile(path) {
|
|
|
26814
26889
|
}
|
|
26815
26890
|
}
|
|
26816
26891
|
function atomicWriteJson(path, value) {
|
|
26817
|
-
|
|
26892
|
+
mkdirSync13(dirname8(path), { recursive: true });
|
|
26818
26893
|
const tmp = `${path}.mcpsh-${process.pid}-${Date.now()}.tmp`;
|
|
26819
|
-
|
|
26894
|
+
writeFileSync12(tmp, JSON.stringify(value, null, 2) + `
|
|
26820
26895
|
`, "utf-8");
|
|
26821
26896
|
const { renameSync: renameSync2 } = __require("node:fs");
|
|
26822
26897
|
renameSync2(tmp, path);
|
|
@@ -26825,33 +26900,33 @@ function backupConfig(args) {
|
|
|
26825
26900
|
if (!existsSync26(args.configPath)) {
|
|
26826
26901
|
return { backupPath: null, existed: false };
|
|
26827
26902
|
}
|
|
26828
|
-
|
|
26903
|
+
mkdirSync13(args.backupsDir, { recursive: true });
|
|
26829
26904
|
const filename = `${args.agentId}__${basename(args.configPath)}.bak`;
|
|
26830
|
-
const backupPath =
|
|
26905
|
+
const backupPath = join22(args.backupsDir, filename);
|
|
26831
26906
|
if (!existsSync26(backupPath)) {
|
|
26832
26907
|
const raw = readFileSync15(args.configPath, "utf-8");
|
|
26833
|
-
|
|
26908
|
+
writeFileSync12(backupPath, raw, "utf-8");
|
|
26834
26909
|
}
|
|
26835
26910
|
return { backupPath, existed: true };
|
|
26836
26911
|
}
|
|
26837
26912
|
function restoreFromBackup(args) {
|
|
26838
26913
|
const filename = `${args.agentId}__${basename(args.configPath)}.bak`;
|
|
26839
|
-
const backupPath =
|
|
26914
|
+
const backupPath = join22(args.backupsDir, filename);
|
|
26840
26915
|
if (!existsSync26(backupPath)) {
|
|
26841
26916
|
return { restored: false };
|
|
26842
26917
|
}
|
|
26843
26918
|
const raw = readFileSync15(backupPath, "utf-8");
|
|
26844
|
-
|
|
26845
|
-
|
|
26919
|
+
mkdirSync13(dirname8(args.configPath), { recursive: true });
|
|
26920
|
+
writeFileSync12(args.configPath, raw, "utf-8");
|
|
26846
26921
|
return { restored: true };
|
|
26847
26922
|
}
|
|
26848
26923
|
|
|
26849
26924
|
// src/lib/dev/agent-connectors/claude-code.ts
|
|
26850
26925
|
function configPath() {
|
|
26851
|
-
return
|
|
26926
|
+
return join23(homedir4(), ".claude.json");
|
|
26852
26927
|
}
|
|
26853
26928
|
function legacyConfigPath() {
|
|
26854
|
-
return
|
|
26929
|
+
return join23(homedir4(), ".claude", "mcp.json");
|
|
26855
26930
|
}
|
|
26856
26931
|
function resolveConfigPath() {
|
|
26857
26932
|
if (existsSync27(configPath()))
|
|
@@ -26866,7 +26941,7 @@ var claudeCodeConnector = {
|
|
|
26866
26941
|
hotkey: "c",
|
|
26867
26942
|
describeLocation: () => resolveConfigPath(),
|
|
26868
26943
|
async detect() {
|
|
26869
|
-
const claudeDir =
|
|
26944
|
+
const claudeDir = join23(homedir4(), ".claude");
|
|
26870
26945
|
if (existsSync27(configPath()) || existsSync27(legacyConfigPath()) || existsSync27(claudeDir)) {
|
|
26871
26946
|
return { installed: true, note: "Found Claude Code config" };
|
|
26872
26947
|
}
|
|
@@ -26915,7 +26990,7 @@ var claudeCodeConnector = {
|
|
|
26915
26990
|
try {
|
|
26916
26991
|
unlinkSync2(path);
|
|
26917
26992
|
} catch {
|
|
26918
|
-
|
|
26993
|
+
writeFileSync13(path, `{}
|
|
26919
26994
|
`, "utf-8");
|
|
26920
26995
|
}
|
|
26921
26996
|
}
|
|
@@ -26928,15 +27003,15 @@ var claudeCodeConnector = {
|
|
|
26928
27003
|
// src/lib/dev/agent-connectors/codex.ts
|
|
26929
27004
|
import {
|
|
26930
27005
|
existsSync as existsSync28,
|
|
26931
|
-
mkdirSync as
|
|
27006
|
+
mkdirSync as mkdirSync14,
|
|
26932
27007
|
readFileSync as readFileSync16,
|
|
26933
27008
|
unlinkSync as unlinkSync3,
|
|
26934
|
-
writeFileSync as
|
|
27009
|
+
writeFileSync as writeFileSync14
|
|
26935
27010
|
} from "node:fs";
|
|
26936
27011
|
import { homedir as homedir5 } from "node:os";
|
|
26937
|
-
import { dirname as
|
|
27012
|
+
import { dirname as dirname9, join as join24 } from "node:path";
|
|
26938
27013
|
function configPath2() {
|
|
26939
|
-
return
|
|
27014
|
+
return join24(homedir5(), ".codex", "config.toml");
|
|
26940
27015
|
}
|
|
26941
27016
|
var SECTION_PREFIX = "mcp_servers.";
|
|
26942
27017
|
function buildSection(name, url) {
|
|
@@ -26974,7 +27049,7 @@ var codexConnector = {
|
|
|
26974
27049
|
hotkey: "x",
|
|
26975
27050
|
describeLocation: () => configPath2(),
|
|
26976
27051
|
async detect() {
|
|
26977
|
-
if (existsSync28(
|
|
27052
|
+
if (existsSync28(join24(homedir5(), ".codex")) || existsSync28(configPath2())) {
|
|
26978
27053
|
return { installed: true, note: "Found ~/.codex/" };
|
|
26979
27054
|
}
|
|
26980
27055
|
return { installed: false };
|
|
@@ -27003,8 +27078,8 @@ var codexConnector = {
|
|
|
27003
27078
|
next += `
|
|
27004
27079
|
`;
|
|
27005
27080
|
next += buildSection(args.name, args.url);
|
|
27006
|
-
|
|
27007
|
-
|
|
27081
|
+
mkdirSync14(dirname9(path), { recursive: true });
|
|
27082
|
+
writeFileSync14(path, next, "utf-8");
|
|
27008
27083
|
return { added: !conflict, conflict };
|
|
27009
27084
|
},
|
|
27010
27085
|
async remove(args) {
|
|
@@ -27014,7 +27089,7 @@ var codexConnector = {
|
|
|
27014
27089
|
const range = findSectionRange(existing, args.name);
|
|
27015
27090
|
if (range) {
|
|
27016
27091
|
const next = existing.slice(0, range.start) + existing.slice(range.end);
|
|
27017
|
-
|
|
27092
|
+
writeFileSync14(path, next, "utf-8");
|
|
27018
27093
|
}
|
|
27019
27094
|
}
|
|
27020
27095
|
const restored = restoreFromBackup({
|
|
@@ -27035,11 +27110,11 @@ var codexConnector = {
|
|
|
27035
27110
|
};
|
|
27036
27111
|
|
|
27037
27112
|
// src/lib/dev/agent-connectors/continue.ts
|
|
27038
|
-
import { existsSync as existsSync29, unlinkSync as unlinkSync4, writeFileSync as
|
|
27113
|
+
import { existsSync as existsSync29, unlinkSync as unlinkSync4, writeFileSync as writeFileSync15 } from "node:fs";
|
|
27039
27114
|
import { homedir as homedir6 } from "node:os";
|
|
27040
|
-
import { join as
|
|
27115
|
+
import { join as join25 } from "node:path";
|
|
27041
27116
|
function configPath3() {
|
|
27042
|
-
return
|
|
27117
|
+
return join25(homedir6(), ".continue", "config.json");
|
|
27043
27118
|
}
|
|
27044
27119
|
function isContinueServerEntry(value) {
|
|
27045
27120
|
return Boolean(value && typeof value === "object" && typeof value.name === "string");
|
|
@@ -27050,7 +27125,7 @@ var continueConnector = {
|
|
|
27050
27125
|
hotkey: "n",
|
|
27051
27126
|
describeLocation: () => configPath3(),
|
|
27052
27127
|
async detect() {
|
|
27053
|
-
const dir =
|
|
27128
|
+
const dir = join25(homedir6(), ".continue");
|
|
27054
27129
|
if (existsSync29(dir) || existsSync29(configPath3())) {
|
|
27055
27130
|
return { installed: true, note: "Found ~/.continue/" };
|
|
27056
27131
|
}
|
|
@@ -27099,7 +27174,7 @@ var continueConnector = {
|
|
|
27099
27174
|
try {
|
|
27100
27175
|
unlinkSync4(path);
|
|
27101
27176
|
} catch {
|
|
27102
|
-
|
|
27177
|
+
writeFileSync15(path, `{}
|
|
27103
27178
|
`, "utf-8");
|
|
27104
27179
|
}
|
|
27105
27180
|
}
|
|
@@ -27110,11 +27185,11 @@ var continueConnector = {
|
|
|
27110
27185
|
};
|
|
27111
27186
|
|
|
27112
27187
|
// src/lib/dev/agent-connectors/cursor.ts
|
|
27113
|
-
import { existsSync as existsSync30, unlinkSync as unlinkSync5, writeFileSync as
|
|
27188
|
+
import { existsSync as existsSync30, unlinkSync as unlinkSync5, writeFileSync as writeFileSync16 } from "node:fs";
|
|
27114
27189
|
import { homedir as homedir7 } from "node:os";
|
|
27115
|
-
import { join as
|
|
27190
|
+
import { join as join26 } from "node:path";
|
|
27116
27191
|
function globalConfigPath() {
|
|
27117
|
-
return
|
|
27192
|
+
return join26(homedir7(), ".cursor", "mcp.json");
|
|
27118
27193
|
}
|
|
27119
27194
|
var cursorConnector = {
|
|
27120
27195
|
id: "cursor",
|
|
@@ -27122,8 +27197,8 @@ var cursorConnector = {
|
|
|
27122
27197
|
hotkey: "u",
|
|
27123
27198
|
describeLocation: () => globalConfigPath(),
|
|
27124
27199
|
async detect() {
|
|
27125
|
-
const cursorDir =
|
|
27126
|
-
const macAppSupport =
|
|
27200
|
+
const cursorDir = join26(homedir7(), ".cursor");
|
|
27201
|
+
const macAppSupport = join26(homedir7(), "Library", "Application Support", "Cursor");
|
|
27127
27202
|
if (existsSync30(cursorDir) || existsSync30(macAppSupport)) {
|
|
27128
27203
|
return { installed: true, note: "Found Cursor config dir" };
|
|
27129
27204
|
}
|
|
@@ -27172,7 +27247,7 @@ var cursorConnector = {
|
|
|
27172
27247
|
try {
|
|
27173
27248
|
unlinkSync5(path);
|
|
27174
27249
|
} catch {
|
|
27175
|
-
|
|
27250
|
+
writeFileSync16(path, `{}
|
|
27176
27251
|
`, "utf-8");
|
|
27177
27252
|
}
|
|
27178
27253
|
}
|
|
@@ -27183,30 +27258,30 @@ var cursorConnector = {
|
|
|
27183
27258
|
};
|
|
27184
27259
|
|
|
27185
27260
|
// src/lib/dev/agent-connectors/vscode-copilot.ts
|
|
27186
|
-
import { existsSync as existsSync31, unlinkSync as unlinkSync6, writeFileSync as
|
|
27261
|
+
import { existsSync as existsSync31, unlinkSync as unlinkSync6, writeFileSync as writeFileSync17 } from "node:fs";
|
|
27187
27262
|
import { homedir as homedir8, platform as platform4 } from "node:os";
|
|
27188
|
-
import { join as
|
|
27263
|
+
import { join as join27, resolve as resolve6 } from "node:path";
|
|
27189
27264
|
function userLevelConfigPath() {
|
|
27190
27265
|
const home = homedir8();
|
|
27191
27266
|
const p2 = platform4();
|
|
27192
27267
|
if (p2 === "darwin")
|
|
27193
|
-
return
|
|
27268
|
+
return join27(home, "Library", "Application Support", "Code", "User", "mcp.json");
|
|
27194
27269
|
if (p2 === "win32") {
|
|
27195
|
-
const appData = process.env["APPDATA"] ??
|
|
27196
|
-
return
|
|
27270
|
+
const appData = process.env["APPDATA"] ?? join27(home, "AppData", "Roaming");
|
|
27271
|
+
return join27(appData, "Code", "User", "mcp.json");
|
|
27197
27272
|
}
|
|
27198
|
-
const xdg = process.env["XDG_CONFIG_HOME"] ??
|
|
27199
|
-
return
|
|
27273
|
+
const xdg = process.env["XDG_CONFIG_HOME"] ?? join27(home, ".config");
|
|
27274
|
+
return join27(xdg, "Code", "User", "mcp.json");
|
|
27200
27275
|
}
|
|
27201
27276
|
function isHomeDir(cwd) {
|
|
27202
|
-
return
|
|
27277
|
+
return resolve6(cwd) === resolve6(homedir8());
|
|
27203
27278
|
}
|
|
27204
27279
|
function hasWorkspaceVscode(cwd) {
|
|
27205
|
-
return existsSync31(
|
|
27280
|
+
return existsSync31(join27(cwd, ".vscode"));
|
|
27206
27281
|
}
|
|
27207
27282
|
function configPath4(cwd) {
|
|
27208
27283
|
if (!isHomeDir(cwd) && hasWorkspaceVscode(cwd)) {
|
|
27209
|
-
return
|
|
27284
|
+
return join27(cwd, ".vscode", "mcp.json");
|
|
27210
27285
|
}
|
|
27211
27286
|
return userLevelConfigPath();
|
|
27212
27287
|
}
|
|
@@ -27268,7 +27343,7 @@ var vscodeCopilotConnector = {
|
|
|
27268
27343
|
try {
|
|
27269
27344
|
unlinkSync6(path);
|
|
27270
27345
|
} catch {
|
|
27271
|
-
|
|
27346
|
+
writeFileSync17(path, `{}
|
|
27272
27347
|
`, "utf-8");
|
|
27273
27348
|
}
|
|
27274
27349
|
}
|
|
@@ -27412,7 +27487,7 @@ function parseGraceMs(value, fallbackMs) {
|
|
|
27412
27487
|
return Math.round(n * 1000);
|
|
27413
27488
|
}
|
|
27414
27489
|
function resolveSpecPath(cwd, raw) {
|
|
27415
|
-
return
|
|
27490
|
+
return isAbsolute3(raw) ? raw : resolve7(cwd, raw);
|
|
27416
27491
|
}
|
|
27417
27492
|
function buildConnectionName(serverId) {
|
|
27418
27493
|
const slug = serverId.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 24) || "mcp-server";
|
|
@@ -28389,11 +28464,11 @@ async function confirmRollback(deploymentId) {
|
|
|
28389
28464
|
// src/commands/doctor.ts
|
|
28390
28465
|
import { existsSync as existsSync34, statSync as statSync6, readFileSync as readFileSync18 } from "node:fs";
|
|
28391
28466
|
import { homedir as homedir9, platform as platform6 } from "node:os";
|
|
28392
|
-
import { join as
|
|
28467
|
+
import { join as join29, delimiter as delimiter3 } from "node:path";
|
|
28393
28468
|
|
|
28394
28469
|
// src/lib/version-check.ts
|
|
28395
|
-
import { existsSync as existsSync33, mkdirSync as
|
|
28396
|
-
import { join as
|
|
28470
|
+
import { existsSync as existsSync33, mkdirSync as mkdirSync15, readFileSync as readFileSync17, writeFileSync as writeFileSync18 } from "node:fs";
|
|
28471
|
+
import { join as join28 } from "node:path";
|
|
28397
28472
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
28398
28473
|
var FETCH_TIMEOUT_MS2 = 2000;
|
|
28399
28474
|
var REGISTRY_URL = "https://registry.npmjs.org/@mcpcloud/cli/latest";
|
|
@@ -28401,7 +28476,7 @@ function cacheDir() {
|
|
|
28401
28476
|
return configDir();
|
|
28402
28477
|
}
|
|
28403
28478
|
function cacheFile() {
|
|
28404
|
-
return
|
|
28479
|
+
return join28(cacheDir(), "version-check.json");
|
|
28405
28480
|
}
|
|
28406
28481
|
function readCache() {
|
|
28407
28482
|
if (!existsSync33(cacheFile()))
|
|
@@ -28418,8 +28493,8 @@ function readCache() {
|
|
|
28418
28493
|
function writeCache(entry) {
|
|
28419
28494
|
try {
|
|
28420
28495
|
if (!existsSync33(cacheDir()))
|
|
28421
|
-
|
|
28422
|
-
|
|
28496
|
+
mkdirSync15(cacheDir(), { recursive: true, mode: 448 });
|
|
28497
|
+
writeFileSync18(cacheFile(), JSON.stringify(entry, null, 2), { mode: 384 });
|
|
28423
28498
|
} catch {}
|
|
28424
28499
|
}
|
|
28425
28500
|
function compareVersions(a, b) {
|
|
@@ -28530,7 +28605,7 @@ function checkNode() {
|
|
|
28530
28605
|
}
|
|
28531
28606
|
function checkConfigFile() {
|
|
28532
28607
|
const t0 = Date.now();
|
|
28533
|
-
const path =
|
|
28608
|
+
const path = join29(homedir9(), ".mcpcloud", "config.json");
|
|
28534
28609
|
if (!existsSync34(path)) {
|
|
28535
28610
|
return {
|
|
28536
28611
|
name: "Config file",
|
|
@@ -28688,7 +28763,7 @@ function checkClaudeCli() {
|
|
|
28688
28763
|
for (const dir of PATH.split(delimiter3)) {
|
|
28689
28764
|
if (!dir)
|
|
28690
28765
|
continue;
|
|
28691
|
-
const candidate =
|
|
28766
|
+
const candidate = join29(dir, exe);
|
|
28692
28767
|
if (existsSync34(candidate)) {
|
|
28693
28768
|
return {
|
|
28694
28769
|
name: "claude CLI",
|
|
@@ -29028,10 +29103,10 @@ function prompt2(question) {
|
|
|
29028
29103
|
throw new Error("Interactive prompts are disabled in CI mode. Pass --org / --project / --name explicitly or run `mcp init` outside CI.");
|
|
29029
29104
|
}
|
|
29030
29105
|
const rl = createInterface2({ input: process.stdin, output: process.stderr });
|
|
29031
|
-
return new Promise((
|
|
29106
|
+
return new Promise((resolve8) => {
|
|
29032
29107
|
rl.question(question, (answer) => {
|
|
29033
29108
|
rl.close();
|
|
29034
|
-
|
|
29109
|
+
resolve8(answer.trim());
|
|
29035
29110
|
});
|
|
29036
29111
|
});
|
|
29037
29112
|
}
|
|
@@ -29631,24 +29706,24 @@ function registerOAuthCommands(program2) {
|
|
|
29631
29706
|
import { spawn as spawn7 } from "node:child_process";
|
|
29632
29707
|
import {
|
|
29633
29708
|
existsSync as existsSync35,
|
|
29634
|
-
mkdirSync as
|
|
29709
|
+
mkdirSync as mkdirSync16,
|
|
29635
29710
|
readdirSync as readdirSync4,
|
|
29636
29711
|
readFileSync as readFileSync19,
|
|
29637
29712
|
rmSync as rmSync3,
|
|
29638
29713
|
statSync as statSync7
|
|
29639
29714
|
} from "node:fs";
|
|
29640
|
-
import { join as
|
|
29715
|
+
import { join as join30 } from "node:path";
|
|
29641
29716
|
import { pathToFileURL } from "node:url";
|
|
29642
29717
|
function pluginsDir() {
|
|
29643
|
-
return
|
|
29718
|
+
return join30(configDir(), "plugins");
|
|
29644
29719
|
}
|
|
29645
29720
|
function ensureDir2() {
|
|
29646
29721
|
const dir = pluginsDir();
|
|
29647
29722
|
if (!existsSync35(dir))
|
|
29648
|
-
|
|
29723
|
+
mkdirSync16(dir, { recursive: true, mode: 448 });
|
|
29649
29724
|
}
|
|
29650
29725
|
function readManifestFromPackageDir(packageDir) {
|
|
29651
|
-
const pkgPath =
|
|
29726
|
+
const pkgPath = join30(packageDir, "package.json");
|
|
29652
29727
|
if (!existsSync35(pkgPath))
|
|
29653
29728
|
return null;
|
|
29654
29729
|
let pkg;
|
|
@@ -29660,7 +29735,7 @@ function readManifestFromPackageDir(packageDir) {
|
|
|
29660
29735
|
if (!pkg.name)
|
|
29661
29736
|
return null;
|
|
29662
29737
|
const relEntry = pkg.mcpsh?.register ?? pkg.main ?? "index.js";
|
|
29663
|
-
const entry =
|
|
29738
|
+
const entry = join30(packageDir, relEntry);
|
|
29664
29739
|
if (!existsSync35(entry))
|
|
29665
29740
|
return null;
|
|
29666
29741
|
return {
|
|
@@ -29676,7 +29751,7 @@ function listInstalledPlugins() {
|
|
|
29676
29751
|
return [];
|
|
29677
29752
|
const out = [];
|
|
29678
29753
|
for (const entry of readdirSync4(dir)) {
|
|
29679
|
-
const full =
|
|
29754
|
+
const full = join30(dir, entry);
|
|
29680
29755
|
let s;
|
|
29681
29756
|
try {
|
|
29682
29757
|
s = statSync7(full);
|
|
@@ -29687,7 +29762,7 @@ function listInstalledPlugins() {
|
|
|
29687
29762
|
continue;
|
|
29688
29763
|
if (entry.startsWith("@")) {
|
|
29689
29764
|
for (const child of readdirSync4(full)) {
|
|
29690
|
-
const m2 = readManifestFromPackageDir(
|
|
29765
|
+
const m2 = readManifestFromPackageDir(join30(full, child));
|
|
29691
29766
|
if (m2)
|
|
29692
29767
|
out.push(m2);
|
|
29693
29768
|
}
|
|
@@ -29722,15 +29797,15 @@ async function loadPlugins(program2) {
|
|
|
29722
29797
|
}
|
|
29723
29798
|
var PACKAGE_SPEC_PATTERN = /^(@[a-z0-9~-][\w.~-]*\/)?[a-z0-9~-][\w.~-]*(@[-\w.^~><=*+|]+)?$/i;
|
|
29724
29799
|
function runNpm(args, cwd) {
|
|
29725
|
-
return new Promise((
|
|
29800
|
+
return new Promise((resolve8) => {
|
|
29726
29801
|
const isWindows = process.platform === "win32";
|
|
29727
29802
|
const child = spawn7(isWindows ? "npm.cmd" : "npm", args, {
|
|
29728
29803
|
shell: isWindows,
|
|
29729
29804
|
cwd,
|
|
29730
29805
|
stdio: "inherit"
|
|
29731
29806
|
});
|
|
29732
|
-
child.on("close", (code) =>
|
|
29733
|
-
child.on("error", () =>
|
|
29807
|
+
child.on("close", (code) => resolve8(code ?? 1));
|
|
29808
|
+
child.on("error", () => resolve8(1));
|
|
29734
29809
|
});
|
|
29735
29810
|
}
|
|
29736
29811
|
async function installPlugin(packageSpec) {
|
|
@@ -29751,12 +29826,12 @@ async function installPlugin(packageSpec) {
|
|
|
29751
29826
|
if (code !== 0) {
|
|
29752
29827
|
throw new Error(`npm install ${packageSpec} exited with code ${code}.`);
|
|
29753
29828
|
}
|
|
29754
|
-
const nm =
|
|
29829
|
+
const nm = join30(dir, "node_modules");
|
|
29755
29830
|
if (!existsSync35(nm)) {
|
|
29756
29831
|
throw new Error(`npm install ran but produced no node_modules under ${dir}.`);
|
|
29757
29832
|
}
|
|
29758
29833
|
const baseName = packageSpec.replace(/@[^@/]+$/, "");
|
|
29759
|
-
const candidatePath = baseName.startsWith("@") ?
|
|
29834
|
+
const candidatePath = baseName.startsWith("@") ? join30(nm, baseName.split("/")[0], baseName.split("/")[1] ?? "") : join30(nm, baseName);
|
|
29760
29835
|
const manifest = readManifestFromPackageDir(candidatePath);
|
|
29761
29836
|
if (!manifest) {
|
|
29762
29837
|
throw new Error(`Installed but could not read plugin manifest at ${candidatePath}.`);
|
|
@@ -29764,10 +29839,10 @@ async function installPlugin(packageSpec) {
|
|
|
29764
29839
|
return { name: manifest.name, entry: manifest.entry };
|
|
29765
29840
|
}
|
|
29766
29841
|
function removePlugin(name) {
|
|
29767
|
-
const nm =
|
|
29842
|
+
const nm = join30(pluginsDir(), "node_modules");
|
|
29768
29843
|
if (!existsSync35(nm))
|
|
29769
29844
|
return false;
|
|
29770
|
-
const target = name.startsWith("@") ?
|
|
29845
|
+
const target = name.startsWith("@") ? join30(nm, name.split("/")[0], name.split("/")[1] ?? "") : join30(nm, name);
|
|
29771
29846
|
if (!existsSync35(target))
|
|
29772
29847
|
return false;
|
|
29773
29848
|
rmSync3(target, { recursive: true, force: true });
|
|
@@ -29775,7 +29850,7 @@ function removePlugin(name) {
|
|
|
29775
29850
|
}
|
|
29776
29851
|
function listInstalledPluginsCombined() {
|
|
29777
29852
|
const direct = listInstalledPlugins();
|
|
29778
|
-
const nm =
|
|
29853
|
+
const nm = join30(pluginsDir(), "node_modules");
|
|
29779
29854
|
if (!existsSync35(nm))
|
|
29780
29855
|
return direct;
|
|
29781
29856
|
const seen = new Set(direct.map((p2) => p2.name));
|
|
@@ -29783,7 +29858,7 @@ function listInstalledPluginsCombined() {
|
|
|
29783
29858
|
for (const entry of readdirSync4(nm)) {
|
|
29784
29859
|
if (entry === ".bin" || entry === ".package-lock.json")
|
|
29785
29860
|
continue;
|
|
29786
|
-
const full =
|
|
29861
|
+
const full = join30(nm, entry);
|
|
29787
29862
|
let s;
|
|
29788
29863
|
try {
|
|
29789
29864
|
s = statSync7(full);
|
|
@@ -29794,7 +29869,7 @@ function listInstalledPluginsCombined() {
|
|
|
29794
29869
|
continue;
|
|
29795
29870
|
if (entry.startsWith("@")) {
|
|
29796
29871
|
for (const child of readdirSync4(full)) {
|
|
29797
|
-
const m2 = readManifestFromPackageDir(
|
|
29872
|
+
const m2 = readManifestFromPackageDir(join30(full, child));
|
|
29798
29873
|
if (m2 && !seen.has(m2.name)) {
|
|
29799
29874
|
seen.add(m2.name);
|
|
29800
29875
|
out.push(m2);
|
|
@@ -30250,7 +30325,7 @@ function clipboardCandidatesFor(platform7, waylandDisplay) {
|
|
|
30250
30325
|
return linux;
|
|
30251
30326
|
}
|
|
30252
30327
|
async function defaultIsExecutable(binary) {
|
|
30253
|
-
return await new Promise((
|
|
30328
|
+
return await new Promise((resolve8) => {
|
|
30254
30329
|
const isWin = process.platform === "win32";
|
|
30255
30330
|
const cmd = isWin ? "where" : "command";
|
|
30256
30331
|
const args = isWin ? [binary] : ["-v", binary];
|
|
@@ -30258,8 +30333,8 @@ async function defaultIsExecutable(binary) {
|
|
|
30258
30333
|
shell: !isWin,
|
|
30259
30334
|
stdio: "ignore"
|
|
30260
30335
|
});
|
|
30261
|
-
child.on("error", () =>
|
|
30262
|
-
child.on("exit", (code) =>
|
|
30336
|
+
child.on("error", () => resolve8(false));
|
|
30337
|
+
child.on("exit", (code) => resolve8(code === 0));
|
|
30263
30338
|
});
|
|
30264
30339
|
}
|
|
30265
30340
|
async function detectClipboard(probe) {
|
|
@@ -30281,7 +30356,7 @@ async function copyToClipboard(text, probe) {
|
|
|
30281
30356
|
};
|
|
30282
30357
|
}
|
|
30283
30358
|
const spawnImpl = probe?.spawnImpl ?? spawn8;
|
|
30284
|
-
return await new Promise((
|
|
30359
|
+
return await new Promise((resolve8) => {
|
|
30285
30360
|
const child = spawnImpl(candidate.binary, candidate.args, {
|
|
30286
30361
|
stdio: ["pipe", "ignore", "pipe"]
|
|
30287
30362
|
});
|
|
@@ -30290,7 +30365,7 @@ async function copyToClipboard(text, probe) {
|
|
|
30290
30365
|
stderr += chunk.toString("utf-8");
|
|
30291
30366
|
});
|
|
30292
30367
|
child.on("error", (err) => {
|
|
30293
|
-
|
|
30368
|
+
resolve8({
|
|
30294
30369
|
kind: "failed",
|
|
30295
30370
|
binary: candidate.binary,
|
|
30296
30371
|
message: err instanceof Error ? err.message : String(err)
|
|
@@ -30298,9 +30373,9 @@ async function copyToClipboard(text, probe) {
|
|
|
30298
30373
|
});
|
|
30299
30374
|
child.on("exit", (code) => {
|
|
30300
30375
|
if (code === 0) {
|
|
30301
|
-
|
|
30376
|
+
resolve8({ kind: "ok", binary: candidate.binary });
|
|
30302
30377
|
} else {
|
|
30303
|
-
|
|
30378
|
+
resolve8({
|
|
30304
30379
|
kind: "failed",
|
|
30305
30380
|
binary: candidate.binary,
|
|
30306
30381
|
message: stderr.trim() || `${candidate.binary} exited with status ${code ?? "?"}`
|
|
@@ -30310,7 +30385,7 @@ async function copyToClipboard(text, probe) {
|
|
|
30310
30385
|
try {
|
|
30311
30386
|
child.stdin?.end(text);
|
|
30312
30387
|
} catch (err) {
|
|
30313
|
-
|
|
30388
|
+
resolve8({
|
|
30314
30389
|
kind: "failed",
|
|
30315
30390
|
binary: candidate.binary,
|
|
30316
30391
|
message: err instanceof Error ? err.message : String(err)
|
|
@@ -31381,11 +31456,11 @@ function displayValueFor(field, value) {
|
|
|
31381
31456
|
// src/lib/tui/state-store.ts
|
|
31382
31457
|
import {
|
|
31383
31458
|
existsSync as existsSync36,
|
|
31384
|
-
mkdirSync as
|
|
31459
|
+
mkdirSync as mkdirSync17,
|
|
31385
31460
|
readFileSync as readFileSync20,
|
|
31386
|
-
writeFileSync as
|
|
31461
|
+
writeFileSync as writeFileSync19
|
|
31387
31462
|
} from "node:fs";
|
|
31388
|
-
import { join as
|
|
31463
|
+
import { join as join31 } from "node:path";
|
|
31389
31464
|
var ALL_TABS = [
|
|
31390
31465
|
"servers",
|
|
31391
31466
|
"projects",
|
|
@@ -31395,7 +31470,7 @@ var ALL_TABS = [
|
|
|
31395
31470
|
"devSessions"
|
|
31396
31471
|
];
|
|
31397
31472
|
function tuiStateFile() {
|
|
31398
|
-
return
|
|
31473
|
+
return join31(configDir(), "tui-state.json");
|
|
31399
31474
|
}
|
|
31400
31475
|
function isTab(v2) {
|
|
31401
31476
|
return typeof v2 === "string" && ALL_TABS.includes(v2);
|
|
@@ -31473,9 +31548,9 @@ function readTuiState() {
|
|
|
31473
31548
|
function writeTuiState(state) {
|
|
31474
31549
|
try {
|
|
31475
31550
|
if (!existsSync36(configDir())) {
|
|
31476
|
-
|
|
31551
|
+
mkdirSync17(configDir(), { recursive: true, mode: 448 });
|
|
31477
31552
|
}
|
|
31478
|
-
|
|
31553
|
+
writeFileSync19(tuiStateFile(), JSON.stringify(state, null, 2), {
|
|
31479
31554
|
encoding: "utf-8",
|
|
31480
31555
|
mode: 384
|
|
31481
31556
|
});
|
|
@@ -33480,7 +33555,7 @@ function registerUiCommand(program2) {
|
|
|
33480
33555
|
}
|
|
33481
33556
|
return false;
|
|
33482
33557
|
};
|
|
33483
|
-
await new Promise((
|
|
33558
|
+
await new Promise((resolve8) => {
|
|
33484
33559
|
const flushAndExit = () => {
|
|
33485
33560
|
try {
|
|
33486
33561
|
if (persistTimer) {
|
|
@@ -33490,7 +33565,7 @@ function registerUiCommand(program2) {
|
|
|
33490
33565
|
writeTuiState(snapshotForPersist());
|
|
33491
33566
|
} catch {}
|
|
33492
33567
|
shutdown(handles);
|
|
33493
|
-
|
|
33568
|
+
resolve8();
|
|
33494
33569
|
};
|
|
33495
33570
|
const executePaletteCommand = (id) => {
|
|
33496
33571
|
if (id.startsWith("tab:")) {
|
|
@@ -34099,7 +34174,7 @@ function registerUiCommand(program2) {
|
|
|
34099
34174
|
|
|
34100
34175
|
// src/commands/update.ts
|
|
34101
34176
|
import { spawn as spawn9 } from "node:child_process";
|
|
34102
|
-
import { dirname as
|
|
34177
|
+
import { dirname as dirname10 } from "node:path";
|
|
34103
34178
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
34104
34179
|
function detectInstallContext() {
|
|
34105
34180
|
const override = process.env["MCPSH_PACKAGE_MANAGER"]?.trim().toLowerCase();
|
|
@@ -34112,7 +34187,7 @@ function detectInstallContext() {
|
|
|
34112
34187
|
}
|
|
34113
34188
|
const here = (() => {
|
|
34114
34189
|
try {
|
|
34115
|
-
return
|
|
34190
|
+
return dirname10(fileURLToPath2(import.meta.url));
|
|
34116
34191
|
} catch {
|
|
34117
34192
|
return process.argv[1] ?? "";
|
|
34118
34193
|
}
|
|
@@ -34160,10 +34235,10 @@ function buildCommand(manager) {
|
|
|
34160
34235
|
}
|
|
34161
34236
|
}
|
|
34162
34237
|
function runShell(command) {
|
|
34163
|
-
return new Promise((
|
|
34238
|
+
return new Promise((resolve8) => {
|
|
34164
34239
|
const child = spawn9(command, { shell: true, stdio: "inherit" });
|
|
34165
|
-
child.on("close", (code) =>
|
|
34166
|
-
child.on("error", () =>
|
|
34240
|
+
child.on("close", (code) => resolve8(code ?? 1));
|
|
34241
|
+
child.on("error", () => resolve8(1));
|
|
34167
34242
|
});
|
|
34168
34243
|
}
|
|
34169
34244
|
function registerUpdateCommand(program2) {
|