create-glosc 0.4.1 → 0.4.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/dist/index.js.map +7 -0
- package/dist/scaffold.js.map +7 -0
- package/dist/templates.js +2 -1
- package/dist/templates.js.map +7 -0
- package/package.json +3 -2
- package/src/templates.ts +2 -1
- package/dist/entrytest.zip +0 -0
- package/dist/entrytest2.zip +0 -0
- package/dist/entrytest3.zip +0 -0
- package/dist/entrytest4.zip +0 -0
- package/dist/entrytest5.zip +0 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["import prompts from \"prompts\";\r\nimport * as path from \"node:path\";\r\nimport * as os from \"node:os\";\r\nimport { scaffoldProject } from \"./scaffold\";\r\n\r\ntype Language = \"python\" | \"typescript\";\r\n\r\ntype ProjectOptions = {\r\n projectName: string;\r\n description: string;\r\n author: string;\r\n language: Language;\r\n mainFileName: string;\r\n readme: boolean;\r\n license: boolean;\r\n};\r\n\r\ntype ParsedArgs = {\r\n defaults: boolean;\r\n language?: string;\r\n mainFileName?: string;\r\n description?: string;\r\n author?: string;\r\n readme?: boolean;\r\n license?: boolean;\r\n projectName?: string;\r\n};\r\n\r\nfunction parseArgs(argv: string[]): ParsedArgs {\r\n const result: ParsedArgs = {\r\n defaults: false,\r\n language: undefined,\r\n mainFileName: undefined,\r\n description: undefined,\r\n author: undefined,\r\n readme: undefined,\r\n license: undefined,\r\n projectName: undefined,\r\n };\r\n\r\n const args = Array.from(argv);\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const a = args[i];\r\n if (!a) continue;\r\n\r\n if (a === \"--defaults\" || a === \"--yes\" || a === \"-y\") {\r\n result.defaults = true;\r\n continue;\r\n }\r\n\r\n if (a === \"--no-readme\") {\r\n result.readme = false;\r\n continue;\r\n }\r\n\r\n if (a === \"--readme\") {\r\n result.readme = true;\r\n continue;\r\n }\r\n\r\n if (a === \"--no-license\") {\r\n result.license = false;\r\n continue;\r\n }\r\n\r\n if (a === \"--license\") {\r\n result.license = true;\r\n continue;\r\n }\r\n\r\n if (a === \"--language\" && i + 1 < args.length) {\r\n result.language = args[++i];\r\n continue;\r\n }\r\n\r\n if (a === \"--main\" && i + 1 < args.length) {\r\n result.mainFileName = args[++i];\r\n continue;\r\n }\r\n\r\n if (a === \"--description\" && i + 1 < args.length) {\r\n result.description = args[++i];\r\n continue;\r\n }\r\n\r\n if (a === \"--author\" && i + 1 < args.length) {\r\n result.author = args[++i];\r\n continue;\r\n }\r\n\r\n if (!a.startsWith(\"-\") && !result.projectName) {\r\n result.projectName = a;\r\n continue;\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction normalizeLanguage(value: unknown): Language | undefined {\r\n const v = String(value || \"\")\r\n .trim()\r\n .toLowerCase();\r\n if (v === \"py\" || v === \"python\") return \"python\";\r\n if (v === \"ts\" || v === \"typescript\") return \"typescript\";\r\n if (v === \"js\" || v === \"javascript\") {\r\n throw new Error(\r\n \"JavaScript template has been removed. Use --language typescript (or omit --language) instead.\"\r\n );\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction normalizeMainFileName(\r\n language: Language,\r\n mainFileNameRaw: unknown\r\n): string {\r\n const trimmed = String(mainFileNameRaw || \"\").trim();\r\n const defaultExt = language === \"python\" ? \".py\" : \".ts\";\r\n const base =\r\n trimmed.length > 0\r\n ? trimmed\r\n : language === \"python\"\r\n ? \"main.py\"\r\n : \"index.ts\";\r\n\r\n if (path.extname(base)) return base;\r\n return `${base}${defaultExt}`;\r\n}\r\n\r\nfunction normalizeProjectName(value: unknown): string {\r\n return String(value || \"\")\r\n .trim()\r\n .replace(/\\s+/g, \"-\");\r\n}\r\n\r\nfunction getDefaultAuthor(): string {\r\n const candidates = [\r\n process.env.GIT_AUTHOR_NAME,\r\n process.env.GIT_COMMITTER_NAME,\r\n process.env.USER,\r\n process.env.USERNAME,\r\n process.env.LOGNAME,\r\n ];\r\n\r\n for (const c of candidates) {\r\n const v = String(c || \"\").trim();\r\n if (v) return v;\r\n }\r\n\r\n try {\r\n const u = os.userInfo();\r\n const name = String(u?.username || \"\").trim();\r\n if (name) return name;\r\n } catch {\r\n // ignore\r\n }\r\n\r\n return \"Your Name\";\r\n}\r\n\r\nasync function run(): Promise<void> {\r\n const argv = process.argv.slice(2);\r\n const args = parseArgs(argv);\r\n\r\n if (args.defaults) {\r\n if (!args.projectName) {\r\n throw new Error(\r\n \"Project name is required (e.g. `npm create glosc@latest my-app -- --defaults`)\"\r\n );\r\n }\r\n\r\n const language = normalizeLanguage(args.language) || \"typescript\";\r\n\r\n const options: ProjectOptions = {\r\n projectName: normalizeProjectName(args.projectName),\r\n description: String(\r\n args.description || \"A brief description of your project\"\r\n ).trim(),\r\n author: String(args.author || getDefaultAuthor()).trim(),\r\n language,\r\n mainFileName: normalizeMainFileName(language, args.mainFileName),\r\n readme: args.readme !== undefined ? Boolean(args.readme) : true,\r\n license: args.license !== undefined ? Boolean(args.license) : true,\r\n };\r\n\r\n await scaffoldProject(options);\r\n return;\r\n }\r\n\r\n // allow `npm create ... <name>` to prefill\r\n prompts.override({\r\n projectName: args.projectName,\r\n author: args.author,\r\n });\r\n\r\n let selectedLanguage: Language | undefined;\r\n\r\n const response = await prompts(\r\n [\r\n {\r\n type: \"text\",\r\n name: \"projectName\",\r\n message: \"Project name:\",\r\n validate: (value: string) => {\r\n const name = String(value || \"\").trim();\r\n if (!name) return \"Project name is required\";\r\n if (name.includes(\"/\") || name.includes(\"\\\\\"))\r\n return \"Project name cannot include path separators\";\r\n return true;\r\n },\r\n },\r\n {\r\n type: \"text\",\r\n name: \"description\",\r\n message: \"Description:\",\r\n initial: \"A brief description of your project\",\r\n },\r\n {\r\n type: \"text\",\r\n name: \"author\",\r\n message: \"Author:\",\r\n initial: getDefaultAuthor(),\r\n },\r\n {\r\n type: \"select\",\r\n name: \"language\",\r\n message: \"Use Language:\",\r\n choices: [\r\n { title: \"Python\", value: \"python\" },\r\n { title: \"TypeScript\", value: \"typescript\" },\r\n ],\r\n onState: (state: { value: Language }) => {\r\n selectedLanguage = state.value;\r\n },\r\n },\r\n {\r\n type: (prev: Language) => (prev ? \"text\" : null),\r\n name: \"mainFileName\",\r\n message: \"Main File Name:\",\r\n initial: (prev: Language) =>\r\n prev === \"python\" ? \"main.py\" : \"index.ts\",\r\n validate: (value: string, values?: { language?: Language }) => {\r\n const name = String(value || \"\").trim();\r\n if (!name) return \"Main file name is required\";\r\n const ext = path.extname(name);\r\n const currentLanguage =\r\n values?.language || selectedLanguage;\r\n if (!currentLanguage) return true;\r\n const expected =\r\n currentLanguage === \"python\" ? \".py\" : \".ts\";\r\n if (ext && ext !== expected)\r\n return `Main file should end with ${expected}`;\r\n return true;\r\n },\r\n },\r\n {\r\n type: \"confirm\",\r\n name: \"readme\",\r\n message: \"Readme:\",\r\n initial: true,\r\n },\r\n {\r\n type: \"confirm\",\r\n name: \"license\",\r\n message: \"License (MIT):\",\r\n initial: true,\r\n },\r\n ],\r\n {\r\n onCancel: () => {\r\n process.exitCode = 1;\r\n return false;\r\n },\r\n }\r\n );\r\n\r\n if (!response || !response.projectName) {\r\n process.exitCode = 1;\r\n return;\r\n }\r\n\r\n const options: ProjectOptions = {\r\n projectName: normalizeProjectName(response.projectName),\r\n description: String(response.description || \"\").trim(),\r\n author: String(response.author || \"\").trim(),\r\n language: response.language as Language,\r\n mainFileName: normalizeMainFileName(\r\n response.language as Language,\r\n response.mainFileName\r\n ),\r\n readme: Boolean(response.readme),\r\n license: Boolean(response.license),\r\n };\r\n\r\n await scaffoldProject(options);\r\n}\r\n\r\nrun().catch((err) => {\r\n // eslint-disable-next-line no-console\r\n console.error(err);\r\n process.exitCode = 1;\r\n});\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["options", "prompts"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/scaffold.ts"],
|
|
4
|
+
"sourcesContent": ["import * as fs from \"node:fs/promises\";\r\nimport * as path from \"node:path\";\r\nimport { spawnSync } from \"node:child_process\";\r\nimport { getProjectFiles, type ProjectOptions } from \"./templates\";\r\n\r\nasync function pathExists(p: string): Promise<boolean> {\r\n try {\r\n await fs.access(p);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nasync function ensureDir(dirPath: string): Promise<void> {\r\n await fs.mkdir(dirPath, { recursive: true });\r\n}\r\n\r\nasync function writeFileEnsuringDir(\r\n filePath: string,\r\n content: string\r\n): Promise<void> {\r\n await ensureDir(path.dirname(filePath));\r\n await fs.writeFile(filePath, content, \"utf8\");\r\n}\r\n\r\nfunction tryInitGitRepo(targetRoot: string): void {\r\n try {\r\n const version = spawnSync(\"git\", [\"--version\"], {\r\n cwd: targetRoot,\r\n stdio: \"ignore\",\r\n shell: false,\r\n });\r\n\r\n if (version.status !== 0) return;\r\n\r\n const init = spawnSync(\"git\", [\"init\"], {\r\n cwd: targetRoot,\r\n stdio: \"ignore\",\r\n shell: false,\r\n });\r\n\r\n if (init.status !== 0) return;\r\n } catch {\r\n // best-effort: do not block scaffolding if git isn't available\r\n }\r\n}\r\n\r\nexport async function scaffoldProject(options: ProjectOptions): Promise<void> {\r\n const targetRoot = path.resolve(process.cwd(), options.projectName);\r\n\r\n if (await pathExists(targetRoot)) {\r\n throw new Error(`Target directory already exists: ${targetRoot}`);\r\n }\r\n\r\n const files = getProjectFiles(options);\r\n\r\n await ensureDir(targetRoot);\r\n\r\n for (const file of files) {\r\n const absPath = path.join(targetRoot, file.relativePath);\r\n await writeFileEnsuringDir(absPath, file.content);\r\n }\r\n\r\n tryInitGitRepo(targetRoot);\r\n\r\n // eslint-disable-next-line no-console\r\n console.log(`\\nCreated project at: ${targetRoot}`);\r\n}\r\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAoB;AACpB,WAAsB;AACtB,gCAA0B;AAC1B,uBAAqD;AAErD,eAAe,WAAW,GAA6B;AACnD,MAAI;AACA,UAAM,GAAG,OAAO,CAAC;AACjB,WAAO;AAAA,EACX,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAEA,eAAe,UAAU,SAAgC;AACrD,QAAM,GAAG,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAC/C;AAEA,eAAe,qBACX,UACA,SACa;AACb,QAAM,UAAU,KAAK,QAAQ,QAAQ,CAAC;AACtC,QAAM,GAAG,UAAU,UAAU,SAAS,MAAM;AAChD;AAEA,SAAS,eAAe,YAA0B;AAC9C,MAAI;AACA,UAAM,cAAU,qCAAU,OAAO,CAAC,WAAW,GAAG;AAAA,MAC5C,KAAK;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACX,CAAC;AAED,QAAI,QAAQ,WAAW,EAAG;AAE1B,UAAM,WAAO,qCAAU,OAAO,CAAC,MAAM,GAAG;AAAA,MACpC,KAAK;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACX,CAAC;AAED,QAAI,KAAK,WAAW,EAAG;AAAA,EAC3B,QAAQ;AAAA,EAER;AACJ;AAEA,eAAsB,gBAAgB,SAAwC;AAC1E,QAAM,aAAa,KAAK,QAAQ,QAAQ,IAAI,GAAG,QAAQ,WAAW;AAElE,MAAI,MAAM,WAAW,UAAU,GAAG;AAC9B,UAAM,IAAI,MAAM,oCAAoC,UAAU,EAAE;AAAA,EACpE;AAEA,QAAM,YAAQ,kCAAgB,OAAO;AAErC,QAAM,UAAU,UAAU;AAE1B,aAAW,QAAQ,OAAO;AACtB,UAAM,UAAU,KAAK,KAAK,YAAY,KAAK,YAAY;AACvD,UAAM,qBAAqB,SAAS,KAAK,OAAO;AAAA,EACpD;AAEA,iBAAe,UAAU;AAGzB,UAAQ,IAAI;AAAA,sBAAyB,UAAU,EAAE;AACrD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/templates.js
CHANGED
|
@@ -408,7 +408,7 @@ function nodePackageJson(options) {
|
|
|
408
408
|
private: true,
|
|
409
409
|
type: "module",
|
|
410
410
|
scripts: {
|
|
411
|
-
build:
|
|
411
|
+
build: `esbuild src/${mainFileName} --bundle --platform=node --format=esm --target=es2022 --packages=external --sourcemap --outfile=${distEntry}`,
|
|
412
412
|
start: `node ${distEntry}`,
|
|
413
413
|
package: "node scripts/package.mjs",
|
|
414
414
|
},
|
|
@@ -416,6 +416,7 @@ function nodePackageJson(options) {
|
|
|
416
416
|
"@modelcontextprotocol/sdk": "^1.24.3",
|
|
417
417
|
},
|
|
418
418
|
devDependencies: {
|
|
419
|
+
esbuild: "^0.20.2",
|
|
419
420
|
typescript: "^5.9.3",
|
|
420
421
|
"@types/node": "^22.19.2",
|
|
421
422
|
},
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/templates.ts"],
|
|
4
|
+
"sourcesContent": ["export type Language = \"python\" | \"typescript\";\r\n\r\nexport type ProjectOptions = {\r\n projectName: string;\r\n description: string;\r\n author: string;\r\n language: Language;\r\n mainFileName: string;\r\n readme: boolean;\r\n license: boolean;\r\n};\r\n\r\nexport type ProjectFile = {\r\n relativePath: string;\r\n content: string;\r\n};\r\n\r\nfunction gitignoreContent(language: Language): string {\r\n const common = [\r\n \"# OS\",\r\n \".DS_Store\",\r\n \"Thumbs.db\",\r\n \"Desktop.ini\",\r\n \"\",\r\n \"# Editors\",\r\n \".vscode/\",\r\n \".idea/\",\r\n \"*.swp\",\r\n \"\",\r\n \"# Env\",\r\n \".env\",\r\n \".env.*\",\r\n \"\",\r\n \"# Logs\",\r\n \"*.log\",\r\n \"\",\r\n \"# Builds / artifacts\",\r\n \"dist/\",\r\n \"build/\",\r\n \"*.zip\",\r\n \"\",\r\n ];\r\n\r\n const node = [\r\n \"# Node\",\r\n \"node_modules/\",\r\n \"npm-debug.log*\",\r\n \"yarn-debug.log*\",\r\n \"yarn-error.log*\",\r\n \"pnpm-debug.log*\",\r\n \"\",\r\n ];\r\n\r\n const python = [\r\n \"# Python\",\r\n \"__pycache__/\",\r\n \"*.py[cod]\",\r\n \"*.pyd\",\r\n \".Python\",\r\n \".venv/\",\r\n \"venv/\",\r\n \"ENV/\",\r\n \"env/\",\r\n \".pytest_cache/\",\r\n \".mypy_cache/\",\r\n \".ruff_cache/\",\r\n \"*.egg-info/\",\r\n \"\",\r\n ];\r\n\r\n return (\r\n common.join(\"\\n\") +\r\n (language === \"typescript\" ? node.join(\"\\n\") : python.join(\"\\n\"))\r\n );\r\n}\r\n\r\nfunction packagingScriptMjs(): string {\r\n // Keep this script dependency-free and avoid nested template literals.\r\n return [\r\n 'import { spawnSync } from \"node:child_process\";',\r\n 'import * as fs from \"node:fs\";',\r\n 'import * as fsp from \"node:fs/promises\";',\r\n 'import * as path from \"node:path\";',\r\n \"\",\r\n \"function run(cmd, args, opts = {}) {\",\r\n \" return spawnSync(cmd, args, {\",\r\n ' stdio: [\"ignore\", \"pipe\", \"pipe\"],',\r\n ' encoding: \"utf8\",',\r\n \" shell: false,\",\r\n \" ...opts,\",\r\n \" });\",\r\n \"}\",\r\n \"\",\r\n \"function runInherit(cmd, args, opts = {}) {\",\r\n \" return spawnSync(cmd, args, {\",\r\n ' stdio: \"inherit\",',\r\n ' encoding: \"utf8\",',\r\n \" shell: false,\",\r\n \" ...opts,\",\r\n \" });\",\r\n \"}\",\r\n \"\",\r\n \"function normalizeRelPath(p) {\",\r\n ' return String(p || \"\").replace(/\\\\\\\\/g, \"/\");',\r\n \"}\",\r\n \"\",\r\n \"function readJsonIfExists(filePath) {\",\r\n \" try {\",\r\n \" if (!fs.existsSync(filePath)) return undefined;\",\r\n ' const raw = fs.readFileSync(filePath, \"utf8\");',\r\n \" return JSON.parse(raw);\",\r\n \" } catch {\",\r\n \" return undefined;\",\r\n \" }\",\r\n \"}\",\r\n \"\",\r\n \"function detectTypeScriptProject() {\",\r\n ' if (fs.existsSync(\"tsconfig.json\")) return true;',\r\n ' const pkg = readJsonIfExists(\"package.json\");',\r\n ' const buildScript = String(pkg?.scripts?.build || \"\");',\r\n ' if (buildScript.includes(\"tsc\")) return true;',\r\n \" if (pkg?.devDependencies?.typescript) return true;\",\r\n \" return false;\",\r\n \"}\",\r\n \"\",\r\n \"function detectDistEntry() {\",\r\n \" // default requested: /dist/index.js\",\r\n ' const defaultEntry = \"dist/index.js\";',\r\n ' const pkg = readJsonIfExists(\"package.json\");',\r\n ' const start = String(pkg?.scripts?.start || \"\").trim();',\r\n \" const m = /^node\\\\s+(.+)$/.exec(start);\",\r\n ' const inferred = m && m[1] ? String(m[1]).trim() : \"\";',\r\n \" const entry = inferred || defaultEntry;\",\r\n \" return normalizeRelPath(entry);\",\r\n \"}\",\r\n \"\",\r\n \"function ensureGitRepoRoot() {\",\r\n ' const r = run(\"git\", [\"rev-parse\", \"--show-toplevel\"], { cwd: process.cwd() });',\r\n \" if (r.status !== 0) {\",\r\n ' const err = (r.stderr || r.stdout || \"\").trim();',\r\n \" throw new Error(\",\r\n ' \"git repo is required for packaging (to respect .gitignore).\\\\n\" + err,',\r\n \" );\",\r\n \" }\",\r\n ' const top = String(r.stdout || \"\").trim();',\r\n ' if (!top) throw new Error(\"Failed to resolve git repo root\");',\r\n \" process.chdir(top);\",\r\n \" return top;\",\r\n \"}\",\r\n \"\",\r\n \"function gitFileList() {\",\r\n ' const r = run(\"git\", [',\r\n ' \"ls-files\",',\r\n ' \"-z\",',\r\n ' \"--cached\",',\r\n ' \"--others\",',\r\n ' \"--exclude-standard\",',\r\n \" ]);\",\r\n \"\",\r\n \" if (r.status !== 0) {\",\r\n ' const err = (r.stderr || r.stdout || \"\").trim();',\r\n \" throw new Error(\",\r\n ' \"git is required for packaging (and to respect .gitignore).\\\\n\" + err,',\r\n \" );\",\r\n \" }\",\r\n \"\",\r\n ' const raw = r.stdout || \"\";',\r\n ' return raw.split(\"\\\\u0000\").filter(Boolean).map(normalizeRelPath);',\r\n \"}\",\r\n \"\",\r\n \"function shouldExcludeFromPackage(relPath) {\",\r\n \" const p = normalizeRelPath(relPath);\",\r\n \" if (!p) return true;\",\r\n \" // 1) scripts/package.mjs does not need to be packaged\",\r\n ' if (p === \"scripts/package.mjs\") return true;',\r\n \" // temp files created by this script\",\r\n ' if (p.startsWith(\".glosc-tmp/\")) return true;',\r\n \" return false;\",\r\n \"}\",\r\n \"\",\r\n \"function uniqStable(list) {\",\r\n \" const seen = new Set();\",\r\n \" const out = [];\",\r\n \" for (const item of list) {\",\r\n \" if (seen.has(item)) continue;\",\r\n \" seen.add(item);\",\r\n \" out.push(item);\",\r\n \" }\",\r\n \" return out;\",\r\n \"}\",\r\n \"\",\r\n \"async function ensureDir(p) {\",\r\n \" await fsp.mkdir(p, { recursive: true });\",\r\n \"}\",\r\n \"\",\r\n \"async function prepareTmpDir() {\",\r\n ' const tmpDir = path.join(process.cwd(), \".glosc-tmp\");',\r\n \" await fsp.rm(tmpDir, { recursive: true, force: true });\",\r\n \" await ensureDir(tmpDir);\",\r\n \" return tmpDir;\",\r\n \"}\",\r\n \"\",\r\n \"async function writeNulSeparatedList(tmpDir, filePaths) {\",\r\n \" // Use NUL-separated pathspec so we can pass it to git safely (no quoting issues).\",\r\n ' const listPath = path.join(tmpDir, \"pathspec.nul\");',\r\n \" const normalized = filePaths.map(normalizeRelPath);\",\r\n ' const buf = Buffer.from(normalized.join(\"\\u0000\") + \"\\u0000\", \"utf8\");',\r\n \" await fsp.writeFile(listPath, buf);\",\r\n \" return listPath;\",\r\n \"}\",\r\n \"\",\r\n \"function gitArchiveZipFromWorkingTreeFiles(outZip, filePaths) {\",\r\n \" // Create a temporary index so we can archive *tracked + untracked* files without\",\r\n \" // touching the user's real index or requiring a commit.\",\r\n ' const tmpIndex = path.join(process.cwd(), \".glosc-tmp\", \"index\");',\r\n \" const env = { ...process.env, GIT_INDEX_FILE: tmpIndex };\",\r\n \"\",\r\n \" // Add files (force-add so ignored build output like dist/index.js can be included).\",\r\n \" const add = run(\",\r\n ' \"git\",',\r\n \" [\",\r\n ' \"add\",',\r\n ' \"-f\",',\r\n ' \"--pathspec-from-file=.glosc-tmp/pathspec.nul\",',\r\n ' \"--pathspec-file-nul\",',\r\n ' \"--\",',\r\n \" ],\",\r\n \" { cwd: process.cwd(), env },\",\r\n \" );\",\r\n \" if (add.status !== 0) {\",\r\n \" // Fallback for older Git versions without --pathspec-from-file.\",\r\n \" const chunkSize = 200;\",\r\n \" for (let i = 0; i < filePaths.length; i += chunkSize) {\",\r\n \" const chunk = filePaths.slice(i, i + chunkSize);\",\r\n ' const r = run(\"git\", [\"add\", \"-f\", \"--\", ...chunk], { cwd: process.cwd(), env });',\r\n \" if (r.status !== 0) {\",\r\n ' const err = (r.stderr || r.stdout || \"\").trim();',\r\n ' throw new Error(\"git add (temp index) failed\\\\n\" + err);',\r\n \" }\",\r\n \" }\",\r\n \" }\",\r\n \"\",\r\n ' const wt = run(\"git\", [\"write-tree\"], { cwd: process.cwd(), env });',\r\n \" if (wt.status !== 0) {\",\r\n ' const err = (wt.stderr || wt.stdout || \"\").trim();',\r\n ' throw new Error(\"git write-tree failed\\\\n\" + err);',\r\n \" }\",\r\n ' const tree = String(wt.stdout || \"\").trim();',\r\n ' if (!tree) throw new Error(\"git write-tree produced empty tree hash\");',\r\n \"\",\r\n \" const ar = run(\",\r\n ' \"git\",',\r\n ' [\"archive\", \"--format=zip\", \"--output\", outZip, tree],',\r\n \" { cwd: process.cwd() },\",\r\n \" );\",\r\n \" if (ar.status !== 0) {\",\r\n ' const err = (ar.stderr || ar.stdout || \"\").trim();',\r\n ' throw new Error(\"git archive failed\\\\n\" + err);',\r\n \" }\",\r\n \"}\",\r\n \"\",\r\n \"function timestamp() {\",\r\n \" const d = new Date();\",\r\n ' const pad = (n) => String(n).padStart(2, \"0\");',\r\n \" return (\",\r\n \" String(d.getFullYear()) +\",\r\n \" pad(d.getMonth() + 1) +\",\r\n \" pad(d.getDate()) +\",\r\n ' \"-\" +',\r\n \" pad(d.getHours()) +\",\r\n \" pad(d.getMinutes()) +\",\r\n \" pad(d.getSeconds())\",\r\n \" );\",\r\n \"}\",\r\n \"\",\r\n \"async function main() {\",\r\n \" ensureGitRepoRoot();\",\r\n \" const isTs = detectTypeScriptProject();\",\r\n \" const distEntry = detectDistEntry();\",\r\n ' const isWin = process.platform === \"win32\";',\r\n \"\",\r\n \" // 2) For TypeScript, run build and package dist entry\",\r\n \" if (isTs) {\",\r\n \" const r = isWin\",\r\n ' ? runInherit(\"cmd\", [\"/d\", \"/s\", \"/c\", \"npm run build\"], { cwd: process.cwd() })',\r\n ' : runInherit(\"npm\", [\"run\", \"build\"], { cwd: process.cwd() });',\r\n ' if (r.error) throw new Error(\"Failed to run npm: \" + String(r.error?.message || r.error));',\r\n ' if (r.status !== 0) throw new Error(\"npm run build failed\");',\r\n \" if (!fs.existsSync(distEntry)) {\",\r\n ' throw new Error(\"Expected build output missing: \" + distEntry);',\r\n \" }\",\r\n \" }\",\r\n \"\",\r\n \" let files = gitFileList().filter((p) => !shouldExcludeFromPackage(p));\",\r\n \"\",\r\n \" if (isTs) {\",\r\n \" // dist/ is typically ignored; ensure we still include the built entry\",\r\n ' files = files.filter((p) => !p.startsWith(\"dist/\"));',\r\n \" files.push(distEntry);\",\r\n \" }\",\r\n \"\",\r\n \" files = uniqStable(files);\",\r\n \"\",\r\n \" if (files.length === 0) {\",\r\n \" throw new Error(\",\r\n ' \"No files found to package. If you just created the project, make sure git is initialized and .gitignore exists.\",',\r\n \" );\",\r\n \" }\",\r\n \"\",\r\n ' const outDir = path.join(process.cwd(), \"dist\");',\r\n \" await ensureDir(outDir);\",\r\n ' const outZip = path.join(outDir, \"glosc-package-\" + timestamp() + \".zip\");',\r\n \"\",\r\n \" const tmpDir = await prepareTmpDir();\",\r\n \" try {\",\r\n \" await writeNulSeparatedList(tmpDir, files);\",\r\n \" gitArchiveZipFromWorkingTreeFiles(outZip, files);\",\r\n \" } finally {\",\r\n \" try {\",\r\n \" await fsp.rm(tmpDir, { recursive: true, force: true });\",\r\n \" } catch {\",\r\n \" // ignore\",\r\n \" }\",\r\n \" }\",\r\n \"\",\r\n \" const st = await fsp.stat(outZip).catch(() => undefined);\",\r\n \" if (!st || st.size <= 0) {\",\r\n ' throw new Error(\"Packaging failed: zip was not created: \" + outZip);',\r\n \" }\",\r\n \"\",\r\n ' console.log(\"Created: \" + outZip);',\r\n \"}\",\r\n \"\",\r\n \"main().catch((err) => {\",\r\n \" console.error(String(err?.message || err));\",\r\n \" process.exit(1);\",\r\n \"});\",\r\n ].join(\"\\n\");\r\n}\r\n\r\nfunction entryPath(options: ProjectOptions): string {\r\n return options.language === \"python\"\r\n ? options.mainFileName\r\n : `src/${options.mainFileName}`;\r\n}\r\n\r\nfunction mcpRuntime(options: ProjectOptions): \"python\" | \"node\" {\r\n return options.language === \"python\" ? \"python\" : \"node\";\r\n}\r\n\r\nfunction mcpEntry(options: ProjectOptions): string {\r\n if (options.language === \"python\") return options.mainFileName;\r\n return `dist/${options.mainFileName.replace(/\\.ts$/i, \".js\")}`;\r\n}\r\n\r\nfunction escapeYamlString(value: unknown): string {\r\n const s = String(value ?? \"\");\r\n const escaped = s.replace(/\"/g, '\\\\\"');\r\n return `\"${escaped}\"`;\r\n}\r\n\r\nfunction mitLicenseText({ author }: Pick<ProjectOptions, \"author\">): string {\r\n const year = new Date().getFullYear();\r\n const owner = String(author || \"\").trim() || \"Copyright Holder\";\r\n return `MIT License\\n\\nCopyright (c) ${year} ${owner}\\n\\nPermission is hereby granted, free of charge, to any person obtaining a copy\\nof this software and associated documentation files (the \\\"Software\\\"), to deal\\nin the Software without restriction, including without limitation the rights\\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\ncopies of the Software, and to permit persons to whom the Software is\\nfurnished to do so, subject to the following conditions:\\n\\nThe above copyright notice and this permission notice shall be included in all\\ncopies or substantial portions of the Software.\\n\\nTHE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\\nSOFTWARE.\\n`;\r\n}\r\n\r\nfunction projectReadme(options: ProjectOptions): string {\r\n const { projectName, description, author, language, mainFileName } =\r\n options;\r\n const langLabel = language === \"python\" ? \"Python\" : \"TypeScript\";\r\n\r\n const entry = entryPath(options);\r\n const runSection =\r\n language === \"python\"\r\n ? `## Run (Python)\\n\\n\\n\\n1) Install deps\\n\\n\\n\\n\\`\\`\\`sh\\npython -m pip install -r requirements.txt\\n\\`\\`\\`\\n\\n\\n\\n2) Run the MCP server (stdio)\\n\\n\\n\\n\\`\\`\\`sh\\npython ${entry}\\n\\`\\`\\`\\n\\n\\n\\nThis server speaks MCP over stdio. Connect using an MCP client (e.g. an editor integration).\\n`\r\n : `## Run (TypeScript)\\n\\n\\n\\n1) Install deps\\n\\n\\n\\n\\`\\`\\`sh\\nnpm install\\n\\`\\`\\`\\n\\n\\n\\n2) Build\\n\\n\\n\\n\\`\\`\\`sh\\nnpm run build\\n\\`\\`\\`\\n\\n\\n\\n3) Run the MCP server (stdio)\\n\\n\\n\\n\\`\\`\\`sh\\nnpm start\\n\\`\\`\\`\\n\\n\\n\\nThis server speaks MCP over stdio. Connect using an MCP client (e.g. an editor integration).\\n`;\r\n\r\n return `# ${projectName}\\n\\n${description || \"\"}\\n\\n## Author\\n\\n${\r\n author || \"\"\r\n }\\n\\n## Language\\n\\n${langLabel}\\n\\n## Entry\\n\\n- ${entry}\\n\\n## MCP Tools\\n\\n- get_current_time: Returns the current time (UTC, ISO 8601)\\n\\n${runSection}\\n\\n## Config\\n\\n- config.yml (see: mcp.runtime / mcp.entry)\\n`;\r\n}\r\n\r\nfunction packagingPackageJson(options: ProjectOptions): string {\r\n const { projectName, description, author } = options;\r\n const pkg: Record<string, unknown> = {\r\n name: projectName,\r\n version: \"0.1.0\",\r\n description: description || \"\",\r\n author: author || \"\",\r\n private: true,\r\n scripts: {\r\n package: \"node scripts/package.mjs\",\r\n },\r\n };\r\n\r\n return JSON.stringify(pkg, null, 2) + \"\\n\";\r\n}\r\n\r\nfunction configYml(options: ProjectOptions): string {\r\n const { projectName, description, author, language, mainFileName } =\r\n options;\r\n return [\r\n `name: ${escapeYamlString(projectName)}`,\r\n `description: ${escapeYamlString(description)}`,\r\n `icon: ${escapeYamlString(\"\")}`,\r\n `language: ${escapeYamlString(language)}`,\r\n `author: ${escapeYamlString(author)}`,\r\n `mcp:`,\r\n ` runtime: ${escapeYamlString(mcpRuntime(options))}`,\r\n ` entry: ${escapeYamlString(mcpEntry(options))}`,\r\n ` cwd: ${escapeYamlString(\".\")}`,\r\n ` env: {}`,\r\n ` args: []`,\r\n \"\",\r\n ].join(\"\\n\");\r\n}\r\n\r\nfunction pythonMain({\r\n projectName,\r\n}: Pick<ProjectOptions, \"projectName\" | \"description\">): string {\r\n const safeName = String(projectName || \"mcp-server\").replace(/\"/g, '\\\\\"');\r\n\r\n return `from datetime import datetime, timezone\\n\\nfrom mcp.server.fastmcp import FastMCP\\n\\n# Minimal MCP server (stdio)\\n\\nmcp = FastMCP(\"${safeName}\")\\n\\n\\n@mcp.tool()\\nasync def get_current_time() -> str:\\n \"\"\"Return the current time in UTC (ISO 8601).\"\"\"\\n\\n return datetime.now(timezone.utc).isoformat()\\n\\n\\ndef main():\\n mcp.run(transport=\"stdio\")\\n\\n\\nif __name__ == \"__main__\":\\n main()\\n`;\r\n}\r\n\r\nfunction pythonRequirements(): string {\r\n return `mcp\\n`;\r\n}\r\n\r\nfunction pythonPyproject({\r\n projectName,\r\n author,\r\n}: Pick<ProjectOptions, \"projectName\" | \"author\">): string {\r\n const safeName = String(projectName || \"glosc-project\")\r\n .trim()\r\n .replace(/\\s+/g, \"-\");\r\n\r\n const safeAuthor = String(author || \"\").replace(/\"/g, '\\\\\"');\r\n\r\n const authorsLine = safeAuthor.trim()\r\n ? `authors = [{ name = \"${safeAuthor}\" }]\\n`\r\n : \"\";\r\n\r\n return `# Minimal pyproject.toml (adjust as needed)\\n\\n[project]\\nname = \"${safeName}\"\\nversion = \"0.1.0\"\\ndescription = \"\"\\n${authorsLine}requires-python = \">=3.10\"\\ndependencies = [\\n \"mcp\",\\n]\\n\\n[build-system]\\nrequires = [\"setuptools>=61.0\"]\\nbuild-backend = \"setuptools.build_meta\"\\n`;\r\n}\r\n\r\nfunction nodePackageJson(options: ProjectOptions): string {\r\n const { projectName, description, author, mainFileName } = options;\r\n const distEntry = `dist/${mainFileName.replace(/\\.ts$/i, \".js\")}`;\r\n\r\n const pkg: Record<string, unknown> = {\r\n name: projectName,\r\n version: \"0.1.0\",\r\n description: description || \"\",\r\n author: author || \"\",\r\n private: true,\r\n type: \"module\",\r\n scripts: {\r\n build: \"tsc -p .\",\r\n start: `node ${distEntry}`,\r\n package: \"node scripts/package.mjs\",\r\n },\r\n dependencies: {\r\n \"@modelcontextprotocol/sdk\": \"^1.24.3\",\r\n },\r\n devDependencies: {\r\n typescript: \"^5.9.3\",\r\n \"@types/node\": \"^22.19.2\",\r\n },\r\n };\r\n\r\n return JSON.stringify(pkg, null, 2) + \"\\n\";\r\n}\r\n\r\nfunction tsConfig(): string {\r\n return (\r\n JSON.stringify(\r\n {\r\n compilerOptions: {\r\n target: \"ES2022\",\r\n module: \"Node16\",\r\n strict: true,\r\n outDir: \"dist\",\r\n rootDir: \"src\",\r\n esModuleInterop: true,\r\n moduleResolution: \"Node16\",\r\n types: [\"node\"],\r\n skipLibCheck: true,\r\n forceConsistentCasingInFileNames: true,\r\n },\r\n include: [\"src/**/*.ts\"],\r\n },\r\n null,\r\n 2\r\n ) + \"\\n\"\r\n );\r\n}\r\n\r\nfunction tsMain({ projectName }: Pick<ProjectOptions, \"projectName\">): string {\r\n const safeName = String(projectName || \"mcp-server\").replace(/\"/g, '\\\\\"');\r\n\r\n return `import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\\n\\nconst server = new McpServer({\\n name: \"${safeName}\",\\n version: \"0.1.0\",\\n});\\n\\nserver.registerTool(\\n \"get_current_time\",\\n {\\n title: \"Get Current Time\",\\n description: \"Return the current time in UTC (ISO 8601)\",\\n inputSchema: {},\\n },\\n async () => {\\n return {\\n content: [\\n {\\n type: \"text\",\\n text: new Date().toISOString(),\\n },\\n ],\\n };\\n },\\n);\\n\\nasync function main() {\\n const transport = new StdioServerTransport();\\n await server.connect(transport);\\n console.error(\"MCP Server running on stdio\");\\n}\\n\\nmain().catch((error) => {\\n console.error(\"Fatal error in main():\", error);\\n process.exit(1);\\n});\\n`;\r\n}\r\n\r\nexport function getProjectFiles(options: ProjectOptions): ProjectFile[] {\r\n const files: ProjectFile[] = [];\r\n\r\n files.push({\r\n relativePath: \".gitignore\",\r\n content: gitignoreContent(options.language),\r\n });\r\n files.push({\r\n relativePath: \"scripts/package.mjs\",\r\n content: packagingScriptMjs(),\r\n });\r\n files.push({ relativePath: \"config.yml\", content: configYml(options) });\r\n\r\n if (options.readme) {\r\n files.push({\r\n relativePath: \"README.md\",\r\n content: projectReadme(options),\r\n });\r\n }\r\n\r\n if (options.license) {\r\n files.push({\r\n relativePath: \"LICENSE\",\r\n content: mitLicenseText(options),\r\n });\r\n }\r\n\r\n if (options.language === \"python\") {\r\n files.push({\r\n relativePath: options.mainFileName,\r\n content: pythonMain(options),\r\n });\r\n files.push({\r\n relativePath: \"requirements.txt\",\r\n content: pythonRequirements(),\r\n });\r\n files.push({\r\n relativePath: \"pyproject.toml\",\r\n content: pythonPyproject(options),\r\n });\r\n files.push({\r\n relativePath: \"package.json\",\r\n content: packagingPackageJson(options),\r\n });\r\n }\r\n\r\n if (options.language === \"typescript\") {\r\n files.push({\r\n relativePath: `src/${options.mainFileName}`,\r\n content: tsMain(options),\r\n });\r\n files.push({\r\n relativePath: \"package.json\",\r\n content: nodePackageJson(options),\r\n });\r\n files.push({ relativePath: \"tsconfig.json\", content: tsConfig() });\r\n }\r\n\r\n return files;\r\n}\r\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBA,SAAS,iBAAiB,UAA4B;AAClD,QAAM,SAAS;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,QAAM,OAAO;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,QAAM,SAAS;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AAEA,SACI,OAAO,KAAK,IAAI,KACf,aAAa,eAAe,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI;AAEvE;AAEA,SAAS,qBAA6B;AAElC,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAC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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-glosc",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Scaffold Glosc projects (Python/TypeScript) via npm create",
|
|
5
5
|
"author": "glosc-ai",
|
|
6
6
|
"license": "MIT",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"build": "tsc -p tsconfig.json",
|
|
17
17
|
"start": "npm run build && node bin/index.js",
|
|
18
18
|
"lint": "npm run build --silent",
|
|
19
|
-
"prepublishOnly": "npm run build"
|
|
19
|
+
"prepublishOnly": "npm run build",
|
|
20
|
+
"publish": "npm publish"
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
22
23
|
"prompts": "^2.4.2"
|
package/src/templates.ts
CHANGED
|
@@ -457,7 +457,7 @@ function nodePackageJson(options: ProjectOptions): string {
|
|
|
457
457
|
private: true,
|
|
458
458
|
type: "module",
|
|
459
459
|
scripts: {
|
|
460
|
-
build:
|
|
460
|
+
build: `esbuild src/${mainFileName} --bundle --platform=node --format=esm --target=es2022 --packages=external --sourcemap --outfile=${distEntry}`,
|
|
461
461
|
start: `node ${distEntry}`,
|
|
462
462
|
package: "node scripts/package.mjs",
|
|
463
463
|
},
|
|
@@ -465,6 +465,7 @@ function nodePackageJson(options: ProjectOptions): string {
|
|
|
465
465
|
"@modelcontextprotocol/sdk": "^1.24.3",
|
|
466
466
|
},
|
|
467
467
|
devDependencies: {
|
|
468
|
+
esbuild: "^0.20.2",
|
|
468
469
|
typescript: "^5.9.3",
|
|
469
470
|
"@types/node": "^22.19.2",
|
|
470
471
|
},
|
package/dist/entrytest.zip
DELETED
|
Binary file
|
package/dist/entrytest2.zip
DELETED
|
Binary file
|
package/dist/entrytest3.zip
DELETED
|
Binary file
|
package/dist/entrytest4.zip
DELETED
|
Binary file
|
package/dist/entrytest5.zip
DELETED
|
Binary file
|