@obov/mext 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/dist/build-cli.d.ts +39 -0
  2. package/dist/build-cli.js +167 -0
  3. package/dist/build-cli.js.map +1 -0
  4. package/dist/build.d.ts +65 -0
  5. package/dist/build.js +252 -0
  6. package/dist/build.js.map +1 -0
  7. package/dist/cli/args.d.ts +107 -0
  8. package/dist/cli/args.js +621 -0
  9. package/dist/cli/args.js.map +1 -0
  10. package/dist/cli/bin.d.ts +2 -0
  11. package/dist/cli/bin.js +13 -0
  12. package/dist/cli/bin.js.map +1 -0
  13. package/dist/cli/build.d.ts +11 -0
  14. package/dist/cli/build.js +87 -0
  15. package/dist/cli/build.js.map +1 -0
  16. package/dist/cli/dev-lock.d.ts +23 -0
  17. package/dist/cli/dev-lock.js +68 -0
  18. package/dist/cli/dev-lock.js.map +1 -0
  19. package/dist/cli/dev-server.d.ts +20 -0
  20. package/dist/cli/dev-server.js +75 -0
  21. package/dist/cli/dev-server.js.map +1 -0
  22. package/dist/cli/dev.d.ts +21 -0
  23. package/dist/cli/dev.js +565 -0
  24. package/dist/cli/dev.js.map +1 -0
  25. package/dist/cli/help.d.ts +31 -0
  26. package/dist/cli/help.js +238 -0
  27. package/dist/cli/help.js.map +1 -0
  28. package/dist/cli/io.d.ts +26 -0
  29. package/dist/cli/io.js +74 -0
  30. package/dist/cli/io.js.map +1 -0
  31. package/dist/cli/login.d.ts +32 -0
  32. package/dist/cli/login.js +284 -0
  33. package/dist/cli/login.js.map +1 -0
  34. package/dist/cli/logout.d.ts +9 -0
  35. package/dist/cli/logout.js +105 -0
  36. package/dist/cli/logout.js.map +1 -0
  37. package/dist/cli/main.d.ts +19 -0
  38. package/dist/cli/main.js +77 -0
  39. package/dist/cli/main.js.map +1 -0
  40. package/dist/cli/mcp.d.ts +16 -0
  41. package/dist/cli/mcp.js +92 -0
  42. package/dist/cli/mcp.js.map +1 -0
  43. package/dist/cli/output.d.ts +78 -0
  44. package/dist/cli/output.js +229 -0
  45. package/dist/cli/output.js.map +1 -0
  46. package/dist/cli/remote.d.ts +17 -0
  47. package/dist/cli/remote.js +35 -0
  48. package/dist/cli/remote.js.map +1 -0
  49. package/dist/cli/run.d.ts +14 -0
  50. package/dist/cli/run.js +218 -0
  51. package/dist/cli/run.js.map +1 -0
  52. package/dist/cli/start.d.ts +8 -0
  53. package/dist/cli/start.js +37 -0
  54. package/dist/cli/start.js.map +1 -0
  55. package/dist/client/cache.d.ts +104 -0
  56. package/dist/client/cache.js +208 -0
  57. package/dist/client/cache.js.map +1 -0
  58. package/dist/client/main.d.ts +31 -0
  59. package/dist/client/main.js +101 -0
  60. package/dist/client/main.js.map +1 -0
  61. package/dist/client/manifest.d.ts +19 -0
  62. package/dist/client/manifest.js +68 -0
  63. package/dist/client/manifest.js.map +1 -0
  64. package/dist/client/runner.d.ts +52 -0
  65. package/dist/client/runner.js +563 -0
  66. package/dist/client/runner.js.map +1 -0
  67. package/dist/command.d.ts +75 -0
  68. package/dist/command.js +44 -0
  69. package/dist/command.js.map +1 -0
  70. package/dist/config.d.ts +111 -0
  71. package/dist/config.js +197 -0
  72. package/dist/config.js.map +1 -0
  73. package/dist/errors.d.ts +74 -0
  74. package/dist/errors.js +38 -0
  75. package/dist/errors.js.map +1 -0
  76. package/dist/ids.d.ts +6 -0
  77. package/dist/ids.js +12 -0
  78. package/dist/ids.js.map +1 -0
  79. package/dist/index.d.ts +46 -0
  80. package/dist/index.js +27 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/instrumentation.d.ts +97 -0
  83. package/dist/instrumentation.js +165 -0
  84. package/dist/instrumentation.js.map +1 -0
  85. package/dist/invoke.d.ts +64 -0
  86. package/dist/invoke.js +152 -0
  87. package/dist/invoke.js.map +1 -0
  88. package/dist/lookup.d.ts +9 -0
  89. package/dist/lookup.js +27 -0
  90. package/dist/lookup.js.map +1 -0
  91. package/dist/manifest.d.ts +68 -0
  92. package/dist/manifest.js +77 -0
  93. package/dist/manifest.js.map +1 -0
  94. package/dist/mcp/constants.d.ts +9 -0
  95. package/dist/mcp/constants.js +10 -0
  96. package/dist/mcp/constants.js.map +1 -0
  97. package/dist/mcp/dispatch.d.ts +66 -0
  98. package/dist/mcp/dispatch.js +249 -0
  99. package/dist/mcp/dispatch.js.map +1 -0
  100. package/dist/mcp/help.d.ts +57 -0
  101. package/dist/mcp/help.js +136 -0
  102. package/dist/mcp/help.js.map +1 -0
  103. package/dist/mcp/http.d.ts +96 -0
  104. package/dist/mcp/http.js +368 -0
  105. package/dist/mcp/http.js.map +1 -0
  106. package/dist/mcp/index.d.ts +15 -0
  107. package/dist/mcp/index.js +9 -0
  108. package/dist/mcp/index.js.map +1 -0
  109. package/dist/mcp/install.d.ts +17 -0
  110. package/dist/mcp/install.js +36 -0
  111. package/dist/mcp/install.js.map +1 -0
  112. package/dist/mcp/mrtr.d.ts +82 -0
  113. package/dist/mcp/mrtr.js +130 -0
  114. package/dist/mcp/mrtr.js.map +1 -0
  115. package/dist/mcp/server.d.ts +63 -0
  116. package/dist/mcp/server.js +210 -0
  117. package/dist/mcp/server.js.map +1 -0
  118. package/dist/mcp/stdio.d.ts +75 -0
  119. package/dist/mcp/stdio.js +222 -0
  120. package/dist/mcp/stdio.js.map +1 -0
  121. package/dist/principal.d.ts +16 -0
  122. package/dist/principal.js +24 -0
  123. package/dist/principal.js.map +1 -0
  124. package/dist/registry.d.ts +90 -0
  125. package/dist/registry.js +169 -0
  126. package/dist/registry.js.map +1 -0
  127. package/dist/remote/browser.d.ts +15 -0
  128. package/dist/remote/browser.js +47 -0
  129. package/dist/remote/browser.js.map +1 -0
  130. package/dist/remote/client.d.ts +113 -0
  131. package/dist/remote/client.js +312 -0
  132. package/dist/remote/client.js.map +1 -0
  133. package/dist/remote/credentials.d.ts +48 -0
  134. package/dist/remote/credentials.js +196 -0
  135. package/dist/remote/credentials.js.map +1 -0
  136. package/dist/remote/index.d.ts +8 -0
  137. package/dist/remote/index.js +5 -0
  138. package/dist/remote/index.js.map +1 -0
  139. package/dist/remote/oauth.d.ts +186 -0
  140. package/dist/remote/oauth.js +507 -0
  141. package/dist/remote/oauth.js.map +1 -0
  142. package/dist/scan.d.ts +34 -0
  143. package/dist/scan.js +155 -0
  144. package/dist/scan.js.map +1 -0
  145. package/dist/start.d.ts +63 -0
  146. package/dist/start.js +269 -0
  147. package/dist/start.js.map +1 -0
  148. package/dist/suggest.d.ts +7 -0
  149. package/dist/suggest.js +45 -0
  150. package/dist/suggest.js.map +1 -0
  151. package/dist/version.d.ts +4 -0
  152. package/dist/version.js +13 -0
  153. package/dist/version.js.map +1 -0
  154. package/package.json +49 -4
  155. package/README.md +0 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/client/cache.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomBytes } from \"node:crypto\"\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\"\nimport { join } from \"node:path\"\nimport { MextError, type MextErrorCode } from \"../errors.ts\"\nimport type { Help } from \"../mcp/help.ts\"\nimport { isRecord, RemoteTransportError, type RemoteTool } from \"../remote/client.ts\"\nimport { canonicalServerUrl, envPrefix } from \"../remote/credentials.ts\"\nimport { manifestHelp, type ClientManifest } from \"./manifest.ts\"\n\n/**\n * 원격 스키마 캐시 · drift 감지 (§5 스키마 drift). 고객 CLI · mext run --url 공용 (번들 포함, Node 내장만 import).\n *\n * D4. 파일 = <cache dir>/<sha256(정규화 서버 URL) 앞 16 hex>.json, 쓰기 = 같은 폴더 임시 파일 → rename (원자적).\n * cache dir = <BIN>_CACHE_DIR → $XDG_CACHE_HOME/<bin> → $HOME/.cache/<bin>. 셋 다 없음 = 캐시 없음.\n * 내용 = SchemaCacheEntry. url · client (bin · version · mext 버전) 가 다르면 무효, 수명 = tools/list ttlMs.\n *\n * 이번 실행의 help 출처 (mode):\n * cache 유효 캐시 (수명 안 · stale 아님). help = 캐시 → (해시 = 내장 manifest 면) 내장 manifest → 서버 (캐시에 추가)\n * embedded 번들 형태 · 유효 캐시 없음 · 서버가 내장 manifest 와 다르다는 기록 없음. help = 내장 manifest\n * server 그 외 (범용 · stale · 서버가 내장 manifest 와 다름). help = 서버 (tools/list + help), 캐시 새로 씀\n * tools/call 결과 _meta 의 manifestHash ≠ 이번 help 의 해시 = stale 표시 (이번 결과는 그대로, 다음 실행이 server).\n * 로컬 파싱 실패 = refetch() 로 server 전환 후 1회 재시도 (runner). 오프라인 = 남은 캐시 · 내장 manifest 로 help 만\n */\n\nexport const SCHEMA_CACHE_FORMAT = 1\n\n/** 캐시 무효화 단위. 하나라도 다르면 캐시 무시 */\nexport interface CacheClient {\n /** 실행 파일 이름 (clientInfo.name) */\n bin: string\n /** clientInfo.version (고객 CLI = cli.version, mext = mext 버전) */\n version: string\n /** 클라이언트 런타임의 @obov/mext 버전 (help 해석 코드) */\n mext: string\n}\n\n/** help 결과 또는 UNKNOWN_COMMAND (경로 해석이 가장 긴 접두부터 시도하므로 없는 대상도 기록) */\nexport type CachedHelp = { help: Help } | { error: Record<string, unknown> & { code: string; message: string } }\n\nexport interface SchemaCacheEntry {\n format: typeof SCHEMA_CACHE_FORMAT\n /** 정규화 서버 URL (파일 이름 해시 충돌 확인) */\n url: string\n client: CacheClient\n /** help · tools 가 속한 서버 manifestHash. 없음 = 서버가 보내지 않음 */\n manifestHash?: string\n /** tools/list 받은 시각 (epoch ms) */\n fetchedAt: number\n /** tools/list ttlMs. 0 = 매 실행 재조회 (오프라인 help 용으로만 남김) */\n ttlMs: number\n /** 서버 manifestHash 가 help 와 다름을 관찰. 다음 실행에서 서버 help 재조회 */\n stale?: true\n /** tools/list 결과 */\n tools: RemoteTool[]\n /** help 대상 (\"\" = 루트) → 결과 */\n help: Record<string, CachedHelp>\n}\n\n/** <BIN>_CACHE_DIR → $XDG_CACHE_HOME/<bin> → $HOME/.cache/<bin> (USERPROFILE). 없으면 undefined (캐시 없음) */\nexport function schemaCacheDir(bin: string, env: Record<string, string | undefined>): string | undefined {\n const forced = env[`${envPrefix(bin)}_CACHE_DIR`]\n if (forced) return forced\n if (env.XDG_CACHE_HOME) return join(env.XDG_CACHE_HOME, bin)\n const home = env.HOME || env.USERPROFILE\n return home ? join(home, \".cache\", bin) : undefined\n}\n\n/** <dir>/<sha256(canonicalServerUrl(url)) 앞 16 hex>.json */\nexport function schemaCacheFile(dir: string, url: string): string {\n return join(dir, `${createHash(\"sha256\").update(canonicalServerUrl(url)).digest(\"hex\").slice(0, 16)}.json`)\n}\n\n/** 읽기 + 형식 · url · client 확인. 없음 · 깨짐 · 불일치 = undefined */\nexport async function readSchemaCache(file: string, url: string, client: CacheClient): Promise<SchemaCacheEntry | undefined> {\n let value: unknown\n try {\n value = JSON.parse(await readFile(file, \"utf8\"))\n } catch {\n return undefined\n }\n if (!isRecord(value) || value.format !== SCHEMA_CACHE_FORMAT || value.url !== canonicalServerUrl(url)) return undefined\n const c = value.client\n if (!isRecord(c) || c.bin !== client.bin || c.version !== client.version || c.mext !== client.mext) return undefined\n if (typeof value.fetchedAt !== \"number\" || typeof value.ttlMs !== \"number\") return undefined\n if (!Array.isArray(value.tools) || !isRecord(value.help)) return undefined\n if (value.manifestHash !== undefined && typeof value.manifestHash !== \"string\") return undefined\n return value as unknown as SchemaCacheEntry\n}\n\n/** 원자적 쓰기 (임시 파일 → rename). 실패는 호출자가 무시 (캐시는 최선) */\nexport async function writeSchemaCache(file: string, entry: SchemaCacheEntry): Promise<void> {\n const dir = join(file, \"..\")\n await mkdir(dir, { recursive: true })\n const tmp = `${file}.${process.pid}.${randomBytes(4).toString(\"hex\")}.tmp`\n try {\n await writeFile(tmp, `${JSON.stringify(entry)}\\n`)\n await rename(tmp, file)\n } catch (error) {\n await rm(tmp, { force: true }).catch(() => {})\n throw error\n }\n}\n\nexport function isFresh(entry: SchemaCacheEntry, now: number): boolean {\n return entry.stale !== true && entry.ttlMs > 0 && now >= entry.fetchedAt && now < entry.fetchedAt + entry.ttlMs\n}\n\n/* 실행 하나의 스키마 상태 */\n\nexport type SchemaMode = \"cache\" | \"embedded\" | \"server\"\n\nexport interface FetchedHelp {\n value: CachedHelp\n /** 응답 _meta[\"dev.mext/manifestHash\"] */\n hash: string | undefined\n}\n\nexport interface SchemaOptions {\n /** 캐시 파일. undefined = 캐시 없음 (읽기 · 쓰기 안 함) */\n file: string | undefined\n url: string\n client: CacheClient\n /** 번들 형태의 내장 manifest + 빌드 시 manifestHash */\n embedded?: { manifest: ClientManifest; hash: string }\n /** 서버 help (tools/call help). UNKNOWN_COMMAND 는 value.error, 그 외 오류 = throw */\n fetchHelp(target: string, tools: () => Promise<RemoteTool[]>): Promise<FetchedHelp>\n /** 서버 tools/list */\n fetchTools(): Promise<{ tools: RemoteTool[]; ttlMs?: number }>\n /** 오프라인 help 안내 (stderr) */\n warn(message: string): void\n now?: () => number\n}\n\nexport interface Schema {\n readonly mode: SchemaMode\n /** HelpSource: 대상 → help. 없는 대상 = MextError UNKNOWN_COMMAND */\n help(target: string): Promise<Help>\n /** 로컬 (cache · embedded) 파싱 실패 후 서버 help 로 전환. 이미 server = false (재시도 안 함) */\n refetch(): boolean\n /** dispatcher 도구 목록 (유효 캐시 = 네트워크 없음) */\n tools(): Promise<RemoteTool[]>\n /** tools/call 결과 _meta 의 manifestHash 관찰. 이번 help 의 해시와 다르면 stale */\n observe(hash: string | undefined): void\n /** 바뀐 내용이 있으면 캐시 파일 쓰기 (실패 무시) */\n save(): Promise<void>\n}\n\nexport async function openSchema(options: SchemaOptions): Promise<Schema> {\n const clock = options.now ?? Date.now\n const started = clock()\n const { embedded } = options\n const previous = options.file ? await readSchemaCache(options.file, options.url, options.client) : undefined\n const diverged =\n previous !== undefined &&\n (previous.stale === true || (embedded !== undefined && previous.manifestHash !== undefined && previous.manifestHash !== embedded.hash))\n let mode: SchemaMode =\n previous !== undefined && isFresh(previous, started) ? \"cache\" : embedded && !diverged ? \"embedded\" : \"server\"\n const cached = mode === \"cache\" ? previous : undefined\n\n let hash = cached ? cached.manifestHash : mode === \"embedded\" ? embedded!.hash : undefined\n let help: Record<string, CachedHelp> = cached ? { ...cached.help } : {}\n let tools: RemoteTool[] | undefined = cached?.tools\n let fetchedAt = cached?.fetchedAt ?? started\n let ttlMs = cached?.ttlMs ?? 0\n let stale = false\n let dirty = false\n let refetched = false\n let warned = false\n let pendingTools: Promise<RemoteTool[]> | undefined\n\n const loadTools = (): Promise<RemoteTool[]> => {\n if (tools) return Promise.resolve(tools)\n return (pendingTools ??= options\n .fetchTools()\n .then((r) => {\n tools = r.tools\n ttlMs = r.ttlMs ?? 0\n fetchedAt = clock()\n dirty = true\n return r.tools\n })\n .finally(() => {\n pendingTools = undefined\n }))\n }\n\n const local = (target: string): Help | undefined => {\n const hit = help[target]\n if (hit) return unpack(hit)\n if (embedded && mode !== \"server\" && hash === embedded.hash) return manifestHelp(embedded.manifest, target)\n return undefined\n }\n\n return {\n get mode() {\n return mode\n },\n async help(target) {\n const found = local(target)\n if (found) return found\n let fetched: FetchedHelp\n try {\n fetched = await options.fetchHelp(target, loadTools)\n } catch (error) {\n // 오프라인: 남은 캐시 (수명 지남 · stale) → 내장 manifest. refetch 중이면 runner 가 원래 로컬 오류를 낸다\n if (error instanceof RemoteTransportError && !refetched) {\n const old = previous?.help[target]\n if (old || embedded) {\n if (!warned) options.warn(`warning: ${error.message} Showing ${old ? \"cached\" : \"built-in\"} help.\\n`)\n warned = true\n return old ? unpack(old) : manifestHelp(embedded!.manifest, target)\n }\n }\n throw error\n }\n if (fetched.hash !== undefined) {\n if (hash === undefined) hash = fetched.hash\n else if (fetched.hash !== hash) {\n if (mode === \"server\") {\n // 실행 중 서버 교체: 이전 응답 버림\n help = {}\n hash = fetched.hash\n } else stale = true\n }\n }\n help[target] = fetched.value\n dirty = true\n return unpack(fetched.value)\n },\n refetch() {\n if (mode === \"server\") return false\n mode = \"server\"\n refetched = true\n help = {}\n hash = undefined\n return true\n },\n tools: loadTools,\n observe(observed) {\n if (observed === undefined) return\n if (hash === undefined) {\n hash = observed\n dirty = true\n } else if (observed !== hash) {\n hash = observed\n stale = true\n dirty = true\n }\n },\n async save() {\n if (!options.file || !dirty || !tools) return\n const entry: SchemaCacheEntry = {\n format: SCHEMA_CACHE_FORMAT,\n url: canonicalServerUrl(options.url),\n client: options.client,\n ...(hash !== undefined ? { manifestHash: hash } : {}),\n fetchedAt,\n ttlMs,\n ...(stale ? { stale: true as const } : {}),\n tools,\n help,\n }\n await writeSchemaCache(options.file, entry).catch(() => {})\n },\n }\n}\n\nfunction unpack(cached: CachedHelp): Help {\n if (\"help\" in cached) return cached.help\n const { code, message, ...details } = cached.error\n throw new MextError(code as MextErrorCode, message, details as never)\n}\n"]}
@@ -0,0 +1,31 @@
1
+ import { type CliIo } from "../cli/io.ts";
2
+ import { type CliErrorFormatter } from "../cli/output.ts";
3
+ import type { ClientManifest } from "./manifest.ts";
4
+ /**
5
+ * 고객 CLI 런타임 (§5). mext build 가 이 모듈 + 설정 (CustomerCliConfig) 을 .mext/cli/bin.js 하나로 번들한다.
6
+ * 번들 · 범용 형태가 같은 코드: manifest 가 있으면 help · 플래그 파싱을 내장 manifest 로, 없으면 서버 help 로.
7
+ * 명령: <bin> help · <bin> <ns> <cmd> [flags] · login · logout · mcp install · --version. 원격 실행 = mext run --url 과 같은 runner
8
+ */
9
+ /** bin.js 에 인라인되는 설정 (mext build 가 생성) */
10
+ export interface CustomerCliConfig {
11
+ bin: string;
12
+ /** 빌드 설정의 서버 MCP 엔드포인트. 실행 시 <BIN>_URL 이 있으면 그 값 */
13
+ url: string;
14
+ /** --version · clientInfo.version */
15
+ version: string;
16
+ packageName: string;
17
+ /** 빌드한 @obov/mext 버전 */
18
+ mextVersion: string;
19
+ /** 빌드 시 manifestHash. 번들 형태 = 내장 manifest 의 해시 (서버 _meta["dev.mext/manifestHash"] 와 비교) */
20
+ manifestHash: string;
21
+ /** 번들 형태의 내장 manifest. 없음 = 범용 형태 */
22
+ manifest?: ClientManifest;
23
+ }
24
+ /** bin.js 에 번들되는 코드 (설정과 달리 JSON 이 아님) */
25
+ export interface CustomerCliHooks {
26
+ /** cli.errors 모듈의 default export */
27
+ formatError?: CliErrorFormatter;
28
+ }
29
+ export declare function runCustomerCli(config: CustomerCliConfig, argv: readonly string[], partialIo?: Partial<CliIo>, hooks?: CustomerCliHooks): Promise<number>;
30
+ /** 프로세스 진입점 (bin.js). 첫 SIGINT = 진행 중 요청 abort (exit 130), 두 번째 = 즉시 종료 */
31
+ export declare function main(config: CustomerCliConfig, hooks?: CustomerCliHooks): Promise<void>;
@@ -0,0 +1,101 @@
1
+ import { table } from "../cli/help.js";
2
+ import { resolveIo } from "../cli/io.js";
3
+ import { loginCommand } from "../cli/login.js";
4
+ import { logoutCommand } from "../cli/logout.js";
5
+ import { EXIT, formatJson } from "../cli/output.js";
6
+ import { mcpInstallText } from "../mcp/install.js";
7
+ import { envPrefix } from "../remote/credentials.js";
8
+ import { runRemote } from "./runner.js";
9
+ export async function runCustomerCli(config, argv, partialIo = {}, hooks = {}) {
10
+ const io = resolveIo(partialIo);
11
+ const { bin } = config;
12
+ const prefix = envPrefix(bin);
13
+ const url = io.env[`${prefix}_URL`] || config.url;
14
+ if (!/^https?:\/\//i.test(url)) {
15
+ io.stderr.write(`error: ${prefix}_URL must be an http(s) URL (got "${url}")\n`);
16
+ return EXIT.usage;
17
+ }
18
+ const [first, ...rest] = argv;
19
+ switch (first) {
20
+ case "--version":
21
+ case "-v":
22
+ io.stdout.write(`${config.version}\n`);
23
+ return EXIT.ok;
24
+ case "login":
25
+ return loginCommand({ bin, url })(rest, io);
26
+ case "logout":
27
+ return logoutCommand({ bin, url })(rest, io);
28
+ case "mcp":
29
+ return mcp(config, url, rest, io);
30
+ case "__mext_inspect":
31
+ // 숨김: 지원 · 디버깅용 내장 설정 (토큰 없음)
32
+ io.stdout.write(formatJson({
33
+ bin,
34
+ url,
35
+ version: config.version,
36
+ packageName: config.packageName,
37
+ mextVersion: config.mextVersion,
38
+ manifestHash: config.manifestHash,
39
+ form: config.manifest ? "bundled" : "universal",
40
+ }));
41
+ return EXIT.ok;
42
+ }
43
+ return runRemote({
44
+ bin,
45
+ url,
46
+ prog: bin,
47
+ login: `${bin} login`,
48
+ version: config.version,
49
+ ...(config.manifest ? { manifest: config.manifest, manifestHash: config.manifestHash } : {}),
50
+ rootHelpFooter: builtinHelp(config, url),
51
+ ...(hooks.formatError ? { formatError: hooks.formatError } : {}),
52
+ }, argv, io);
53
+ }
54
+ /** 프로세스 진입점 (bin.js). 첫 SIGINT = 진행 중 요청 abort (exit 130), 두 번째 = 즉시 종료 */
55
+ export async function main(config, hooks = {}) {
56
+ const controller = new AbortController();
57
+ process.on("SIGINT", () => {
58
+ if (controller.signal.aborted)
59
+ process.exit(130);
60
+ controller.abort();
61
+ });
62
+ const code = await runCustomerCli(config, process.argv.slice(2), { signal: controller.signal }, hooks);
63
+ process.stdout.write("", () => process.stderr.write("", () => process.exit(code)));
64
+ }
65
+ function mcp(config, url, argv, io) {
66
+ const [sub, ...rest] = argv;
67
+ const isHelp = (t) => t === "--help" || t === "-h";
68
+ const usage = `Usage:\n ${config.bin} mcp install Print MCP client registration commands (does not modify client config files)\n`;
69
+ if (sub !== undefined && (isHelp(sub) || (sub === "install" && rest.some(isHelp)))) {
70
+ io.stdout.write(usage);
71
+ return EXIT.ok;
72
+ }
73
+ if (sub === "install" && rest.length === 0) {
74
+ io.stdout.write(`${mcpInstallText({ name: config.bin, url, stdioCommand: false, auth: true })}\n`);
75
+ return EXIT.ok;
76
+ }
77
+ io.stderr.write(`error: ${sub === undefined ? "missing subcommand" : `unknown argument "${argv.join(" ")}"`}\n\n${usage}`);
78
+ return EXIT.usage;
79
+ }
80
+ /** 사람용 루트 help 뒤의 내장 명령 · 환경변수 */
81
+ function builtinHelp(config, url) {
82
+ const { bin } = config;
83
+ const prefix = envPrefix(bin);
84
+ return [
85
+ "CLI commands:",
86
+ ...table([
87
+ ["login", `Log in to ${url} (${bin} login --help)`],
88
+ ["logout", "Revoke and remove the stored token"],
89
+ ["mcp install", "Print MCP client registration commands"],
90
+ ["--version", "Print the version"],
91
+ ]).map((l) => ` ${l}`),
92
+ "",
93
+ "Environment:",
94
+ ...table([
95
+ [`${prefix}_TOKEN`, `API token (instead of ${bin} login)`],
96
+ [`${prefix}_URL`, `Server URL (default: ${config.url})`],
97
+ ]).map((l) => ` ${l}`),
98
+ "",
99
+ ].join("\n");
100
+ }
101
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/client/main.ts"],"names":[],"mappings":"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","sourcesContent":["import { table } from \"../cli/help.ts\"\nimport { resolveIo, type CliIo } from \"../cli/io.ts\"\nimport { loginCommand } from \"../cli/login.ts\"\nimport { logoutCommand } from \"../cli/logout.ts\"\nimport { EXIT, formatJson, type CliErrorFormatter } from \"../cli/output.ts\"\nimport { mcpInstallText } from \"../mcp/install.ts\"\nimport { envPrefix } from \"../remote/credentials.ts\"\nimport type { ClientManifest } from \"./manifest.ts\"\nimport { runRemote } from \"./runner.ts\"\n\n/**\n * 고객 CLI 런타임 (§5). mext build 가 이 모듈 + 설정 (CustomerCliConfig) 을 .mext/cli/bin.js 하나로 번들한다.\n * 번들 · 범용 형태가 같은 코드: manifest 가 있으면 help · 플래그 파싱을 내장 manifest 로, 없으면 서버 help 로.\n * 명령: <bin> help · <bin> <ns> <cmd> [flags] · login · logout · mcp install · --version. 원격 실행 = mext run --url 과 같은 runner\n */\n\n/** bin.js 에 인라인되는 설정 (mext build 가 생성) */\nexport interface CustomerCliConfig {\n bin: string\n /** 빌드 설정의 서버 MCP 엔드포인트. 실행 시 <BIN>_URL 이 있으면 그 값 */\n url: string\n /** --version · clientInfo.version */\n version: string\n packageName: string\n /** 빌드한 @obov/mext 버전 */\n mextVersion: string\n /** 빌드 시 manifestHash. 번들 형태 = 내장 manifest 의 해시 (서버 _meta[\"dev.mext/manifestHash\"] 와 비교) */\n manifestHash: string\n /** 번들 형태의 내장 manifest. 없음 = 범용 형태 */\n manifest?: ClientManifest\n}\n\n/** bin.js 에 번들되는 코드 (설정과 달리 JSON 이 아님) */\nexport interface CustomerCliHooks {\n /** cli.errors 모듈의 default export */\n formatError?: CliErrorFormatter\n}\n\nexport async function runCustomerCli(\n config: CustomerCliConfig,\n argv: readonly string[],\n partialIo: Partial<CliIo> = {},\n hooks: CustomerCliHooks = {},\n): Promise<number> {\n const io = resolveIo(partialIo)\n const { bin } = config\n const prefix = envPrefix(bin)\n const url = io.env[`${prefix}_URL`] || config.url\n if (!/^https?:\\/\\//i.test(url)) {\n io.stderr.write(`error: ${prefix}_URL must be an http(s) URL (got \"${url}\")\\n`)\n return EXIT.usage\n }\n const [first, ...rest] = argv\n switch (first) {\n case \"--version\":\n case \"-v\":\n io.stdout.write(`${config.version}\\n`)\n return EXIT.ok\n case \"login\":\n return loginCommand({ bin, url })(rest, io)\n case \"logout\":\n return logoutCommand({ bin, url })(rest, io)\n case \"mcp\":\n return mcp(config, url, rest, io)\n case \"__mext_inspect\":\n // 숨김: 지원 · 디버깅용 내장 설정 (토큰 없음)\n io.stdout.write(\n formatJson({\n bin,\n url,\n version: config.version,\n packageName: config.packageName,\n mextVersion: config.mextVersion,\n manifestHash: config.manifestHash,\n form: config.manifest ? \"bundled\" : \"universal\",\n }),\n )\n return EXIT.ok\n }\n return runRemote(\n {\n bin,\n url,\n prog: bin,\n login: `${bin} login`,\n version: config.version,\n ...(config.manifest ? { manifest: config.manifest, manifestHash: config.manifestHash } : {}),\n rootHelpFooter: builtinHelp(config, url),\n ...(hooks.formatError ? { formatError: hooks.formatError } : {}),\n },\n argv,\n io,\n )\n}\n\n/** 프로세스 진입점 (bin.js). 첫 SIGINT = 진행 중 요청 abort (exit 130), 두 번째 = 즉시 종료 */\nexport async function main(config: CustomerCliConfig, hooks: CustomerCliHooks = {}): Promise<void> {\n const controller = new AbortController()\n process.on(\"SIGINT\", () => {\n if (controller.signal.aborted) process.exit(130)\n controller.abort()\n })\n const code = await runCustomerCli(config, process.argv.slice(2), { signal: controller.signal }, hooks)\n process.stdout.write(\"\", () => process.stderr.write(\"\", () => process.exit(code)))\n}\n\nfunction mcp(config: CustomerCliConfig, url: string, argv: readonly string[], io: CliIo): number {\n const [sub, ...rest] = argv\n const isHelp = (t: string) => t === \"--help\" || t === \"-h\"\n const usage = `Usage:\\n ${config.bin} mcp install Print MCP client registration commands (does not modify client config files)\\n`\n if (sub !== undefined && (isHelp(sub) || (sub === \"install\" && rest.some(isHelp)))) {\n io.stdout.write(usage)\n return EXIT.ok\n }\n if (sub === \"install\" && rest.length === 0) {\n io.stdout.write(`${mcpInstallText({ name: config.bin, url, stdioCommand: false, auth: true })}\\n`)\n return EXIT.ok\n }\n io.stderr.write(`error: ${sub === undefined ? \"missing subcommand\" : `unknown argument \"${argv.join(\" \")}\"`}\\n\\n${usage}`)\n return EXIT.usage\n}\n\n/** 사람용 루트 help 뒤의 내장 명령 · 환경변수 */\nfunction builtinHelp(config: CustomerCliConfig, url: string): string {\n const { bin } = config\n const prefix = envPrefix(bin)\n return [\n \"CLI commands:\",\n ...table([\n [\"login\", `Log in to ${url} (${bin} login --help)`],\n [\"logout\", \"Revoke and remove the stored token\"],\n [\"mcp install\", \"Print MCP client registration commands\"],\n [\"--version\", \"Print the version\"],\n ]).map((l) => ` ${l}`),\n \"\",\n \"Environment:\",\n ...table([\n [`${prefix}_TOKEN`, `API token (instead of ${bin} login)`],\n [`${prefix}_URL`, `Server URL (default: ${config.url})`],\n ]).map((l) => ` ${l}`),\n \"\",\n ].join(\"\\n\")\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import type { Manifest, ManifestCommand, ManifestNamespace } from "../manifest.ts";
2
+ import type { Help } from "../mcp/help.ts";
3
+ /**
4
+ * 고객 CLI 번들 형태의 내장 manifest = 빌드 manifest 에서 서버 전용 항목 (file · module · 빌드 경로) 을 뺀 것.
5
+ * help 결과는 서버 help (mcp/help.ts help()) 와 같은 모양 (split 노출의 tool 필드 제외)
6
+ */
7
+ export type ClientManifestCommand = Omit<ManifestCommand, "file">;
8
+ export interface ClientManifest {
9
+ /** commands/_index.md */
10
+ description?: string;
11
+ /** 루트 제외, ID 순 */
12
+ namespaces: ManifestNamespace[];
13
+ /** ID 순 */
14
+ commands: ClientManifestCommand[];
15
+ }
16
+ /** 빌드 manifest → 내장 manifest (mext build 가 호출) */
17
+ export declare function clientManifest(manifest: Pick<Manifest, "description" | "namespaces" | "commands">): ClientManifest;
18
+ /** 내장 manifest 의 help (target "" = 루트 · 네임스페이스 · 명령어 ID · 별칭). 없는 target = UNKNOWN_COMMAND */
19
+ export declare function manifestHelp(manifest: ClientManifest, target: string): Help;
@@ -0,0 +1,68 @@
1
+ import { parentNamespace } from "../ids.js";
2
+ import { unknownCommand } from "../lookup.js";
3
+ /** 빌드 manifest → 내장 manifest (mext build 가 호출) */
4
+ export function clientManifest(manifest) {
5
+ const out = {
6
+ namespaces: manifest.namespaces.map((n) => ({ ...n })),
7
+ commands: manifest.commands.map((c) => {
8
+ const { file: _file, module: _module, ...rest } = c;
9
+ return rest;
10
+ }),
11
+ };
12
+ if (manifest.description !== undefined)
13
+ out.description = manifest.description;
14
+ return out;
15
+ }
16
+ /** 내장 manifest 의 help (target "" = 루트 · 네임스페이스 · 명령어 ID · 별칭). 없는 target = UNKNOWN_COMMAND */
17
+ export function manifestHelp(manifest, target) {
18
+ const id = target.trim();
19
+ const namespaces = new Map(manifest.namespaces.map((n) => [n.id, n]));
20
+ const children = (ns) => ({
21
+ namespaces: manifest.namespaces.filter((n) => parentNamespace(n.id) === ns).map(namespaceSummary),
22
+ commands: manifest.commands.filter((c) => parentNamespace(c.id) === ns).map(commandSummary),
23
+ });
24
+ // 키 순서 = 서버 help (--help --json 출력이 같은 텍스트)
25
+ if (id === "") {
26
+ const out = { kind: "root", ...children("") };
27
+ if (manifest.description !== undefined)
28
+ out.description = manifest.description;
29
+ return out;
30
+ }
31
+ const ns = namespaces.get(id);
32
+ if (ns) {
33
+ const out = { kind: "namespace", id, ...children(id) };
34
+ if (ns.description !== undefined)
35
+ out.description = ns.description;
36
+ const self = manifest.commands.find((c) => c.id === id);
37
+ if (self)
38
+ out.command = commandHelp(self);
39
+ return out;
40
+ }
41
+ const command = manifest.commands.find((c) => c.id === id) ?? manifest.commands.find((c) => c.aliases.includes(id));
42
+ if (command)
43
+ return commandHelp(command);
44
+ throw unknownCommand(id, manifest.commands.flatMap((c) => [[c.id, c.id], ...c.aliases.map((a) => [a, c.id])]), (n) => namespaces.has(n));
45
+ }
46
+ function namespaceSummary(ns) {
47
+ const first = ns.description?.split("\n").find((l) => l.trim() !== "");
48
+ return first === undefined ? { id: ns.id } : { id: ns.id, description: first.replace(/^#+\s*/, "").trim() };
49
+ }
50
+ function commandSummary(c) {
51
+ return {
52
+ id: c.id,
53
+ description: c.description,
54
+ readOnly: c.readOnly,
55
+ destructive: c.destructive,
56
+ requiresConfirmation: c.requiresConfirmation,
57
+ };
58
+ }
59
+ /** mcp/help.ts commandHelp 와 같은 errors 규칙 */
60
+ function commandHelp(c) {
61
+ const errors = ["INVALID_ARGUMENT"];
62
+ if (!c.readOnly || c.scopes.length > 0)
63
+ errors.push("UNAUTHENTICATED", "PERMISSION_DENIED");
64
+ if (c.requiresConfirmation)
65
+ errors.push("INPUT_UNAVAILABLE", "INPUT_DECLINED");
66
+ return { kind: "command", ...c, errors };
67
+ }
68
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/client/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { parentNamespace } from \"../ids.ts\"\nimport { unknownCommand } from \"../lookup.ts\"\nimport type { Manifest, ManifestCommand, ManifestNamespace } from \"../manifest.ts\"\nimport type { CommandHelp, Help, HelpCommandSummary, HelpNamespaceSummary, NamespaceHelp, RootHelp } from \"../mcp/help.ts\"\n\n/**\n * 고객 CLI 번들 형태의 내장 manifest = 빌드 manifest 에서 서버 전용 항목 (file · module · 빌드 경로) 을 뺀 것.\n * help 결과는 서버 help (mcp/help.ts help()) 와 같은 모양 (split 노출의 tool 필드 제외)\n */\n\nexport type ClientManifestCommand = Omit<ManifestCommand, \"file\">\n\nexport interface ClientManifest {\n /** commands/_index.md */\n description?: string\n /** 루트 제외, ID 순 */\n namespaces: ManifestNamespace[]\n /** ID 순 */\n commands: ClientManifestCommand[]\n}\n\n/** 빌드 manifest → 내장 manifest (mext build 가 호출) */\nexport function clientManifest(manifest: Pick<Manifest, \"description\" | \"namespaces\" | \"commands\">): ClientManifest {\n const out: ClientManifest = {\n namespaces: manifest.namespaces.map((n) => ({ ...n })),\n commands: manifest.commands.map((c) => {\n const { file: _file, module: _module, ...rest } = c as ManifestCommand & { module?: string }\n return rest\n }),\n }\n if (manifest.description !== undefined) out.description = manifest.description\n return out\n}\n\n/** 내장 manifest 의 help (target \"\" = 루트 · 네임스페이스 · 명령어 ID · 별칭). 없는 target = UNKNOWN_COMMAND */\nexport function manifestHelp(manifest: ClientManifest, target: string): Help {\n const id = target.trim()\n const namespaces = new Map(manifest.namespaces.map((n) => [n.id, n]))\n const children = (ns: string) => ({\n namespaces: manifest.namespaces.filter((n) => parentNamespace(n.id) === ns).map(namespaceSummary),\n commands: manifest.commands.filter((c) => parentNamespace(c.id) === ns).map(commandSummary),\n })\n // 키 순서 = 서버 help (--help --json 출력이 같은 텍스트)\n if (id === \"\") {\n const out: RootHelp = { kind: \"root\", ...children(\"\") }\n if (manifest.description !== undefined) out.description = manifest.description\n return out\n }\n const ns = namespaces.get(id)\n if (ns) {\n const out: NamespaceHelp = { kind: \"namespace\", id, ...children(id) }\n if (ns.description !== undefined) out.description = ns.description\n const self = manifest.commands.find((c) => c.id === id)\n if (self) out.command = commandHelp(self)\n return out\n }\n const command = manifest.commands.find((c) => c.id === id) ?? manifest.commands.find((c) => c.aliases.includes(id))\n if (command) return commandHelp(command)\n throw unknownCommand(\n id,\n manifest.commands.flatMap((c): [string, string][] => [[c.id, c.id], ...c.aliases.map((a): [string, string] => [a, c.id])]),\n (n) => namespaces.has(n),\n )\n}\n\nfunction namespaceSummary(ns: ManifestNamespace): HelpNamespaceSummary {\n const first = ns.description?.split(\"\\n\").find((l) => l.trim() !== \"\")\n return first === undefined ? { id: ns.id } : { id: ns.id, description: first.replace(/^#+\\s*/, \"\").trim() }\n}\n\nfunction commandSummary(c: ClientManifestCommand): HelpCommandSummary {\n return {\n id: c.id,\n description: c.description,\n readOnly: c.readOnly,\n destructive: c.destructive,\n requiresConfirmation: c.requiresConfirmation,\n }\n}\n\n/** mcp/help.ts commandHelp 와 같은 errors 규칙 */\nfunction commandHelp(c: ClientManifestCommand): CommandHelp {\n const errors = [\"INVALID_ARGUMENT\"]\n if (!c.readOnly || c.scopes.length > 0) errors.push(\"UNAUTHENTICATED\", \"PERMISSION_DENIED\")\n if (c.requiresConfirmation) errors.push(\"INPUT_UNAVAILABLE\", \"INPUT_DECLINED\")\n return { kind: \"command\", ...c, errors }\n}\n"]}
@@ -0,0 +1,52 @@
1
+ import type { CommandHelp, Help } from "../mcp/help.ts";
2
+ import type { RegisteredCommand } from "../registry.ts";
3
+ import { type CliIo } from "../cli/io.ts";
4
+ import { type CliErrorFormatter } from "../cli/output.ts";
5
+ import { type ClientManifest } from "./manifest.ts";
6
+ /**
7
+ * 원격 실행 공용 runner: mext run --url (bin = mext) 과 고객 CLI (bin = cli.bin) 가 같은 코드 경로.
8
+ * 서버 MCP 엔드포인트의 dispatcher 도구 (execute · split 의 query · mutate) 호출. 권한 검사는 서버만.
9
+ * 경로 해석 · help · 플래그 파싱 = HelpSource (캐시 · 내장 manifest · 서버 help, client/cache.ts) 의 입력 스키마 (JSON Schema).
10
+ * 로컬 파싱 실패 (UNKNOWN_COMMAND · INVALID_ARGUMENT) = 서버 help 로 1회 재시도. tools/call 결과의 manifestHash 로 drift 감지.
11
+ * 토큰 = <BIN>_TOKEN, 없으면 저장된 토큰 (<bin> login). 출력 · exit code 는 로컬 모드와 같다.
12
+ *
13
+ * 이 모듈 (와 import 대상) 은 고객 CLI 번들에 들어간다: Zod · MCP 서버 SDK · 핸들러 · 스캔 · 빌드 코드 import 금지.
14
+ */
15
+ export interface RemoteRunOptions {
16
+ /** 실행 파일 이름. 토큰 환경변수 (<BIN>_TOKEN) · 자격 증명 위치 (credentialStore bin) · clientInfo.name */
17
+ bin: string;
18
+ /** MCP 엔드포인트 */
19
+ url: string;
20
+ /** help · 오류 안내의 명령 접두. "mext run --url <url>" · "myapp" */
21
+ prog: string;
22
+ /** login 안내 명령. "mext login --url <url>" · "myapp login" */
23
+ login: string;
24
+ /** clientInfo.version */
25
+ version: string;
26
+ /**
27
+ * 번들 형태: 내장 manifest 로 help · 경로 해석 · 플래그 파싱 (help 에 네트워크 없음, 명령어 실행만 tools/list · tools/call).
28
+ * 없음 = 범용 형태: 서버 help 조회
29
+ */
30
+ manifest?: ClientManifest;
31
+ /** 내장 manifest 의 manifestHash (빌드 시). manifest 와 같이 지정 */
32
+ manifestHash?: string;
33
+ /** 사람용 루트 help 뒤에 붙일 텍스트 (고객 CLI 의 login · logout · mcp install 목록) */
34
+ rootHelpFooter?: string;
35
+ /** 오류 출력 · exit code 커스텀 (cli.errors). 없음 = mext 기본 */
36
+ formatError?: CliErrorFormatter;
37
+ }
38
+ /** help 출처. 서버 (tools/list → dispatcher help 호출) · 내장 manifest · 스키마 캐시 (client/cache.ts Schema) */
39
+ export interface HelpSource {
40
+ /** 대상 ("" = 루트) → help. 없는 대상 = MextError UNKNOWN_COMMAND */
41
+ help(target: string): Promise<Help>;
42
+ }
43
+ export declare function runRemote(options: RemoteRunOptions, argv: readonly string[], io: CliIo): Promise<number>;
44
+ /** 번들 형태: 내장 manifest (네트워크 없음) */
45
+ export declare function manifestHelpSource(manifest: ClientManifest): HelpSource;
46
+ /** 원격 명령어 help → RegisteredCommand (CLI 필드 = inputSchema 분석) */
47
+ export declare function entryFromHelp(help: CommandHelp): RegisteredCommand;
48
+ /** 서버 핸들러 예외 등 mext 구조화 오류 외의 도구 오류. --json = 서버 오류 본문 그대로, exit 1 */
49
+ export declare class RemoteExecutionError extends Error {
50
+ readonly body: Record<string, unknown>;
51
+ constructor(body: Record<string, unknown>);
52
+ }