create-glosc 0.1.1 → 0.2.1
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/README.md +3 -4
- package/dist/index.js +28 -2
- package/dist/templates.js +9 -4
- package/package.json +1 -1
- package/src/index.ts +29 -2
- package/src/templates.ts +10 -6
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ npm create glosc@latest <your-project-name>
|
|
|
15
15
|
```sh
|
|
16
16
|
Project name: <your-project-name>
|
|
17
17
|
Description: A brief description of your project
|
|
18
|
-
Author:
|
|
18
|
+
Author: <system-username>
|
|
19
19
|
Use Language: Python / TypeScript
|
|
20
20
|
Main File Name: main.py / index.ts
|
|
21
21
|
Readme: Y / N
|
|
@@ -31,8 +31,7 @@ License: MIT
|
|
|
31
31
|
```sh
|
|
32
32
|
|
|
33
33
|
<your-project-name>/
|
|
34
|
-
├──
|
|
35
|
-
│ ├── main.py # MCP Server 入口 (Python, stdio)
|
|
34
|
+
├── main.py # MCP Server 入口 (Python, stdio)
|
|
36
35
|
├── pyproject.toml # 项目配置
|
|
37
36
|
├── requirements.txt # 依赖文件
|
|
38
37
|
├── config.yml # 配置文件
|
|
@@ -59,7 +58,7 @@ Python:
|
|
|
59
58
|
|
|
60
59
|
```sh
|
|
61
60
|
python -m pip install -r requirements.txt
|
|
62
|
-
python
|
|
61
|
+
python main.py
|
|
63
62
|
```
|
|
64
63
|
|
|
65
64
|
TypeScript:
|
package/dist/index.js
CHANGED
|
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
const prompts_1 = __importDefault(require("prompts"));
|
|
40
40
|
const path = __importStar(require("node:path"));
|
|
41
|
+
const os = __importStar(require("node:os"));
|
|
41
42
|
const scaffold_1 = require("./scaffold");
|
|
42
43
|
function parseArgs(argv) {
|
|
43
44
|
const result = {
|
|
@@ -123,6 +124,30 @@ function normalizeMainFileName(language, mainFileNameRaw) {
|
|
|
123
124
|
return base;
|
|
124
125
|
return `${base}${defaultExt}`;
|
|
125
126
|
}
|
|
127
|
+
function getDefaultAuthor() {
|
|
128
|
+
const candidates = [
|
|
129
|
+
process.env.GIT_AUTHOR_NAME,
|
|
130
|
+
process.env.GIT_COMMITTER_NAME,
|
|
131
|
+
process.env.USER,
|
|
132
|
+
process.env.USERNAME,
|
|
133
|
+
process.env.LOGNAME,
|
|
134
|
+
];
|
|
135
|
+
for (const c of candidates) {
|
|
136
|
+
const v = String(c || "").trim();
|
|
137
|
+
if (v)
|
|
138
|
+
return v;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const u = os.userInfo();
|
|
142
|
+
const name = String(u?.username || "").trim();
|
|
143
|
+
if (name)
|
|
144
|
+
return name;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// ignore
|
|
148
|
+
}
|
|
149
|
+
return "Your Name";
|
|
150
|
+
}
|
|
126
151
|
async function run() {
|
|
127
152
|
const argv = process.argv.slice(2);
|
|
128
153
|
const args = parseArgs(argv);
|
|
@@ -134,7 +159,7 @@ async function run() {
|
|
|
134
159
|
const options = {
|
|
135
160
|
projectName: String(args.projectName).trim(),
|
|
136
161
|
description: String(args.description || "A brief description of your project").trim(),
|
|
137
|
-
author: String(args.author ||
|
|
162
|
+
author: String(args.author || getDefaultAuthor()).trim(),
|
|
138
163
|
language,
|
|
139
164
|
mainFileName: normalizeMainFileName(language, args.mainFileName),
|
|
140
165
|
readme: args.readme !== undefined ? Boolean(args.readme) : true,
|
|
@@ -146,6 +171,7 @@ async function run() {
|
|
|
146
171
|
// allow `npm create ... <name>` to prefill
|
|
147
172
|
prompts_1.default.override({
|
|
148
173
|
projectName: args.projectName,
|
|
174
|
+
author: args.author,
|
|
149
175
|
});
|
|
150
176
|
let selectedLanguage;
|
|
151
177
|
const response = await (0, prompts_1.default)([
|
|
@@ -172,7 +198,7 @@ async function run() {
|
|
|
172
198
|
type: "text",
|
|
173
199
|
name: "author",
|
|
174
200
|
message: "Author:",
|
|
175
|
-
initial:
|
|
201
|
+
initial: getDefaultAuthor(),
|
|
176
202
|
},
|
|
177
203
|
{
|
|
178
204
|
type: "select",
|
package/dist/templates.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getProjectFiles = getProjectFiles;
|
|
4
|
+
function entryPath(options) {
|
|
5
|
+
return options.language === "python"
|
|
6
|
+
? options.mainFileName
|
|
7
|
+
: `src/${options.mainFileName}`;
|
|
8
|
+
}
|
|
4
9
|
function escapeYamlString(value) {
|
|
5
10
|
const s = String(value ?? "");
|
|
6
11
|
const escaped = s.replace(/"/g, '\\"');
|
|
@@ -14,7 +19,7 @@ function mitLicenseText({ author }) {
|
|
|
14
19
|
function projectReadme(options) {
|
|
15
20
|
const { projectName, description, author, language, mainFileName } = options;
|
|
16
21
|
const langLabel = language === "python" ? "Python" : "TypeScript";
|
|
17
|
-
const entry =
|
|
22
|
+
const entry = entryPath(options);
|
|
18
23
|
const runSection = language === "python"
|
|
19
24
|
? `## 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`
|
|
20
25
|
: `## 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`;
|
|
@@ -27,7 +32,7 @@ function configYml(options) {
|
|
|
27
32
|
`description: ${escapeYamlString(description)}`,
|
|
28
33
|
`author: ${escapeYamlString(author)}`,
|
|
29
34
|
`language: ${escapeYamlString(language)}`,
|
|
30
|
-
`entry: ${escapeYamlString(
|
|
35
|
+
`entry: ${escapeYamlString(entryPath(options))}`,
|
|
31
36
|
"",
|
|
32
37
|
].join("\n");
|
|
33
38
|
}
|
|
@@ -89,7 +94,7 @@ function tsConfig() {
|
|
|
89
94
|
include: ["src/**/*.ts"],
|
|
90
95
|
}, null, 2) + "\n");
|
|
91
96
|
}
|
|
92
|
-
function tsMain({ projectName
|
|
97
|
+
function tsMain({ projectName }) {
|
|
93
98
|
const safeName = String(projectName || "mcp-server").replace(/"/g, '\\"');
|
|
94
99
|
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`;
|
|
95
100
|
}
|
|
@@ -110,7 +115,7 @@ function getProjectFiles(options) {
|
|
|
110
115
|
}
|
|
111
116
|
if (options.language === "python") {
|
|
112
117
|
files.push({
|
|
113
|
-
relativePath:
|
|
118
|
+
relativePath: options.mainFileName,
|
|
114
119
|
content: pythonMain(options),
|
|
115
120
|
});
|
|
116
121
|
files.push({
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import prompts from "prompts";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
+
import * as os from "node:os";
|
|
3
4
|
import { scaffoldProject } from "./scaffold";
|
|
4
5
|
|
|
5
6
|
type Language = "python" | "typescript";
|
|
@@ -128,6 +129,31 @@ function normalizeMainFileName(
|
|
|
128
129
|
return `${base}${defaultExt}`;
|
|
129
130
|
}
|
|
130
131
|
|
|
132
|
+
function getDefaultAuthor(): string {
|
|
133
|
+
const candidates = [
|
|
134
|
+
process.env.GIT_AUTHOR_NAME,
|
|
135
|
+
process.env.GIT_COMMITTER_NAME,
|
|
136
|
+
process.env.USER,
|
|
137
|
+
process.env.USERNAME,
|
|
138
|
+
process.env.LOGNAME,
|
|
139
|
+
];
|
|
140
|
+
|
|
141
|
+
for (const c of candidates) {
|
|
142
|
+
const v = String(c || "").trim();
|
|
143
|
+
if (v) return v;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
const u = os.userInfo();
|
|
148
|
+
const name = String(u?.username || "").trim();
|
|
149
|
+
if (name) return name;
|
|
150
|
+
} catch {
|
|
151
|
+
// ignore
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return "Your Name";
|
|
155
|
+
}
|
|
156
|
+
|
|
131
157
|
async function run(): Promise<void> {
|
|
132
158
|
const argv = process.argv.slice(2);
|
|
133
159
|
const args = parseArgs(argv);
|
|
@@ -146,7 +172,7 @@ async function run(): Promise<void> {
|
|
|
146
172
|
description: String(
|
|
147
173
|
args.description || "A brief description of your project"
|
|
148
174
|
).trim(),
|
|
149
|
-
author: String(args.author ||
|
|
175
|
+
author: String(args.author || getDefaultAuthor()).trim(),
|
|
150
176
|
language,
|
|
151
177
|
mainFileName: normalizeMainFileName(language, args.mainFileName),
|
|
152
178
|
readme: args.readme !== undefined ? Boolean(args.readme) : true,
|
|
@@ -160,6 +186,7 @@ async function run(): Promise<void> {
|
|
|
160
186
|
// allow `npm create ... <name>` to prefill
|
|
161
187
|
prompts.override({
|
|
162
188
|
projectName: args.projectName,
|
|
189
|
+
author: args.author,
|
|
163
190
|
});
|
|
164
191
|
|
|
165
192
|
let selectedLanguage: Language | undefined;
|
|
@@ -188,7 +215,7 @@ async function run(): Promise<void> {
|
|
|
188
215
|
type: "text",
|
|
189
216
|
name: "author",
|
|
190
217
|
message: "Author:",
|
|
191
|
-
initial:
|
|
218
|
+
initial: getDefaultAuthor(),
|
|
192
219
|
},
|
|
193
220
|
{
|
|
194
221
|
type: "select",
|
package/src/templates.ts
CHANGED
|
@@ -15,6 +15,12 @@ export type ProjectFile = {
|
|
|
15
15
|
content: string;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
function entryPath(options: ProjectOptions): string {
|
|
19
|
+
return options.language === "python"
|
|
20
|
+
? options.mainFileName
|
|
21
|
+
: `src/${options.mainFileName}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
function escapeYamlString(value: unknown): string {
|
|
19
25
|
const s = String(value ?? "");
|
|
20
26
|
const escaped = s.replace(/"/g, '\\"');
|
|
@@ -32,7 +38,7 @@ function projectReadme(options: ProjectOptions): string {
|
|
|
32
38
|
options;
|
|
33
39
|
const langLabel = language === "python" ? "Python" : "TypeScript";
|
|
34
40
|
|
|
35
|
-
const entry =
|
|
41
|
+
const entry = entryPath(options);
|
|
36
42
|
const runSection =
|
|
37
43
|
language === "python"
|
|
38
44
|
? `## 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`
|
|
@@ -51,7 +57,7 @@ function configYml(options: ProjectOptions): string {
|
|
|
51
57
|
`description: ${escapeYamlString(description)}`,
|
|
52
58
|
`author: ${escapeYamlString(author)}`,
|
|
53
59
|
`language: ${escapeYamlString(language)}`,
|
|
54
|
-
`entry: ${escapeYamlString(
|
|
60
|
+
`entry: ${escapeYamlString(entryPath(options))}`,
|
|
55
61
|
"",
|
|
56
62
|
].join("\n");
|
|
57
63
|
}
|
|
@@ -136,9 +142,7 @@ function tsConfig(): string {
|
|
|
136
142
|
);
|
|
137
143
|
}
|
|
138
144
|
|
|
139
|
-
function tsMain({
|
|
140
|
-
projectName,
|
|
141
|
-
}: Pick<ProjectOptions, "projectName">): string {
|
|
145
|
+
function tsMain({ projectName }: Pick<ProjectOptions, "projectName">): string {
|
|
142
146
|
const safeName = String(projectName || "mcp-server").replace(/"/g, '\\"');
|
|
143
147
|
|
|
144
148
|
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`;
|
|
@@ -165,7 +169,7 @@ export function getProjectFiles(options: ProjectOptions): ProjectFile[] {
|
|
|
165
169
|
|
|
166
170
|
if (options.language === "python") {
|
|
167
171
|
files.push({
|
|
168
|
-
relativePath:
|
|
172
|
+
relativePath: options.mainFileName,
|
|
169
173
|
content: pythonMain(options),
|
|
170
174
|
});
|
|
171
175
|
files.push({
|