create-mcp-use-app 0.14.9 → 0.14.10
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 +205 -109
- package/dist/utils.d.ts +14 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10,22 +10,97 @@ import { spawn, spawnSync } from "child_process";
|
|
|
10
10
|
import {
|
|
11
11
|
copyFileSync,
|
|
12
12
|
cpSync,
|
|
13
|
-
existsSync,
|
|
13
|
+
existsSync as existsSync2,
|
|
14
14
|
mkdirSync,
|
|
15
15
|
mkdtempSync,
|
|
16
|
-
readdirSync,
|
|
17
|
-
readFileSync,
|
|
16
|
+
readdirSync as readdirSync2,
|
|
17
|
+
readFileSync as readFileSync2,
|
|
18
18
|
rmSync,
|
|
19
|
-
writeFileSync
|
|
19
|
+
writeFileSync as writeFileSync2
|
|
20
20
|
} from "fs";
|
|
21
21
|
import { tmpdir } from "os";
|
|
22
|
-
import { dirname, join
|
|
22
|
+
import { dirname, join as join2 } from "path";
|
|
23
23
|
import { Readable } from "stream";
|
|
24
24
|
import { pipeline } from "stream/promises";
|
|
25
25
|
import { fileURLToPath } from "url";
|
|
26
26
|
import ora from "ora";
|
|
27
27
|
import React, { useState } from "react";
|
|
28
28
|
import { extract } from "tar";
|
|
29
|
+
|
|
30
|
+
// src/utils.ts
|
|
31
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync } from "fs";
|
|
32
|
+
import { basename, join, resolve } from "path";
|
|
33
|
+
var SAFE_DIR_ENTRIES = /* @__PURE__ */ new Set([
|
|
34
|
+
".claude",
|
|
35
|
+
".cursor",
|
|
36
|
+
".DS_Store",
|
|
37
|
+
".git",
|
|
38
|
+
".gitattributes",
|
|
39
|
+
".gitignore",
|
|
40
|
+
".gitlab-ci.yml",
|
|
41
|
+
".hg",
|
|
42
|
+
".hgcheck",
|
|
43
|
+
".hgignore",
|
|
44
|
+
".idea",
|
|
45
|
+
".npmignore",
|
|
46
|
+
".travis.yml",
|
|
47
|
+
".vscode",
|
|
48
|
+
".zed",
|
|
49
|
+
"LICENSE",
|
|
50
|
+
"Thumbs.db",
|
|
51
|
+
"docs",
|
|
52
|
+
"mkdocs.yml",
|
|
53
|
+
"npm-debug.log",
|
|
54
|
+
"yarn-debug.log",
|
|
55
|
+
"yarn-error.log",
|
|
56
|
+
"yarnrc.yml",
|
|
57
|
+
".yarn"
|
|
58
|
+
]);
|
|
59
|
+
function isSafeEntry(name) {
|
|
60
|
+
return SAFE_DIR_ENTRIES.has(name);
|
|
61
|
+
}
|
|
62
|
+
function findUnsafeEntries(dir) {
|
|
63
|
+
return readdirSync(dir).filter((entry) => !isSafeEntry(entry)).sort();
|
|
64
|
+
}
|
|
65
|
+
function sanitizePackageName(raw) {
|
|
66
|
+
return raw.toLowerCase().replace(/[^a-z0-9_.-]/g, "-").replace(/^[.-]+/, "").replace(/[.-]+$/, "") || "my-app";
|
|
67
|
+
}
|
|
68
|
+
function deriveProjectInfo(rawName, cwd) {
|
|
69
|
+
const name = rawName.trim();
|
|
70
|
+
if (name === ".") {
|
|
71
|
+
const displayName = basename(cwd);
|
|
72
|
+
return {
|
|
73
|
+
useCurrentDir: true,
|
|
74
|
+
projectPath: cwd,
|
|
75
|
+
displayName,
|
|
76
|
+
packageName: sanitizePackageName(displayName)
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
useCurrentDir: false,
|
|
81
|
+
projectPath: resolve(cwd, name),
|
|
82
|
+
displayName: name,
|
|
83
|
+
packageName: name
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function updatePackageJson(projectPath, projectName) {
|
|
87
|
+
const packageJsonPath = join(projectPath, "package.json");
|
|
88
|
+
const packageJsonContent = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
89
|
+
packageJsonContent.name = projectName;
|
|
90
|
+
packageJsonContent.description = `MCP server: ${projectName}`;
|
|
91
|
+
writeFileSync(packageJsonPath, JSON.stringify(packageJsonContent, null, 2));
|
|
92
|
+
}
|
|
93
|
+
function updateIndexTs(projectPath, projectName) {
|
|
94
|
+
const indexPath = join(projectPath, "index.ts");
|
|
95
|
+
if (!existsSync(indexPath)) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
let content = readFileSync(indexPath, "utf-8");
|
|
99
|
+
content = content.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
|
|
100
|
+
writeFileSync(indexPath, content);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// src/index.tsx
|
|
29
104
|
var __filename = fileURLToPath(import.meta.url);
|
|
30
105
|
var __dirname = dirname(__filename);
|
|
31
106
|
function runPackageManager(packageManager, args, cwd) {
|
|
@@ -123,7 +198,7 @@ async function addSkillsToProject(projectPath) {
|
|
|
123
198
|
const REPO_NAME = "mcp-use";
|
|
124
199
|
const REPO_COMMIT = "main";
|
|
125
200
|
const tarballUrl = `https://codeload.github.com/${REPO_OWNER}/${REPO_NAME}/tar.gz/${REPO_COMMIT}`;
|
|
126
|
-
const tempDir = mkdtempSync(
|
|
201
|
+
const tempDir = mkdtempSync(join2(tmpdir(), "mcp-use-skills-"));
|
|
127
202
|
try {
|
|
128
203
|
const response = await fetch(tarballUrl);
|
|
129
204
|
if (!response.ok) {
|
|
@@ -138,8 +213,8 @@ async function addSkillsToProject(projectPath) {
|
|
|
138
213
|
// Removes 'mcp-use-{commit}/' prefix
|
|
139
214
|
})
|
|
140
215
|
);
|
|
141
|
-
const skillsPath =
|
|
142
|
-
if (!
|
|
216
|
+
const skillsPath = join2(tempDir, "skills");
|
|
217
|
+
if (!existsSync2(skillsPath)) {
|
|
143
218
|
throw new Error("Skills folder not found in tarball");
|
|
144
219
|
}
|
|
145
220
|
const presets = ["cursor", "claude-code", "codex"];
|
|
@@ -150,10 +225,10 @@ async function addSkillsToProject(projectPath) {
|
|
|
150
225
|
};
|
|
151
226
|
for (const preset of presets) {
|
|
152
227
|
const folderName = presetFolders[preset];
|
|
153
|
-
const outputPath =
|
|
228
|
+
const outputPath = join2(projectPath, folderName, "skills");
|
|
154
229
|
cpSync(skillsPath, outputPath, { recursive: true });
|
|
155
230
|
}
|
|
156
|
-
const skillNames =
|
|
231
|
+
const skillNames = readdirSync2(skillsPath, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
157
232
|
sendInstallTelemetryEvent(presets.join(","), skillNames.join(","));
|
|
158
233
|
} catch (error) {
|
|
159
234
|
console.log(
|
|
@@ -207,7 +282,7 @@ function renderLogo() {
|
|
|
207
282
|
console.log(chalk.gray.bold(" by Manufact"));
|
|
208
283
|
}
|
|
209
284
|
var packageJson = JSON.parse(
|
|
210
|
-
|
|
285
|
+
readFileSync2(join2(__dirname, "../package.json"), "utf-8")
|
|
211
286
|
);
|
|
212
287
|
function getCurrentPackageVersions(isDevelopment = false, useCanary = false) {
|
|
213
288
|
const versions = {};
|
|
@@ -241,7 +316,7 @@ function getCurrentPackageVersions(isDevelopment = false, useCanary = false) {
|
|
|
241
316
|
return versions;
|
|
242
317
|
}
|
|
243
318
|
function processTemplateFile(filePath, versions, isDevelopment = false, useCanary = false) {
|
|
244
|
-
const content =
|
|
319
|
+
const content = readFileSync2(filePath, "utf-8");
|
|
245
320
|
let processedContent = content;
|
|
246
321
|
for (const [packageName, version] of Object.entries(versions)) {
|
|
247
322
|
const placeholder = `{{${packageName}_version}}`;
|
|
@@ -305,11 +380,11 @@ function processTemplateFile(filePath, versions, isDevelopment = false, useCanar
|
|
|
305
380
|
return processedContent;
|
|
306
381
|
}
|
|
307
382
|
function getAvailableTemplates() {
|
|
308
|
-
const templatesDir =
|
|
309
|
-
if (!
|
|
383
|
+
const templatesDir = join2(__dirname, "templates");
|
|
384
|
+
if (!existsSync2(templatesDir)) {
|
|
310
385
|
return [];
|
|
311
386
|
}
|
|
312
|
-
return
|
|
387
|
+
return readdirSync2(templatesDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name).sort();
|
|
313
388
|
}
|
|
314
389
|
function listTemplates() {
|
|
315
390
|
console.log("");
|
|
@@ -317,18 +392,18 @@ function listTemplates() {
|
|
|
317
392
|
console.log("");
|
|
318
393
|
console.log(chalk.bold("Available Templates:"));
|
|
319
394
|
console.log("");
|
|
320
|
-
const templatesDir =
|
|
395
|
+
const templatesDir = join2(__dirname, "templates");
|
|
321
396
|
const availableTemplates = getAvailableTemplates();
|
|
322
397
|
if (availableTemplates.length === 0) {
|
|
323
398
|
console.log(chalk.red("\u274C No templates found!"));
|
|
324
399
|
return;
|
|
325
400
|
}
|
|
326
401
|
for (const template of availableTemplates) {
|
|
327
|
-
const packageJsonPath =
|
|
402
|
+
const packageJsonPath = join2(templatesDir, template, "package.json");
|
|
328
403
|
let description = "MCP server template";
|
|
329
|
-
if (
|
|
404
|
+
if (existsSync2(packageJsonPath)) {
|
|
330
405
|
try {
|
|
331
|
-
const packageJson2 = JSON.parse(
|
|
406
|
+
const packageJson2 = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
|
|
332
407
|
description = packageJson2.description || description;
|
|
333
408
|
} catch (error) {
|
|
334
409
|
}
|
|
@@ -377,53 +452,74 @@ program.name("create-mcp-use-app").description("Create a new MCP server project"
|
|
|
377
452
|
if (!selectedTemplate) {
|
|
378
453
|
selectedTemplate = "starter";
|
|
379
454
|
}
|
|
380
|
-
const
|
|
381
|
-
if (!
|
|
455
|
+
const trimmedProjectName = projectName.trim();
|
|
456
|
+
if (!trimmedProjectName) {
|
|
382
457
|
console.error(chalk.red("\u274C Project name cannot be empty"));
|
|
383
458
|
process.exit(1);
|
|
384
459
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
)
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
460
|
+
const { useCurrentDir, projectPath, displayName, packageName } = deriveProjectInfo(trimmedProjectName, process.cwd());
|
|
461
|
+
if (useCurrentDir) {
|
|
462
|
+
const unsafeEntries = findUnsafeEntries(projectPath);
|
|
463
|
+
if (unsafeEntries.length > 0) {
|
|
464
|
+
console.error(
|
|
465
|
+
chalk.red(
|
|
466
|
+
"\u274C Cannot initialize here \u2014 these entries would clash with the template:"
|
|
467
|
+
)
|
|
468
|
+
);
|
|
469
|
+
for (const entry of unsafeEntries) {
|
|
470
|
+
console.error(chalk.red(` \u2022 ${entry}`));
|
|
471
|
+
}
|
|
472
|
+
console.error("");
|
|
473
|
+
console.error(
|
|
474
|
+
chalk.yellow(
|
|
475
|
+
" Remove these files, or pass a project name to scaffold into a new subdirectory instead."
|
|
476
|
+
)
|
|
477
|
+
);
|
|
478
|
+
process.exit(1);
|
|
479
|
+
}
|
|
480
|
+
} else {
|
|
481
|
+
if (trimmedProjectName.includes("..") || trimmedProjectName.includes("/") || trimmedProjectName.includes("\\")) {
|
|
482
|
+
console.error(
|
|
483
|
+
chalk.red(
|
|
484
|
+
'\u274C Project name cannot contain path separators or ".."'
|
|
485
|
+
)
|
|
486
|
+
);
|
|
487
|
+
console.error(
|
|
488
|
+
chalk.yellow(' Use simple names like "my-mcp-server"')
|
|
489
|
+
);
|
|
490
|
+
process.exit(1);
|
|
491
|
+
}
|
|
492
|
+
const protectedNames = [
|
|
493
|
+
"node_modules",
|
|
494
|
+
".git",
|
|
495
|
+
".env",
|
|
496
|
+
"package.json",
|
|
497
|
+
"src",
|
|
498
|
+
"dist"
|
|
499
|
+
];
|
|
500
|
+
if (protectedNames.includes(trimmedProjectName.toLowerCase())) {
|
|
501
|
+
console.error(
|
|
502
|
+
chalk.red(`\u274C Cannot use protected name "${trimmedProjectName}"`)
|
|
503
|
+
);
|
|
504
|
+
console.error(
|
|
505
|
+
chalk.yellow(" Please choose a different project name")
|
|
506
|
+
);
|
|
507
|
+
process.exit(1);
|
|
508
|
+
}
|
|
509
|
+
if (existsSync2(projectPath)) {
|
|
510
|
+
console.error(
|
|
511
|
+
chalk.red(`\u274C Directory "${trimmedProjectName}" already exists!`)
|
|
512
|
+
);
|
|
513
|
+
console.error(
|
|
514
|
+
chalk.yellow(
|
|
515
|
+
" Please choose a different name or remove the existing directory"
|
|
516
|
+
)
|
|
517
|
+
);
|
|
518
|
+
process.exit(1);
|
|
519
|
+
}
|
|
520
|
+
mkdirSync(projectPath, { recursive: true });
|
|
425
521
|
}
|
|
426
|
-
|
|
522
|
+
console.log(chalk.cyan(`\u{1F680} Creating MCP server "${displayName}"...`));
|
|
427
523
|
const validatedTemplate = validateTemplateName(selectedTemplate);
|
|
428
524
|
const versions = getCurrentPackageVersions(options.dev, options.canary);
|
|
429
525
|
await copyTemplate(
|
|
@@ -433,8 +529,8 @@ program.name("create-mcp-use-app").description("Create a new MCP server project"
|
|
|
433
529
|
options.dev,
|
|
434
530
|
options.canary
|
|
435
531
|
);
|
|
436
|
-
updatePackageJson(projectPath,
|
|
437
|
-
updateIndexTs(projectPath,
|
|
532
|
+
updatePackageJson(projectPath, packageName);
|
|
533
|
+
updateIndexTs(projectPath, packageName);
|
|
438
534
|
if (options.template !== void 0) {
|
|
439
535
|
if (options.install === void 0) {
|
|
440
536
|
options.install = false;
|
|
@@ -527,7 +623,7 @@ program.name("create-mcp-use-app").description("Create a new MCP server project"
|
|
|
527
623
|
}
|
|
528
624
|
console.log("");
|
|
529
625
|
console.log(chalk.bold("\u{1F4C1} Project structure:"));
|
|
530
|
-
console.log(` ${
|
|
626
|
+
console.log(` ${useCurrentDir ? "." : displayName}/`);
|
|
531
627
|
if (skillsInstalled) {
|
|
532
628
|
console.log(" \u251C\u2500\u2500 .agent/skills/");
|
|
533
629
|
console.log(" \u251C\u2500\u2500 .claude/skills/");
|
|
@@ -564,7 +660,9 @@ program.name("create-mcp-use-app").description("Create a new MCP server project"
|
|
|
564
660
|
}
|
|
565
661
|
console.log("");
|
|
566
662
|
console.log(chalk.bold("\u{1F680} To get started:"));
|
|
567
|
-
|
|
663
|
+
if (!useCurrentDir) {
|
|
664
|
+
console.log(chalk.cyan(` cd ${displayName}`));
|
|
665
|
+
}
|
|
568
666
|
if (!shouldInstall) {
|
|
569
667
|
console.log(
|
|
570
668
|
chalk.cyan(` ${getInstallCommand(usedPackageManager)}`)
|
|
@@ -752,7 +850,7 @@ function validateTemplateName(template) {
|
|
|
752
850
|
async function copyTemplate(projectPath, template, versions, isDevelopment = false, useCanary = false) {
|
|
753
851
|
const repoInfo = parseGitHubRepoUrl(template);
|
|
754
852
|
if (repoInfo) {
|
|
755
|
-
const tempDir = mkdtempSync(
|
|
853
|
+
const tempDir = mkdtempSync(join2(tmpdir(), "create-mcp-use-app-"));
|
|
756
854
|
try {
|
|
757
855
|
await cloneGitHubRepo(repoInfo, tempDir);
|
|
758
856
|
copyDirectoryWithProcessing(
|
|
@@ -775,12 +873,12 @@ async function copyTemplate(projectPath, template, versions, isDevelopment = fal
|
|
|
775
873
|
}
|
|
776
874
|
return;
|
|
777
875
|
}
|
|
778
|
-
const templatePath =
|
|
779
|
-
if (!
|
|
876
|
+
const templatePath = join2(__dirname, "templates", template);
|
|
877
|
+
if (!existsSync2(templatePath)) {
|
|
780
878
|
console.error(chalk.red(`\u274C Template "${template}" not found!`));
|
|
781
|
-
const templatesDir =
|
|
782
|
-
if (
|
|
783
|
-
const availableTemplates =
|
|
879
|
+
const templatesDir = join2(__dirname, "templates");
|
|
880
|
+
if (existsSync2(templatesDir)) {
|
|
881
|
+
const availableTemplates = readdirSync2(templatesDir, {
|
|
784
882
|
withFileTypes: true
|
|
785
883
|
}).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name).sort();
|
|
786
884
|
console.log(`Available templates: ${availableTemplates.join(", ")}`);
|
|
@@ -807,14 +905,14 @@ async function copyTemplate(projectPath, template, versions, isDevelopment = fal
|
|
|
807
905
|
);
|
|
808
906
|
}
|
|
809
907
|
function copyDirectoryWithProcessing(src, dest, versions, isDevelopment, useCanary = false) {
|
|
810
|
-
const entries =
|
|
908
|
+
const entries = readdirSync2(src, { withFileTypes: true });
|
|
811
909
|
for (const entry of entries) {
|
|
812
910
|
if (entry.name === ".git") {
|
|
813
911
|
continue;
|
|
814
912
|
}
|
|
815
|
-
const srcPath =
|
|
913
|
+
const srcPath = join2(src, entry.name);
|
|
816
914
|
const destName = entry.name === "gitignore" ? ".gitignore" : entry.name;
|
|
817
|
-
const destPath =
|
|
915
|
+
const destPath = join2(dest, destName);
|
|
818
916
|
if (entry.isDirectory()) {
|
|
819
917
|
mkdirSync(destPath, { recursive: true });
|
|
820
918
|
copyDirectoryWithProcessing(
|
|
@@ -832,29 +930,13 @@ function copyDirectoryWithProcessing(src, dest, versions, isDevelopment, useCana
|
|
|
832
930
|
isDevelopment,
|
|
833
931
|
useCanary
|
|
834
932
|
);
|
|
835
|
-
|
|
933
|
+
writeFileSync2(destPath, processedContent);
|
|
836
934
|
} else {
|
|
837
935
|
copyFileSync(srcPath, destPath);
|
|
838
936
|
}
|
|
839
937
|
}
|
|
840
938
|
}
|
|
841
939
|
}
|
|
842
|
-
function updatePackageJson(projectPath, projectName) {
|
|
843
|
-
const packageJsonPath = join(projectPath, "package.json");
|
|
844
|
-
const packageJsonContent = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
845
|
-
packageJsonContent.name = projectName;
|
|
846
|
-
packageJsonContent.description = `MCP server: ${projectName}`;
|
|
847
|
-
writeFileSync(packageJsonPath, JSON.stringify(packageJsonContent, null, 2));
|
|
848
|
-
}
|
|
849
|
-
function updateIndexTs(projectPath, projectName) {
|
|
850
|
-
const indexPath = join(projectPath, "index.ts");
|
|
851
|
-
if (!existsSync(indexPath)) {
|
|
852
|
-
return;
|
|
853
|
-
}
|
|
854
|
-
let content = readFileSync(indexPath, "utf-8");
|
|
855
|
-
content = content.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
|
|
856
|
-
writeFileSync(indexPath, content);
|
|
857
|
-
}
|
|
858
940
|
function InstallPrompt({
|
|
859
941
|
packageManager,
|
|
860
942
|
onSubmit
|
|
@@ -924,17 +1006,31 @@ function ProjectNameInput({ onSubmit }) {
|
|
|
924
1006
|
setError("Project name is required");
|
|
925
1007
|
return;
|
|
926
1008
|
}
|
|
927
|
-
if (
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1009
|
+
if (trimmed === ".") {
|
|
1010
|
+
const unsafeEntries = findUnsafeEntries(process.cwd());
|
|
1011
|
+
if (unsafeEntries.length > 0) {
|
|
1012
|
+
const list = unsafeEntries.map((entry) => ` \u2022 ${entry}`).join("\n");
|
|
1013
|
+
setError(
|
|
1014
|
+
`Cannot initialize here \u2014 these entries would clash with the template:
|
|
1015
|
+
${list}
|
|
1016
|
+
|
|
1017
|
+
Remove these files, or pick a project name to scaffold into a subdirectory.`
|
|
1018
|
+
);
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
} else {
|
|
1022
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(trimmed)) {
|
|
1023
|
+
setError(
|
|
1024
|
+
"Project name can only contain letters, numbers, hyphens, and underscores"
|
|
1025
|
+
);
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
if (existsSync2(join2(process.cwd(), trimmed))) {
|
|
1029
|
+
setError(
|
|
1030
|
+
`Directory "${trimmed}" already exists! Please choose a different name.`
|
|
1031
|
+
);
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
938
1034
|
}
|
|
939
1035
|
onSubmit(trimmed);
|
|
940
1036
|
};
|
|
@@ -958,20 +1054,20 @@ async function promptForProjectName() {
|
|
|
958
1054
|
function TemplateSelector({
|
|
959
1055
|
onSelect
|
|
960
1056
|
}) {
|
|
961
|
-
const templatesDir =
|
|
962
|
-
if (!
|
|
1057
|
+
const templatesDir = join2(__dirname, "templates");
|
|
1058
|
+
if (!existsSync2(templatesDir)) {
|
|
963
1059
|
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, "\u274C Templates directory not found at: ", templatesDir), /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, " __dirname: ", __dirname));
|
|
964
1060
|
}
|
|
965
|
-
const availableTemplates =
|
|
1061
|
+
const availableTemplates = readdirSync2(templatesDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name).sort();
|
|
966
1062
|
if (availableTemplates.length === 0) {
|
|
967
1063
|
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: "red" }, "\u274C No templates found in: ", templatesDir));
|
|
968
1064
|
}
|
|
969
1065
|
const items = availableTemplates.map((template) => {
|
|
970
|
-
const packageJsonPath =
|
|
1066
|
+
const packageJsonPath = join2(templatesDir, template, "package.json");
|
|
971
1067
|
let description = "MCP server template";
|
|
972
|
-
if (
|
|
1068
|
+
if (existsSync2(packageJsonPath)) {
|
|
973
1069
|
try {
|
|
974
|
-
const packageJson2 = JSON.parse(
|
|
1070
|
+
const packageJson2 = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
|
|
975
1071
|
description = packageJson2.description || description;
|
|
976
1072
|
} catch (error) {
|
|
977
1073
|
}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const SAFE_DIR_ENTRIES: Set<string>;
|
|
2
|
+
export declare function isSafeEntry(name: string): boolean;
|
|
3
|
+
export declare function findUnsafeEntries(dir: string): string[];
|
|
4
|
+
export declare function sanitizePackageName(raw: string): string;
|
|
5
|
+
export type ProjectInfo = {
|
|
6
|
+
useCurrentDir: boolean;
|
|
7
|
+
projectPath: string;
|
|
8
|
+
displayName: string;
|
|
9
|
+
packageName: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function deriveProjectInfo(rawName: string, cwd: string): ProjectInfo;
|
|
12
|
+
export declare function updatePackageJson(projectPath: string, projectName: string): void;
|
|
13
|
+
export declare function updateIndexTs(projectPath: string, projectName: string): void;
|
|
14
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,gBAAgB,aAyB3B,CAAC;AAEH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAID,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAIvD;AAKD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQvD;AAMD,MAAM,MAAM,WAAW,GAAG;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAiB3E;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAQzE;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAUrE"}
|