@obov/mext 0.1.0 → 0.2.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/build-cli.js +10 -3
- package/dist/build-cli.js.map +1 -1
- package/dist/cli/dev-server.js +2 -1
- package/dist/cli/dev-server.js.map +1 -1
- package/dist/cli/dev.js +2 -1
- package/dist/cli/dev.js.map +1 -1
- package/dist/cli/output.d.ts +44 -0
- package/dist/cli/output.js +57 -0
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/run.js +10 -10
- package/dist/cli/run.js.map +1 -1
- package/dist/client/main.d.ts +8 -2
- package/dist/client/main.js +4 -3
- package/dist/client/main.js.map +1 -1
- package/dist/client/runner.d.ts +3 -0
- package/dist/client/runner.js +13 -12
- package/dist/client/runner.js.map +1 -1
- package/dist/config.d.ts +58 -0
- package/dist/config.js +77 -2
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/http.d.ts +4 -0
- package/dist/mcp/http.js +2 -0
- package/dist/mcp/http.js.map +1 -1
- package/dist/mcp/server.d.ts +5 -0
- package/dist/mcp/server.js +7 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/stdio.d.ts +18 -0
- package/dist/mcp/stdio.js +155 -12
- package/dist/mcp/stdio.js.map +1 -1
- package/dist/start.js +3 -1
- package/dist/start.js.map +1 -1
- package/package.json +1 -1
package/dist/build-cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { chmodSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { isBuiltin } from "node:module";
|
|
3
|
-
import { join } from "node:path";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { clientManifest } from "./client/manifest.js";
|
|
6
6
|
import { CLI_BUILTIN_COMMANDS } from "./config.js";
|
|
@@ -55,10 +55,17 @@ export async function buildCustomerCli(options) {
|
|
|
55
55
|
manifestHash: manifest.manifestHash,
|
|
56
56
|
...(bundled ? { manifest: clientManifest(manifest) } : {}),
|
|
57
57
|
};
|
|
58
|
+
const errorsFile = cli.errors === undefined ? undefined : resolve(options.cwd, cli.errors);
|
|
59
|
+
if (errorsFile !== undefined && !existsSync(errorsFile)) {
|
|
60
|
+
throw new MextBuildError([{ code: "INVALID_CONFIG", message: `cli.errors file not found: ${cli.errors}` }]);
|
|
61
|
+
}
|
|
58
62
|
const entry = [
|
|
59
63
|
`import { main } from ${JSON.stringify(RUNTIME_ENTRY)}`,
|
|
64
|
+
...(errorsFile !== undefined ? [`import formatError from ${JSON.stringify(errorsFile)}`] : []),
|
|
60
65
|
"",
|
|
61
|
-
|
|
66
|
+
errorsFile !== undefined
|
|
67
|
+
? `await main(${JSON.stringify(config)}, { formatError })`
|
|
68
|
+
: `await main(${JSON.stringify(config)})`,
|
|
62
69
|
"",
|
|
63
70
|
].join("\n");
|
|
64
71
|
let output;
|
package/dist/build-cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-cli.js","sourceRoot":"","sources":["../src/build-cli.ts"],"names":[],"mappings":"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","sourcesContent":["import { chmodSync, mkdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\"\nimport { isBuiltin } from \"node:module\"\nimport { join } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport type { RolldownModule, RolldownOutputItem } from \"./build.ts\"\nimport { clientManifest } from \"./client/manifest.ts\"\nimport type { CustomerCliConfig } from \"./client/main.ts\"\nimport { CLI_BUILTIN_COMMANDS, type CliConfig } from \"./config.ts\"\nimport { MextBuildError, type BuildIssue } from \"./errors.ts\"\nimport type { BuildManifest } from \"./manifest.ts\"\nimport type { Registry } from \"./registry.ts\"\nimport { envPrefix } from \"./remote/credentials.ts\"\n\n/**\n * 고객 CLI 패키지 (.mext/cli/, §5). mext build 가 config.cli 가 있을 때 호출.\n * bin.js = client/main.ts (고객 CLI 런타임) + 인라인 설정 (CustomerCliConfig) 의 rolldown 단일 번들. 외부 = Node 내장만\n * (의존성 전부 번들 → package.json dependencies 없음). 런타임은 Zod · MCP 서버 SDK · 핸들러 · 스캔 · 빌드 코드를 import 하지 않는다\n */\n\n/** .mext/ 아래 고객 CLI 폴더 */\nexport const CLI_DIR = \"cli\"\nexport const CLI_BIN_FILE = \"bin.js\"\n/** 고객 CLI package.json engines.node (번들 target node22, 타입 제거 불필요) */\nexport const CLI_NODE_ENGINE = \">=22\"\n\n/** 고객 CLI 런타임 엔트리 (src = .ts, dist = .js: 이 파일과 같은 확장자) */\nconst RUNTIME_ENTRY = fileURLToPath(new URL(`./client/main${import.meta.url.slice(import.meta.url.lastIndexOf(\".\"))}`, import.meta.url))\nconst ENTRY_ID = \"\\0mext-customer-cli\"\n\nexport interface CustomerCliBuild {\n /** 절대 경로 (.mext/cli) */\n dir: string\n bin: string\n packageName: string\n version: string\n form: \"bundled\" | \"universal\"\n /** .mext/cli 기준 생성 파일 (정렬) */\n files: string[]\n /** bin.js 바이트 */\n size: number\n}\n\n/** cli 설정이 있을 때 루트 세그먼트가 고객 CLI 내장 명령 (login · logout · mcp) 과 겹치면 RESERVED_ID */\nexport function customerCliIssues(cli: CliConfig | undefined, registry: Registry): BuildIssue[] {\n if (!cli) return []\n // 루트 별칭은 Registry 가 금지하므로 루트 명령어 · 네임스페이스만 본다\n const root = registry.namespaces.get(\"\")\n const ids = new Set([...(root?.commands ?? []), ...(root?.namespaces ?? [])])\n return [...ids]\n .filter((id) => CLI_BUILTIN_COMMANDS.includes(id))\n .sort()\n .map((id) => {\n const file = registry.commands.get(id)?.file\n return {\n code: \"RESERVED_ID\",\n message: `\"${id}\" is a built-in command of the customer CLI (${cli.bin} ${id}). Rename it or remove cli from mext.config.ts`,\n id,\n ...(file !== undefined ? { file } : {}),\n }\n })\n}\n\nexport interface BuildCustomerCliOptions {\n rolldown: RolldownModule\n /** 도입 프로젝트 루트 (package.json version) */\n cwd: string\n /** .mext/ 절대 경로 */\n outDir: string\n cli: CliConfig\n manifest: BuildManifest\n}\n\nexport async function buildCustomerCli(options: BuildCustomerCliOptions): Promise<CustomerCliBuild> {\n const { cli, manifest } = options\n const dir = join(options.outDir, CLI_DIR)\n mkdirSync(dir, { recursive: true })\n const version = cli.version ?? projectVersion(options.cwd) ?? \"0.0.0\"\n const packageName = cli.packageName ?? cli.bin\n const bundled = cli.manifest !== false\n const config: CustomerCliConfig = {\n bin: cli.bin,\n url: cli.url,\n version,\n packageName,\n mextVersion: manifest.mextVersion,\n manifestHash: manifest.manifestHash,\n ...(bundled ? { manifest: clientManifest(manifest) } : {}),\n }\n const entry = [\n `import { main } from ${JSON.stringify(RUNTIME_ENTRY)}`,\n \"\",\n `await main(${JSON.stringify(config)})`,\n \"\",\n ].join(\"\\n\")\n\n let output: readonly RolldownOutputItem[]\n try {\n ;({ output } = await options.rolldown.build({\n cwd: options.cwd,\n input: { bin: ENTRY_ID },\n platform: \"node\",\n external: (id: string): boolean => id.startsWith(\"node:\") || isBuiltin(id),\n plugins: [\n {\n name: \"mext-customer-cli\",\n resolveId: (id: string) => (id === ENTRY_ID ? ENTRY_ID : null),\n load: (id: string) => (id === ENTRY_ID ? entry : null),\n },\n ],\n transform: { target: \"node22\" },\n logLevel: \"warn\",\n output: {\n dir,\n format: \"esm\",\n entryFileNames: CLI_BIN_FILE,\n banner: \"#!/usr/bin/env node\",\n codeSplitting: false,\n sourcemap: false,\n },\n }))\n } catch (error) {\n throw new MextBuildError([\n { code: \"BUNDLE_FAILED\", message: `customer CLI: ${error instanceof Error ? error.message : String(error)}` },\n ])\n }\n const emitted = output.map((o) => o.fileName)\n if (emitted.length !== 1 || emitted[0] !== CLI_BIN_FILE) {\n throw new Error(`mext build: customer CLI bundle must be a single ${CLI_BIN_FILE} (got ${emitted.join(\", \")})`)\n }\n const binPath = join(dir, CLI_BIN_FILE)\n chmodSync(binPath, 0o755)\n\n const pkg = {\n name: packageName,\n version,\n description: `Command-line client for ${cli.url}`,\n type: \"module\",\n bin: { [cli.bin]: `./${CLI_BIN_FILE}` },\n files: [CLI_BIN_FILE],\n engines: { node: CLI_NODE_ENGINE },\n }\n writeFileSync(join(dir, \"package.json\"), `${JSON.stringify(pkg, null, 2)}\\n`)\n writeFileSync(join(dir, \"README.md\"), readme(cli, packageName))\n\n return {\n dir,\n bin: cli.bin,\n packageName,\n version,\n form: bundled ? \"bundled\" : \"universal\",\n files: [CLI_BIN_FILE, \"README.md\", \"package.json\"],\n size: statSync(binPath).size,\n }\n}\n\nfunction projectVersion(cwd: string): string | undefined {\n try {\n const pkg = JSON.parse(readFileSync(join(cwd, \"package.json\"), \"utf8\")) as { version?: unknown }\n return typeof pkg.version === \"string\" && pkg.version !== \"\" ? pkg.version : undefined\n } catch {\n return undefined\n }\n}\n\nfunction readme(cli: CliConfig, packageName: string): string {\n const { bin } = cli\n const prefix = envPrefix(bin)\n return [\n `# ${packageName}`,\n \"\",\n `Command-line client for ${cli.url}. Generated by mext build.`,\n \"\",\n \"```sh\",\n `npm install -g ${packageName}`,\n `${bin} login # log in (browser, device code, or --with-token)`,\n `${bin} help # commands`,\n `${bin} <namespace> <command> --help`,\n `${bin} mcp install # MCP client registration commands`,\n `${bin} logout`,\n \"```\",\n \"\",\n \"Environment:\",\n \"\",\n `- \\`${prefix}_TOKEN\\`: API token (used instead of the stored login)`,\n `- \\`${prefix}_URL\\`: server URL (default: ${cli.url})`,\n `- \\`${prefix}_NO_KEYRING=1\\`: store the token in \\`~/.config/${bin}/credentials.json\\` instead of the OS keychain`,\n `- \\`${prefix}_CACHE_DIR\\`: server schema cache folder (default: \\`\\${XDG_CACHE_HOME:-~/.cache}/${bin}\\`)`,\n \"\",\n \"Exit codes: 0 success · 1 error · 2 invalid arguments or unknown command · 77 authentication or permission · 130 interrupted.\",\n \"\",\n ].join(\"\\n\")\n}\n"]}
|
|
1
|
+
{"version":3,"file":"build-cli.js","sourceRoot":"","sources":["../src/build-cli.ts"],"names":[],"mappings":"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","sourcesContent":["import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\"\nimport { isBuiltin } from \"node:module\"\nimport { join, resolve } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport type { RolldownModule, RolldownOutputItem } from \"./build.ts\"\nimport { clientManifest } from \"./client/manifest.ts\"\nimport type { CustomerCliConfig } from \"./client/main.ts\"\nimport { CLI_BUILTIN_COMMANDS, type CliConfig } from \"./config.ts\"\nimport { MextBuildError, type BuildIssue } from \"./errors.ts\"\nimport type { BuildManifest } from \"./manifest.ts\"\nimport type { Registry } from \"./registry.ts\"\nimport { envPrefix } from \"./remote/credentials.ts\"\n\n/**\n * 고객 CLI 패키지 (.mext/cli/, §5). mext build 가 config.cli 가 있을 때 호출.\n * bin.js = client/main.ts (고객 CLI 런타임) + 인라인 설정 (CustomerCliConfig) 의 rolldown 단일 번들. 외부 = Node 내장만\n * (의존성 전부 번들 → package.json dependencies 없음). 런타임은 Zod · MCP 서버 SDK · 핸들러 · 스캔 · 빌드 코드를 import 하지 않는다\n */\n\n/** .mext/ 아래 고객 CLI 폴더 */\nexport const CLI_DIR = \"cli\"\nexport const CLI_BIN_FILE = \"bin.js\"\n/** 고객 CLI package.json engines.node (번들 target node22, 타입 제거 불필요) */\nexport const CLI_NODE_ENGINE = \">=22\"\n\n/** 고객 CLI 런타임 엔트리 (src = .ts, dist = .js: 이 파일과 같은 확장자) */\nconst RUNTIME_ENTRY = fileURLToPath(new URL(`./client/main${import.meta.url.slice(import.meta.url.lastIndexOf(\".\"))}`, import.meta.url))\nconst ENTRY_ID = \"\\0mext-customer-cli\"\n\nexport interface CustomerCliBuild {\n /** 절대 경로 (.mext/cli) */\n dir: string\n bin: string\n packageName: string\n version: string\n form: \"bundled\" | \"universal\"\n /** .mext/cli 기준 생성 파일 (정렬) */\n files: string[]\n /** bin.js 바이트 */\n size: number\n}\n\n/** cli 설정이 있을 때 루트 세그먼트가 고객 CLI 내장 명령 (login · logout · mcp) 과 겹치면 RESERVED_ID */\nexport function customerCliIssues(cli: CliConfig | undefined, registry: Registry): BuildIssue[] {\n if (!cli) return []\n // 루트 별칭은 Registry 가 금지하므로 루트 명령어 · 네임스페이스만 본다\n const root = registry.namespaces.get(\"\")\n const ids = new Set([...(root?.commands ?? []), ...(root?.namespaces ?? [])])\n return [...ids]\n .filter((id) => CLI_BUILTIN_COMMANDS.includes(id))\n .sort()\n .map((id) => {\n const file = registry.commands.get(id)?.file\n return {\n code: \"RESERVED_ID\",\n message: `\"${id}\" is a built-in command of the customer CLI (${cli.bin} ${id}). Rename it or remove cli from mext.config.ts`,\n id,\n ...(file !== undefined ? { file } : {}),\n }\n })\n}\n\nexport interface BuildCustomerCliOptions {\n rolldown: RolldownModule\n /** 도입 프로젝트 루트 (package.json version) */\n cwd: string\n /** .mext/ 절대 경로 */\n outDir: string\n cli: CliConfig\n manifest: BuildManifest\n}\n\nexport async function buildCustomerCli(options: BuildCustomerCliOptions): Promise<CustomerCliBuild> {\n const { cli, manifest } = options\n const dir = join(options.outDir, CLI_DIR)\n mkdirSync(dir, { recursive: true })\n const version = cli.version ?? projectVersion(options.cwd) ?? \"0.0.0\"\n const packageName = cli.packageName ?? cli.bin\n const bundled = cli.manifest !== false\n const config: CustomerCliConfig = {\n bin: cli.bin,\n url: cli.url,\n version,\n packageName,\n mextVersion: manifest.mextVersion,\n manifestHash: manifest.manifestHash,\n ...(bundled ? { manifest: clientManifest(manifest) } : {}),\n }\n const errorsFile = cli.errors === undefined ? undefined : resolve(options.cwd, cli.errors)\n if (errorsFile !== undefined && !existsSync(errorsFile)) {\n throw new MextBuildError([{ code: \"INVALID_CONFIG\", message: `cli.errors file not found: ${cli.errors}` }])\n }\n const entry = [\n `import { main } from ${JSON.stringify(RUNTIME_ENTRY)}`,\n ...(errorsFile !== undefined ? [`import formatError from ${JSON.stringify(errorsFile)}`] : []),\n \"\",\n errorsFile !== undefined\n ? `await main(${JSON.stringify(config)}, { formatError })`\n : `await main(${JSON.stringify(config)})`,\n \"\",\n ].join(\"\\n\")\n\n let output: readonly RolldownOutputItem[]\n try {\n ;({ output } = await options.rolldown.build({\n cwd: options.cwd,\n input: { bin: ENTRY_ID },\n platform: \"node\",\n external: (id: string): boolean => id.startsWith(\"node:\") || isBuiltin(id),\n plugins: [\n {\n name: \"mext-customer-cli\",\n resolveId: (id: string) => (id === ENTRY_ID ? ENTRY_ID : null),\n load: (id: string) => (id === ENTRY_ID ? entry : null),\n },\n ],\n transform: { target: \"node22\" },\n logLevel: \"warn\",\n output: {\n dir,\n format: \"esm\",\n entryFileNames: CLI_BIN_FILE,\n banner: \"#!/usr/bin/env node\",\n codeSplitting: false,\n sourcemap: false,\n },\n }))\n } catch (error) {\n throw new MextBuildError([\n { code: \"BUNDLE_FAILED\", message: `customer CLI: ${error instanceof Error ? error.message : String(error)}` },\n ])\n }\n const emitted = output.map((o) => o.fileName)\n if (emitted.length !== 1 || emitted[0] !== CLI_BIN_FILE) {\n throw new Error(`mext build: customer CLI bundle must be a single ${CLI_BIN_FILE} (got ${emitted.join(\", \")})`)\n }\n const binPath = join(dir, CLI_BIN_FILE)\n chmodSync(binPath, 0o755)\n\n const pkg = {\n name: packageName,\n version,\n description: `Command-line client for ${cli.url}`,\n type: \"module\",\n bin: { [cli.bin]: `./${CLI_BIN_FILE}` },\n files: [CLI_BIN_FILE],\n engines: { node: CLI_NODE_ENGINE },\n }\n writeFileSync(join(dir, \"package.json\"), `${JSON.stringify(pkg, null, 2)}\\n`)\n writeFileSync(join(dir, \"README.md\"), readme(cli, packageName))\n\n return {\n dir,\n bin: cli.bin,\n packageName,\n version,\n form: bundled ? \"bundled\" : \"universal\",\n files: [CLI_BIN_FILE, \"README.md\", \"package.json\"],\n size: statSync(binPath).size,\n }\n}\n\nfunction projectVersion(cwd: string): string | undefined {\n try {\n const pkg = JSON.parse(readFileSync(join(cwd, \"package.json\"), \"utf8\")) as { version?: unknown }\n return typeof pkg.version === \"string\" && pkg.version !== \"\" ? pkg.version : undefined\n } catch {\n return undefined\n }\n}\n\nfunction readme(cli: CliConfig, packageName: string): string {\n const { bin } = cli\n const prefix = envPrefix(bin)\n return [\n `# ${packageName}`,\n \"\",\n `Command-line client for ${cli.url}. Generated by mext build.`,\n \"\",\n \"```sh\",\n `npm install -g ${packageName}`,\n `${bin} login # log in (browser, device code, or --with-token)`,\n `${bin} help # commands`,\n `${bin} <namespace> <command> --help`,\n `${bin} mcp install # MCP client registration commands`,\n `${bin} logout`,\n \"```\",\n \"\",\n \"Environment:\",\n \"\",\n `- \\`${prefix}_TOKEN\\`: API token (used instead of the stored login)`,\n `- \\`${prefix}_URL\\`: server URL (default: ${cli.url})`,\n `- \\`${prefix}_NO_KEYRING=1\\`: store the token in \\`~/.config/${bin}/credentials.json\\` instead of the OS keychain`,\n `- \\`${prefix}_CACHE_DIR\\`: server schema cache folder (default: \\`\\${XDG_CACHE_HOME:-~/.cache}/${bin}\\`)`,\n \"\",\n \"Exit codes: 0 success · 1 error · 2 invalid arguments or unknown command · 77 authentication or permission · 130 interrupted.\",\n \"\",\n ].join(\"\\n\")\n}\n"]}
|
package/dist/cli/dev-server.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 요청은 감독 프로세스 (부모) 가 받아 이 포트로 중계한다. 부모 IPC 가 끊기면 종료.
|
|
5
5
|
*/
|
|
6
6
|
import { createServer } from "node:http";
|
|
7
|
-
import { loadConfig, resolveCommandsDir } from "../config.js";
|
|
7
|
+
import { loadConfig, mcpDeclarations, resolveCommandsDir } from "../config.js";
|
|
8
8
|
import { loadProjectInstrumentation } from "../instrumentation.js";
|
|
9
9
|
import { createMcpHttpHandler } from "../mcp/http.js";
|
|
10
10
|
import { loadRegistry } from "../scan.js";
|
|
@@ -38,6 +38,7 @@ async function main() {
|
|
|
38
38
|
...(config.auth ? { auth: config.auth } : {}),
|
|
39
39
|
...(config.tools ? { tools: config.tools } : {}),
|
|
40
40
|
...(config.oauth ? { oauth: config.oauth } : {}),
|
|
41
|
+
...mcpDeclarations(config),
|
|
41
42
|
server: config.server?.allowedOrigins ? { allowedOrigins: config.server.allowedOrigins } : {},
|
|
42
43
|
onerror: (error) => process.stderr.write(`mcp: ${error.message}\n`),
|
|
43
44
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-server.js","sourceRoot":"","sources":["../../src/cli/dev-server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"dev-server.js","sourceRoot":"","sources":["../../src/cli/dev-server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAC9E,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAWzC,MAAM,IAAI,GAAG,CAAC,OAAwB,EAAiB,EAAE,CACvD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IACtB,IAAI,CAAC,OAAO,CAAC,SAAS;QAAE,OAAO,OAAO,EAAE,CAAA;IACxC,OAAO,CAAC,IAAK,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;AACxD,CAAC,CAAC,CAAA;AAEJ,+DAA+D;AAC/D,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;AAC9B,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;AAE/C,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,qCAAqC;IACrC,MAAM,eAAe,GAAG,MAAM,0BAA0B,CAAC,GAAG,CAAC,CAAA;IAC7D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAA;IACpC,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IACnD,MAAM,IAAI,CAAC;QACT,IAAI,EAAE,QAAQ;QACd,WAAW;QACX,MAAM,EAAE;YACN,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3E;KACF,CAAC,CAAA;IACF,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,CAAA;IAChD,MAAM,QAAQ,GAAG,oBAAoB,CAAC;QACpC,QAAQ;QACR,eAAe;QACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,GAAG,eAAe,CAAC,MAAM,CAAC;QAC1B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE;QAC7F,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,KAAK,CAAC,OAAO,IAAI,CAAC;KACpE,CAAC,CAAA;IACF,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAA;IACrC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;QAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;YACjC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YAC3B,OAAO,EAAE,CAAA;QACX,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAyB,EAAE,EAAE;QAClD,IAAI,OAAO,EAAE,IAAI,KAAK,UAAU;YAAE,OAAM;QACxC,KAAK,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YACjC,MAAM,CAAC,mBAAmB,EAAE,CAAA;YAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;QACrC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAG,MAAM,CAAC,OAAO,EAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;AAC/G,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE;IACpC,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA;AAEF,gGAAgG;AAChG,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,KAAK,YAAY,WAAW,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChD,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QAC3C,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACjE,CAAC;IACD,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC/D,CAAC","sourcesContent":["/**\n * mext dev 의 서버 자식 프로세스 엔트리 (cli/dev.ts 가 fork). 직접 실행하지 않는다.\n * cwd 의 mext.config.ts · commands/ 를 로드해 127.0.0.1 임의 포트에서 MCP HTTP 처리기를 띄우고 IPC 로 보고한다.\n * 요청은 감독 프로세스 (부모) 가 받아 이 포트로 중계한다. 부모 IPC 가 끊기면 종료.\n */\nimport { createServer } from \"node:http\"\nimport type { AddressInfo } from \"node:net\"\nimport { loadConfig, mcpDeclarations, resolveCommandsDir } from \"../config.ts\"\nimport { loadProjectInstrumentation } from \"../instrumentation.ts\"\nimport { createMcpHttpHandler } from \"../mcp/http.ts\"\nimport { loadRegistry } from \"../scan.ts\"\n\n/** 자식 → 부모 */\nexport type DevChildMessage =\n | { type: \"config\"; commandsDir: string; server: { host?: string; port?: number } }\n | { type: \"ready\"; port: number; commands: number }\n | { type: \"error\"; message: string }\n\n/** 부모 → 자식 */\nexport type DevParentMessage = { type: \"shutdown\" }\n\nconst send = (message: DevChildMessage): Promise<void> =>\n new Promise((resolve) => {\n if (!process.connected) return resolve()\n process.send!(message, undefined, {}, () => resolve())\n })\n\n// 터미널 Ctrl-C 는 프로세스 그룹 전체에 간다. 종료는 부모가 정한다 (shutdown · IPC 끊김)\nprocess.on(\"SIGINT\", () => {})\nprocess.on(\"disconnect\", () => process.exit(0))\n\nasync function main(): Promise<void> {\n const cwd = process.cwd()\n // register() = 명령어 · config import 전\n const instrumentation = await loadProjectInstrumentation(cwd)\n const config = await loadConfig(cwd)\n const commandsDir = resolveCommandsDir(cwd, config)\n await send({\n type: \"config\",\n commandsDir,\n server: {\n ...(config.server?.host !== undefined ? { host: config.server.host } : {}),\n ...(config.server?.port !== undefined ? { port: config.server.port } : {}),\n },\n })\n const registry = await loadRegistry(commandsDir)\n const listener = createMcpHttpHandler({\n registry,\n instrumentation,\n ...(config.app ? { app: config.app } : {}),\n ...(config.auth ? { auth: config.auth } : {}),\n ...(config.tools ? { tools: config.tools } : {}),\n ...(config.oauth ? { oauth: config.oauth } : {}),\n ...mcpDeclarations(config),\n server: config.server?.allowedOrigins ? { allowedOrigins: config.server.allowedOrigins } : {},\n onerror: (error) => process.stderr.write(`mcp: ${error.message}\\n`),\n })\n const server = createServer(listener)\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject)\n server.listen(0, \"127.0.0.1\", () => {\n server.off(\"error\", reject)\n resolve()\n })\n })\n process.on(\"message\", (message: DevParentMessage) => {\n if (message?.type !== \"shutdown\") return\n void listener.close().finally(() => {\n server.closeAllConnections()\n server.close(() => process.exit(0))\n })\n })\n await send({ type: \"ready\", port: (server.address() as AddressInfo).port, commands: registry.commands.size })\n}\n\nmain().catch(async (error: unknown) => {\n await send({ type: \"error\", message: describeLoadError(error) })\n process.exit(1)\n})\n\n/** SyntaxError 는 stack 첫 줄들에 파일 위치가 있다 (ESM 파싱 오류). 그 외는 message (MextBuildError = issue 목록) */\nfunction describeLoadError(error: unknown): string {\n if (error instanceof SyntaxError && error.stack) {\n const at = error.stack.indexOf(\"\\n at \")\n return (at < 0 ? error.stack : error.stack.slice(0, at)).trim()\n }\n return error instanceof Error ? error.message : String(error)\n}\n"]}
|
package/dist/cli/dev.js
CHANGED
|
@@ -4,7 +4,7 @@ import { createServer, request as httpRequest } from "node:http";
|
|
|
4
4
|
import { basename, dirname, extname, relative, resolve } from "node:path";
|
|
5
5
|
import { Writable } from "node:stream";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
|
-
import { CONFIG_FILE, loadConfig, resolveCommandsDir, resolveLocalPrincipal } from "../config.js";
|
|
7
|
+
import { CONFIG_FILE, loadConfig, mcpStdioDeclarations, resolveCommandsDir, resolveLocalPrincipal } from "../config.js";
|
|
8
8
|
import { DEFAULT_HOST, DEFAULT_PORT, MCP_PATH } from "../mcp/constants.js";
|
|
9
9
|
import { loadProjectInstrumentation } from "../instrumentation.js";
|
|
10
10
|
import { redirectStdout, serveMcpStdio } from "../mcp/stdio.js";
|
|
@@ -90,6 +90,7 @@ async function stdio(io) {
|
|
|
90
90
|
principal,
|
|
91
91
|
...(config.app ? { app: config.app } : {}),
|
|
92
92
|
...(config.tools ? { tools: config.tools } : {}),
|
|
93
|
+
...mcpStdioDeclarations(config),
|
|
93
94
|
stdin: io.stdin,
|
|
94
95
|
stdout: wire,
|
|
95
96
|
onerror: (error) => io.stderr.write(`mcp: ${error.message}\n`),
|
package/dist/cli/dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"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","sourcesContent":["import { fork, type ChildProcess } from \"node:child_process\"\nimport { existsSync, watch, type FSWatcher } from \"node:fs\"\nimport { createServer, request as httpRequest, type IncomingMessage, type Server, type ServerResponse } from \"node:http\"\nimport type { AddressInfo } from \"node:net\"\nimport { basename, dirname, extname, relative, resolve } from \"node:path\"\nimport { Writable } from \"node:stream\"\nimport { fileURLToPath } from \"node:url\"\nimport { CONFIG_FILE, loadConfig, resolveCommandsDir, resolveLocalPrincipal } from \"../config.ts\"\nimport { DEFAULT_HOST, DEFAULT_PORT, MCP_PATH } from \"../mcp/constants.ts\"\nimport { loadProjectInstrumentation } from \"../instrumentation.ts\"\nimport { redirectStdout, serveMcpStdio } from \"../mcp/stdio.ts\"\nimport { loadRegistry } from \"../scan.ts\"\nimport { acquireDevLock, releaseDevLock, updateDevLock, type DevLock } from \"./dev-lock.ts\"\nimport type { DevChildMessage, DevParentMessage } from \"./dev-server.ts\"\nimport { table } from \"./help.ts\"\nimport type { CliIo, CliWriter } from \"./io.ts\"\nimport { EXIT, exitCodeOf, formatError } from \"./output.ts\"\n\nexport const DEV_PROG = \"mext dev\"\n\n/** 감시 대상 프로젝트 루트 파일 (commandsDir/** 와 함께) */\nexport const DEV_WATCHED_ROOT_FILES: readonly string[] = [CONFIG_FILE, \"instrumentation.ts\"]\n\n/** 파일 변경 → 재시작 debounce (ms) */\nexport const DEV_DEBOUNCE_MS = 100\n\n/**\n * mext dev [--port <n>] [--host <h>] 개발 HTTP 서버. 감독 프로세스 + 서버 자식 (파일 변경 시 교체)\n * mext dev --stdio stdio 서버 (감시 없음, 같은 프로세스)\n */\nexport async function devCommand(argv: readonly string[], io: CliIo): Promise<number> {\n const parsed = parseDevArgs(argv)\n if (typeof parsed === \"string\") {\n io.stderr.write(`error: ${parsed}\\nRun \"${DEV_PROG} --help\" for usage.\\n`)\n return EXIT.usage\n }\n if (parsed.help) {\n io.stdout.write(devHelp())\n return EXIT.ok\n }\n if (parsed.stdio) return stdio(io)\n return supervise(parsed, io)\n}\n\ninterface DevArgs {\n help: boolean\n stdio: boolean\n port?: number\n host?: string\n}\n\n/** 반환 문자열 = 사용법 오류 메시지 */\nexport function parseDevArgs(argv: readonly string[]): DevArgs | string {\n const args: DevArgs = { help: false, stdio: false }\n for (let i = 0; i < argv.length; i++) {\n const tok = argv[i]!\n if (tok === \"--help\" || tok === \"-h\") {\n args.help = true\n continue\n }\n if (tok === \"--stdio\") {\n args.stdio = true\n continue\n }\n if (!tok.startsWith(\"--\")) return `unexpected argument \"${tok}\"`\n const eq = tok.indexOf(\"=\")\n const name = eq < 0 ? tok.slice(2) : tok.slice(2, eq)\n if (name !== \"port\" && name !== \"host\") return `unknown flag --${name}`\n const value = eq < 0 ? argv[++i] : tok.slice(eq + 1)\n if (value === undefined || value === \"\") return `--${name} requires a value`\n if (name === \"port\") {\n const port = Number(value)\n if (!Number.isInteger(port) || port < 0 || port > 65_535) return `--port must be an integer between 0 and 65535`\n args.port = port\n } else args.host = value\n }\n if (args.stdio && (args.port !== undefined || args.host !== undefined)) return \"--port and --host do not apply to --stdio\"\n return args\n}\n\n/* ---------------------------------------------------------------- stdio */\n\n/**\n * stdio: stdout = MCP 메시지만. D4: 이 프로세스의 그 외 stdout 쓰기 (console.log · process.stdout.write) 는\n * 명령어 import 전부터 종료까지 stderr 로 돌린다. stdin EOF = 연결 종료 → 바로 반환 (bin 이 exit).\n * 감시 · 잠금 없음: MCP 클라이언트가 프로세스를 소유 · 재실행한다\n */\nasync function stdio(io: CliIo): Promise<number> {\n const redirect = io.stdout === process.stdout ? redirectStdout() : undefined\n const wire = redirect?.wire ?? writerStream(io.stdout)\n try {\n const instrumentation = await loadProjectInstrumentation(io.cwd)\n const config = await loadConfig(io.cwd)\n const registry = await loadRegistry(resolveCommandsDir(io.cwd, config))\n const principal = await resolveLocalPrincipal(config)\n const server = serveMcpStdio({\n registry,\n instrumentation,\n principal,\n ...(config.app ? { app: config.app } : {}),\n ...(config.tools ? { tools: config.tools } : {}),\n stdin: io.stdin,\n stdout: wire,\n onerror: (error) => io.stderr.write(`mcp: ${error.message}\\n`),\n })\n const onAbort = (): void => void server.close()\n if (io.signal?.aborted) onAbort()\n io.signal?.addEventListener(\"abort\", onAbort, { once: true })\n await server.closed\n io.signal?.removeEventListener(\"abort\", onAbort)\n return io.signal?.aborted ? EXIT.interrupted : EXIT.ok\n } catch (error) {\n io.stderr.write(formatError(error, DEV_PROG))\n return exitCodeOf(error)\n }\n // redirect 는 원복하지 않는다: 종료 중 남은 핸들러 출력도 stdout 에 섞이지 않게 (프로세스는 곧 exit)\n}\n\n/** 주입된 CliWriter (테스트) → transport 용 Writable */\nfunction writerStream(writer: CliWriter): Writable {\n return new Writable({\n write(chunk: Buffer | string, _encoding, callback) {\n writer.write(typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\"))\n callback()\n },\n })\n}\n\n/* ---------------------------------------------------------------- HTTP 감독 프로세스 */\n\n/**\n * 감독 프로세스 (이 프로세스) 는 사용자 코드를 import 하지 않는다. listen 소켓 · HTTP 연결을 쥐고\n * 요청마다 현재 서버 자식 (dev-server.ts, 127.0.0.1 임의 포트) 으로 중계한다.\n * 파일 변경 → 새 자식 fork → ready 후 전환, 이전 자식은 진행 중 요청이 끝나면 종료.\n * D2: 재시작 중 (새 자식 준비 전) 들어온 요청은 대기 후 새 자식이 처리. 새 자식 로드 실패 = 이전 자식이 처리\n */\nasync function supervise(args: DevArgs, io: CliIo): Promise<number> {\n const cwd = resolve(io.cwd)\n const log = (line: string): void => void io.stderr.write(`${DEV_PROG}: ${line}\\n`)\n\n let lock: DevLock\n try {\n const got = acquireDevLock(cwd)\n if (\"running\" in got) {\n const where = got.running.url ? `at ${got.running.url}` : \"(starting)\"\n io.stderr.write(\n `error: ${DEV_PROG} is already running ${where} (PID ${got.running.pid}).\\n` +\n \"Stop it first, or connect to that server.\\n\",\n )\n return EXIT.error\n }\n lock = got.acquired\n } catch (error) {\n io.stderr.write(formatError(error, DEV_PROG))\n return EXIT.error\n }\n const onExit = (): void => releaseDevLock(cwd)\n process.on(\"exit\", onExit)\n\n const supervisor = new DevSupervisor(cwd, log)\n try {\n const first = await supervisor.start()\n const host = args.host ?? first?.host ?? DEFAULT_HOST\n const port = args.port ?? first?.port ?? DEFAULT_PORT\n const url = await supervisor.listen(host, port)\n lock = { ...lock, url }\n updateDevLock(cwd, lock)\n io.stderr.write(`MCP dev server (Streamable HTTP) listening on ${url}\\n`)\n supervisor.watchFiles()\n // SIGINT (io.signal) 까지 실행\n await new Promise<void>((done) => {\n if (io.signal?.aborted) return done()\n io.signal?.addEventListener(\"abort\", () => done(), { once: true })\n })\n return EXIT.ok\n } catch (error) {\n io.stderr.write(formatError(error, DEV_PROG))\n return exitCodeOf(error)\n } finally {\n await supervisor.close()\n releaseDevLock(cwd)\n process.off(\"exit\", onExit)\n }\n}\n\ninterface ServerChild {\n seq: number\n proc: ChildProcess\n /** ready 후 자식의 127.0.0.1 포트 */\n port?: number\n inflight: number\n retiring: boolean\n startedAt: number\n}\n\n/** 자식 엔트리. tsc 빌드 (.js) · 원본 (.ts) 모두 이 모듈과 같은 확장자 */\nconst CHILD_ENTRY = fileURLToPath(new URL(`./dev-server${extname(fileURLToPath(import.meta.url))}`, import.meta.url))\n\n/** 요청 · 응답에서 중계하지 않는 hop-by-hop 헤더 */\nconst HOP_HEADERS = new Set([\"connection\", \"keep-alive\", \"proxy-connection\", \"upgrade\", \"te\", \"trailer\"])\n\nclass DevSupervisor {\n private readonly cwd: string\n private readonly log: (line: string) => void\n private server: Server | undefined\n private current: ServerChild | undefined\n private pending: ServerChild | undefined\n private readonly retired = new Set<ServerChild>()\n /** 새 자식 준비 전까지 대기 중인 요청 (D2) */\n private queue: (() => void)[] = []\n /** 자식이 하나도 없을 때의 로드 오류 (요청에 구조화 오류로 응답) */\n private loadError: string | undefined\n private commandsDir: string\n private bound: { host: string; port: number } | undefined\n private warnedServerChange = false\n private seq = 0\n private closing = false\n private watchers = new Map<string, FSWatcher>()\n private debounce: NodeJS.Timeout | undefined\n private changed = new Set<string>()\n private firstConfig: ((server: { host?: string; port?: number } | undefined) => void) | undefined\n\n constructor(cwd: string, log: (line: string) => void) {\n this.cwd = cwd\n this.log = log\n this.commandsDir = resolve(cwd, \"commands\")\n }\n\n /** 첫 자식 fork. 자식이 보고한 config.server (host · port) 반환. config 로드 실패 = undefined */\n start(): Promise<{ host?: string; port?: number } | undefined> {\n return new Promise((done) => {\n this.firstConfig = done\n this.spawn()\n })\n }\n\n async listen(host: string, port: number): Promise<string> {\n const server = createServer((req, res) => this.dispatch(req, res))\n this.server = server\n await new Promise<void>((done, reject) => {\n server.once(\"error\", reject)\n server.listen(port, host, () => {\n server.off(\"error\", reject)\n done()\n })\n })\n const address = server.address() as AddressInfo\n this.bound = { host, port }\n const shown = host.includes(\":\") && !host.startsWith(\"[\") ? `[${host}]` : host\n return `http://${shown}:${address.port}${MCP_PATH}`\n }\n\n /* -------------------------------------------------------------- 자식 수명 */\n\n private spawn(): void {\n if (this.closing) return\n if (this.pending) this.stop(this.pending)\n const child: ServerChild = {\n seq: ++this.seq,\n proc: fork(CHILD_ENTRY, [], {\n cwd: this.cwd,\n // node --test 의 실행 옵션은 자식에 넘기지 않는다 (--conditions 등은 유지)\n execArgv: process.execArgv.filter((a) => !a.startsWith(\"--test\")),\n stdio: [\"ignore\", \"inherit\", \"inherit\", \"ipc\"],\n }),\n inflight: 0,\n retiring: false,\n startedAt: Date.now(),\n }\n this.pending = child\n let failed = false\n child.proc.on(\"message\", (message: DevChildMessage) => {\n if (message.type === \"config\") this.onConfig(child, message)\n else if (message.type === \"ready\") this.onReady(child, message.port, message.commands)\n else if (message.type === \"error\") {\n failed = true\n this.onLoadFailed(child, message.message)\n }\n })\n child.proc.on(\"error\", (error) => {\n if (!failed) this.onLoadFailed(child, error.message)\n failed = true\n })\n child.proc.on(\"exit\", (code, signal) => {\n this.retired.delete(child)\n if (this.pending === child && !failed) {\n failed = true\n this.onLoadFailed(child, `server process exited (${signal ?? `code ${code}`}) before it was ready`)\n } else if (this.current === child) {\n this.current = undefined\n if (this.closing) return\n this.log(`server process exited unexpectedly (${signal ?? `code ${code}`}); restarting`)\n this.spawn()\n }\n })\n }\n\n private onConfig(child: ServerChild, message: Extract<DevChildMessage, { type: \"config\" }>): void {\n if (child !== this.pending) return\n if (this.firstConfig) {\n this.firstConfig(message.server)\n this.firstConfig = undefined\n } else if (\n this.bound &&\n !this.warnedServerChange &&\n ((message.server.host !== undefined && message.server.host !== this.bound.host) ||\n (message.server.port !== undefined && message.server.port !== this.bound.port))\n ) {\n this.warnedServerChange = true\n this.log(\"server.host / server.port changes in mext.config.ts apply after restarting mext dev\")\n }\n if (message.commandsDir !== this.commandsDir) {\n this.commandsDir = message.commandsDir\n if (this.watchers.size > 0) this.watchFiles()\n }\n }\n\n private onReady(child: ServerChild, port: number, commands: number): void {\n if (child !== this.pending) return\n const previous = this.current\n child.port = port\n this.pending = undefined\n this.current = child\n this.loadError = undefined\n const ms = Date.now() - child.startedAt\n this.log(`${previous ? \"reloaded\" : \"ready\"} (${commands} command${commands === 1 ? \"\" : \"s\"}, ${ms}ms)`)\n if (previous) this.retire(previous)\n this.flush()\n // commands/ 가 없던 상태에서 생겼으면 감시 시작\n if (this.watchers.size > 0 && !this.watchers.has(this.commandsDir)) this.watchFiles()\n }\n\n private onLoadFailed(child: ServerChild, message: string): void {\n if (child !== this.pending) return\n this.pending = undefined\n if (this.firstConfig) {\n this.firstConfig(undefined)\n this.firstConfig = undefined\n }\n if (this.current) {\n this.log(`reload failed; still serving the previous version. Fix the error and save to retry.\\n${indent(message)}`)\n } else {\n this.loadError = message\n this.log(`load failed; requests return an error until the next change.\\n${indent(message)}`)\n }\n this.flush()\n }\n\n /** 진행 중 요청이 끝나면 종료 */\n private retire(child: ServerChild): void {\n child.retiring = true\n this.retired.add(child)\n if (child.inflight === 0) this.stop(child)\n }\n\n private stop(child: ServerChild): void {\n if (child.proc.exitCode !== null || child.proc.signalCode !== null) return\n // 준비 전 (로드 중) 자식은 shutdown 메시지를 처리하지 않는다\n if (child.port !== undefined && child.proc.connected) {\n child.proc.send({ type: \"shutdown\" } satisfies DevParentMessage, () => {})\n } else child.proc.kill(\"SIGTERM\")\n setTimeout(() => {\n if (child.proc.exitCode === null && child.proc.signalCode === null) child.proc.kill(\"SIGKILL\")\n }, 3_000).unref()\n }\n\n /* -------------------------------------------------------------- 요청 중계 */\n\n private dispatch(req: IncomingMessage, res: ServerResponse): void {\n if (this.pending) {\n this.queue.push(() => this.dispatch(req, res))\n return\n }\n const child = this.current\n if (child?.port !== undefined) return this.proxy(child, req, res)\n this.sendUnavailable(req, res, this.loadError ?? \"the server process is not running\")\n }\n\n private flush(): void {\n const queued = this.queue\n this.queue = []\n for (const run of queued) run()\n }\n\n private proxy(child: ServerChild, req: IncomingMessage, res: ServerResponse): void {\n // 대기 중 클라이언트가 끊은 요청\n if (res.destroyed || req.destroyed) return\n child.inflight++\n let finished = false\n const done = (): void => {\n if (finished) return\n finished = true\n child.inflight--\n if (child.retiring && child.inflight === 0) this.stop(child)\n }\n const headers: Record<string, string | string[]> = {}\n for (const [name, value] of Object.entries(req.headers)) {\n if (value !== undefined && !HOP_HEADERS.has(name)) headers[name] = value\n }\n const upstream = httpRequest({\n host: \"127.0.0.1\",\n port: child.port,\n method: req.method,\n path: req.url,\n headers,\n agent: false,\n })\n upstream.on(\"response\", (up) => {\n const out: Record<string, string | string[]> = {}\n for (const [name, value] of Object.entries(up.headers)) {\n if (value !== undefined && !HOP_HEADERS.has(name)) out[name] = value\n }\n res.writeHead(up.statusCode ?? 502, out)\n res.flushHeaders()\n up.pipe(res)\n up.on(\"error\", () => res.destroy())\n up.on(\"aborted\", () => res.destroy())\n })\n upstream.on(\"error\", (error) => {\n if (res.headersSent) res.destroy()\n else if (!res.destroyed) {\n sendJson(res, 502, rpcError(-32_603, `mext dev: server process did not respond (${error.message}).`))\n }\n done()\n })\n // 클라이언트 연결 종료 (SSE 취소 포함) = 자식으로의 요청도 닫아 ctx.signal abort\n res.on(\"close\", () => {\n if (!res.writableFinished) upstream.destroy()\n done()\n })\n req.pipe(upstream)\n }\n\n /** 자식 없음 (로드 실패) = 503 + JSON-RPC 오류. MCP 엔드포인트 외 경로도 같은 응답 */\n private sendUnavailable(req: IncomingMessage, res: ServerResponse, message: string): void {\n const chunks: Buffer[] = []\n let size = 0\n req.on(\"data\", (chunk: Buffer) => {\n size += chunk.length\n if (size <= 1024 * 1024) chunks.push(chunk)\n })\n req.on(\"end\", () => {\n const text =\n \"mext dev: the project failed to load. Fix the error and save; the server reloads automatically.\\n\" + message\n sendJson(res, 503, rpcError(-32_603, text, { loadError: message }, requestId(Buffer.concat(chunks))))\n })\n }\n\n /* -------------------------------------------------------------- 파일 감시 */\n\n /** commandsDir (recursive) + 프로젝트 루트 (mext.config.ts · instrumentation.ts · commandsDir 생성 · 삭제) */\n watchFiles(): void {\n if (this.closing) return\n for (const w of this.watchers.values()) w.close()\n this.watchers.clear()\n const rootNames = new Set(DEV_WATCHED_ROOT_FILES)\n if (dirname(this.commandsDir) === this.cwd) rootNames.add(basename(this.commandsDir))\n this.addWatcher(this.cwd, false, (name) => (rootNames.has(name) ? name : undefined))\n if (existsSync(this.commandsDir)) {\n this.addWatcher(this.commandsDir, true, (name) => relative(this.cwd, resolve(this.commandsDir, name)))\n }\n }\n\n private addWatcher(dir: string, recursive: boolean, accept: (name: string) => string | undefined): void {\n try {\n const watcher = watch(dir, { recursive, persistent: false }, (_event, filename) => {\n const name = filename === null ? undefined : accept(filename.toString())\n if (name !== undefined) this.schedule(name)\n })\n watcher.on(\"error\", (error) => {\n this.log(`file watching stopped for ${relative(this.cwd, dir) || \".\"} (${error.message})`)\n watcher.close()\n this.watchers.delete(dir)\n })\n this.watchers.set(dir, watcher)\n } catch (error) {\n // R3: Linux inotify 한도 (ENOSPC) 등. 서버는 계속, 재시작은 수동\n this.log(`cannot watch ${relative(this.cwd, dir) || \".\"} (${(error as Error).message}); restart mext dev after changes`)\n }\n }\n\n private schedule(name: string): void {\n if (this.closing) return\n this.changed.add(name)\n clearTimeout(this.debounce)\n this.debounce = setTimeout(() => {\n const names = [...this.changed]\n this.changed.clear()\n const shown = names.slice(0, 3).join(\", \") + (names.length > 3 ? `, +${names.length - 3} more` : \"\")\n this.log(`change detected (${shown}); reloading`)\n this.spawn()\n }, DEV_DEBOUNCE_MS)\n }\n\n /* -------------------------------------------------------------- 종료 */\n\n async close(): Promise<void> {\n this.closing = true\n clearTimeout(this.debounce)\n for (const w of this.watchers.values()) w.close()\n this.watchers.clear()\n const children = [this.current, this.pending, ...this.retired].filter((c): c is ServerChild => c !== undefined)\n const exited = children.map(\n (c) =>\n new Promise<void>((done) => {\n if (c.proc.exitCode !== null || c.proc.signalCode !== null) return done()\n c.proc.once(\"exit\", () => done())\n this.stop(c)\n }),\n )\n if (this.server) {\n const server = this.server\n server.closeAllConnections()\n await new Promise<void>((done) => server.close(() => done()))\n }\n this.flush()\n await Promise.all(exited)\n }\n}\n\nfunction indent(text: string): string {\n return text\n .split(\"\\n\")\n .map((l) => ` ${l}`)\n .join(\"\\n\")\n}\n\nfunction sendJson(res: ServerResponse, status: number, body: unknown): void {\n if (res.headersSent || res.destroyed) return\n const text = JSON.stringify(body)\n res.writeHead(status, { \"Content-Type\": \"application/json\", \"Content-Length\": Buffer.byteLength(text) })\n res.end(text)\n}\n\nfunction rpcError(code: number, message: string, data?: unknown, id: string | number | null = null) {\n return { jsonrpc: \"2.0\", id, error: data === undefined ? { code, message } : { code, message, data } }\n}\n\nfunction requestId(body: Buffer): string | number | null {\n try {\n const { id } = JSON.parse(body.toString(\"utf8\")) as { id?: unknown }\n return typeof id === \"string\" || typeof id === \"number\" ? id : null\n } catch {\n return null\n }\n}\n\nexport function devHelp(): string {\n const lines = [\n \"Run the development MCP server (MCP 2026-07-28). Reloads on file changes.\",\n \"\",\n \"Usage:\",\n ` ${DEV_PROG} [--port <n>] [--host <host>]`,\n ` ${DEV_PROG} --stdio`,\n \"\",\n \"Modes:\",\n ...table([\n [\n DEV_PROG,\n `Streamable HTTP at POST http://${DEFAULT_HOST}:${DEFAULT_PORT}${MCP_PATH} (mext.config.ts: app · auth · tools · server · oauth)`,\n ],\n [\"\", `Watches commands/, ${DEV_WATCHED_ROOT_FILES.join(\", \")} and restarts the server process; the port stays open`],\n [`${DEV_PROG} --stdio`, \"stdio (line-delimited JSON-RPC). Local principal; other stdout output goes to stderr. No watching\"],\n ]).map((l) => ` ${l}`),\n \"\",\n \"Flags:\",\n ...table([\n [\"--port <n>\", `HTTP port (default server.port or ${DEFAULT_PORT}; 0 = any free port)`],\n [\"--host <host>\", `HTTP bind address (default server.host or ${DEFAULT_HOST})`],\n [\"--stdio\", \"Serve over stdin/stdout instead of HTTP\"],\n [\"-h, --help\", \"Show help\"],\n ]).map((l) => ` ${l}`),\n \"\",\n \"One HTTP dev server per project: .mext/dev/lock records { pid, url, startedAt } (add .mext/ to .gitignore).\",\n 'Register with an MCP client: \"mext mcp install\".',\n ]\n return `${lines.join(\"\\n\")}\\n`\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"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","sourcesContent":["import { fork, type ChildProcess } from \"node:child_process\"\nimport { existsSync, watch, type FSWatcher } from \"node:fs\"\nimport { createServer, request as httpRequest, type IncomingMessage, type Server, type ServerResponse } from \"node:http\"\nimport type { AddressInfo } from \"node:net\"\nimport { basename, dirname, extname, relative, resolve } from \"node:path\"\nimport { Writable } from \"node:stream\"\nimport { fileURLToPath } from \"node:url\"\nimport { CONFIG_FILE, loadConfig, mcpStdioDeclarations, resolveCommandsDir, resolveLocalPrincipal } from \"../config.ts\"\nimport { DEFAULT_HOST, DEFAULT_PORT, MCP_PATH } from \"../mcp/constants.ts\"\nimport { loadProjectInstrumentation } from \"../instrumentation.ts\"\nimport { redirectStdout, serveMcpStdio } from \"../mcp/stdio.ts\"\nimport { loadRegistry } from \"../scan.ts\"\nimport { acquireDevLock, releaseDevLock, updateDevLock, type DevLock } from \"./dev-lock.ts\"\nimport type { DevChildMessage, DevParentMessage } from \"./dev-server.ts\"\nimport { table } from \"./help.ts\"\nimport type { CliIo, CliWriter } from \"./io.ts\"\nimport { EXIT, exitCodeOf, formatError } from \"./output.ts\"\n\nexport const DEV_PROG = \"mext dev\"\n\n/** 감시 대상 프로젝트 루트 파일 (commandsDir/** 와 함께) */\nexport const DEV_WATCHED_ROOT_FILES: readonly string[] = [CONFIG_FILE, \"instrumentation.ts\"]\n\n/** 파일 변경 → 재시작 debounce (ms) */\nexport const DEV_DEBOUNCE_MS = 100\n\n/**\n * mext dev [--port <n>] [--host <h>] 개발 HTTP 서버. 감독 프로세스 + 서버 자식 (파일 변경 시 교체)\n * mext dev --stdio stdio 서버 (감시 없음, 같은 프로세스)\n */\nexport async function devCommand(argv: readonly string[], io: CliIo): Promise<number> {\n const parsed = parseDevArgs(argv)\n if (typeof parsed === \"string\") {\n io.stderr.write(`error: ${parsed}\\nRun \"${DEV_PROG} --help\" for usage.\\n`)\n return EXIT.usage\n }\n if (parsed.help) {\n io.stdout.write(devHelp())\n return EXIT.ok\n }\n if (parsed.stdio) return stdio(io)\n return supervise(parsed, io)\n}\n\ninterface DevArgs {\n help: boolean\n stdio: boolean\n port?: number\n host?: string\n}\n\n/** 반환 문자열 = 사용법 오류 메시지 */\nexport function parseDevArgs(argv: readonly string[]): DevArgs | string {\n const args: DevArgs = { help: false, stdio: false }\n for (let i = 0; i < argv.length; i++) {\n const tok = argv[i]!\n if (tok === \"--help\" || tok === \"-h\") {\n args.help = true\n continue\n }\n if (tok === \"--stdio\") {\n args.stdio = true\n continue\n }\n if (!tok.startsWith(\"--\")) return `unexpected argument \"${tok}\"`\n const eq = tok.indexOf(\"=\")\n const name = eq < 0 ? tok.slice(2) : tok.slice(2, eq)\n if (name !== \"port\" && name !== \"host\") return `unknown flag --${name}`\n const value = eq < 0 ? argv[++i] : tok.slice(eq + 1)\n if (value === undefined || value === \"\") return `--${name} requires a value`\n if (name === \"port\") {\n const port = Number(value)\n if (!Number.isInteger(port) || port < 0 || port > 65_535) return `--port must be an integer between 0 and 65535`\n args.port = port\n } else args.host = value\n }\n if (args.stdio && (args.port !== undefined || args.host !== undefined)) return \"--port and --host do not apply to --stdio\"\n return args\n}\n\n/* ---------------------------------------------------------------- stdio */\n\n/**\n * stdio: stdout = MCP 메시지만. D4: 이 프로세스의 그 외 stdout 쓰기 (console.log · process.stdout.write) 는\n * 명령어 import 전부터 종료까지 stderr 로 돌린다. stdin EOF = 연결 종료 → 바로 반환 (bin 이 exit).\n * 감시 · 잠금 없음: MCP 클라이언트가 프로세스를 소유 · 재실행한다\n */\nasync function stdio(io: CliIo): Promise<number> {\n const redirect = io.stdout === process.stdout ? redirectStdout() : undefined\n const wire = redirect?.wire ?? writerStream(io.stdout)\n try {\n const instrumentation = await loadProjectInstrumentation(io.cwd)\n const config = await loadConfig(io.cwd)\n const registry = await loadRegistry(resolveCommandsDir(io.cwd, config))\n const principal = await resolveLocalPrincipal(config)\n const server = serveMcpStdio({\n registry,\n instrumentation,\n principal,\n ...(config.app ? { app: config.app } : {}),\n ...(config.tools ? { tools: config.tools } : {}),\n ...mcpStdioDeclarations(config),\n stdin: io.stdin,\n stdout: wire,\n onerror: (error) => io.stderr.write(`mcp: ${error.message}\\n`),\n })\n const onAbort = (): void => void server.close()\n if (io.signal?.aborted) onAbort()\n io.signal?.addEventListener(\"abort\", onAbort, { once: true })\n await server.closed\n io.signal?.removeEventListener(\"abort\", onAbort)\n return io.signal?.aborted ? EXIT.interrupted : EXIT.ok\n } catch (error) {\n io.stderr.write(formatError(error, DEV_PROG))\n return exitCodeOf(error)\n }\n // redirect 는 원복하지 않는다: 종료 중 남은 핸들러 출력도 stdout 에 섞이지 않게 (프로세스는 곧 exit)\n}\n\n/** 주입된 CliWriter (테스트) → transport 용 Writable */\nfunction writerStream(writer: CliWriter): Writable {\n return new Writable({\n write(chunk: Buffer | string, _encoding, callback) {\n writer.write(typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\"))\n callback()\n },\n })\n}\n\n/* ---------------------------------------------------------------- HTTP 감독 프로세스 */\n\n/**\n * 감독 프로세스 (이 프로세스) 는 사용자 코드를 import 하지 않는다. listen 소켓 · HTTP 연결을 쥐고\n * 요청마다 현재 서버 자식 (dev-server.ts, 127.0.0.1 임의 포트) 으로 중계한다.\n * 파일 변경 → 새 자식 fork → ready 후 전환, 이전 자식은 진행 중 요청이 끝나면 종료.\n * D2: 재시작 중 (새 자식 준비 전) 들어온 요청은 대기 후 새 자식이 처리. 새 자식 로드 실패 = 이전 자식이 처리\n */\nasync function supervise(args: DevArgs, io: CliIo): Promise<number> {\n const cwd = resolve(io.cwd)\n const log = (line: string): void => void io.stderr.write(`${DEV_PROG}: ${line}\\n`)\n\n let lock: DevLock\n try {\n const got = acquireDevLock(cwd)\n if (\"running\" in got) {\n const where = got.running.url ? `at ${got.running.url}` : \"(starting)\"\n io.stderr.write(\n `error: ${DEV_PROG} is already running ${where} (PID ${got.running.pid}).\\n` +\n \"Stop it first, or connect to that server.\\n\",\n )\n return EXIT.error\n }\n lock = got.acquired\n } catch (error) {\n io.stderr.write(formatError(error, DEV_PROG))\n return EXIT.error\n }\n const onExit = (): void => releaseDevLock(cwd)\n process.on(\"exit\", onExit)\n\n const supervisor = new DevSupervisor(cwd, log)\n try {\n const first = await supervisor.start()\n const host = args.host ?? first?.host ?? DEFAULT_HOST\n const port = args.port ?? first?.port ?? DEFAULT_PORT\n const url = await supervisor.listen(host, port)\n lock = { ...lock, url }\n updateDevLock(cwd, lock)\n io.stderr.write(`MCP dev server (Streamable HTTP) listening on ${url}\\n`)\n supervisor.watchFiles()\n // SIGINT (io.signal) 까지 실행\n await new Promise<void>((done) => {\n if (io.signal?.aborted) return done()\n io.signal?.addEventListener(\"abort\", () => done(), { once: true })\n })\n return EXIT.ok\n } catch (error) {\n io.stderr.write(formatError(error, DEV_PROG))\n return exitCodeOf(error)\n } finally {\n await supervisor.close()\n releaseDevLock(cwd)\n process.off(\"exit\", onExit)\n }\n}\n\ninterface ServerChild {\n seq: number\n proc: ChildProcess\n /** ready 후 자식의 127.0.0.1 포트 */\n port?: number\n inflight: number\n retiring: boolean\n startedAt: number\n}\n\n/** 자식 엔트리. tsc 빌드 (.js) · 원본 (.ts) 모두 이 모듈과 같은 확장자 */\nconst CHILD_ENTRY = fileURLToPath(new URL(`./dev-server${extname(fileURLToPath(import.meta.url))}`, import.meta.url))\n\n/** 요청 · 응답에서 중계하지 않는 hop-by-hop 헤더 */\nconst HOP_HEADERS = new Set([\"connection\", \"keep-alive\", \"proxy-connection\", \"upgrade\", \"te\", \"trailer\"])\n\nclass DevSupervisor {\n private readonly cwd: string\n private readonly log: (line: string) => void\n private server: Server | undefined\n private current: ServerChild | undefined\n private pending: ServerChild | undefined\n private readonly retired = new Set<ServerChild>()\n /** 새 자식 준비 전까지 대기 중인 요청 (D2) */\n private queue: (() => void)[] = []\n /** 자식이 하나도 없을 때의 로드 오류 (요청에 구조화 오류로 응답) */\n private loadError: string | undefined\n private commandsDir: string\n private bound: { host: string; port: number } | undefined\n private warnedServerChange = false\n private seq = 0\n private closing = false\n private watchers = new Map<string, FSWatcher>()\n private debounce: NodeJS.Timeout | undefined\n private changed = new Set<string>()\n private firstConfig: ((server: { host?: string; port?: number } | undefined) => void) | undefined\n\n constructor(cwd: string, log: (line: string) => void) {\n this.cwd = cwd\n this.log = log\n this.commandsDir = resolve(cwd, \"commands\")\n }\n\n /** 첫 자식 fork. 자식이 보고한 config.server (host · port) 반환. config 로드 실패 = undefined */\n start(): Promise<{ host?: string; port?: number } | undefined> {\n return new Promise((done) => {\n this.firstConfig = done\n this.spawn()\n })\n }\n\n async listen(host: string, port: number): Promise<string> {\n const server = createServer((req, res) => this.dispatch(req, res))\n this.server = server\n await new Promise<void>((done, reject) => {\n server.once(\"error\", reject)\n server.listen(port, host, () => {\n server.off(\"error\", reject)\n done()\n })\n })\n const address = server.address() as AddressInfo\n this.bound = { host, port }\n const shown = host.includes(\":\") && !host.startsWith(\"[\") ? `[${host}]` : host\n return `http://${shown}:${address.port}${MCP_PATH}`\n }\n\n /* -------------------------------------------------------------- 자식 수명 */\n\n private spawn(): void {\n if (this.closing) return\n if (this.pending) this.stop(this.pending)\n const child: ServerChild = {\n seq: ++this.seq,\n proc: fork(CHILD_ENTRY, [], {\n cwd: this.cwd,\n // node --test 의 실행 옵션은 자식에 넘기지 않는다 (--conditions 등은 유지)\n execArgv: process.execArgv.filter((a) => !a.startsWith(\"--test\")),\n stdio: [\"ignore\", \"inherit\", \"inherit\", \"ipc\"],\n }),\n inflight: 0,\n retiring: false,\n startedAt: Date.now(),\n }\n this.pending = child\n let failed = false\n child.proc.on(\"message\", (message: DevChildMessage) => {\n if (message.type === \"config\") this.onConfig(child, message)\n else if (message.type === \"ready\") this.onReady(child, message.port, message.commands)\n else if (message.type === \"error\") {\n failed = true\n this.onLoadFailed(child, message.message)\n }\n })\n child.proc.on(\"error\", (error) => {\n if (!failed) this.onLoadFailed(child, error.message)\n failed = true\n })\n child.proc.on(\"exit\", (code, signal) => {\n this.retired.delete(child)\n if (this.pending === child && !failed) {\n failed = true\n this.onLoadFailed(child, `server process exited (${signal ?? `code ${code}`}) before it was ready`)\n } else if (this.current === child) {\n this.current = undefined\n if (this.closing) return\n this.log(`server process exited unexpectedly (${signal ?? `code ${code}`}); restarting`)\n this.spawn()\n }\n })\n }\n\n private onConfig(child: ServerChild, message: Extract<DevChildMessage, { type: \"config\" }>): void {\n if (child !== this.pending) return\n if (this.firstConfig) {\n this.firstConfig(message.server)\n this.firstConfig = undefined\n } else if (\n this.bound &&\n !this.warnedServerChange &&\n ((message.server.host !== undefined && message.server.host !== this.bound.host) ||\n (message.server.port !== undefined && message.server.port !== this.bound.port))\n ) {\n this.warnedServerChange = true\n this.log(\"server.host / server.port changes in mext.config.ts apply after restarting mext dev\")\n }\n if (message.commandsDir !== this.commandsDir) {\n this.commandsDir = message.commandsDir\n if (this.watchers.size > 0) this.watchFiles()\n }\n }\n\n private onReady(child: ServerChild, port: number, commands: number): void {\n if (child !== this.pending) return\n const previous = this.current\n child.port = port\n this.pending = undefined\n this.current = child\n this.loadError = undefined\n const ms = Date.now() - child.startedAt\n this.log(`${previous ? \"reloaded\" : \"ready\"} (${commands} command${commands === 1 ? \"\" : \"s\"}, ${ms}ms)`)\n if (previous) this.retire(previous)\n this.flush()\n // commands/ 가 없던 상태에서 생겼으면 감시 시작\n if (this.watchers.size > 0 && !this.watchers.has(this.commandsDir)) this.watchFiles()\n }\n\n private onLoadFailed(child: ServerChild, message: string): void {\n if (child !== this.pending) return\n this.pending = undefined\n if (this.firstConfig) {\n this.firstConfig(undefined)\n this.firstConfig = undefined\n }\n if (this.current) {\n this.log(`reload failed; still serving the previous version. Fix the error and save to retry.\\n${indent(message)}`)\n } else {\n this.loadError = message\n this.log(`load failed; requests return an error until the next change.\\n${indent(message)}`)\n }\n this.flush()\n }\n\n /** 진행 중 요청이 끝나면 종료 */\n private retire(child: ServerChild): void {\n child.retiring = true\n this.retired.add(child)\n if (child.inflight === 0) this.stop(child)\n }\n\n private stop(child: ServerChild): void {\n if (child.proc.exitCode !== null || child.proc.signalCode !== null) return\n // 준비 전 (로드 중) 자식은 shutdown 메시지를 처리하지 않는다\n if (child.port !== undefined && child.proc.connected) {\n child.proc.send({ type: \"shutdown\" } satisfies DevParentMessage, () => {})\n } else child.proc.kill(\"SIGTERM\")\n setTimeout(() => {\n if (child.proc.exitCode === null && child.proc.signalCode === null) child.proc.kill(\"SIGKILL\")\n }, 3_000).unref()\n }\n\n /* -------------------------------------------------------------- 요청 중계 */\n\n private dispatch(req: IncomingMessage, res: ServerResponse): void {\n if (this.pending) {\n this.queue.push(() => this.dispatch(req, res))\n return\n }\n const child = this.current\n if (child?.port !== undefined) return this.proxy(child, req, res)\n this.sendUnavailable(req, res, this.loadError ?? \"the server process is not running\")\n }\n\n private flush(): void {\n const queued = this.queue\n this.queue = []\n for (const run of queued) run()\n }\n\n private proxy(child: ServerChild, req: IncomingMessage, res: ServerResponse): void {\n // 대기 중 클라이언트가 끊은 요청\n if (res.destroyed || req.destroyed) return\n child.inflight++\n let finished = false\n const done = (): void => {\n if (finished) return\n finished = true\n child.inflight--\n if (child.retiring && child.inflight === 0) this.stop(child)\n }\n const headers: Record<string, string | string[]> = {}\n for (const [name, value] of Object.entries(req.headers)) {\n if (value !== undefined && !HOP_HEADERS.has(name)) headers[name] = value\n }\n const upstream = httpRequest({\n host: \"127.0.0.1\",\n port: child.port,\n method: req.method,\n path: req.url,\n headers,\n agent: false,\n })\n upstream.on(\"response\", (up) => {\n const out: Record<string, string | string[]> = {}\n for (const [name, value] of Object.entries(up.headers)) {\n if (value !== undefined && !HOP_HEADERS.has(name)) out[name] = value\n }\n res.writeHead(up.statusCode ?? 502, out)\n res.flushHeaders()\n up.pipe(res)\n up.on(\"error\", () => res.destroy())\n up.on(\"aborted\", () => res.destroy())\n })\n upstream.on(\"error\", (error) => {\n if (res.headersSent) res.destroy()\n else if (!res.destroyed) {\n sendJson(res, 502, rpcError(-32_603, `mext dev: server process did not respond (${error.message}).`))\n }\n done()\n })\n // 클라이언트 연결 종료 (SSE 취소 포함) = 자식으로의 요청도 닫아 ctx.signal abort\n res.on(\"close\", () => {\n if (!res.writableFinished) upstream.destroy()\n done()\n })\n req.pipe(upstream)\n }\n\n /** 자식 없음 (로드 실패) = 503 + JSON-RPC 오류. MCP 엔드포인트 외 경로도 같은 응답 */\n private sendUnavailable(req: IncomingMessage, res: ServerResponse, message: string): void {\n const chunks: Buffer[] = []\n let size = 0\n req.on(\"data\", (chunk: Buffer) => {\n size += chunk.length\n if (size <= 1024 * 1024) chunks.push(chunk)\n })\n req.on(\"end\", () => {\n const text =\n \"mext dev: the project failed to load. Fix the error and save; the server reloads automatically.\\n\" + message\n sendJson(res, 503, rpcError(-32_603, text, { loadError: message }, requestId(Buffer.concat(chunks))))\n })\n }\n\n /* -------------------------------------------------------------- 파일 감시 */\n\n /** commandsDir (recursive) + 프로젝트 루트 (mext.config.ts · instrumentation.ts · commandsDir 생성 · 삭제) */\n watchFiles(): void {\n if (this.closing) return\n for (const w of this.watchers.values()) w.close()\n this.watchers.clear()\n const rootNames = new Set(DEV_WATCHED_ROOT_FILES)\n if (dirname(this.commandsDir) === this.cwd) rootNames.add(basename(this.commandsDir))\n this.addWatcher(this.cwd, false, (name) => (rootNames.has(name) ? name : undefined))\n if (existsSync(this.commandsDir)) {\n this.addWatcher(this.commandsDir, true, (name) => relative(this.cwd, resolve(this.commandsDir, name)))\n }\n }\n\n private addWatcher(dir: string, recursive: boolean, accept: (name: string) => string | undefined): void {\n try {\n const watcher = watch(dir, { recursive, persistent: false }, (_event, filename) => {\n const name = filename === null ? undefined : accept(filename.toString())\n if (name !== undefined) this.schedule(name)\n })\n watcher.on(\"error\", (error) => {\n this.log(`file watching stopped for ${relative(this.cwd, dir) || \".\"} (${error.message})`)\n watcher.close()\n this.watchers.delete(dir)\n })\n this.watchers.set(dir, watcher)\n } catch (error) {\n // R3: Linux inotify 한도 (ENOSPC) 등. 서버는 계속, 재시작은 수동\n this.log(`cannot watch ${relative(this.cwd, dir) || \".\"} (${(error as Error).message}); restart mext dev after changes`)\n }\n }\n\n private schedule(name: string): void {\n if (this.closing) return\n this.changed.add(name)\n clearTimeout(this.debounce)\n this.debounce = setTimeout(() => {\n const names = [...this.changed]\n this.changed.clear()\n const shown = names.slice(0, 3).join(\", \") + (names.length > 3 ? `, +${names.length - 3} more` : \"\")\n this.log(`change detected (${shown}); reloading`)\n this.spawn()\n }, DEV_DEBOUNCE_MS)\n }\n\n /* -------------------------------------------------------------- 종료 */\n\n async close(): Promise<void> {\n this.closing = true\n clearTimeout(this.debounce)\n for (const w of this.watchers.values()) w.close()\n this.watchers.clear()\n const children = [this.current, this.pending, ...this.retired].filter((c): c is ServerChild => c !== undefined)\n const exited = children.map(\n (c) =>\n new Promise<void>((done) => {\n if (c.proc.exitCode !== null || c.proc.signalCode !== null) return done()\n c.proc.once(\"exit\", () => done())\n this.stop(c)\n }),\n )\n if (this.server) {\n const server = this.server\n server.closeAllConnections()\n await new Promise<void>((done) => server.close(() => done()))\n }\n this.flush()\n await Promise.all(exited)\n }\n}\n\nfunction indent(text: string): string {\n return text\n .split(\"\\n\")\n .map((l) => ` ${l}`)\n .join(\"\\n\")\n}\n\nfunction sendJson(res: ServerResponse, status: number, body: unknown): void {\n if (res.headersSent || res.destroyed) return\n const text = JSON.stringify(body)\n res.writeHead(status, { \"Content-Type\": \"application/json\", \"Content-Length\": Buffer.byteLength(text) })\n res.end(text)\n}\n\nfunction rpcError(code: number, message: string, data?: unknown, id: string | number | null = null) {\n return { jsonrpc: \"2.0\", id, error: data === undefined ? { code, message } : { code, message, data } }\n}\n\nfunction requestId(body: Buffer): string | number | null {\n try {\n const { id } = JSON.parse(body.toString(\"utf8\")) as { id?: unknown }\n return typeof id === \"string\" || typeof id === \"number\" ? id : null\n } catch {\n return null\n }\n}\n\nexport function devHelp(): string {\n const lines = [\n \"Run the development MCP server (MCP 2026-07-28). Reloads on file changes.\",\n \"\",\n \"Usage:\",\n ` ${DEV_PROG} [--port <n>] [--host <host>]`,\n ` ${DEV_PROG} --stdio`,\n \"\",\n \"Modes:\",\n ...table([\n [\n DEV_PROG,\n `Streamable HTTP at POST http://${DEFAULT_HOST}:${DEFAULT_PORT}${MCP_PATH} (mext.config.ts: app · auth · tools · server · oauth)`,\n ],\n [\"\", `Watches commands/, ${DEV_WATCHED_ROOT_FILES.join(\", \")} and restarts the server process; the port stays open`],\n [`${DEV_PROG} --stdio`, \"stdio (line-delimited JSON-RPC). Local principal; other stdout output goes to stderr. No watching\"],\n ]).map((l) => ` ${l}`),\n \"\",\n \"Flags:\",\n ...table([\n [\"--port <n>\", `HTTP port (default server.port or ${DEFAULT_PORT}; 0 = any free port)`],\n [\"--host <host>\", `HTTP bind address (default server.host or ${DEFAULT_HOST})`],\n [\"--stdio\", \"Serve over stdin/stdout instead of HTTP\"],\n [\"-h, --help\", \"Show help\"],\n ]).map((l) => ` ${l}`),\n \"\",\n \"One HTTP dev server per project: .mext/dev/lock records { pid, url, startedAt } (add .mext/ to .gitignore).\",\n 'Register with an MCP client: \"mext mcp install\".',\n ]\n return `${lines.join(\"\\n\")}\\n`\n}\n"]}
|
package/dist/cli/output.d.ts
CHANGED
|
@@ -32,3 +32,47 @@ export declare function formatResult(value: unknown): string;
|
|
|
32
32
|
export declare function formatJson(value: unknown): string;
|
|
33
33
|
/** ctx.progress → stderr 한 줄 */
|
|
34
34
|
export declare function formatProgress(update: ProgressUpdate): string;
|
|
35
|
+
/** cli.errors formatter 입력: 오류 하나 + mext 기본 출력 */
|
|
36
|
+
export interface CliErrorInfo {
|
|
37
|
+
/** MextErrorCode · EXECUTION_ERROR · INTERRUPTED · REMOTE_ERROR · 서버 핸들러 오류 code 등 (= body.code) */
|
|
38
|
+
code: string;
|
|
39
|
+
message: string;
|
|
40
|
+
/** 오류 상세 (MextError.details · 서버 오류 본문의 code · message 외 필드) */
|
|
41
|
+
details: Record<string, unknown>;
|
|
42
|
+
/** INVALID_ARGUMENT issues 의 "경로: 메시지" (경로 없으면 메시지). 그 외 [] */
|
|
43
|
+
reasons: string[];
|
|
44
|
+
/** mext 기본 --json 오류 본문 */
|
|
45
|
+
body: Record<string, unknown>;
|
|
46
|
+
/** mext 기본 사람용 텍스트 (끝 줄바꿈 포함) */
|
|
47
|
+
text: string;
|
|
48
|
+
/** mext 기본 exit code (0 · 1 · 2 · 77 · 130) */
|
|
49
|
+
exitCode: number;
|
|
50
|
+
/** --json 지정 여부 */
|
|
51
|
+
json: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** formatter 출력. 지정한 필드만 기본값 대체 (stderr 기본 = json ? body JSON : text, stdout 기본 = 없음) */
|
|
54
|
+
export interface CliErrorOutput {
|
|
55
|
+
exitCode?: number;
|
|
56
|
+
stderr?: string;
|
|
57
|
+
stdout?: string;
|
|
58
|
+
}
|
|
59
|
+
/** cli.errors 모듈의 default export. undefined 반환 = mext 기본 */
|
|
60
|
+
export type CliErrorFormatter = (error: CliErrorInfo) => CliErrorOutput | undefined | void;
|
|
61
|
+
export interface CliErrorWriter {
|
|
62
|
+
stdout: {
|
|
63
|
+
write(chunk: string): unknown;
|
|
64
|
+
};
|
|
65
|
+
stderr: {
|
|
66
|
+
write(chunk: string): unknown;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 오류 출력 (기본 = json ? body : text) + formatter 적용 → exit code.
|
|
71
|
+
* formatter 예외 · 잘못된 exitCode = 기본값 + stderr 경고 1줄
|
|
72
|
+
*/
|
|
73
|
+
export declare function emitError(io: CliErrorWriter, error: {
|
|
74
|
+
body: Record<string, unknown>;
|
|
75
|
+
text: string;
|
|
76
|
+
exitCode: number;
|
|
77
|
+
json: boolean;
|
|
78
|
+
}, formatter: CliErrorFormatter | undefined): number;
|
package/dist/cli/output.js
CHANGED
|
@@ -169,4 +169,61 @@ export function formatProgress(update) {
|
|
|
169
169
|
const head = update.total !== undefined ? `[${update.progress}/${update.total}]` : `[${update.progress}]`;
|
|
170
170
|
return `${update.message ? `${head} ${update.message}` : head}\n`;
|
|
171
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* 오류 출력 (기본 = json ? body : text) + formatter 적용 → exit code.
|
|
174
|
+
* formatter 예외 · 잘못된 exitCode = 기본값 + stderr 경고 1줄
|
|
175
|
+
*/
|
|
176
|
+
export function emitError(io, error, formatter) {
|
|
177
|
+
const fallback = error.json ? formatJson(error.body) : error.text;
|
|
178
|
+
if (!formatter) {
|
|
179
|
+
io.stderr.write(fallback);
|
|
180
|
+
return error.exitCode;
|
|
181
|
+
}
|
|
182
|
+
const { code, message, ...rest } = error.body;
|
|
183
|
+
const details = isRecord(rest.details) ? rest.details : rest;
|
|
184
|
+
const info = {
|
|
185
|
+
code: typeof code === "string" ? code : "EXECUTION_ERROR",
|
|
186
|
+
message: typeof message === "string" ? message : String(message ?? ""),
|
|
187
|
+
details,
|
|
188
|
+
reasons: reasonsOf(details),
|
|
189
|
+
body: error.body,
|
|
190
|
+
text: error.text,
|
|
191
|
+
exitCode: error.exitCode,
|
|
192
|
+
json: error.json,
|
|
193
|
+
};
|
|
194
|
+
let out;
|
|
195
|
+
try {
|
|
196
|
+
out = formatter(info);
|
|
197
|
+
}
|
|
198
|
+
catch (e) {
|
|
199
|
+
io.stderr.write(fallback);
|
|
200
|
+
io.stderr.write(`warning: cli.errors formatter failed: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
201
|
+
return error.exitCode;
|
|
202
|
+
}
|
|
203
|
+
if (out === undefined || out === null) {
|
|
204
|
+
io.stderr.write(fallback);
|
|
205
|
+
return error.exitCode;
|
|
206
|
+
}
|
|
207
|
+
if (out.stdout !== undefined)
|
|
208
|
+
io.stdout.write(out.stdout);
|
|
209
|
+
io.stderr.write(out.stderr ?? fallback);
|
|
210
|
+
if (out.exitCode === undefined)
|
|
211
|
+
return error.exitCode;
|
|
212
|
+
if (!Number.isInteger(out.exitCode) || out.exitCode < 0 || out.exitCode > 255) {
|
|
213
|
+
io.stderr.write(`warning: cli.errors formatter returned an invalid exitCode (${String(out.exitCode)})\n`);
|
|
214
|
+
return error.exitCode;
|
|
215
|
+
}
|
|
216
|
+
return out.exitCode;
|
|
217
|
+
}
|
|
218
|
+
/** INVALID_ARGUMENT details.issues → "경로: 메시지" */
|
|
219
|
+
function reasonsOf(details) {
|
|
220
|
+
const issues = details.issues;
|
|
221
|
+
if (!Array.isArray(issues))
|
|
222
|
+
return [];
|
|
223
|
+
return issues.flatMap((i) => {
|
|
224
|
+
if (!isRecord(i) || typeof i.message !== "string")
|
|
225
|
+
return [];
|
|
226
|
+
return [typeof i.path === "string" && i.path !== "" ? `${i.path}: ${i.message}` : i.message];
|
|
227
|
+
});
|
|
228
|
+
}
|
|
172
229
|
//# sourceMappingURL=output.js.map
|
package/dist/cli/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ProgressUpdate } from \"../command.ts\"\nimport { isMextError, MextBuildError, MextError } from \"../errors.ts\"\nimport { toKebab } from \"./args.ts\"\nimport { cliPath, table } from \"./help.ts\"\n\n/** exit code (spec §5) */\nexport const EXIT = {\n ok: 0,\n error: 1,\n usage: 2,\n auth: 77,\n interrupted: 130,\n} as const\n\n/** 실행 중 SIGINT (ctx.signal abort) 를 나타내는 CLI 내부 오류 */\nexport class CliInterrupted extends Error {\n constructor() {\n super(\"Interrupted.\")\n this.name = \"CliInterrupted\"\n }\n}\n\n/**\n * 오류 → exit code.\n * INVALID_ARGUMENT · UNKNOWN_COMMAND · INPUT_UNAVAILABLE = 2 · UNAUTHENTICATED · PERMISSION_DENIED = 77 · SIGINT = 130 · 그 외 = 1\n */\nexport function exitCodeOf(error: unknown): number {\n if (error instanceof CliInterrupted) return EXIT.interrupted\n if (error instanceof MextError) {\n switch (error.code) {\n case \"INVALID_ARGUMENT\":\n case \"UNKNOWN_COMMAND\":\n case \"INPUT_UNAVAILABLE\":\n return EXIT.usage\n case \"UNAUTHENTICATED\":\n case \"PERMISSION_DENIED\":\n return EXIT.auth\n }\n }\n return EXIT.error\n}\n\n/**\n * --json 오류 본문. MextError = toJSON(), 빌드 오류 = BUILD_ERROR + issues,\n * SIGINT = INTERRUPTED, 핸들러 예외 = EXECUTION_ERROR\n */\nexport function errorJson(error: unknown): Record<string, unknown> {\n if (error instanceof MextError) return error.toJSON()\n if (error instanceof MextBuildError) return { code: \"BUILD_ERROR\", message: error.message, issues: error.issues }\n if (error instanceof CliInterrupted) return { code: \"INTERRUPTED\", message: error.message }\n return { code: \"EXECUTION_ERROR\", message: error instanceof Error ? error.message : String(error) }\n}\n\n/** 사람용 오류 텍스트 (끝 줄바꿈 포함) */\nexport function formatError(error: unknown, prog: string): string {\n const lines: string[] = []\n if (isMextError(error, \"INVALID_ARGUMENT\")) {\n const d = error.details\n lines.push(d.command === \"\" ? \"error: invalid arguments\" : `error: invalid arguments for ${cliPath(d.command)}`)\n const rows = d.issues.map((i) => {\n if (i.path === \"\") return [i.message]\n return [flagOf(i.path), d.missing_fields.includes(i.path) ? \"required\" : i.message]\n })\n lines.push(...table(rows.filter((r) => r.length === 2)).map((l) => ` ${l}`))\n lines.push(...rows.filter((r) => r.length === 1).map((r) => ` ${r[0]}`))\n if (d.command !== \"\") lines.push(`Run \"${prog} ${cliPath(d.command)} --help\" for usage.`)\n } else if (isMextError(error, \"UNKNOWN_COMMAND\")) {\n const d = error.details\n if (d.command === \"\") lines.push(\"error: no command given\")\n else if (error.message.startsWith(\"Unknown command\")) lines.push(`error: unknown command \"${cliPath(d.command)}\"`)\n else lines.push(`error: ${error.message}`)\n if (d.suggested.length > 0) lines.push(`Did you mean: ${d.suggested.map((s) => `${prog} ${cliPath(s)}`).join(\", \")}?`)\n lines.push(`Run \"${usageCommand(prog, d.usage)}\" for available commands.`)\n } else if (isMextError(error, \"PERMISSION_DENIED\")) {\n const d = error.details\n lines.push(`error: ${error.message}`)\n lines.push(` required scopes: ${d.required_scopes.join(\", \") || \"(none)\"}`)\n lines.push(` held scopes: ${d.held_scopes.join(\", \") || \"(none)\"}`)\n } else if (isMextError(error, \"UNAUTHENTICATED\")) {\n lines.push(`error: ${error.message}`)\n if (error.details.login !== undefined) lines.push(`Run \"${error.details.login}\" to log in.`)\n } else if (isMextError(error, \"INPUT_UNAVAILABLE\")) {\n lines.push(`error: ${error.message}`)\n } else if (error instanceof Error) {\n lines.push(`error: ${error.message}`)\n } else {\n lines.push(`error: ${String(error)}`)\n }\n return `${lines.join(\"\\n\")}\\n`\n}\n\n/** \"help\" → \"mext run help\" · \"help users\" → \"mext run users --help\" */\nfunction usageCommand(prog: string, usage: string): string {\n const target = usage.replace(/^help\\s*/, \"\")\n return target === \"\" ? `${prog} help` : `${prog} ${cliPath(target)} --help`\n}\n\n/** 입력 경로 → 플래그 표기 (\"filter.minAge\" → \"--filter.min-age\") */\nfunction flagOf(path: string): string {\n return `--${path\n .split(\".\")\n .map((s) => (/^\\d+$/.test(s) ? s : toKebab(s)))\n .join(\".\")}`\n}\n\n/**\n * 사람용 결과 텍스트 (끝 줄바꿈 포함, undefined = 빈 문자열).\n * 문자열 = 그대로 · 원시 값 = String · 객체 배열 = 표 · 원시 배열 = 줄마다 · 객체 = 키 값 정렬. 중첩 값은 JSON 한 줄\n */\nexport function formatResult(value: unknown): string {\n if (value === undefined) return \"\"\n if (value === null) return \"null\\n\"\n if (typeof value === \"string\") return value.endsWith(\"\\n\") ? value : `${value}\\n`\n if (Array.isArray(value)) {\n if (value.length === 0) return \"(empty)\\n\"\n if (value.every(isRecord)) {\n const columns: string[] = []\n for (const row of value) for (const k of Object.keys(row)) if (!columns.includes(k)) columns.push(k)\n return lines(table([columns, ...value.map((row) => columns.map((c) => cell(row[c])))]))\n }\n return lines(value.map(cell))\n }\n if (isRecord(value)) {\n const entries = Object.entries(value).filter(([, v]) => v !== undefined)\n if (entries.length === 0) return \"(empty)\\n\"\n return lines(table(entries.map(([k, v]) => [k, cell(v)])))\n }\n return `${cell(value)}\\n`\n}\n\n/** --json 결과 */\nexport function formatJson(value: unknown): string {\n return `${JSON.stringify(value === undefined ? null : value, null, 2)}\\n`\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) && !(value instanceof Date)\n}\n\nfunction cell(value: unknown): string {\n if (value === undefined || value === null) return \"\"\n if (typeof value === \"string\") return value\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\") return String(value)\n if (value instanceof Date) return value.toISOString()\n return JSON.stringify(value) ?? \"\"\n}\n\nfunction lines(list: string[]): string {\n return `${list.join(\"\\n\")}\\n`\n}\n\n/** ctx.progress → stderr 한 줄 */\nexport function formatProgress(update: ProgressUpdate): string {\n const head = update.total !== undefined ? `[${update.progress}/${update.total}]` : `[${update.progress}]`\n return `${update.message ? `${head} ${update.message}` : head}\\n`\n}\n"]}
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ProgressUpdate } from \"../command.ts\"\nimport { isMextError, MextBuildError, MextError } from \"../errors.ts\"\nimport { toKebab } from \"./args.ts\"\nimport { cliPath, table } from \"./help.ts\"\n\n/** exit code (spec §5) */\nexport const EXIT = {\n ok: 0,\n error: 1,\n usage: 2,\n auth: 77,\n interrupted: 130,\n} as const\n\n/** 실행 중 SIGINT (ctx.signal abort) 를 나타내는 CLI 내부 오류 */\nexport class CliInterrupted extends Error {\n constructor() {\n super(\"Interrupted.\")\n this.name = \"CliInterrupted\"\n }\n}\n\n/**\n * 오류 → exit code.\n * INVALID_ARGUMENT · UNKNOWN_COMMAND · INPUT_UNAVAILABLE = 2 · UNAUTHENTICATED · PERMISSION_DENIED = 77 · SIGINT = 130 · 그 외 = 1\n */\nexport function exitCodeOf(error: unknown): number {\n if (error instanceof CliInterrupted) return EXIT.interrupted\n if (error instanceof MextError) {\n switch (error.code) {\n case \"INVALID_ARGUMENT\":\n case \"UNKNOWN_COMMAND\":\n case \"INPUT_UNAVAILABLE\":\n return EXIT.usage\n case \"UNAUTHENTICATED\":\n case \"PERMISSION_DENIED\":\n return EXIT.auth\n }\n }\n return EXIT.error\n}\n\n/**\n * --json 오류 본문. MextError = toJSON(), 빌드 오류 = BUILD_ERROR + issues,\n * SIGINT = INTERRUPTED, 핸들러 예외 = EXECUTION_ERROR\n */\nexport function errorJson(error: unknown): Record<string, unknown> {\n if (error instanceof MextError) return error.toJSON()\n if (error instanceof MextBuildError) return { code: \"BUILD_ERROR\", message: error.message, issues: error.issues }\n if (error instanceof CliInterrupted) return { code: \"INTERRUPTED\", message: error.message }\n return { code: \"EXECUTION_ERROR\", message: error instanceof Error ? error.message : String(error) }\n}\n\n/** 사람용 오류 텍스트 (끝 줄바꿈 포함) */\nexport function formatError(error: unknown, prog: string): string {\n const lines: string[] = []\n if (isMextError(error, \"INVALID_ARGUMENT\")) {\n const d = error.details\n lines.push(d.command === \"\" ? \"error: invalid arguments\" : `error: invalid arguments for ${cliPath(d.command)}`)\n const rows = d.issues.map((i) => {\n if (i.path === \"\") return [i.message]\n return [flagOf(i.path), d.missing_fields.includes(i.path) ? \"required\" : i.message]\n })\n lines.push(...table(rows.filter((r) => r.length === 2)).map((l) => ` ${l}`))\n lines.push(...rows.filter((r) => r.length === 1).map((r) => ` ${r[0]}`))\n if (d.command !== \"\") lines.push(`Run \"${prog} ${cliPath(d.command)} --help\" for usage.`)\n } else if (isMextError(error, \"UNKNOWN_COMMAND\")) {\n const d = error.details\n if (d.command === \"\") lines.push(\"error: no command given\")\n else if (error.message.startsWith(\"Unknown command\")) lines.push(`error: unknown command \"${cliPath(d.command)}\"`)\n else lines.push(`error: ${error.message}`)\n if (d.suggested.length > 0) lines.push(`Did you mean: ${d.suggested.map((s) => `${prog} ${cliPath(s)}`).join(\", \")}?`)\n lines.push(`Run \"${usageCommand(prog, d.usage)}\" for available commands.`)\n } else if (isMextError(error, \"PERMISSION_DENIED\")) {\n const d = error.details\n lines.push(`error: ${error.message}`)\n lines.push(` required scopes: ${d.required_scopes.join(\", \") || \"(none)\"}`)\n lines.push(` held scopes: ${d.held_scopes.join(\", \") || \"(none)\"}`)\n } else if (isMextError(error, \"UNAUTHENTICATED\")) {\n lines.push(`error: ${error.message}`)\n if (error.details.login !== undefined) lines.push(`Run \"${error.details.login}\" to log in.`)\n } else if (isMextError(error, \"INPUT_UNAVAILABLE\")) {\n lines.push(`error: ${error.message}`)\n } else if (error instanceof Error) {\n lines.push(`error: ${error.message}`)\n } else {\n lines.push(`error: ${String(error)}`)\n }\n return `${lines.join(\"\\n\")}\\n`\n}\n\n/** \"help\" → \"mext run help\" · \"help users\" → \"mext run users --help\" */\nfunction usageCommand(prog: string, usage: string): string {\n const target = usage.replace(/^help\\s*/, \"\")\n return target === \"\" ? `${prog} help` : `${prog} ${cliPath(target)} --help`\n}\n\n/** 입력 경로 → 플래그 표기 (\"filter.minAge\" → \"--filter.min-age\") */\nfunction flagOf(path: string): string {\n return `--${path\n .split(\".\")\n .map((s) => (/^\\d+$/.test(s) ? s : toKebab(s)))\n .join(\".\")}`\n}\n\n/**\n * 사람용 결과 텍스트 (끝 줄바꿈 포함, undefined = 빈 문자열).\n * 문자열 = 그대로 · 원시 값 = String · 객체 배열 = 표 · 원시 배열 = 줄마다 · 객체 = 키 값 정렬. 중첩 값은 JSON 한 줄\n */\nexport function formatResult(value: unknown): string {\n if (value === undefined) return \"\"\n if (value === null) return \"null\\n\"\n if (typeof value === \"string\") return value.endsWith(\"\\n\") ? value : `${value}\\n`\n if (Array.isArray(value)) {\n if (value.length === 0) return \"(empty)\\n\"\n if (value.every(isRecord)) {\n const columns: string[] = []\n for (const row of value) for (const k of Object.keys(row)) if (!columns.includes(k)) columns.push(k)\n return lines(table([columns, ...value.map((row) => columns.map((c) => cell(row[c])))]))\n }\n return lines(value.map(cell))\n }\n if (isRecord(value)) {\n const entries = Object.entries(value).filter(([, v]) => v !== undefined)\n if (entries.length === 0) return \"(empty)\\n\"\n return lines(table(entries.map(([k, v]) => [k, cell(v)])))\n }\n return `${cell(value)}\\n`\n}\n\n/** --json 결과 */\nexport function formatJson(value: unknown): string {\n return `${JSON.stringify(value === undefined ? null : value, null, 2)}\\n`\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) && !(value instanceof Date)\n}\n\nfunction cell(value: unknown): string {\n if (value === undefined || value === null) return \"\"\n if (typeof value === \"string\") return value\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\") return String(value)\n if (value instanceof Date) return value.toISOString()\n return JSON.stringify(value) ?? \"\"\n}\n\nfunction lines(list: string[]): string {\n return `${list.join(\"\\n\")}\\n`\n}\n\n/** ctx.progress → stderr 한 줄 */\nexport function formatProgress(update: ProgressUpdate): string {\n const head = update.total !== undefined ? `[${update.progress}/${update.total}]` : `[${update.progress}]`\n return `${update.message ? `${head} ${update.message}` : head}\\n`\n}\n\n/* ---------------------------------------------------------------- 오류 출력 커스텀 (cli.errors, spec §5) */\n\n/** cli.errors formatter 입력: 오류 하나 + mext 기본 출력 */\nexport interface CliErrorInfo {\n /** MextErrorCode · EXECUTION_ERROR · INTERRUPTED · REMOTE_ERROR · 서버 핸들러 오류 code 등 (= body.code) */\n code: string\n message: string\n /** 오류 상세 (MextError.details · 서버 오류 본문의 code · message 외 필드) */\n details: Record<string, unknown>\n /** INVALID_ARGUMENT issues 의 \"경로: 메시지\" (경로 없으면 메시지). 그 외 [] */\n reasons: string[]\n /** mext 기본 --json 오류 본문 */\n body: Record<string, unknown>\n /** mext 기본 사람용 텍스트 (끝 줄바꿈 포함) */\n text: string\n /** mext 기본 exit code (0 · 1 · 2 · 77 · 130) */\n exitCode: number\n /** --json 지정 여부 */\n json: boolean\n}\n\n/** formatter 출력. 지정한 필드만 기본값 대체 (stderr 기본 = json ? body JSON : text, stdout 기본 = 없음) */\nexport interface CliErrorOutput {\n exitCode?: number\n stderr?: string\n stdout?: string\n}\n\n/** cli.errors 모듈의 default export. undefined 반환 = mext 기본 */\nexport type CliErrorFormatter = (error: CliErrorInfo) => CliErrorOutput | undefined | void\n\nexport interface CliErrorWriter {\n stdout: { write(chunk: string): unknown }\n stderr: { write(chunk: string): unknown }\n}\n\n/**\n * 오류 출력 (기본 = json ? body : text) + formatter 적용 → exit code.\n * formatter 예외 · 잘못된 exitCode = 기본값 + stderr 경고 1줄\n */\nexport function emitError(\n io: CliErrorWriter,\n error: { body: Record<string, unknown>; text: string; exitCode: number; json: boolean },\n formatter: CliErrorFormatter | undefined,\n): number {\n const fallback = error.json ? formatJson(error.body) : error.text\n if (!formatter) {\n io.stderr.write(fallback)\n return error.exitCode\n }\n const { code, message, ...rest } = error.body\n const details = isRecord(rest.details) ? rest.details : rest\n const info: CliErrorInfo = {\n code: typeof code === \"string\" ? code : \"EXECUTION_ERROR\",\n message: typeof message === \"string\" ? message : String(message ?? \"\"),\n details,\n reasons: reasonsOf(details),\n body: error.body,\n text: error.text,\n exitCode: error.exitCode,\n json: error.json,\n }\n let out: CliErrorOutput | undefined | void\n try {\n out = formatter(info)\n } catch (e) {\n io.stderr.write(fallback)\n io.stderr.write(`warning: cli.errors formatter failed: ${e instanceof Error ? e.message : String(e)}\\n`)\n return error.exitCode\n }\n if (out === undefined || out === null) {\n io.stderr.write(fallback)\n return error.exitCode\n }\n if (out.stdout !== undefined) io.stdout.write(out.stdout)\n io.stderr.write(out.stderr ?? fallback)\n if (out.exitCode === undefined) return error.exitCode\n if (!Number.isInteger(out.exitCode) || out.exitCode < 0 || out.exitCode > 255) {\n io.stderr.write(`warning: cli.errors formatter returned an invalid exitCode (${String(out.exitCode)})\\n`)\n return error.exitCode\n }\n return out.exitCode\n}\n\n/** INVALID_ARGUMENT details.issues → \"경로: 메시지\" */\nfunction reasonsOf(details: Record<string, unknown>): string[] {\n const issues = details.issues\n if (!Array.isArray(issues)) return []\n return issues.flatMap((i) => {\n if (!isRecord(i) || typeof i.message !== \"string\") return []\n return [typeof i.path === \"string\" && i.path !== \"\" ? `${i.path}: ${i.message}` : i.message]\n })\n}\n"]}
|