@obov/mext 0.1.0 → 0.3.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.d.ts +2 -1
- package/dist/build-cli.js +24 -14
- package/dist/build-cli.js.map +1 -1
- package/dist/build.d.ts +23 -3
- package/dist/build.js +58 -5
- package/dist/build.js.map +1 -1
- package/dist/cli/build.js +5 -0
- package/dist/cli/build.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 +45 -1
- package/dist/cli/output.js +60 -3
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/run.d.ts +26 -0
- package/dist/cli/run.js +41 -20
- 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 +67 -2
- package/dist/config.js +89 -4
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +19 -1
- package/dist/errors.js +47 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instrumentation.d.ts +2 -2
- package/dist/instrumentation.js +5 -5
- package/dist/instrumentation.js.map +1 -1
- package/dist/local-bin.d.ts +20 -0
- package/dist/local-bin.js +102 -0
- package/dist/local-bin.js.map +1 -0
- package/dist/mcp/dispatch.d.ts +1 -1
- package/dist/mcp/dispatch.js +3 -3
- package/dist/mcp/dispatch.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/install.d.ts +2 -2
- package/dist/mcp/install.js +18 -0
- package/dist/mcp/install.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.d.ts +2 -1
- package/dist/start.js +13 -1
- package/dist/start.js.map +1 -1
- package/package.json +1 -1
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
|
@@ -17,7 +17,7 @@ export declare class CliInterrupted extends Error {
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function exitCodeOf(error: unknown): number;
|
|
19
19
|
/**
|
|
20
|
-
* --json 오류 본문. MextError = toJSON(), 빌드 오류 = BUILD_ERROR + issues,
|
|
20
|
+
* --json 오류 본문. MextError · CommandError = toJSON(), 빌드 오류 = BUILD_ERROR + issues,
|
|
21
21
|
* SIGINT = INTERRUPTED, 핸들러 예외 = EXECUTION_ERROR
|
|
22
22
|
*/
|
|
23
23
|
export declare function errorJson(error: unknown): Record<string, unknown>;
|
|
@@ -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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isMextError, MextBuildError, MextError } from "../errors.js";
|
|
1
|
+
import { CommandError, isMextError, MextBuildError, MextError } from "../errors.js";
|
|
2
2
|
import { toKebab } from "./args.js";
|
|
3
3
|
import { cliPath, table } from "./help.js";
|
|
4
4
|
/** exit code (spec §5) */
|
|
@@ -37,11 +37,11 @@ export function exitCodeOf(error) {
|
|
|
37
37
|
return EXIT.error;
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
|
-
* --json 오류 본문. MextError = toJSON(), 빌드 오류 = BUILD_ERROR + issues,
|
|
40
|
+
* --json 오류 본문. MextError · CommandError = toJSON(), 빌드 오류 = BUILD_ERROR + issues,
|
|
41
41
|
* SIGINT = INTERRUPTED, 핸들러 예외 = EXECUTION_ERROR
|
|
42
42
|
*/
|
|
43
43
|
export function errorJson(error) {
|
|
44
|
-
if (error instanceof MextError)
|
|
44
|
+
if (error instanceof MextError || error instanceof CommandError)
|
|
45
45
|
return error.toJSON();
|
|
46
46
|
if (error instanceof MextBuildError)
|
|
47
47
|
return { code: "BUILD_ERROR", message: error.message, issues: error.issues };
|
|
@@ -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 { CommandError, 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 · CommandError = toJSON(), 빌드 오류 = BUILD_ERROR + issues,\n * SIGINT = INTERRUPTED, 핸들러 예외 = EXECUTION_ERROR\n */\nexport function errorJson(error: unknown): Record<string, unknown> {\n if (error instanceof MextError || error instanceof CommandError) 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"]}
|
package/dist/cli/run.d.ts
CHANGED
|
@@ -1,12 +1,38 @@
|
|
|
1
|
+
import { type MextConfig } from "../config.ts";
|
|
2
|
+
import { type Instrumentation } from "../instrumentation.ts";
|
|
1
3
|
import { type Registry } from "../registry.ts";
|
|
2
4
|
import { type CliIo } from "./io.ts";
|
|
5
|
+
import { type CliErrorFormatter } from "./output.ts";
|
|
3
6
|
export declare const RUN_PROG = "mext run";
|
|
7
|
+
/** 로컬 실행에 필요한 것: 계측 · 설정 · Registry (+ cli.errors formatter) */
|
|
8
|
+
export interface LocalRunLoaded {
|
|
9
|
+
instrumentation: Instrumentation;
|
|
10
|
+
config: MextConfig;
|
|
11
|
+
registry: Registry;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 로컬 실행 코어의 입력. mext run = 소스 (commands/ · mext.config.ts), 로컬 bin = .mext/ 빌드 (start.ts runLocalBin)
|
|
15
|
+
*/
|
|
16
|
+
export interface LocalRunSource {
|
|
17
|
+
/** help · 오류 안내의 명령 이름 ("mext run" · "<bin>") */
|
|
18
|
+
prog: string;
|
|
19
|
+
/** 루트 help 뒤에 붙일 텍스트 (로컬 bin 내장 명령) */
|
|
20
|
+
footer?: string;
|
|
21
|
+
/** instrumentation register → 설정 → formatter (setFormatter 로 즉시 전달, 이후 오류에 적용) → Registry */
|
|
22
|
+
load(setFormatter: (formatter: CliErrorFormatter | undefined) => void): Promise<LocalRunLoaded>;
|
|
23
|
+
}
|
|
24
|
+
/** mext run 의 소스: 도입 프로젝트 (cwd) 의 instrumentation.ts · mext.config.ts · cli.errors · commands/ */
|
|
25
|
+
export declare function projectSource(cwd: string): LocalRunSource;
|
|
4
26
|
/**
|
|
5
27
|
* mext run <ns> <cmd> [flags] — 로컬 실행 (ctx.principal.kind = local, mext.config.ts 의 localPrincipal 로 변경 가능).
|
|
6
28
|
* mext run help [target] · mext run [<ns> [<cmd>]] --help · --json · --yes.
|
|
7
29
|
* --url <url> (또는 MEXT_URL) = 원격 실행 (cli/remote.ts)
|
|
8
30
|
*/
|
|
9
31
|
export declare function runCommand(argv: readonly string[], io: CliIo): Promise<number>;
|
|
32
|
+
/**
|
|
33
|
+
* 로컬 실행 코어 (mext run · 로컬 bin 공통). argv = 명령 경로 · 플래그 (help [target] 포함). 반환 = exit code
|
|
34
|
+
*/
|
|
35
|
+
export declare function runLocalCommand(argv: readonly string[], io: CliIo, source: LocalRunSource): Promise<number>;
|
|
10
36
|
/** 앞쪽 경로 토큰 → 가장 긴 네임스페이스 · 명령어 (별칭 포함) ID */
|
|
11
37
|
export declare function resolvePath(registry: Registry, tokens: readonly string[]): {
|
|
12
38
|
id: string;
|
package/dist/cli/run.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createApp, loadConfig, resolveCommandsDir, resolveLocalPrincipal } from "../config.js";
|
|
1
|
+
import { createApp, loadCliErrorFormatter, loadConfig, resolveCommandsDir, resolveLocalPrincipal } from "../config.js";
|
|
2
2
|
import { MextError } from "../errors.js";
|
|
3
3
|
import { isSegment } from "../ids.js";
|
|
4
4
|
import { loadProjectInstrumentation } from "../instrumentation.js";
|
|
@@ -9,9 +9,24 @@ import { loadRegistry } from "../scan.js";
|
|
|
9
9
|
import { analyzeInput, assertCliConvertible, coerceValue, parseArgs } from "./args.js";
|
|
10
10
|
import { cliPath, renderHelp } from "./help.js";
|
|
11
11
|
import { createLineReader, readAll } from "./io.js";
|
|
12
|
-
import { CliInterrupted, EXIT, errorJson, exitCodeOf, formatError, formatJson, formatProgress, formatResult } from "./output.js";
|
|
12
|
+
import { CliInterrupted, emitError, EXIT, errorJson, exitCodeOf, formatError, formatJson, formatProgress, formatResult, } from "./output.js";
|
|
13
13
|
import { remoteTarget, runRemoteCommand } from "./remote.js";
|
|
14
14
|
export const RUN_PROG = "mext run";
|
|
15
|
+
/** mext run 의 소스: 도입 프로젝트 (cwd) 의 instrumentation.ts · mext.config.ts · cli.errors · commands/ */
|
|
16
|
+
export function projectSource(cwd) {
|
|
17
|
+
return {
|
|
18
|
+
prog: RUN_PROG,
|
|
19
|
+
async load(setFormatter) {
|
|
20
|
+
// instrumentation.ts register() = 설정 · 명령어 모듈 import 전 (프로세스당 1회)
|
|
21
|
+
const instrumentation = await loadProjectInstrumentation(cwd);
|
|
22
|
+
const config = await loadConfig(cwd);
|
|
23
|
+
setFormatter(await loadCliErrorFormatter(cwd, config));
|
|
24
|
+
const registry = await loadRegistry(resolveCommandsDir(cwd, config));
|
|
25
|
+
assertCliConvertible(registry);
|
|
26
|
+
return { instrumentation, config, registry };
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
15
30
|
/**
|
|
16
31
|
* mext run <ns> <cmd> [flags] — 로컬 실행 (ctx.principal.kind = local, mext.config.ts 의 localPrincipal 로 변경 가능).
|
|
17
32
|
* mext run help [target] · mext run [<ns> [<cmd>]] --help · --json · --yes.
|
|
@@ -21,7 +36,13 @@ export async function runCommand(argv, io) {
|
|
|
21
36
|
const remote = remoteTarget(argv, io.env);
|
|
22
37
|
if (remote)
|
|
23
38
|
return runRemoteCommand(remote, io);
|
|
24
|
-
|
|
39
|
+
return runLocalCommand(argv, io, projectSource(io.cwd));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 로컬 실행 코어 (mext run · 로컬 bin 공통). argv = 명령 경로 · 플래그 (help [target] 포함). 반환 = exit code
|
|
43
|
+
*/
|
|
44
|
+
export async function runLocalCommand(argv, io, source) {
|
|
45
|
+
const prog = source.prog;
|
|
25
46
|
const lead = { json: false, yes: false, help: false };
|
|
26
47
|
let i = 0;
|
|
27
48
|
for (; i < argv.length; i++) {
|
|
@@ -42,19 +63,16 @@ export async function runCommand(argv, io) {
|
|
|
42
63
|
const beforeDashDash = rest.indexOf("--") < 0 ? rest : rest.slice(0, rest.indexOf("--"));
|
|
43
64
|
const json = lead.json || beforeDashDash.includes("--json");
|
|
44
65
|
const lines = createLineReader(io);
|
|
66
|
+
let formatter;
|
|
45
67
|
try {
|
|
46
|
-
|
|
47
|
-
const instrumentation = await loadProjectInstrumentation(io.cwd);
|
|
48
|
-
const config = await loadConfig(io.cwd);
|
|
49
|
-
const registry = await loadRegistry(resolveCommandsDir(io.cwd, config));
|
|
50
|
-
assertCliConvertible(registry);
|
|
68
|
+
const { instrumentation, config, registry } = await source.load((f) => (formatter = f));
|
|
51
69
|
// mext run help [target...]
|
|
52
70
|
if (rest[0] === "help") {
|
|
53
71
|
const targetTokens = rest.slice(1).filter((t) => !t.startsWith("-"));
|
|
54
72
|
const { id, consumed } = resolvePath(registry, targetTokens);
|
|
55
73
|
if (consumed < targetTokens.length)
|
|
56
74
|
throw unknownAt(registry, id, targetTokens.slice(consumed));
|
|
57
|
-
return printHelp(registry, id, io, prog, json, config.tools);
|
|
75
|
+
return printHelp(registry, id, io, prog, json, config.tools, source.footer);
|
|
58
76
|
}
|
|
59
77
|
const { id, consumed } = resolvePath(registry, rest);
|
|
60
78
|
const entry = id === "" ? undefined : resolveCommand(registry, id);
|
|
@@ -68,15 +86,14 @@ export async function runCommand(argv, io) {
|
|
|
68
86
|
}
|
|
69
87
|
const help = lead.help || beforeDashDash.includes("--help") || beforeDashDash.includes("-h");
|
|
70
88
|
if (help)
|
|
71
|
-
return printHelp(registry, id, io, prog, json, config.tools);
|
|
89
|
+
return printHelp(registry, id, io, prog, json, config.tools, source.footer);
|
|
72
90
|
if (!entry) {
|
|
73
91
|
// 네임스페이스 (루트 포함) 만 지정 = 명령어 없음
|
|
74
92
|
const error = new MextError("UNKNOWN_COMMAND", id === "" ? "No command given." : `"${cliPath(id)}" is a namespace. Specify a command.`, { command: id, suggested: [], usage: id === "" ? "help" : `help ${id}` });
|
|
75
93
|
if (json)
|
|
76
|
-
return report(error, io, prog, true);
|
|
77
|
-
|
|
78
|
-
io
|
|
79
|
-
return EXIT.usage;
|
|
94
|
+
return report(error, io, prog, true, formatter);
|
|
95
|
+
const text = `${formatError(error, prog)}\n${helpText(registry, id, prog, source.footer)}`;
|
|
96
|
+
return emitError(io, { body: errorJson(error), text, exitCode: EXIT.usage, json: false }, formatter);
|
|
80
97
|
}
|
|
81
98
|
const principal = await resolveLocalPrincipal(config);
|
|
82
99
|
authorize(entry, principal); // 권한 → 입력 검증 순서 (invoke 와 같음)
|
|
@@ -113,7 +130,7 @@ export async function runCommand(argv, io) {
|
|
|
113
130
|
}
|
|
114
131
|
}
|
|
115
132
|
catch (error) {
|
|
116
|
-
return report(error, io, prog, json);
|
|
133
|
+
return report(error, io, prog, json, formatter);
|
|
117
134
|
}
|
|
118
135
|
finally {
|
|
119
136
|
lines.close();
|
|
@@ -156,14 +173,18 @@ function unknownAt(registry, id, tail) {
|
|
|
156
173
|
return new MextError("UNKNOWN_COMMAND", `Unknown command "${unknown}".`, { command: unknown, suggested: [], usage: "help" });
|
|
157
174
|
}
|
|
158
175
|
/** --help --json = MCP help 의 structuredContent 와 같은 데이터 (mext mcp 의 tools 노출 기준) */
|
|
159
|
-
function printHelp(registry, id, io, prog, json, tools) {
|
|
176
|
+
function printHelp(registry, id, io, prog, json, tools, footer) {
|
|
160
177
|
const toolFor = tools === "split" ? (e) => (e.command.readOnly ? "query" : "mutate") : undefined;
|
|
161
|
-
io.stdout.write(json ? formatJson(help(registry, id, toolFor ? { toolFor } : {})) :
|
|
178
|
+
io.stdout.write(json ? formatJson(help(registry, id, toolFor ? { toolFor } : {})) : helpText(registry, id, prog, footer));
|
|
162
179
|
return EXIT.ok;
|
|
163
180
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
181
|
+
/** 사람용 help. 루트면 footer 를 붙인다 */
|
|
182
|
+
function helpText(registry, id, prog, footer) {
|
|
183
|
+
const text = renderHelp(registry, id, { prog });
|
|
184
|
+
return id === "" && footer ? `${text}\n${footer}` : text;
|
|
185
|
+
}
|
|
186
|
+
function report(error, io, prog, json, formatter) {
|
|
187
|
+
return emitError(io, { body: errorJson(error), text: formatError(error, prog), exitCode: exitCodeOf(error), json }, formatter);
|
|
167
188
|
}
|
|
168
189
|
function usageError(message) {
|
|
169
190
|
return new MextError("INVALID_ARGUMENT", message, {
|