@obov/mext 0.0.0-stage → 0.1.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 +39 -0
- package/dist/build-cli.js +160 -0
- package/dist/build-cli.js.map +1 -0
- package/dist/build.d.ts +65 -0
- package/dist/build.js +252 -0
- package/dist/build.js.map +1 -0
- package/dist/cli/args.d.ts +107 -0
- package/dist/cli/args.js +621 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/bin.d.ts +2 -0
- package/dist/cli/bin.js +13 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/build.d.ts +11 -0
- package/dist/cli/build.js +87 -0
- package/dist/cli/build.js.map +1 -0
- package/dist/cli/dev-lock.d.ts +23 -0
- package/dist/cli/dev-lock.js +68 -0
- package/dist/cli/dev-lock.js.map +1 -0
- package/dist/cli/dev-server.d.ts +20 -0
- package/dist/cli/dev-server.js +74 -0
- package/dist/cli/dev-server.js.map +1 -0
- package/dist/cli/dev.d.ts +21 -0
- package/dist/cli/dev.js +564 -0
- package/dist/cli/dev.js.map +1 -0
- package/dist/cli/help.d.ts +31 -0
- package/dist/cli/help.js +238 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/io.d.ts +26 -0
- package/dist/cli/io.js +74 -0
- package/dist/cli/io.js.map +1 -0
- package/dist/cli/login.d.ts +32 -0
- package/dist/cli/login.js +284 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/logout.d.ts +9 -0
- package/dist/cli/logout.js +105 -0
- package/dist/cli/logout.js.map +1 -0
- package/dist/cli/main.d.ts +19 -0
- package/dist/cli/main.js +77 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/mcp.d.ts +16 -0
- package/dist/cli/mcp.js +92 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/output.d.ts +34 -0
- package/dist/cli/output.js +172 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/remote.d.ts +17 -0
- package/dist/cli/remote.js +35 -0
- package/dist/cli/remote.js.map +1 -0
- package/dist/cli/run.d.ts +14 -0
- package/dist/cli/run.js +218 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/start.d.ts +8 -0
- package/dist/cli/start.js +37 -0
- package/dist/cli/start.js.map +1 -0
- package/dist/client/cache.d.ts +104 -0
- package/dist/client/cache.js +208 -0
- package/dist/client/cache.js.map +1 -0
- package/dist/client/main.d.ts +25 -0
- package/dist/client/main.js +100 -0
- package/dist/client/main.js.map +1 -0
- package/dist/client/manifest.d.ts +19 -0
- package/dist/client/manifest.js +68 -0
- package/dist/client/manifest.js.map +1 -0
- package/dist/client/runner.d.ts +49 -0
- package/dist/client/runner.js +562 -0
- package/dist/client/runner.js.map +1 -0
- package/dist/command.d.ts +75 -0
- package/dist/command.js +44 -0
- package/dist/command.js.map +1 -0
- package/dist/config.d.ts +53 -0
- package/dist/config.js +122 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +74 -0
- package/dist/errors.js +38 -0
- package/dist/errors.js.map +1 -0
- package/dist/ids.d.ts +6 -0
- package/dist/ids.js +12 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/instrumentation.d.ts +97 -0
- package/dist/instrumentation.js +165 -0
- package/dist/instrumentation.js.map +1 -0
- package/dist/invoke.d.ts +64 -0
- package/dist/invoke.js +152 -0
- package/dist/invoke.js.map +1 -0
- package/dist/lookup.d.ts +9 -0
- package/dist/lookup.js +27 -0
- package/dist/lookup.js.map +1 -0
- package/dist/manifest.d.ts +68 -0
- package/dist/manifest.js +77 -0
- package/dist/manifest.js.map +1 -0
- package/dist/mcp/constants.d.ts +9 -0
- package/dist/mcp/constants.js +10 -0
- package/dist/mcp/constants.js.map +1 -0
- package/dist/mcp/dispatch.d.ts +66 -0
- package/dist/mcp/dispatch.js +249 -0
- package/dist/mcp/dispatch.js.map +1 -0
- package/dist/mcp/help.d.ts +57 -0
- package/dist/mcp/help.js +136 -0
- package/dist/mcp/help.js.map +1 -0
- package/dist/mcp/http.d.ts +92 -0
- package/dist/mcp/http.js +366 -0
- package/dist/mcp/http.js.map +1 -0
- package/dist/mcp/index.d.ts +15 -0
- package/dist/mcp/index.js +9 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/install.d.ts +17 -0
- package/dist/mcp/install.js +36 -0
- package/dist/mcp/install.js.map +1 -0
- package/dist/mcp/mrtr.d.ts +82 -0
- package/dist/mcp/mrtr.js +130 -0
- package/dist/mcp/mrtr.js.map +1 -0
- package/dist/mcp/server.d.ts +58 -0
- package/dist/mcp/server.js +204 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/stdio.d.ts +57 -0
- package/dist/mcp/stdio.js +79 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/principal.d.ts +16 -0
- package/dist/principal.js +24 -0
- package/dist/principal.js.map +1 -0
- package/dist/registry.d.ts +90 -0
- package/dist/registry.js +169 -0
- package/dist/registry.js.map +1 -0
- package/dist/remote/browser.d.ts +15 -0
- package/dist/remote/browser.js +47 -0
- package/dist/remote/browser.js.map +1 -0
- package/dist/remote/client.d.ts +113 -0
- package/dist/remote/client.js +312 -0
- package/dist/remote/client.js.map +1 -0
- package/dist/remote/credentials.d.ts +48 -0
- package/dist/remote/credentials.js +196 -0
- package/dist/remote/credentials.js.map +1 -0
- package/dist/remote/index.d.ts +8 -0
- package/dist/remote/index.js +5 -0
- package/dist/remote/index.js.map +1 -0
- package/dist/remote/oauth.d.ts +186 -0
- package/dist/remote/oauth.js +507 -0
- package/dist/remote/oauth.js.map +1 -0
- package/dist/scan.d.ts +34 -0
- package/dist/scan.js +155 -0
- package/dist/scan.js.map +1 -0
- package/dist/start.d.ts +63 -0
- package/dist/start.js +267 -0
- package/dist/start.js.map +1 -0
- package/dist/suggest.d.ts +7 -0
- package/dist/suggest.js +45 -0
- package/dist/suggest.js.map +1 -0
- package/dist/version.d.ts +4 -0
- package/dist/version.js +13 -0
- package/dist/version.js.map +1 -0
- package/package.json +49 -4
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/client/runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { COMMAND, type Command } from \"../command.ts\"\nimport { MextError, type MextErrorCode, type MextErrorDetails } from \"../errors.ts\"\nimport { isSegment } from \"../ids.ts\"\nimport type { CommandHelp, Help } from \"../mcp/help.ts\"\nimport type { NamespaceInfo, RegisteredCommand, Registry } from \"../registry.ts\"\nimport {\n createRemoteClient,\n isRecord,\n RemoteInputRequiredError,\n RemoteRpcError,\n RemoteTransportError,\n RemoteUnauthorizedError,\n type CallToolOptions,\n type CallToolResult,\n type InputRequired,\n type InputResponses,\n type RemoteClient,\n type RemoteTool,\n} from \"../remote/client.ts\"\nimport { credentialStore, envPrefix, type CredentialStore, type StoredCredentials } from \"../remote/credentials.ts\"\nimport { isExpired, OAuthFlowError, refreshCredentials } from \"../remote/oauth.ts\"\nimport { cliSpecFromJsonSchema, coerceValue, defineCliSpec, parseArgs } from \"../cli/args.ts\"\nimport { cliPath, renderHelp } from \"../cli/help.ts\"\nimport { createLineReader, readAll, type CliIo, type LineReader } from \"../cli/io.ts\"\nimport {\n CliInterrupted,\n EXIT,\n errorJson,\n exitCodeOf,\n formatError,\n formatJson,\n formatProgress,\n formatResult,\n} from \"../cli/output.ts\"\nimport { MANIFEST_HASH_META_KEY } from \"../mcp/constants.ts\"\nimport { VERSION } from \"../version.ts\"\nimport { openSchema, schemaCacheDir, schemaCacheFile, type FetchedHelp, type Schema } from \"./cache.ts\"\nimport { manifestHelp, type ClientManifest } from \"./manifest.ts\"\n\n/**\n * 원격 실행 공용 runner: mext run --url (bin = mext) 과 고객 CLI (bin = cli.bin) 가 같은 코드 경로.\n * 서버 MCP 엔드포인트의 dispatcher 도구 (execute · split 의 query · mutate) 호출. 권한 검사는 서버만.\n * 경로 해석 · help · 플래그 파싱 = HelpSource (캐시 · 내장 manifest · 서버 help, client/cache.ts) 의 입력 스키마 (JSON Schema).\n * 로컬 파싱 실패 (UNKNOWN_COMMAND · INVALID_ARGUMENT) = 서버 help 로 1회 재시도. tools/call 결과의 manifestHash 로 drift 감지.\n * 토큰 = <BIN>_TOKEN, 없으면 저장된 토큰 (<bin> login). 출력 · exit code 는 로컬 모드와 같다.\n *\n * 이 모듈 (와 import 대상) 은 고객 CLI 번들에 들어간다: Zod · MCP 서버 SDK · 핸들러 · 스캔 · 빌드 코드 import 금지.\n */\n\nexport interface RemoteRunOptions {\n /** 실행 파일 이름. 토큰 환경변수 (<BIN>_TOKEN) · 자격 증명 위치 (credentialStore bin) · clientInfo.name */\n bin: string\n /** MCP 엔드포인트 */\n url: string\n /** help · 오류 안내의 명령 접두. \"mext run --url <url>\" · \"myapp\" */\n prog: string\n /** login 안내 명령. \"mext login --url <url>\" · \"myapp login\" */\n login: string\n /** clientInfo.version */\n version: string\n /**\n * 번들 형태: 내장 manifest 로 help · 경로 해석 · 플래그 파싱 (help 에 네트워크 없음, 명령어 실행만 tools/list · tools/call).\n * 없음 = 범용 형태: 서버 help 조회\n */\n manifest?: ClientManifest\n /** 내장 manifest 의 manifestHash (빌드 시). manifest 와 같이 지정 */\n manifestHash?: string\n /** 사람용 루트 help 뒤에 붙일 텍스트 (고객 CLI 의 login · logout · mcp install 목록) */\n rootHelpFooter?: string\n}\n\n/** help 출처. 서버 (tools/list → dispatcher help 호출) · 내장 manifest · 스키마 캐시 (client/cache.ts Schema) */\nexport interface HelpSource {\n /** 대상 (\"\" = 루트) → help. 없는 대상 = MextError UNKNOWN_COMMAND */\n help(target: string): Promise<Help>\n}\n\nexport async function runRemote(options: RemoteRunOptions, argv: readonly string[], io: CliIo): Promise<number> {\n const { url, prog } = options\n const tokenEnv = `${envPrefix(options.bin)}_TOKEN`\n const ctx: ReportContext = { login: options.login, tokenEnv, auth: undefined, footer: options.rootHelpFooter }\n const lead = { json: false, yes: false, help: false }\n let i = 0\n for (; i < argv.length; i++) {\n const tok = argv[i]!\n if (!tok.startsWith(\"-\") || tok === \"-\") break\n if (tok === \"--json\") lead.json = true\n else if (tok === \"--yes\") lead.yes = true\n else if (tok === \"--help\" || tok === \"-h\") lead.help = true\n else return report(usageError(`unknown flag ${tok} before the command`), io, prog, argv.includes(\"--json\"), ctx)\n }\n const rest = argv.slice(i)\n const beforeDashDash = rest.indexOf(\"--\") < 0 ? rest : rest.slice(0, rest.indexOf(\"--\"))\n const json = lead.json || beforeDashDash.includes(\"--json\")\n\n const controller = new AbortController()\n const onAbort = (): void => controller.abort(io.signal?.reason)\n if (io.signal?.aborted) onAbort()\n io.signal?.addEventListener(\"abort\", onAbort, { once: true })\n const lines = createLineReader(io)\n let session: Session | undefined\n let schema: Schema | undefined\n try {\n if (!/^https?:\\/\\//i.test(url)) throw usageError(`--url must be an http(s) URL (got \"${url}\")`)\n session = openSession(options, tokenEnv, io, controller.signal)\n const s = session\n schema = await openRunSchema(options, s, ctx, io)\n const source: HelpSource = schema\n const wantsHelp = lead.help || beforeDashDash.includes(\"--help\") || beforeDashDash.includes(\"-h\")\n let stdin: Promise<string> | undefined\n const readStdin = (): Promise<string> => (stdin ??= readAll(io.stdin))\n\n // 경로 해석 · 플래그 파싱 (로컬). 실패하면 서버 help 로 1회 재시도\n const plan = async (): Promise<Plan> => {\n // <prog> help [target...]\n if (rest[0] === \"help\") {\n const tokens = rest.slice(1).filter((t) => !t.startsWith(\"-\"))\n const resolved = await resolveRemotePath(source, tokens)\n if (resolved.consumed < tokens.length) throw await unknownAt(source, resolved, tokens.slice(resolved.consumed))\n return { kind: \"help\", help: resolved.help }\n }\n const resolved = await resolveRemotePath(source, rest)\n const { help, consumed } = resolved\n const command = help.kind === \"command\" ? help : help.kind === \"namespace\" ? help.command : undefined\n const next = rest[consumed]\n const acceptsPositional = command !== undefined && command.positional.length > 0\n if (help.kind !== \"command\" && next !== undefined && !next.startsWith(\"-\") && !acceptsPositional) {\n throw await unknownAt(source, resolved, rest.slice(consumed))\n }\n if (wantsHelp) return { kind: \"help\", help }\n if (!command) return { kind: \"namespace\", help }\n const entry = entryFromHelp(command)\n const parsed = await parseArgs(entry, rest.slice(consumed), { readStdin })\n return { kind: \"run\", command, entry, input: parsed.input, yes: parsed.yes }\n }\n let planned: Plan\n try {\n planned = await plan()\n } catch (error) {\n if (!isLocalParseFailure(error) || !schema.refetch()) throw error\n try {\n planned = await plan()\n } catch (retryError) {\n // 재조회 실패 (오프라인 등) = 원래 로컬 오류\n if (retryError instanceof RemoteTransportError || retryError instanceof RemoteRpcError) throw error\n throw retryError\n }\n }\n\n if (planned.kind === \"help\") return printHelp(planned.help, io, prog, json, ctx)\n if (planned.kind === \"namespace\") {\n const { help } = planned\n const id = help.kind === \"namespace\" ? help.id : \"\"\n const error = new MextError(\n \"UNKNOWN_COMMAND\",\n id === \"\" ? \"No command given.\" : `\"${cliPath(id)}\" is a namespace. Specify a command.`,\n { command: id, suggested: [], usage: id === \"\" ? \"help\" : `help ${id}` },\n )\n if (json) return report(error, io, prog, true, ctx)\n io.stderr.write(formatError(error, prog))\n io.stderr.write(`\\n${helpText(help, prog, ctx)}`)\n return EXIT.usage\n }\n\n const { command, entry } = planned\n const yes = lead.yes || planned.yes\n const tool = commandTool(dispatcherOf(url, await schema.tools()), command)\n const args = { command: entry.id, args: planned.input as Record<string, unknown> }\n const result = await s.call((o) =>\n s.client.callTool(tool, args, {\n ...o,\n progressToken: \"mext-cli\",\n onNotification: (method, params) => {\n if (method !== \"notifications/progress\" || typeof params.progress !== \"number\") return\n const update: { progress: number; total?: number; message?: string } = { progress: params.progress }\n if (typeof params.total === \"number\") update.total = params.total\n if (typeof params.message === \"string\") update.message = params.message\n io.stderr.write(formatProgress(update))\n },\n onInputRequired: inputHandler(io, lines, yes, entry.id, controller.signal),\n }),\n )\n // drift: 이번 결과는 그대로, 다르면 캐시 stale (다음 실행에서 서버 help)\n schema.observe(metaHash(result))\n if (result.isError === true) throw toolError(result, ctx)\n const value = result.structuredContent === undefined ? textValue(result) : result.structuredContent\n io.stdout.write(json ? formatJson(value) : formatResult(value))\n return EXIT.ok\n } catch (error) {\n if (session) ctx.auth = session.auth\n if (controller.signal.aborted) return report(new CliInterrupted(), io, prog, json, ctx)\n return report(error, io, prog, json, ctx)\n } finally {\n io.signal?.removeEventListener(\"abort\", onAbort)\n lines.close()\n await schema?.save()\n }\n}\n\n/** 로컬 경로 해석 · 플래그 파싱 결과 */\ntype Plan =\n | { kind: \"help\"; help: Help }\n | { kind: \"namespace\"; help: Help }\n | { kind: \"run\"; command: CommandHelp; entry: RegisteredCommand; input: unknown; yes: boolean }\n\n/** 서버 help 재조회 대상 로컬 오류 */\nfunction isLocalParseFailure(error: unknown): boolean {\n return error instanceof MextError && (error.code === \"UNKNOWN_COMMAND\" || error.code === \"INVALID_ARGUMENT\")\n}\n\n/** 결과 _meta[\"dev.mext/manifestHash\"] */\nfunction metaHash(result: CallToolResult): string | undefined {\n const meta = result._meta\n const value = isRecord(meta) ? meta[MANIFEST_HASH_META_KEY] : undefined\n return typeof value === \"string\" ? value : undefined\n}\n\n/** 이번 실행의 스키마 상태: 캐시 파일 (<BIN>_CACHE_DIR · XDG · HOME) · 내장 manifest · 서버 help */\nfunction openRunSchema(options: RemoteRunOptions, s: Session, ctx: ReportContext, io: CliIo): Promise<Schema> {\n const dir = schemaCacheDir(options.bin, io.env)\n return openSchema({\n file: dir === undefined ? undefined : schemaCacheFile(dir, options.url),\n url: options.url,\n client: { bin: options.bin, version: options.version, mext: VERSION },\n ...(options.manifest && options.manifestHash !== undefined\n ? { embedded: { manifest: options.manifest, hash: options.manifestHash } }\n : {}),\n fetchHelp: serverHelpFetcher(s, ctx),\n fetchTools: async () => {\n const r = await s.call((o) => s.client.listToolsResult(o))\n dispatcherOf(s.url, r.tools)\n return r.ttlMs === undefined ? { tools: r.tools } : { tools: r.tools, ttlMs: r.ttlMs }\n },\n warn: (message) => io.stderr.write(message),\n })\n}\n\n/* 세션: 클라이언트 · 토큰 · dispatcher 도구 */\n\n/** 토큰 출처. undefined = 아직 요청 전 (저장분 미조회) */\ntype AuthSource = \"env\" | \"stored\" | \"none\" | undefined\n\ninterface Tools {\n /** tools/list 결과 */\n list: RemoteTool[]\n /** help 호출 도구 (execute 또는 split 의 query) */\n helpTool: RemoteTool\n}\n\ninterface Session {\n url: string\n client: RemoteClient\n /** 요청한 토큰 출처 (첫 요청 때 결정) */\n readonly auth: AuthSource\n /** 401 이면 refresh_token 으로 1회 갱신 후 재시도 */\n call<T>(fn: (options: { signal: AbortSignal }) => Promise<T>): Promise<T>\n}\n\n/** 네트워크 · 키체인 접근은 첫 요청까지 미룬다 (번들 형태의 help 는 둘 다 없음) */\nfunction openSession(options: RemoteRunOptions, tokenEnv: string, io: CliIo, signal: AbortSignal): Session {\n const { url } = options\n const envToken = io.env[tokenEnv] !== undefined && io.env[tokenEnv] !== \"\" ? io.env[tokenEnv] : undefined\n const store: CredentialStore | undefined =\n envToken === undefined ? credentialStore({ env: io.env, bin: options.bin }) : undefined\n let stored: StoredCredentials | undefined\n let auth: AuthSource = envToken !== undefined ? \"env\" : undefined\n let refreshed = false\n const refresh = async (): Promise<boolean> => {\n if (!store || !stored?.refresh_token || refreshed) return false\n refreshed = true\n try {\n stored = await refreshCredentials(stored)\n await store.set(url, stored).catch(() => {})\n return true\n } catch {\n return false\n }\n }\n let loading: Promise<void> | undefined\n const load = (): Promise<void> =>\n (loading ??= (async () => {\n if (!store) return\n stored = await store.get(url).catch(() => undefined)\n if (stored && isExpired(stored)) await refresh()\n auth = stored ? \"stored\" : \"none\"\n })())\n const client = createRemoteClient({\n url,\n clientInfo: { name: options.bin, version: options.version },\n token: async () => {\n await load()\n return envToken ?? stored?.access_token\n },\n })\n const call = async <T>(fn: (o: { signal: AbortSignal }) => Promise<T>): Promise<T> => {\n try {\n return await fn({ signal })\n } catch (error) {\n if (error instanceof RemoteUnauthorizedError && (await refresh())) return fn({ signal })\n throw error\n }\n }\n return {\n url,\n client,\n get auth() {\n return auth\n },\n call,\n }\n}\n\n/** tools/list 결과 → dispatcher 도구 (execute 또는 query · mutate). 없으면 RemoteTransportError */\nfunction dispatcherOf(url: string, list: RemoteTool[]): Tools {\n const execute = list.find((t) => t.name === \"execute\")\n const query = list.find((t) => t.name === \"query\")\n const helpTool = execute ?? query\n if (!helpTool || (!execute && !list.some((t) => t.name === \"mutate\"))) {\n throw new RemoteTransportError(`${url} does not expose mext dispatcher tools (execute, or query and mutate).`)\n }\n return { list, helpTool }\n}\n\n/** 명령어를 호출할 도구: help 의 tool (split) → execute → readOnly 면 query, 아니면 mutate */\nfunction commandTool(tools: Tools, command: CommandHelp): RemoteTool {\n const byName = (name: string | undefined) => (name === undefined ? undefined : tools.list.find((t) => t.name === name))\n return byName(command.tool) ?? byName(\"execute\") ?? byName(command.readOnly ? \"query\" : \"mutate\") ?? tools.helpTool\n}\n\n/** 서버의 dispatcher help (tools/call). UNKNOWN_COMMAND = 캐시할 결과, 그 외 오류 = throw */\nfunction serverHelpFetcher(\n s: Session,\n ctx: ReportContext,\n): (target: string, tools: () => Promise<RemoteTool[]>) => Promise<FetchedHelp> {\n return async (target, tools) => {\n const { helpTool } = dispatcherOf(s.url, await tools())\n const args = target === \"\" ? { command: \"help\" } : { command: \"help\", args: { target } }\n const result = await s.call((o) => s.client.callTool(helpTool, args, o))\n const hash = metaHash(result)\n if (result.isError === true) {\n const error = toolError(result, ctx)\n if (error instanceof MextError && error.code === \"UNKNOWN_COMMAND\") return { value: { error: error.toJSON() }, hash }\n throw error\n }\n const value = result.structuredContent\n if (!isRecord(value) || (value.kind !== \"root\" && value.kind !== \"namespace\" && value.kind !== \"command\")) {\n throw new RemoteTransportError(`${s.url} returned an unexpected help result.`)\n }\n return { value: { help: value as unknown as Help }, hash }\n }\n}\n\n/** 번들 형태: 내장 manifest (네트워크 없음) */\nexport function manifestHelpSource(manifest: ClientManifest): HelpSource {\n return { help: async (target) => manifestHelp(manifest, target) }\n}\n\n/* 경로 해석: 앞쪽 세그먼트 토큰의 가장 긴 접두 (로컬 resolvePath 와 같은 결과) */\n\ninterface ResolvedPath {\n help: Help\n consumed: number\n /** 가장 긴 후보의 UNKNOWN_COMMAND (있으면) */\n unknown: MextError | undefined\n}\n\nasync function resolveRemotePath(source: HelpSource, tokens: readonly string[]): Promise<ResolvedPath> {\n const segs: string[] = []\n for (const t of tokens) {\n if (!isSegment(t)) break\n segs.push(t)\n }\n let unknown: MextError | undefined\n for (let k = segs.length; k >= 0; k--) {\n try {\n return { help: await source.help(segs.slice(0, k).join(\".\")), consumed: k, unknown }\n } catch (error) {\n if (k > 0 && error instanceof MextError && error.code === \"UNKNOWN_COMMAND\") {\n unknown ??= error\n continue\n }\n throw error\n }\n }\n throw new Error(\"unreachable\")\n}\n\n/** 해석되지 않은 경로 → UNKNOWN_COMMAND (suggested · usage) */\nasync function unknownAt(source: HelpSource, resolved: ResolvedPath, tail: readonly string[]): Promise<MextError> {\n if (resolved.unknown) return resolved.unknown\n const id = resolved.help.kind === \"root\" ? \"\" : resolved.help.id\n const first = tail.find((t) => !t.startsWith(\"-\"))\n const candidate = [id, first ?? \"\"].filter((x) => x !== \"\").join(\".\")\n try {\n await source.help(candidate)\n } catch (error) {\n if (error instanceof MextError) return error\n throw error\n }\n return new MextError(\"UNKNOWN_COMMAND\", `Unknown command \"${candidate}\".`, { command: candidate, suggested: [], usage: \"help\" })\n}\n\n/* help → 로컬 렌더러용 Registry (같은 help 텍스트) */\n\n/** 원격 명령어의 input 자리. CLI 필드는 defineCliSpec (JSON Schema 분석) 이 정하므로 Zod 스키마가 필요 없다 */\nconst REMOTE_INPUT = { _zod: { def: { shape: {} } } } as unknown as Command[\"input\"]\n\nfunction commandOf(meta: {\n description: string\n readOnly: boolean\n destructive: boolean\n requiresConfirmation: boolean\n scopes?: readonly string[]\n examples?: readonly unknown[]\n positional?: readonly string[]\n}): Command {\n return {\n [COMMAND]: true,\n description: meta.description,\n input: REMOTE_INPUT,\n output: undefined,\n readOnly: meta.readOnly,\n destructive: meta.destructive,\n requiresConfirmation: meta.requiresConfirmation,\n scopes: [...(meta.scopes ?? [])],\n examples: [...(meta.examples ?? [])] as Command[\"examples\"],\n positional: [...(meta.positional ?? [])],\n aliases: [],\n execute() {\n throw new Error(\"remote command\")\n },\n }\n}\n\n/** 원격 명령어 help → RegisteredCommand (CLI 필드 = inputSchema 분석) */\nexport function entryFromHelp(help: CommandHelp): RegisteredCommand {\n const entry: RegisteredCommand = {\n id: help.id,\n command: commandOf(help),\n aliases: [...help.aliases],\n file: undefined,\n inputSchema: help.inputSchema,\n outputSchema: help.outputSchema,\n }\n defineCliSpec(entry, cliSpecFromJsonSchema(help.inputSchema, help.positional))\n return entry\n}\n\nfunction registryFromHelp(help: Help): Registry {\n const commands = new Map<string, RegisteredCommand>()\n const aliases = new Map<string, string>()\n const namespaces = new Map<string, NamespaceInfo>()\n if (help.kind === \"command\") {\n const entry = entryFromHelp(help)\n commands.set(entry.id, entry)\n for (const a of entry.aliases) aliases.set(a, entry.id)\n namespaces.set(\"\", { id: \"\", description: undefined, commands: [], namespaces: [] })\n return { commands, aliases, namespaces }\n }\n const id = help.kind === \"root\" ? \"\" : help.id\n namespaces.set(id, {\n id,\n description: help.description,\n commands: help.commands.map((c) => c.id),\n namespaces: help.namespaces.map((n) => n.id),\n })\n for (const n of help.namespaces) namespaces.set(n.id, { id: n.id, description: n.description, commands: [], namespaces: [] })\n for (const c of help.commands) {\n commands.set(c.id, {\n id: c.id,\n command: commandOf(c),\n aliases: [],\n file: undefined,\n inputSchema: {},\n outputSchema: undefined,\n })\n }\n if (help.kind === \"namespace\" && help.command) commands.set(help.command.id, entryFromHelp(help.command))\n return { commands, aliases, namespaces }\n}\n\n/** 사람용 help 텍스트. 루트면 footer (고객 CLI 내장 명령) 를 붙인다 */\nfunction helpText(help: Help, prog: string, ctx: ReportContext): string {\n const target = help.kind === \"root\" ? \"\" : help.id\n const text = renderHelp(registryFromHelp(help), target, { prog })\n return help.kind === \"root\" && ctx.footer ? `${text}\\n${ctx.footer}` : text\n}\n\n/** --help --json = help 결과 그대로 (서버 help 의 structuredContent · 내장 manifest help) */\nfunction printHelp(help: Help, io: CliIo, prog: string, json: boolean, ctx: ReportContext): number {\n io.stdout.write(json ? formatJson(help) : helpText(help, prog, ctx))\n return EXIT.ok\n}\n\n/* 결과 · 오류 */\n\nconst MEXT_CODES: readonly MextErrorCode[] = [\n \"UNKNOWN_COMMAND\",\n \"INVALID_ARGUMENT\",\n \"UNAUTHENTICATED\",\n \"PERMISSION_DENIED\",\n \"INPUT_UNAVAILABLE\",\n]\n\n/** 서버 핸들러 예외 등 mext 구조화 오류 외의 도구 오류. --json = 서버 오류 본문 그대로, exit 1 */\nexport class RemoteExecutionError extends Error {\n readonly body: Record<string, unknown>\n constructor(body: Record<string, unknown>) {\n super(typeof body.message === \"string\" ? body.message : \"Remote command failed.\")\n this.name = \"RemoteExecutionError\"\n this.body = body\n }\n}\n\ninterface ReportContext {\n /** login 안내 명령 */\n login: string\n /** <BIN>_TOKEN */\n tokenEnv: string\n auth: AuthSource\n /** 루트 help footer */\n footer?: string | undefined\n}\n\n/** isError 결과 → MextError (code 가 mext 구조화 오류면) 또는 RemoteExecutionError */\nfunction toolError(result: CallToolResult, ctx: ReportContext): Error {\n const sc = result.structuredContent\n const body = isRecord(sc) && isRecord(sc.error) ? sc.error : undefined\n if (!body) return new RemoteExecutionError({ code: \"EXECUTION_FAILED\", message: textValue(result) ?? \"Remote command failed.\" })\n const { code, message, ...details } = body\n if (typeof code === \"string\" && (MEXT_CODES as readonly string[]).includes(code)) {\n const text = typeof message === \"string\" ? message : code\n if (code === \"UNAUTHENTICATED\") {\n return new MextError(\"UNAUTHENTICATED\", text, { ...(details as MextErrorDetails[\"UNAUTHENTICATED\"]), login: ctx.login })\n }\n return new MextError(code as MextErrorCode, text, details as never)\n }\n return new RemoteExecutionError(body)\n}\n\nfunction textValue(result: CallToolResult): string | undefined {\n const texts = (result.content ?? []).flatMap((c) =>\n isRecord(c) && c.type === \"text\" && typeof c.text === \"string\" ? [c.text] : [],\n )\n return texts.length > 0 ? texts.join(\"\\n\") : undefined\n}\n\n/** 401 → UNAUTHENTICATED (login 안내 포함) */\nfunction unauthenticatedFrom(error: RemoteUnauthorizedError, ctx: ReportContext): MextError {\n const data = isRecord(error.data) ? error.data : {}\n const reason =\n data.reason === \"invalid_token\" || data.reason === \"missing_token\"\n ? data.reason\n : error.challenge.error === \"invalid_token\"\n ? \"invalid_token\"\n : \"missing_token\"\n let message = typeof data.message === \"string\" ? data.message : error.message\n if (ctx.auth === \"env\") message += ` ${ctx.tokenEnv} was rejected.`\n return new MextError(\"UNAUTHENTICATED\", message, { reason, login: ctx.login })\n}\n\nfunction report(error: unknown, io: CliIo, prog: string, json: boolean, ctx: ReportContext): number {\n let e = error\n if (e instanceof RemoteUnauthorizedError) e = unauthenticatedFrom(e, ctx)\n if (json) {\n io.stderr.write(formatJson(errorBody(e)))\n return exitCodeOf(e)\n }\n io.stderr.write(formatError(e, prog))\n if (e instanceof MextError && e.code === \"PERMISSION_DENIED\" && ctx.auth === \"none\") {\n const reason = (e.details as MextErrorDetails[\"PERMISSION_DENIED\"]).reason\n if (reason === \"anonymous\") io.stderr.write(`Run \"${ctx.login}\" to log in.\\n`)\n }\n return exitCodeOf(e)\n}\n\nfunction errorBody(error: unknown): Record<string, unknown> {\n if (error instanceof RemoteExecutionError) return error.body\n if (\n error instanceof RemoteTransportError ||\n error instanceof RemoteRpcError ||\n error instanceof RemoteInputRequiredError ||\n error instanceof OAuthFlowError\n ) {\n const body: Record<string, unknown> = { code: \"REMOTE_ERROR\", message: error.message }\n if (error instanceof RemoteRpcError) body.rpc = { code: error.code, status: error.status, data: error.data }\n return body\n }\n return errorJson(error)\n}\n\nfunction usageError(message: string): MextError<\"INVALID_ARGUMENT\"> {\n return new MextError(\"INVALID_ARGUMENT\", message, {\n command: \"\",\n missing_fields: [],\n issues: [{ path: \"\", code: \"unknown_flag\", message }],\n expected_schema: {},\n examples: [],\n })\n}\n\n/* MRTR: InputRequiredResult → 프롬프트 → inputResponses */\n\n/**\n * elicitation/create (form) 만 처리 (clientCapabilities = elicitation.form).\n * requestedSchema 가 boolean 속성 하나 = 확인: --yes → 승인, TTY → [y/N], 그 외 INPUT_UNAVAILABLE.\n * 그 외 form = TTY 에서 필드별 입력 (스키마 모양으로 변환), TTY 없음 = INPUT_UNAVAILABLE.\n * 응답 = { action: \"accept\", content }. 이번 라운드 요청에 대한 응답만 보낸다\n */\nfunction inputHandler(\n io: CliIo,\n lines: LineReader,\n yes: boolean,\n command: string,\n signal: AbortSignal,\n): NonNullable<CallToolOptions[\"onInputRequired\"]> {\n const unavailable = (message: string, hint: string) =>\n new MextError(\"INPUT_UNAVAILABLE\", `${command} asked \"${message}\", but stdin is not a terminal.${hint}`, { command })\n const ask = async (prompt: string): Promise<string> => {\n const answer = await lines.question(prompt, signal)\n if (signal.aborted) throw new CliInterrupted()\n return answer ?? \"\"\n }\n return async (required: InputRequired): Promise<InputResponses> => {\n const out: InputResponses = {}\n for (const [key, request] of Object.entries(required.inputRequests ?? {})) {\n const params = isRecord(request.params) ? request.params : {}\n const message = typeof params.message === \"string\" ? params.message : \"Input required\"\n if (request.method !== \"elicitation/create\") {\n throw new RemoteTransportError(`${command}: unsupported input request ${request.method}.`)\n }\n if (params.mode === \"url\") {\n if (!io.isTTY) throw unavailable(message, \" Run it in an interactive terminal.\")\n await ask(`${message}\\n ${String(params.url)}\\nPress Enter when done. `)\n out[key] = { action: \"accept\" }\n continue\n }\n const schema = isRecord(params.requestedSchema) ? params.requestedSchema : { type: \"object\", properties: {} }\n const confirmKey = confirmField(schema)\n if (confirmKey !== undefined) {\n if (yes) {\n out[key] = { action: \"accept\", content: { [confirmKey]: true } }\n continue\n }\n if (!io.isTTY) throw unavailable(message, \" Pass --yes to approve.\")\n const answer = await ask(`${message} [y/N] `)\n out[key] = { action: \"accept\", content: { [confirmKey]: /^y(es)?$/i.test(answer.trim()) } }\n continue\n }\n if (!io.isTTY) throw unavailable(message, \" Run it in an interactive terminal.\")\n io.stderr.write(`${message}\\n`)\n const spec = cliSpecFromJsonSchema(schema)\n const content: Record<string, unknown> = {}\n for (const f of spec.fields) {\n const answer = await ask(` ${f.key}${f.required ? \"\" : \" (optional)\"}: `)\n if (answer === \"\") continue\n if (f.kind.type === \"array\") {\n const kind = f.kind\n content[f.key] = answer.split(\",\").map((s) => {\n const r = coerceValue(kind, s.trim())\n return r.ok ? r.value : s\n })\n continue\n }\n const r = coerceValue(f.kind, answer)\n content[f.key] = r.ok ? r.value : answer\n }\n out[key] = { action: \"accept\", content }\n }\n return out\n }\n}\n\n/** requestedSchema 의 속성이 boolean 하나면 그 키 (확인 요청) */\nfunction confirmField(schema: Record<string, unknown>): string | undefined {\n const props = schema.properties\n if (!isRecord(props)) return undefined\n const keys = Object.keys(props)\n if (keys.length !== 1) return undefined\n const p = props[keys[0]!]\n return isRecord(p) && p.type === \"boolean\" ? keys[0] : undefined\n}\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type * as z from "zod";
|
|
2
|
+
import type { Principal } from "./principal.ts";
|
|
3
|
+
/**
|
|
4
|
+
* 도입 프로젝트가 declaration merging 으로 채우는 ctx.app 타입.
|
|
5
|
+
*
|
|
6
|
+
* declare module "@obov/mext" { interface MextApp { db: Db } }
|
|
7
|
+
*/
|
|
8
|
+
export interface MextApp {
|
|
9
|
+
}
|
|
10
|
+
export interface ProgressUpdate {
|
|
11
|
+
progress: number;
|
|
12
|
+
total?: number;
|
|
13
|
+
message?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ConfirmRequest {
|
|
16
|
+
kind: "confirm";
|
|
17
|
+
message: string;
|
|
18
|
+
}
|
|
19
|
+
export interface InputRequest<S extends z.ZodObject = z.ZodObject> {
|
|
20
|
+
kind: "input";
|
|
21
|
+
message: string;
|
|
22
|
+
schema: S;
|
|
23
|
+
}
|
|
24
|
+
export type AskRequest = ConfirmRequest | InputRequest;
|
|
25
|
+
/** ctx.ask. confirm = boolean, input = schema 로 검증된 값 */
|
|
26
|
+
export interface Ask {
|
|
27
|
+
(request: ConfirmRequest): Promise<boolean>;
|
|
28
|
+
<S extends z.ZodObject>(request: InputRequest<S>): Promise<z.output<S>>;
|
|
29
|
+
}
|
|
30
|
+
export interface CommandContext {
|
|
31
|
+
principal: Principal;
|
|
32
|
+
signal: AbortSignal;
|
|
33
|
+
progress(update: ProgressUpdate): void;
|
|
34
|
+
ask: Ask;
|
|
35
|
+
app: MextApp;
|
|
36
|
+
}
|
|
37
|
+
export type InputSchema = z.ZodObject;
|
|
38
|
+
type InputKey<I extends InputSchema> = keyof z.input<I> & string;
|
|
39
|
+
export interface CommandDefinition<I extends InputSchema, R> {
|
|
40
|
+
/** 필수. help · MCP 설명의 원본 */
|
|
41
|
+
description: string;
|
|
42
|
+
/** 필수. 최상위 z.object */
|
|
43
|
+
input: I;
|
|
44
|
+
/** 선택. MCP outputSchema 의 원본 */
|
|
45
|
+
output?: z.ZodType;
|
|
46
|
+
readOnly?: boolean;
|
|
47
|
+
destructive?: boolean;
|
|
48
|
+
requiresConfirmation?: boolean;
|
|
49
|
+
/** 실행에 필요한 scopes. 전부 보유해야 실행 */
|
|
50
|
+
scopes?: readonly string[];
|
|
51
|
+
examples?: readonly z.input<I>[];
|
|
52
|
+
/** CLI positional 인자로 받을 input 키 순서 */
|
|
53
|
+
positional?: readonly InputKey<I>[];
|
|
54
|
+
/** 같은 네임스페이스 안 kebab-case 세그먼트. commands/users/get.ts 의 "fetch" → users.fetch */
|
|
55
|
+
aliases?: readonly string[];
|
|
56
|
+
execute(input: z.output<I>, ctx: CommandContext): R | Promise<R>;
|
|
57
|
+
}
|
|
58
|
+
export declare const COMMAND: unique symbol;
|
|
59
|
+
export interface Command<I extends InputSchema = InputSchema, R = unknown> {
|
|
60
|
+
readonly [COMMAND]: true;
|
|
61
|
+
readonly description: string;
|
|
62
|
+
readonly input: I;
|
|
63
|
+
readonly output: z.ZodType | undefined;
|
|
64
|
+
readonly readOnly: boolean;
|
|
65
|
+
readonly destructive: boolean;
|
|
66
|
+
readonly requiresConfirmation: boolean;
|
|
67
|
+
readonly scopes: readonly string[];
|
|
68
|
+
readonly examples: readonly z.input<I>[];
|
|
69
|
+
readonly positional: readonly string[];
|
|
70
|
+
readonly aliases: readonly string[];
|
|
71
|
+
execute(input: z.output<I>, ctx: CommandContext): R | Promise<R>;
|
|
72
|
+
}
|
|
73
|
+
export declare function defineCommand<I extends InputSchema, R>(definition: CommandDefinition<I, R>): Command<I, R>;
|
|
74
|
+
export declare function isCommand(value: unknown): value is Command;
|
|
75
|
+
export {};
|
package/dist/command.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const COMMAND = Symbol.for("@obov/mext/command");
|
|
2
|
+
export function defineCommand(definition) {
|
|
3
|
+
const d = definition;
|
|
4
|
+
if (typeof d.description !== "string" || d.description.trim() === "") {
|
|
5
|
+
throw new TypeError("defineCommand: description must be a non-empty string");
|
|
6
|
+
}
|
|
7
|
+
if (!isObjectSchema(d.input)) {
|
|
8
|
+
throw new TypeError("defineCommand: input must be a top-level z.object schema");
|
|
9
|
+
}
|
|
10
|
+
if (typeof d.execute !== "function") {
|
|
11
|
+
throw new TypeError("defineCommand: execute must be a function");
|
|
12
|
+
}
|
|
13
|
+
const shapeKeys = Object.keys(d.input.shape);
|
|
14
|
+
for (const key of d.positional ?? []) {
|
|
15
|
+
if (!shapeKeys.includes(key)) {
|
|
16
|
+
throw new TypeError(`defineCommand: positional "${key}" is not an input key`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const execute = d.execute;
|
|
20
|
+
return Object.freeze({
|
|
21
|
+
[COMMAND]: true,
|
|
22
|
+
description: d.description,
|
|
23
|
+
input: d.input,
|
|
24
|
+
output: d.output,
|
|
25
|
+
readOnly: d.readOnly === true,
|
|
26
|
+
destructive: d.destructive === true,
|
|
27
|
+
requiresConfirmation: d.requiresConfirmation === true,
|
|
28
|
+
scopes: Object.freeze([...(d.scopes ?? [])]),
|
|
29
|
+
examples: Object.freeze([...(d.examples ?? [])]),
|
|
30
|
+
positional: Object.freeze([...(d.positional ?? [])]),
|
|
31
|
+
aliases: Object.freeze([...(d.aliases ?? [])]),
|
|
32
|
+
execute(input, ctx) {
|
|
33
|
+
return execute.call(definition, input, ctx);
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export function isCommand(value) {
|
|
38
|
+
return typeof value === "object" && value !== null && value[COMMAND] === true;
|
|
39
|
+
}
|
|
40
|
+
function isObjectSchema(value) {
|
|
41
|
+
const def = value?._zod?.def;
|
|
42
|
+
return def?.type === "object" && typeof value.safeParseAsync === "function";
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAmEA,MAAM,CAAC,MAAM,OAAO,GAAkB,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAU,CAAA;AAiB/E,MAAM,UAAU,aAAa,CAA2B,UAAmC;IACzF,MAAM,CAAC,GAAG,UAA8C,CAAA;IACxD,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrE,MAAM,IAAI,SAAS,CAAC,uDAAuD,CAAC,CAAA;IAC9E,CAAC;IACD,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,SAAS,CAAC,0DAA0D,CAAC,CAAA;IACjF,CAAC;IACD,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QACpC,MAAM,IAAI,SAAS,CAAC,2CAA2C,CAAC,CAAA;IAClE,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IAC5C,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,SAAS,CAAC,8BAA8B,GAAG,uBAAuB,CAAC,CAAA;QAC/E,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAA;IACzB,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,CAAC,OAAO,CAAC,EAAE,IAAa;QACxB,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,QAAQ,EAAE,CAAC,CAAC,QAAQ,KAAK,IAAI;QAC7B,WAAW,EAAE,CAAC,CAAC,WAAW,KAAK,IAAI;QACnC,oBAAoB,EAAE,CAAC,CAAC,oBAAoB,KAAK,IAAI;QACrD,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;QAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC;QAChD,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC;QACpD,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9C,OAAO,CAAC,KAAkB,EAAE,GAAmB;YAC7C,OAAO,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;QAC7C,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAK,KAAiC,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;AAC5G,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,MAAM,GAAG,GAAI,KAA6D,EAAE,IAAI,EAAE,GAAG,CAAA;IACrF,OAAO,GAAG,EAAE,IAAI,KAAK,QAAQ,IAAI,OAAQ,KAAsC,CAAC,cAAc,KAAK,UAAU,CAAA;AAC/G,CAAC","sourcesContent":["import type * as z from \"zod\"\nimport type { Principal } from \"./principal.ts\"\n\n/**\n * 도입 프로젝트가 declaration merging 으로 채우는 ctx.app 타입.\n *\n * declare module \"@obov/mext\" { interface MextApp { db: Db } }\n */\nexport interface MextApp {}\n\nexport interface ProgressUpdate {\n progress: number\n total?: number\n message?: string\n}\n\nexport interface ConfirmRequest {\n kind: \"confirm\"\n message: string\n}\n\nexport interface InputRequest<S extends z.ZodObject = z.ZodObject> {\n kind: \"input\"\n message: string\n schema: S\n}\n\nexport type AskRequest = ConfirmRequest | InputRequest\n\n/** ctx.ask. confirm = boolean, input = schema 로 검증된 값 */\nexport interface Ask {\n (request: ConfirmRequest): Promise<boolean>\n <S extends z.ZodObject>(request: InputRequest<S>): Promise<z.output<S>>\n}\n\nexport interface CommandContext {\n principal: Principal\n signal: AbortSignal\n progress(update: ProgressUpdate): void\n ask: Ask\n app: MextApp\n}\n\nexport type InputSchema = z.ZodObject\n\ntype InputKey<I extends InputSchema> = keyof z.input<I> & string\n\nexport interface CommandDefinition<I extends InputSchema, R> {\n /** 필수. help · MCP 설명의 원본 */\n description: string\n /** 필수. 최상위 z.object */\n input: I\n /** 선택. MCP outputSchema 의 원본 */\n output?: z.ZodType\n readOnly?: boolean\n destructive?: boolean\n requiresConfirmation?: boolean\n /** 실행에 필요한 scopes. 전부 보유해야 실행 */\n scopes?: readonly string[]\n examples?: readonly z.input<I>[]\n /** CLI positional 인자로 받을 input 키 순서 */\n positional?: readonly InputKey<I>[]\n /** 같은 네임스페이스 안 kebab-case 세그먼트. commands/users/get.ts 의 \"fetch\" → users.fetch */\n aliases?: readonly string[]\n execute(input: z.output<I>, ctx: CommandContext): R | Promise<R>\n}\n\nexport const COMMAND: unique symbol = Symbol.for(\"@obov/mext/command\") as never\n\nexport interface Command<I extends InputSchema = InputSchema, R = unknown> {\n readonly [COMMAND]: true\n readonly description: string\n readonly input: I\n readonly output: z.ZodType | undefined\n readonly readOnly: boolean\n readonly destructive: boolean\n readonly requiresConfirmation: boolean\n readonly scopes: readonly string[]\n readonly examples: readonly z.input<I>[]\n readonly positional: readonly string[]\n readonly aliases: readonly string[]\n execute(input: z.output<I>, ctx: CommandContext): R | Promise<R>\n}\n\nexport function defineCommand<I extends InputSchema, R>(definition: CommandDefinition<I, R>): Command<I, R> {\n const d = definition as Partial<CommandDefinition<I, R>>\n if (typeof d.description !== \"string\" || d.description.trim() === \"\") {\n throw new TypeError(\"defineCommand: description must be a non-empty string\")\n }\n if (!isObjectSchema(d.input)) {\n throw new TypeError(\"defineCommand: input must be a top-level z.object schema\")\n }\n if (typeof d.execute !== \"function\") {\n throw new TypeError(\"defineCommand: execute must be a function\")\n }\n const shapeKeys = Object.keys(d.input.shape)\n for (const key of d.positional ?? []) {\n if (!shapeKeys.includes(key)) {\n throw new TypeError(`defineCommand: positional \"${key}\" is not an input key`)\n }\n }\n const execute = d.execute\n return Object.freeze({\n [COMMAND]: true as const,\n description: d.description,\n input: d.input,\n output: d.output,\n readOnly: d.readOnly === true,\n destructive: d.destructive === true,\n requiresConfirmation: d.requiresConfirmation === true,\n scopes: Object.freeze([...(d.scopes ?? [])]),\n examples: Object.freeze([...(d.examples ?? [])]),\n positional: Object.freeze([...(d.positional ?? [])]),\n aliases: Object.freeze([...(d.aliases ?? [])]),\n execute(input: z.output<I>, ctx: CommandContext) {\n return execute.call(definition, input, ctx)\n },\n })\n}\n\nexport function isCommand(value: unknown): value is Command {\n return typeof value === \"object\" && value !== null && (value as Record<symbol, unknown>)[COMMAND] === true\n}\n\nfunction isObjectSchema(value: unknown): value is InputSchema {\n const def = (value as { _zod?: { def?: { type?: unknown } } } | undefined)?._zod?.def\n return def?.type === \"object\" && typeof (value as { safeParseAsync?: unknown }).safeParseAsync === \"function\"\n}\n"]}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { MextApp } from "./command.ts";
|
|
2
|
+
import type { OAuthResourceOptions } from "./mcp/http.ts";
|
|
3
|
+
import { type Principal } from "./principal.ts";
|
|
4
|
+
/** mext.config.ts 의 default export */
|
|
5
|
+
export interface MextConfig {
|
|
6
|
+
/** 명령어 폴더. 설정 파일 위치 (cwd) 기준. 기본 "commands" */
|
|
7
|
+
commandsDir?: string;
|
|
8
|
+
/** ctx.app 팩토리. 실행 프로세스당 1회 */
|
|
9
|
+
app?: () => MextApp | Promise<MextApp>;
|
|
10
|
+
/** HTTP 전용. 요청마다 Authorization 헤더로 주체 생성. 잘못된 토큰 = unauthenticated() throw */
|
|
11
|
+
auth?: (req: {
|
|
12
|
+
authorization: string | undefined;
|
|
13
|
+
}) => Principal | Promise<Principal>;
|
|
14
|
+
/** MCP 노출 방식. 기본 "execute" */
|
|
15
|
+
tools?: "execute" | "split";
|
|
16
|
+
server?: {
|
|
17
|
+
host?: string;
|
|
18
|
+
port?: number;
|
|
19
|
+
allowedOrigins?: string[];
|
|
20
|
+
};
|
|
21
|
+
/** HTTP 전용. OAuth 보호 자원 메타데이터 (인가 서버 위치). mext login · MCP 클라이언트의 discovery */
|
|
22
|
+
oauth?: OAuthResourceOptions;
|
|
23
|
+
/** 로컬 실행 (mext run · stdio) 주체. 기본 localPrincipal() */
|
|
24
|
+
localPrincipal?: Principal | (() => Principal | Promise<Principal>);
|
|
25
|
+
/** 고객 CLI (mext build → .mext/cli/). 없으면 고객 CLI 를 만들지 않는다 */
|
|
26
|
+
cli?: CliConfig;
|
|
27
|
+
}
|
|
28
|
+
/** mext.config.ts 의 cli (§5 고객 CLI 설정) */
|
|
29
|
+
export interface CliConfig {
|
|
30
|
+
/** 실행 파일 이름 (kebab-case). 환경변수 접두 (MYAPP_TOKEN · MYAPP_URL) · 설정 폴더 (~/.config/<bin>) */
|
|
31
|
+
bin: string;
|
|
32
|
+
/** 서버 MCP 엔드포인트 (http(s)). 실행 시 <BIN>_URL 환경변수가 있으면 그 값 */
|
|
33
|
+
url: string;
|
|
34
|
+
/** npm 패키지 이름. 기본 = bin */
|
|
35
|
+
packageName?: string;
|
|
36
|
+
/** 고객 CLI 버전 (--version · clientInfo). 기본 = 도입 프로젝트 package.json version */
|
|
37
|
+
version?: string;
|
|
38
|
+
/** true = 번들 형태 (내장 manifest, 기본), false = 범용 형태 (help · 스키마를 서버에서 조회) */
|
|
39
|
+
manifest?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export declare const CONFIG_FILE = "mext.config.ts";
|
|
42
|
+
/** 고객 CLI 의 내장 명령 (루트 세그먼트로 쓸 수 없음) */
|
|
43
|
+
export declare const CLI_BUILTIN_COMMANDS: readonly string[];
|
|
44
|
+
/** 타입 도우미. 값은 그대로 반환 */
|
|
45
|
+
export declare function defineConfig(config: MextConfig): MextConfig;
|
|
46
|
+
/** cwd 의 mext.config.ts 를 import. 없으면 {}. 형식이 틀리면 TypeError (모르는 키 포함) */
|
|
47
|
+
export declare function loadConfig(cwd?: string): Promise<MextConfig>;
|
|
48
|
+
/** commands/ 절대 경로 */
|
|
49
|
+
export declare function resolveCommandsDir(cwd: string, config: MextConfig): string;
|
|
50
|
+
/** 로컬 실행 주체: config.localPrincipal (값 · 함수) 또는 localPrincipal() */
|
|
51
|
+
export declare function resolveLocalPrincipal(config: MextConfig): Promise<Principal>;
|
|
52
|
+
/** ctx.app: config.app() 또는 {} */
|
|
53
|
+
export declare function createApp(config: MextConfig): Promise<MextApp>;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
10
|
+
import { join, resolve } from "node:path";
|
|
11
|
+
import { pathToFileURL } from "node:url";
|
|
12
|
+
import { isSegment } from "./ids.js";
|
|
13
|
+
import { localPrincipal } from "./principal.js";
|
|
14
|
+
export const CONFIG_FILE = "mext.config.ts";
|
|
15
|
+
const CONFIG_KEYS = ["commandsDir", "app", "auth", "tools", "server", "oauth", "localPrincipal", "cli"];
|
|
16
|
+
const CLI_KEYS = ["bin", "url", "packageName", "version", "manifest"];
|
|
17
|
+
/** 고객 CLI 의 내장 명령 (루트 세그먼트로 쓸 수 없음) */
|
|
18
|
+
export const CLI_BUILTIN_COMMANDS = ["help", "login", "logout", "mcp"];
|
|
19
|
+
/** 타입 도우미. 값은 그대로 반환 */
|
|
20
|
+
export function defineConfig(config) {
|
|
21
|
+
return config;
|
|
22
|
+
}
|
|
23
|
+
/** cwd 의 mext.config.ts 를 import. 없으면 {}. 형식이 틀리면 TypeError (모르는 키 포함) */
|
|
24
|
+
export async function loadConfig(cwd = process.cwd()) {
|
|
25
|
+
const file = join(resolve(cwd), CONFIG_FILE);
|
|
26
|
+
if (!existsSync(file))
|
|
27
|
+
return {};
|
|
28
|
+
const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(file).href)));
|
|
29
|
+
return validateConfig(mod.default);
|
|
30
|
+
}
|
|
31
|
+
/** commands/ 절대 경로 */
|
|
32
|
+
export function resolveCommandsDir(cwd, config) {
|
|
33
|
+
return resolve(cwd, config.commandsDir ?? "commands");
|
|
34
|
+
}
|
|
35
|
+
/** 로컬 실행 주체: config.localPrincipal (값 · 함수) 또는 localPrincipal() */
|
|
36
|
+
export async function resolveLocalPrincipal(config) {
|
|
37
|
+
const p = config.localPrincipal;
|
|
38
|
+
if (p === undefined)
|
|
39
|
+
return localPrincipal();
|
|
40
|
+
return typeof p === "function" ? await p() : p;
|
|
41
|
+
}
|
|
42
|
+
/** ctx.app: config.app() 또는 {} */
|
|
43
|
+
export async function createApp(config) {
|
|
44
|
+
return config.app ? await config.app() : {};
|
|
45
|
+
}
|
|
46
|
+
function validateConfig(value) {
|
|
47
|
+
const fail = (message) => {
|
|
48
|
+
throw new TypeError(`${CONFIG_FILE}: ${message}`);
|
|
49
|
+
};
|
|
50
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
51
|
+
return fail("default export must be an object (export default defineConfig({ ... }))");
|
|
52
|
+
}
|
|
53
|
+
const c = value;
|
|
54
|
+
const unknown = Object.keys(c).filter((k) => !CONFIG_KEYS.includes(k));
|
|
55
|
+
if (unknown.length > 0)
|
|
56
|
+
fail(`unknown key${unknown.length === 1 ? "" : "s"}: ${unknown.join(", ")}`);
|
|
57
|
+
if (c.commandsDir !== undefined && typeof c.commandsDir !== "string")
|
|
58
|
+
fail("commandsDir must be a string");
|
|
59
|
+
if (c.app !== undefined && typeof c.app !== "function")
|
|
60
|
+
fail("app must be a function");
|
|
61
|
+
if (c.auth !== undefined && typeof c.auth !== "function")
|
|
62
|
+
fail("auth must be a function");
|
|
63
|
+
if (c.tools !== undefined && c.tools !== "execute" && c.tools !== "split")
|
|
64
|
+
fail('tools must be "execute" or "split"');
|
|
65
|
+
if (c.server !== undefined && (typeof c.server !== "object" || c.server === null))
|
|
66
|
+
fail("server must be an object");
|
|
67
|
+
if (c.oauth !== undefined) {
|
|
68
|
+
const o = c.oauth;
|
|
69
|
+
if (typeof o !== "object" || o === null || !Array.isArray(o.authorizationServers) || o.authorizationServers.length === 0) {
|
|
70
|
+
fail("oauth.authorizationServers must be a non-empty array of URLs");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const lp = c.localPrincipal;
|
|
74
|
+
if (lp !== undefined && typeof lp !== "function" && !isPrincipal(lp)) {
|
|
75
|
+
fail("localPrincipal must be a Principal ({ id, kind, scopes }) or a function");
|
|
76
|
+
}
|
|
77
|
+
if (c.cli !== undefined)
|
|
78
|
+
validateCli(c.cli, fail);
|
|
79
|
+
return c;
|
|
80
|
+
}
|
|
81
|
+
function validateCli(value, fail) {
|
|
82
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
83
|
+
fail("cli must be an object ({ bin, url })");
|
|
84
|
+
const cli = value;
|
|
85
|
+
const unknown = Object.keys(cli).filter((k) => !CLI_KEYS.includes(k));
|
|
86
|
+
if (unknown.length > 0)
|
|
87
|
+
fail(`unknown cli key${unknown.length === 1 ? "" : "s"}: ${unknown.join(", ")}`);
|
|
88
|
+
if (typeof cli.bin !== "string" || !isSegment(cli.bin))
|
|
89
|
+
fail('cli.bin must be a kebab-case name (e.g. "myapp")');
|
|
90
|
+
if (typeof cli.url !== "string" || !isHttpUrl(cli.url))
|
|
91
|
+
fail("cli.url must be an http(s) URL of the MCP endpoint");
|
|
92
|
+
if (cli.packageName !== undefined && (typeof cli.packageName !== "string" || !NPM_NAME.test(cli.packageName))) {
|
|
93
|
+
fail('cli.packageName must be an npm package name (e.g. "@example/myapp-cli")');
|
|
94
|
+
}
|
|
95
|
+
if (cli.version !== undefined && (typeof cli.version !== "string" || cli.version.trim() === "")) {
|
|
96
|
+
fail("cli.version must be a non-empty string");
|
|
97
|
+
}
|
|
98
|
+
if (cli.manifest !== undefined && typeof cli.manifest !== "boolean")
|
|
99
|
+
fail("cli.manifest must be a boolean");
|
|
100
|
+
}
|
|
101
|
+
/** npm 패키지 이름 (소문자 · scope 선택) */
|
|
102
|
+
const NPM_NAME = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
|
|
103
|
+
function isHttpUrl(value) {
|
|
104
|
+
if (!/^https?:\/\//i.test(value))
|
|
105
|
+
return false;
|
|
106
|
+
try {
|
|
107
|
+
new URL(value);
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function isPrincipal(value) {
|
|
115
|
+
const p = value;
|
|
116
|
+
return (typeof p === "object" &&
|
|
117
|
+
p !== null &&
|
|
118
|
+
typeof p.id === "string" &&
|
|
119
|
+
(p.kind === "local" || p.kind === "token" || p.kind === "anonymous") &&
|
|
120
|
+
Array.isArray(p.scopes));
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\"\nimport { join, resolve } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport type { MextApp } from \"./command.ts\"\nimport { isSegment } from \"./ids.ts\"\nimport type { OAuthResourceOptions } from \"./mcp/http.ts\"\nimport { localPrincipal, type Principal } from \"./principal.ts\"\n\n/** mext.config.ts 의 default export */\nexport interface MextConfig {\n /** 명령어 폴더. 설정 파일 위치 (cwd) 기준. 기본 \"commands\" */\n commandsDir?: string\n /** ctx.app 팩토리. 실행 프로세스당 1회 */\n app?: () => MextApp | Promise<MextApp>\n /** HTTP 전용. 요청마다 Authorization 헤더로 주체 생성. 잘못된 토큰 = unauthenticated() throw */\n auth?: (req: { authorization: string | undefined }) => Principal | Promise<Principal>\n /** MCP 노출 방식. 기본 \"execute\" */\n tools?: \"execute\" | \"split\"\n server?: { host?: string; port?: number; allowedOrigins?: string[] }\n /** HTTP 전용. OAuth 보호 자원 메타데이터 (인가 서버 위치). mext login · MCP 클라이언트의 discovery */\n oauth?: OAuthResourceOptions\n /** 로컬 실행 (mext run · stdio) 주체. 기본 localPrincipal() */\n localPrincipal?: Principal | (() => Principal | Promise<Principal>)\n /** 고객 CLI (mext build → .mext/cli/). 없으면 고객 CLI 를 만들지 않는다 */\n cli?: CliConfig\n}\n\n/** mext.config.ts 의 cli (§5 고객 CLI 설정) */\nexport interface CliConfig {\n /** 실행 파일 이름 (kebab-case). 환경변수 접두 (MYAPP_TOKEN · MYAPP_URL) · 설정 폴더 (~/.config/<bin>) */\n bin: string\n /** 서버 MCP 엔드포인트 (http(s)). 실행 시 <BIN>_URL 환경변수가 있으면 그 값 */\n url: string\n /** npm 패키지 이름. 기본 = bin */\n packageName?: string\n /** 고객 CLI 버전 (--version · clientInfo). 기본 = 도입 프로젝트 package.json version */\n version?: string\n /** true = 번들 형태 (내장 manifest, 기본), false = 범용 형태 (help · 스키마를 서버에서 조회) */\n manifest?: boolean\n}\n\nexport const CONFIG_FILE = \"mext.config.ts\"\n\nconst CONFIG_KEYS: readonly string[] = [\"commandsDir\", \"app\", \"auth\", \"tools\", \"server\", \"oauth\", \"localPrincipal\", \"cli\"]\nconst CLI_KEYS: readonly string[] = [\"bin\", \"url\", \"packageName\", \"version\", \"manifest\"]\n/** 고객 CLI 의 내장 명령 (루트 세그먼트로 쓸 수 없음) */\nexport const CLI_BUILTIN_COMMANDS: readonly string[] = [\"help\", \"login\", \"logout\", \"mcp\"]\n\n/** 타입 도우미. 값은 그대로 반환 */\nexport function defineConfig(config: MextConfig): MextConfig {\n return config\n}\n\n/** cwd 의 mext.config.ts 를 import. 없으면 {}. 형식이 틀리면 TypeError (모르는 키 포함) */\nexport async function loadConfig(cwd: string = process.cwd()): Promise<MextConfig> {\n const file = join(resolve(cwd), CONFIG_FILE)\n if (!existsSync(file)) return {}\n const mod = (await import(pathToFileURL(file).href)) as { default?: unknown }\n return validateConfig(mod.default)\n}\n\n/** commands/ 절대 경로 */\nexport function resolveCommandsDir(cwd: string, config: MextConfig): string {\n return resolve(cwd, config.commandsDir ?? \"commands\")\n}\n\n/** 로컬 실행 주체: config.localPrincipal (값 · 함수) 또는 localPrincipal() */\nexport async function resolveLocalPrincipal(config: MextConfig): Promise<Principal> {\n const p = config.localPrincipal\n if (p === undefined) return localPrincipal()\n return typeof p === \"function\" ? await p() : p\n}\n\n/** ctx.app: config.app() 또는 {} */\nexport async function createApp(config: MextConfig): Promise<MextApp> {\n return config.app ? await config.app() : ({} as MextApp)\n}\n\nfunction validateConfig(value: unknown): MextConfig {\n const fail = (message: string): never => {\n throw new TypeError(`${CONFIG_FILE}: ${message}`)\n }\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return fail(\"default export must be an object (export default defineConfig({ ... }))\")\n }\n const c = value as Record<string, unknown>\n const unknown = Object.keys(c).filter((k) => !CONFIG_KEYS.includes(k))\n if (unknown.length > 0) fail(`unknown key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`)\n if (c.commandsDir !== undefined && typeof c.commandsDir !== \"string\") fail(\"commandsDir must be a string\")\n if (c.app !== undefined && typeof c.app !== \"function\") fail(\"app must be a function\")\n if (c.auth !== undefined && typeof c.auth !== \"function\") fail(\"auth must be a function\")\n if (c.tools !== undefined && c.tools !== \"execute\" && c.tools !== \"split\") fail('tools must be \"execute\" or \"split\"')\n if (c.server !== undefined && (typeof c.server !== \"object\" || c.server === null)) fail(\"server must be an object\")\n if (c.oauth !== undefined) {\n const o = c.oauth as { authorizationServers?: unknown } | null\n if (typeof o !== \"object\" || o === null || !Array.isArray(o.authorizationServers) || o.authorizationServers.length === 0) {\n fail(\"oauth.authorizationServers must be a non-empty array of URLs\")\n }\n }\n const lp = c.localPrincipal\n if (lp !== undefined && typeof lp !== \"function\" && !isPrincipal(lp)) {\n fail(\"localPrincipal must be a Principal ({ id, kind, scopes }) or a function\")\n }\n if (c.cli !== undefined) validateCli(c.cli, fail)\n return c as MextConfig\n}\n\nfunction validateCli(value: unknown, fail: (message: string) => never): void {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) fail(\"cli must be an object ({ bin, url })\")\n const cli = value as Record<string, unknown>\n const unknown = Object.keys(cli).filter((k) => !CLI_KEYS.includes(k))\n if (unknown.length > 0) fail(`unknown cli key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`)\n if (typeof cli.bin !== \"string\" || !isSegment(cli.bin)) fail('cli.bin must be a kebab-case name (e.g. \"myapp\")')\n if (typeof cli.url !== \"string\" || !isHttpUrl(cli.url)) fail(\"cli.url must be an http(s) URL of the MCP endpoint\")\n if (cli.packageName !== undefined && (typeof cli.packageName !== \"string\" || !NPM_NAME.test(cli.packageName))) {\n fail('cli.packageName must be an npm package name (e.g. \"@example/myapp-cli\")')\n }\n if (cli.version !== undefined && (typeof cli.version !== \"string\" || cli.version.trim() === \"\")) {\n fail(\"cli.version must be a non-empty string\")\n }\n if (cli.manifest !== undefined && typeof cli.manifest !== \"boolean\") fail(\"cli.manifest must be a boolean\")\n}\n\n/** npm 패키지 이름 (소문자 · scope 선택) */\nconst NPM_NAME = /^(?:@[a-z0-9][a-z0-9._~-]*\\/)?[a-z0-9][a-z0-9._~-]*$/\n\nfunction isHttpUrl(value: string): boolean {\n if (!/^https?:\\/\\//i.test(value)) return false\n try {\n new URL(value)\n return true\n } catch {\n return false\n }\n}\n\nfunction isPrincipal(value: unknown): value is Principal {\n const p = value as Partial<Principal> | null\n return (\n typeof p === \"object\" &&\n p !== null &&\n typeof p.id === \"string\" &&\n (p.kind === \"local\" || p.kind === \"token\" || p.kind === \"anonymous\") &&\n Array.isArray(p.scopes)\n )\n}\n"]}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export type BuildIssueCode = "COMMANDS_DIR_MISSING" | "PATH_COLLISION" | "DUPLICATE_ID" | "INVALID_SEGMENT" | "INVALID_ALIAS" | "RESERVED_ID" | "ROOT_INDEX" | "INVALID_COMMAND" | "LOAD_FAILED" | "SCHEMA_UNREPRESENTABLE" | "CLI_UNCONVERTIBLE" | "BUNDLE_FAILED";
|
|
2
|
+
export interface BuildIssue {
|
|
3
|
+
code: BuildIssueCode;
|
|
4
|
+
message: string;
|
|
5
|
+
/** commands/ 기준 상대 경로 (posix) */
|
|
6
|
+
file?: string;
|
|
7
|
+
id?: string;
|
|
8
|
+
}
|
|
9
|
+
/** 스캔 · Registry 생성의 빌드 오류. 발견한 문제를 모두 모아 한 번에 던진다 */
|
|
10
|
+
export declare class MextBuildError extends Error {
|
|
11
|
+
readonly issues: readonly BuildIssue[];
|
|
12
|
+
constructor(issues: readonly BuildIssue[]);
|
|
13
|
+
}
|
|
14
|
+
export type MextErrorCode = "UNKNOWN_COMMAND" | "INVALID_ARGUMENT" | "UNAUTHENTICATED" | "PERMISSION_DENIED" | "INPUT_UNAVAILABLE" | "INPUT_DECLINED";
|
|
15
|
+
export interface ArgumentIssue {
|
|
16
|
+
/** 점 구분 경로. "" = 입력 전체 */
|
|
17
|
+
path: string;
|
|
18
|
+
code: string;
|
|
19
|
+
message: string;
|
|
20
|
+
}
|
|
21
|
+
export interface MextErrorDetails {
|
|
22
|
+
UNKNOWN_COMMAND: {
|
|
23
|
+
command: string;
|
|
24
|
+
/** 유사 정식 ID (가까운 순) */
|
|
25
|
+
suggested: string[];
|
|
26
|
+
/** 다음에 볼 help 대상. "help" (루트) · "help users" (네임스페이스) */
|
|
27
|
+
usage: string;
|
|
28
|
+
};
|
|
29
|
+
INVALID_ARGUMENT: {
|
|
30
|
+
command: string;
|
|
31
|
+
/** 원본 입력에 없는 필수 필드 경로 */
|
|
32
|
+
missing_fields: string[];
|
|
33
|
+
issues: ArgumentIssue[];
|
|
34
|
+
/** input JSON Schema 2020-12 */
|
|
35
|
+
expected_schema: Record<string, unknown>;
|
|
36
|
+
examples: unknown[];
|
|
37
|
+
};
|
|
38
|
+
UNAUTHENTICATED: {
|
|
39
|
+
reason: "missing_token" | "invalid_token";
|
|
40
|
+
/** CLI 원격 실행: 토큰 발급 명령 (mext login --url <url>) */
|
|
41
|
+
login?: string;
|
|
42
|
+
};
|
|
43
|
+
PERMISSION_DENIED: {
|
|
44
|
+
command: string;
|
|
45
|
+
/** anonymous = 인증 없는 주체의 readOnly 외 명령어 · read_only = readOnly 전용 호출 (split query) · scope = scopes 부족 */
|
|
46
|
+
reason: "anonymous" | "read_only" | "scope";
|
|
47
|
+
required_scopes: string[];
|
|
48
|
+
held_scopes: string[];
|
|
49
|
+
};
|
|
50
|
+
/** ctx.ask 를 처리할 수 없는 실행 환경 (TTY 없는 CLI 등) */
|
|
51
|
+
INPUT_UNAVAILABLE: {
|
|
52
|
+
command: string;
|
|
53
|
+
};
|
|
54
|
+
/** ctx.ask 거절 · 취소. confirm = requiresConfirmation 확인 거절 (실행 안 함), input = 입력 요청 거절 */
|
|
55
|
+
INPUT_DECLINED: {
|
|
56
|
+
command: string;
|
|
57
|
+
kind: "confirm" | "input";
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** 구조화 오류. 어댑터는 code 로 분기하고 toJSON() 을 응답 본문으로 쓴다 */
|
|
61
|
+
export declare class MextError<C extends MextErrorCode = MextErrorCode> extends Error {
|
|
62
|
+
readonly code: C;
|
|
63
|
+
readonly details: MextErrorDetails[C];
|
|
64
|
+
constructor(code: C, message: string, details: MextErrorDetails[C]);
|
|
65
|
+
toJSON(): {
|
|
66
|
+
code: C;
|
|
67
|
+
message: string;
|
|
68
|
+
} & MextErrorDetails[C];
|
|
69
|
+
}
|
|
70
|
+
export declare function isMextError<C extends MextErrorCode>(error: unknown, code?: C): error is MextError<C>;
|
|
71
|
+
/** auth 단계에서 어댑터가 던지는 오류. anonymous 로 낮추지 않는다 */
|
|
72
|
+
export declare function unauthenticated(reason: MextErrorDetails["UNAUTHENTICATED"]["reason"]): MextError<"UNAUTHENTICATED">;
|
|
73
|
+
/** ctx.ask 거절. AskHandler 가 input 요청 거절 · 취소에 던진다. invoke 는 requiresConfirmation 확인 거절에 던진다 */
|
|
74
|
+
export declare function inputDeclined(command: string, kind: "confirm" | "input"): MextError<"INPUT_DECLINED">;
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** 스캔 · Registry 생성의 빌드 오류. 발견한 문제를 모두 모아 한 번에 던진다 */
|
|
2
|
+
export class MextBuildError extends Error {
|
|
3
|
+
issues;
|
|
4
|
+
constructor(issues) {
|
|
5
|
+
super(`mext build failed (${issues.length} issue${issues.length === 1 ? "" : "s"})\n` +
|
|
6
|
+
issues.map((i) => ` ${i.code}${i.file ? ` ${i.file}` : ""}: ${i.message}`).join("\n"));
|
|
7
|
+
this.name = "MextBuildError";
|
|
8
|
+
this.issues = issues;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** 구조화 오류. 어댑터는 code 로 분기하고 toJSON() 을 응답 본문으로 쓴다 */
|
|
12
|
+
export class MextError extends Error {
|
|
13
|
+
code;
|
|
14
|
+
details;
|
|
15
|
+
constructor(code, message, details) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = "MextError";
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.details = details;
|
|
20
|
+
}
|
|
21
|
+
toJSON() {
|
|
22
|
+
return { code: this.code, message: this.message, ...this.details };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function isMextError(error, code) {
|
|
26
|
+
return error instanceof MextError && (code === undefined || error.code === code);
|
|
27
|
+
}
|
|
28
|
+
/** auth 단계에서 어댑터가 던지는 오류. anonymous 로 낮추지 않는다 */
|
|
29
|
+
export function unauthenticated(reason) {
|
|
30
|
+
const message = reason === "missing_token" ? "Authentication required." : "Invalid authentication token.";
|
|
31
|
+
return new MextError("UNAUTHENTICATED", message, { reason });
|
|
32
|
+
}
|
|
33
|
+
/** ctx.ask 거절. AskHandler 가 input 요청 거절 · 취소에 던진다. invoke 는 requiresConfirmation 확인 거절에 던진다 */
|
|
34
|
+
export function inputDeclined(command, kind) {
|
|
35
|
+
const message = kind === "confirm" ? `${command} was not confirmed and did not run.` : `${command} requested input, but it was declined.`;
|
|
36
|
+
return new MextError("INPUT_DECLINED", message, { command, kind });
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAsBA,sDAAsD;AACtD,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,MAAM,CAAuB;IAEtC,YAAY,MAA6B;QACvC,KAAK,CACH,sBAAsB,MAAM,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK;YAC7E,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACzF,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAyDD,qDAAqD;AACrD,MAAM,OAAO,SAAmD,SAAQ,KAAK;IAClE,IAAI,CAAG;IACP,OAAO,CAAqB;IAErC,YAAY,IAAO,EAAE,OAAe,EAAE,OAA4B;QAChE,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,WAAW,CAAA;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,MAAM;QACJ,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;IACpE,CAAC;CACF;AAED,MAAM,UAAU,WAAW,CAA0B,KAAc,EAAE,IAAQ;IAC3E,OAAO,KAAK,YAAY,SAAS,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;AAClF,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,eAAe,CAAC,MAAqD;IACnF,MAAM,OAAO,GAAG,MAAM,KAAK,eAAe,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,+BAA+B,CAAA;IACzG,OAAO,IAAI,SAAS,CAAC,iBAAiB,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;AAC9D,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,IAAyB;IACtE,MAAM,OAAO,GACX,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,qCAAqC,CAAC,CAAC,CAAC,GAAG,OAAO,wCAAwC,CAAA;IAC3H,OAAO,IAAI,SAAS,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;AACpE,CAAC","sourcesContent":["export type BuildIssueCode =\n | \"COMMANDS_DIR_MISSING\"\n | \"PATH_COLLISION\"\n | \"DUPLICATE_ID\"\n | \"INVALID_SEGMENT\"\n | \"INVALID_ALIAS\"\n | \"RESERVED_ID\"\n | \"ROOT_INDEX\"\n | \"INVALID_COMMAND\"\n | \"LOAD_FAILED\"\n | \"SCHEMA_UNREPRESENTABLE\"\n | \"CLI_UNCONVERTIBLE\"\n | \"BUNDLE_FAILED\"\n\nexport interface BuildIssue {\n code: BuildIssueCode\n message: string\n /** commands/ 기준 상대 경로 (posix) */\n file?: string\n id?: string\n}\n\n/** 스캔 · Registry 생성의 빌드 오류. 발견한 문제를 모두 모아 한 번에 던진다 */\nexport class MextBuildError extends Error {\n readonly issues: readonly BuildIssue[]\n\n constructor(issues: readonly BuildIssue[]) {\n super(\n `mext build failed (${issues.length} issue${issues.length === 1 ? \"\" : \"s\"})\\n` +\n issues.map((i) => ` ${i.code}${i.file ? ` ${i.file}` : \"\"}: ${i.message}`).join(\"\\n\"),\n )\n this.name = \"MextBuildError\"\n this.issues = issues\n }\n}\n\nexport type MextErrorCode =\n | \"UNKNOWN_COMMAND\"\n | \"INVALID_ARGUMENT\"\n | \"UNAUTHENTICATED\"\n | \"PERMISSION_DENIED\"\n | \"INPUT_UNAVAILABLE\"\n | \"INPUT_DECLINED\"\n\nexport interface ArgumentIssue {\n /** 점 구분 경로. \"\" = 입력 전체 */\n path: string\n code: string\n message: string\n}\n\nexport interface MextErrorDetails {\n UNKNOWN_COMMAND: {\n command: string\n /** 유사 정식 ID (가까운 순) */\n suggested: string[]\n /** 다음에 볼 help 대상. \"help\" (루트) · \"help users\" (네임스페이스) */\n usage: string\n }\n INVALID_ARGUMENT: {\n command: string\n /** 원본 입력에 없는 필수 필드 경로 */\n missing_fields: string[]\n issues: ArgumentIssue[]\n /** input JSON Schema 2020-12 */\n expected_schema: Record<string, unknown>\n examples: unknown[]\n }\n UNAUTHENTICATED: {\n reason: \"missing_token\" | \"invalid_token\"\n /** CLI 원격 실행: 토큰 발급 명령 (mext login --url <url>) */\n login?: string\n }\n PERMISSION_DENIED: {\n command: string\n /** anonymous = 인증 없는 주체의 readOnly 외 명령어 · read_only = readOnly 전용 호출 (split query) · scope = scopes 부족 */\n reason: \"anonymous\" | \"read_only\" | \"scope\"\n required_scopes: string[]\n held_scopes: string[]\n }\n /** ctx.ask 를 처리할 수 없는 실행 환경 (TTY 없는 CLI 등) */\n INPUT_UNAVAILABLE: {\n command: string\n }\n /** ctx.ask 거절 · 취소. confirm = requiresConfirmation 확인 거절 (실행 안 함), input = 입력 요청 거절 */\n INPUT_DECLINED: {\n command: string\n kind: \"confirm\" | \"input\"\n }\n}\n\n/** 구조화 오류. 어댑터는 code 로 분기하고 toJSON() 을 응답 본문으로 쓴다 */\nexport class MextError<C extends MextErrorCode = MextErrorCode> extends Error {\n readonly code: C\n readonly details: MextErrorDetails[C]\n\n constructor(code: C, message: string, details: MextErrorDetails[C]) {\n super(message)\n this.name = \"MextError\"\n this.code = code\n this.details = details\n }\n\n toJSON(): { code: C; message: string } & MextErrorDetails[C] {\n return { code: this.code, message: this.message, ...this.details }\n }\n}\n\nexport function isMextError<C extends MextErrorCode>(error: unknown, code?: C): error is MextError<C> {\n return error instanceof MextError && (code === undefined || error.code === code)\n}\n\n/** auth 단계에서 어댑터가 던지는 오류. anonymous 로 낮추지 않는다 */\nexport function unauthenticated(reason: MextErrorDetails[\"UNAUTHENTICATED\"][\"reason\"]): MextError<\"UNAUTHENTICATED\"> {\n const message = reason === \"missing_token\" ? \"Authentication required.\" : \"Invalid authentication token.\"\n return new MextError(\"UNAUTHENTICATED\", message, { reason })\n}\n\n/** ctx.ask 거절. AskHandler 가 input 요청 거절 · 취소에 던진다. invoke 는 requiresConfirmation 확인 거절에 던진다 */\nexport function inputDeclined(command: string, kind: \"confirm\" | \"input\"): MextError<\"INPUT_DECLINED\"> {\n const message =\n kind === \"confirm\" ? `${command} was not confirmed and did not run.` : `${command} requested input, but it was declined.`\n return new MextError(\"INPUT_DECLINED\", message, { command, kind })\n}\n"]}
|
package/dist/ids.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** 경로 세그먼트 · 별칭 규칙: kebab-case 만 */
|
|
2
|
+
export declare const SEGMENT_PATTERN: RegExp;
|
|
3
|
+
/** 루트에 둘 수 없는 세그먼트 (help 탐색 · CLI help 와 충돌) */
|
|
4
|
+
export declare const RESERVED_ROOT_SEGMENTS: readonly string[];
|
|
5
|
+
export declare function isSegment(value: string): boolean;
|
|
6
|
+
export declare function parentNamespace(id: string): string;
|
package/dist/ids.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** 경로 세그먼트 · 별칭 규칙: kebab-case 만 */
|
|
2
|
+
export const SEGMENT_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
3
|
+
/** 루트에 둘 수 없는 세그먼트 (help 탐색 · CLI help 와 충돌) */
|
|
4
|
+
export const RESERVED_ROOT_SEGMENTS = ["help"];
|
|
5
|
+
export function isSegment(value) {
|
|
6
|
+
return SEGMENT_PATTERN.test(value);
|
|
7
|
+
}
|
|
8
|
+
export function parentNamespace(id) {
|
|
9
|
+
const i = id.lastIndexOf(".");
|
|
10
|
+
return i === -1 ? "" : id.slice(0, i);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=ids.js.map
|