@obov/mext 0.4.0 → 0.6.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/approval.d.ts +33 -0
- package/dist/approval.js +36 -0
- package/dist/approval.js.map +1 -0
- package/dist/audit.d.ts +123 -0
- package/dist/audit.js +221 -0
- package/dist/audit.js.map +1 -0
- package/dist/build-cli.d.ts +1 -0
- package/dist/build-cli.js +2 -1
- package/dist/build-cli.js.map +1 -1
- package/dist/build.d.ts +2 -0
- package/dist/build.js +30 -3
- package/dist/build.js.map +1 -1
- package/dist/caller.d.ts +53 -0
- package/dist/caller.js +51 -0
- package/dist/caller.js.map +1 -0
- package/dist/cli/build.js +6 -3
- package/dist/cli/build.js.map +1 -1
- package/dist/cli/dev-audit.d.ts +25 -0
- package/dist/cli/dev-audit.js +84 -0
- package/dist/cli/dev-audit.js.map +1 -0
- package/dist/cli/dev-lock.d.ts +3 -1
- package/dist/cli/dev-lock.js +12 -5
- package/dist/cli/dev-lock.js.map +1 -1
- package/dist/cli/dev-server.d.ts +9 -0
- package/dist/cli/dev-server.js +24 -1
- package/dist/cli/dev-server.js.map +1 -1
- package/dist/cli/dev-tap.d.ts +20 -0
- package/dist/cli/dev-tap.js +70 -0
- package/dist/cli/dev-tap.js.map +1 -0
- package/dist/cli/dev.js +16 -4
- package/dist/cli/dev.js.map +1 -1
- package/dist/cli/help.js +2 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/inspect.d.ts +7 -0
- package/dist/cli/inspect.js +699 -0
- package/dist/cli/inspect.js.map +1 -0
- package/dist/cli/main.js +8 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/output.d.ts +1 -1
- package/dist/cli/output.js +3 -2
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/run.js +28 -4
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/types.d.ts +9 -0
- package/dist/cli/types.js +77 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/client/index.d.ts +10 -0
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/manifest.js +6 -2
- package/dist/client/manifest.js.map +1 -1
- package/dist/client/runner.js +37 -3
- package/dist/client/runner.js.map +1 -1
- package/dist/client/typed.d.ts +54 -0
- package/dist/client/typed.js +490 -0
- package/dist/client/typed.js.map +1 -0
- package/dist/client/types.d.ts +196 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/command.d.ts +61 -5
- package/dist/command.js +42 -1
- package/dist/command.js.map +1 -1
- package/dist/config.d.ts +42 -10
- package/dist/config.js +32 -7
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +21 -3
- package/dist/errors.js +13 -0
- package/dist/errors.js.map +1 -1
- package/dist/expose.d.ts +9 -0
- package/dist/expose.js +52 -0
- package/dist/expose.js.map +1 -0
- package/dist/index.d.ts +15 -6
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/inspect/agent.d.ts +104 -0
- package/dist/inspect/agent.js +125 -0
- package/dist/inspect/agent.js.map +1 -0
- package/dist/inspect/audit.d.ts +46 -0
- package/dist/inspect/audit.js +133 -0
- package/dist/inspect/audit.js.map +1 -0
- package/dist/inspect/compare.d.ts +12 -0
- package/dist/inspect/compare.js +31 -0
- package/dist/inspect/compare.js.map +1 -0
- package/dist/inspect/index.d.ts +17 -0
- package/dist/inspect/index.js +12 -0
- package/dist/inspect/index.js.map +1 -0
- package/dist/inspect/inspector.d.ts +168 -0
- package/dist/inspect/inspector.js +392 -0
- package/dist/inspect/inspector.js.map +1 -0
- package/dist/inspect/profiles.d.ts +95 -0
- package/dist/inspect/profiles.js +235 -0
- package/dist/inspect/profiles.js.map +1 -0
- package/dist/inspect/scenario.d.ts +126 -0
- package/dist/inspect/scenario.js +555 -0
- package/dist/inspect/scenario.js.map +1 -0
- package/dist/inspect/ui-server.d.ts +31 -0
- package/dist/inspect/ui-server.js +378 -0
- package/dist/inspect/ui-server.js.map +1 -0
- package/dist/inspect/ui.html +917 -0
- package/dist/instrumentation.d.ts +13 -2
- package/dist/instrumentation.js +11 -1
- package/dist/instrumentation.js.map +1 -1
- package/dist/invoke.d.ts +32 -5
- package/dist/invoke.js +150 -16
- package/dist/invoke.js.map +1 -1
- package/dist/manifest.d.ts +13 -2
- package/dist/manifest.js +5 -1
- package/dist/manifest.js.map +1 -1
- package/dist/mcp/constants.d.ts +5 -0
- package/dist/mcp/constants.js +5 -0
- package/dist/mcp/constants.js.map +1 -1
- package/dist/mcp/dispatch.d.ts +1 -1
- package/dist/mcp/dispatch.js +14 -3
- package/dist/mcp/dispatch.js.map +1 -1
- package/dist/mcp/help.d.ts +2 -0
- package/dist/mcp/help.js +6 -1
- package/dist/mcp/help.js.map +1 -1
- package/dist/mcp/http.d.ts +16 -2
- package/dist/mcp/http.js +76 -7
- package/dist/mcp/http.js.map +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/install.d.ts +1 -1
- package/dist/mcp/install.js +3 -2
- package/dist/mcp/install.js.map +1 -1
- package/dist/mcp/server.d.ts +12 -1
- package/dist/mcp/server.js +63 -17
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/stdio.d.ts +4 -0
- package/dist/mcp/stdio.js +28 -0
- package/dist/mcp/stdio.js.map +1 -1
- package/dist/mcp/tasks.d.ts +3 -1
- package/dist/mcp/tasks.js +6 -3
- package/dist/mcp/tasks.js.map +1 -1
- package/dist/principal.d.ts +22 -0
- package/dist/principal.js +29 -0
- package/dist/principal.js.map +1 -1
- package/dist/registry.d.ts +5 -0
- package/dist/registry.js +21 -0
- package/dist/registry.js.map +1 -1
- package/dist/remote/client.d.ts +2 -0
- package/dist/remote/client.js +3 -2
- package/dist/remote/client.js.map +1 -1
- package/dist/remote/oauth.d.ts +1 -1
- package/dist/remote/oauth.js +1 -1
- package/dist/remote/oauth.js.map +1 -1
- package/dist/runtime.d.ts +10 -0
- package/dist/runtime.js +11 -0
- package/dist/runtime.js.map +1 -0
- package/dist/start.js +6 -2
- package/dist/start.js.map +1 -1
- package/dist/suggest.js +1 -1
- package/dist/suggest.js.map +1 -1
- package/dist/typegen.d.ts +27 -0
- package/dist/typegen.js +62 -0
- package/dist/typegen.js.map +1 -0
- package/dist/version-constant.d.ts +5 -0
- package/dist/version-constant.js +6 -0
- package/dist/version-constant.js.map +1 -0
- package/dist/version.d.ts +1 -2
- package/dist/version.js +1 -2
- package/dist/version.js.map +1 -1
- package/package.json +14 -3
package/dist/mcp/tasks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/mcp/tasks.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\"\nimport { ProtocolError, ProtocolErrorCode, type McpServer } from \"@modelcontextprotocol/server\"\nimport * as z from \"zod\"\nimport type { ProgressUpdate } from \"../command.ts\"\nimport type { AskHandler, DetachedExecution } from \"../invoke.ts\"\nimport type { Principal } from \"../principal.ts\"\nimport type { RegisteredCommand, Registry } from \"../registry.ts\"\nimport { STATE_KEY_PREFIX, type MextState } from \"../state.ts\"\nimport { errorResult, valueResult, type ToolCallResult } from \"./dispatch.ts\"\nimport {\n ASK_KEY_PREFIX,\n askAnswer,\n elicitation,\n elicitResult,\n modeUnavailable,\n type ElicitationModes,\n type ElicitationRequest,\n type ElicitResultValue,\n} from \"./mrtr.ts\"\n\n/**\n * MCP tasks 확장 (io.modelcontextprotocol/tasks, §12.6). 서버 측: task 생성 (invoke detach) · tasks/get · update · cancel.\n *\n * D5: SDK 2.4.0 은 tasks 런타임이 없다 (task 메서드 = 2025-11-25 어휘, typed API 미제공). 단 3-arg setRequestHandler\n * (custom params schema) 로 tasks/get · update · cancel 을 등록할 수 있고 (era gate 통과), Mcp-Name = params.taskId 헤더 검증은\n * SDK 가 한다. tools/call 결과 resultType \"task\" 는 SDK 가 그대로 통과시킨다. 그래서 mext 가 이 파일에서 직접 구현한다.\n *\n * D2: store 키 (값 = JSON, 접두 \"mext:\", 키마다 writer 하나)\n * mext:task:<taskId> TaskRecord. writer = 실행 프로세스 (생성 · 상태 · heartbeat · 결과)\n * mext:task:<taskId>:input:<ask-N> 답 (ElicitResult). writer = tasks/update 를 받은 프로세스. 이미 있으면 무시\n * mext:task:<taskId>:cancel 취소 기록 ({}). writer = tasks/cancel 을 받은 프로세스\n * bus 채널 mext:task:<taskId> = 답 · 취소 도착 알림 ({\"type\":\"input\"|\"cancel\"}). 내용은 store 가 원본, 메시지는 깨우기만.\n * bus 없음 = 실행 프로세스가 storePollMs (1초) 마다 store 폴링. 같은 프로세스의 task = 직접 깨움.\n * store ttl: 실행 중 = ttlMs + lostAfterMs (heartbeat 마다 연장, 유실 후 failed 를 ttlMs 동안 조회), 종료 = ttlMs.\n *\n * R4: ctx.ask 의미 차이. MRTR (동기) = 라운드마다 핸들러 재실행 (ask 이전 코드 반복), task = 재실행 없이 대기\n * (ask 이전 코드 1회). 키 (ask-0 · ask-1 …) · elicitation 형식 · 답 해석 (askAnswer) · 미선언 mode = INPUT_UNAVAILABLE 은 같다.\n * 두 경로 모두에서 맞게 동작하려면 MRTR 규칙 (부작용은 ask 뒤) 을 따른다.\n */\n\nexport const TASKS_EXTENSION = \"io.modelcontextprotocol/tasks\"\n\nexport interface TaskTiming {\n /** CreateTaskResult · tasks/get 의 pollIntervalMs (클라이언트 폴링 권장 간격) */\n pollIntervalMs: number\n /** 실행 프로세스의 heartbeat (레코드 갱신) 간격 */\n heartbeatMs: number\n /** heartbeat 이 이보다 오래 없으면 tasks/get = failed (TASK_LOST) */\n lostAfterMs: number\n /** bus 없음: 실행 프로세스의 답 · 취소 store 폴링 간격 */\n storePollMs: number\n /** close (SIGTERM · SIGINT) 시 실행 중 task 정리 상한 */\n shutdownMs: number\n}\n\nexport const TASK_TIMING: Readonly<TaskTiming> = Object.freeze({\n pollIntervalMs: 2_000,\n heartbeatMs: 10_000,\n lostAfterMs: 30_000,\n storePollMs: 1_000,\n shutdownMs: 5_000,\n})\n\n/** tasks/get failed 의 error.data.code (실행 프로세스 유실) */\nexport const TASK_LOST = \"TASK_LOST\"\n\nexport type TaskStatus = \"working\" | \"input_required\" | \"completed\" | \"failed\" | \"cancelled\"\n\n/** tools/call 의 task 응답 (resultType \"task\") */\nexport interface CreateTaskResult {\n resultType: \"task\"\n taskId: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n pollIntervalMs: number\n _meta?: Record<string, unknown>\n}\n\n/** tasks/get 결과 (resultType 은 SDK 가 \"complete\" 로 채운다) */\nexport interface TaskView {\n taskId: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n pollIntervalMs: number\n /** input_required */\n inputRequests?: Record<string, ElicitationRequest>\n /** completed = 같은 요청의 동기 tools/call 결과 */\n result?: TaskResult\n /** failed (TASK_LOST) */\n error?: TaskError\n}\n\ntype TaskResult = ToolCallResult & { resultType: \"complete\"; _meta?: Record<string, unknown> }\n\ninterface TaskError {\n code: number\n message: string\n data?: Record<string, unknown>\n}\n\n/** D2: mext:task:<taskId> 의 값 */\ninterface TaskRecord {\n v: 1\n taskId: string\n /** 바인딩 \"<kind>:<id>\". 다른 주체 = 없는 task */\n principal: string\n command: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n /** epoch ms. heartbeatMs 마다 갱신 */\n heartbeatAt: number\n inputRequests?: Record<string, ElicitationRequest>\n result?: TaskResult\n}\n\nexport interface TaskRuntimeOptions {\n state: MextState\n timing?: Partial<TaskTiming>\n /** 완료 결과 _meta (동기 결과와 같은 manifestHash) */\n meta?: Record<string, unknown>\n /** store · bus 예외 보고. 기본 stderr 1줄 */\n onerror?: (error: unknown) => void\n}\n\n/** 요청 하나의 task 조건 */\nexport interface TaskRequestOptions {\n principal: Principal\n /** 생성 요청이 선언한 elicitation mode (ctx.ask 가능 여부, MRTR 과 같은 규칙) */\n modes: ElicitationModes\n /** handler.js: 응답 후 실행 유지 (플랫폼 waitUntil) */\n waitUntil?: (promise: Promise<unknown>) => void\n}\n\nexport interface TaskRequest {\n /** invoke 의 detach. task 명령어가 아니면 undefined (동기) */\n detach(entry: RegisteredCommand): Promise<DetachedExecution | undefined>\n /** 생성 중 store · bus 예외 (있으면 요청 = -32603) */\n readonly failure: unknown\n}\n\nexport interface TaskRuntime {\n readonly timing: TaskTiming\n request(options: TaskRequestOptions): TaskRequest\n get(taskId: string, principal: Principal): Promise<TaskView>\n update(taskId: string, principal: Principal, inputResponses: Record<string, unknown>): Promise<void>\n cancel(taskId: string, principal: Principal): Promise<void>\n /** 실행 중 task 취소 → cancelled 기록 (상한 shutdownMs). 이후 새 task 없음 (동기 실행) */\n close(): Promise<void>\n}\n\n/** registry 에 task 명령어가 있는지 (선언 조건) */\nexport function hasTaskCommands(registry: Registry): boolean {\n for (const entry of registry.commands.values()) if (entry.command.task) return true\n return false\n}\n\n/** 요청 _meta 의 clientCapabilities 에 tasks 확장 선언 */\nexport function declaresTasks(clientCapabilities: unknown): boolean {\n const extensions = (clientCapabilities as { extensions?: unknown } | undefined)?.extensions\n return isPlainObject(extensions) && extensions[TASKS_EXTENSION] !== undefined\n}\n\n/**\n * HTTP: task 가 될 수 있는 tools/call 인지 (응답 = application/json, §12.6). 확장 선언 + 대상 명령어가 task 명령어.\n * 대상 = dispatcher 의 arguments.command (별칭 포함), 그 외 = 도구 이름 (command 노출)\n */\nexport function requestsTask(registry: Registry, body: unknown): boolean {\n if (!isPlainObject(body) || body.method !== \"tools/call\" || !isPlainObject(body.params)) return false\n const params = body.params\n const meta = isPlainObject(params._meta) ? params._meta : undefined\n if (!declaresTasks(meta?.[\"io.modelcontextprotocol/clientCapabilities\"])) return false\n const args = isPlainObject(params.arguments) ? params.arguments : undefined\n const target = typeof args?.command === \"string\" ? args.command : params.name\n if (typeof target !== \"string\") return false\n const id = registry.commands.has(target) ? target : registry.aliases.get(target)\n return id !== undefined && registry.commands.get(id)?.command.task !== undefined\n}\n\nconst recordKey = (taskId: string): string => `${STATE_KEY_PREFIX}task:${taskId}`\nconst inputKey = (taskId: string, key: string): string => `${recordKey(taskId)}:input:${key}`\nconst cancelKey = (taskId: string): string => `${recordKey(taskId)}:cancel`\nconst taskChannel = (taskId: string): string => `${STATE_KEY_PREFIX}task:${taskId}`\n\nconst TERMINAL: ReadonlySet<TaskStatus> = new Set([\"completed\", \"failed\", \"cancelled\"])\n\n/** 같은 프로세스에서 실행 중인 task */\ninterface RunningTask {\n /** 답 · 취소를 store 에서 다시 읽는다 */\n wake(): Promise<void>\n abort(reason: unknown): void\n /** 종료 기록 완료 */\n done: Promise<void>\n /** 아직 끝나지 않았으면 cancelled 기록 (종료 상한) */\n forceCancel(): Promise<void>\n}\n\nexport function createTaskRuntime(options: TaskRuntimeOptions): TaskRuntime {\n const { store, bus } = options.state\n const timing: TaskTiming = { ...TASK_TIMING, ...options.timing }\n const meta = options.meta ?? {}\n const report = options.onerror ?? defaultOnError\n const running = new Map<string, RunningTask>()\n let closed = false\n\n /** store · bus 호출. 예외 = 보고 + -32603 */\n const storeCall = async <T>(fn: () => Promise<T>): Promise<T> => {\n try {\n return await fn()\n } catch (error) {\n safeReport(report, error)\n throw new ProtocolError(ProtocolErrorCode.InternalError, \"State store error\")\n }\n }\n\n const readRecord = async (taskId: string, principal: Principal): Promise<TaskRecord> => {\n const raw = await storeCall(() => store.get(recordKey(taskId)))\n const record = raw === undefined ? undefined : parseRecord(raw)\n if (!record || record.taskId !== taskId || record.principal !== bindingOf(principal)) throw unknownTask(taskId)\n return record\n }\n\n const lost = (record: TaskRecord): boolean =>\n !TERMINAL.has(record.status) && Date.now() - record.heartbeatAt > timing.lostAfterMs\n\n /** 답 · 취소 도착 알림: 같은 프로세스 = 직접, 그 외 = bus (없으면 실행 프로세스가 폴링) */\n const notify = async (taskId: string, type: \"input\" | \"cancel\"): Promise<void> => {\n const local = running.get(taskId)\n if (local) return void (await local.wake())\n if (bus) await storeCall(() => bus.publish(taskChannel(taskId), JSON.stringify({ type })))\n }\n\n const start = async (entry: RegisteredCommand, request: TaskRequestOptions): Promise<DetachedExecution> => {\n const taskId = randomBytes(16).toString(\"base64url\")\n const created = new Date().toISOString()\n const record: TaskRecord = {\n v: 1,\n taskId,\n principal: bindingOf(request.principal),\n command: entry.id,\n status: \"working\",\n createdAt: created,\n lastUpdatedAt: created,\n ttlMs: entry.command.task!.ttlMs,\n heartbeatAt: Date.now(),\n }\n const controller = new AbortController()\n const waiters = new Map<string, (answer: ElicitResultValue) => void>()\n let finalized = false\n let resolveDone!: () => void\n const done = new Promise<void>((resolve) => (resolveDone = resolve))\n const touch = (): void => void (record.lastUpdatedAt = new Date().toISOString())\n\n // 순서 보장 · 합치기: 쓰는 중 변경 = 끝난 뒤 최신 상태로 한 번 더\n let writing: Promise<void> | undefined\n let dirty = false\n const persist = (): Promise<void> => {\n dirty = true\n writing ??= (async () => {\n try {\n while (dirty) {\n dirty = false\n const ttlMs = TERMINAL.has(record.status) ? record.ttlMs : record.ttlMs + timing.lostAfterMs\n await store.set(recordKey(taskId), JSON.stringify(record), { ttlMs })\n }\n } finally {\n writing = undefined\n }\n })()\n return writing\n }\n const persistLater = (): void => void persist().catch((error: unknown) => safeReport(report, error))\n\n const wake = async (): Promise<void> => {\n try {\n if (!controller.signal.aborted && (await store.get(cancelKey(taskId))) !== undefined) {\n controller.abort(new DOMException(\"Task cancelled\", \"AbortError\"))\n }\n for (const [key, resolve] of [...waiters]) {\n const raw = await store.get(inputKey(taskId, key))\n const answer = raw === undefined ? undefined : elicitResult(parseJson(raw))\n if (answer) resolve(answer)\n }\n } catch (error) {\n safeReport(report, error)\n }\n }\n\n let heartbeat: ReturnType<typeof setInterval> | undefined\n let poll: ReturnType<typeof setInterval> | undefined\n let unsubscribe: (() => Promise<void>) | undefined\n const stopTimers = (): void => {\n if (heartbeat !== undefined) clearInterval(heartbeat)\n if (poll !== undefined) clearInterval(poll)\n }\n\n const finish = async (): Promise<void> => {\n if (finalized) return\n finalized = true\n stopTimers()\n delete record.inputRequests\n touch()\n waiters.clear()\n try {\n await persist()\n } catch (error) {\n safeReport(report, error)\n }\n running.delete(taskId)\n try {\n await unsubscribe?.()\n } catch (error) {\n safeReport(report, error)\n }\n resolveDone()\n }\n\n let index = 0\n const ask: AskHandler = async (askRequest) => {\n const key = `${ASK_KEY_PREFIX}${index++}`\n if (!(askRequest.kind === \"url\" ? request.modes.url : request.modes.form)) throw modeUnavailable(askRequest)\n controller.signal.throwIfAborted()\n let onAbort!: () => void\n const answered = new Promise<ElicitResultValue>((resolve, reject) => {\n onAbort = () => {\n waiters.delete(key)\n reject(controller.signal.reason)\n }\n controller.signal.addEventListener(\"abort\", onAbort, { once: true })\n waiters.set(key, (answer) => {\n waiters.delete(key)\n controller.signal.removeEventListener(\"abort\", onAbort)\n resolve(answer)\n })\n })\n answered.catch(() => {})\n record.inputRequests = { ...record.inputRequests, [key]: elicitation(askRequest) }\n record.status = \"input_required\"\n touch()\n try {\n await persist()\n } catch (error) {\n waiters.delete(key)\n controller.signal.removeEventListener(\"abort\", onAbort)\n throw error\n }\n const response = await answered\n if (record.inputRequests) {\n delete record.inputRequests[key]\n if (Object.keys(record.inputRequests).length === 0) delete record.inputRequests\n }\n if (!record.inputRequests && !finalized) record.status = \"working\"\n touch()\n if (!finalized) persistLater()\n return askAnswer(askRequest, response)\n }\n\n const progress = (update: ProgressUpdate): void => {\n if (finalized) return\n record.statusMessage =\n update.message ?? (update.total !== undefined ? `${update.progress}/${update.total}` : String(update.progress))\n touch()\n persistLater()\n }\n\n const task: RunningTask = {\n wake,\n abort: (reason) => controller.abort(reason),\n done,\n async forceCancel() {\n if (finalized) return\n record.status = \"cancelled\"\n await finish()\n },\n }\n running.set(taskId, task)\n try {\n if (bus) unsubscribe = await bus.subscribe(taskChannel(taskId), () => void wake())\n // store 기록 후 응답 (tasks/get 이 바로 성공해야 한다)\n await persist()\n } catch (error) {\n running.delete(taskId)\n await unsubscribe?.().catch(() => {})\n throw error\n }\n heartbeat = setInterval(() => {\n record.heartbeatAt = Date.now()\n persistLater()\n }, timing.heartbeatMs)\n heartbeat.unref?.()\n if (!bus) {\n poll = setInterval(() => void wake(), timing.storePollMs)\n poll.unref?.()\n }\n request.waitUntil?.(done)\n\n const handle: CreateTaskResult = {\n resultType: \"task\",\n taskId,\n status: \"working\",\n createdAt: record.createdAt,\n lastUpdatedAt: record.lastUpdatedAt,\n ttlMs: record.ttlMs,\n pollIntervalMs: timing.pollIntervalMs,\n }\n return {\n handle,\n signal: controller.signal,\n ask,\n progress,\n async settle(outcome) {\n if (finalized) return\n if (\"error\" in outcome && controller.signal.aborted) {\n // 취소 후 예외 = cancelled. 핸들러가 끝까지 가면 (값 반환) 그 결과\n record.status = \"cancelled\"\n } else {\n record.status = \"completed\"\n const result = \"error\" in outcome ? errorResult(outcome.error) : valueResult(outcome.value)\n record.result = { ...result, resultType: \"complete\", _meta: { ...meta } }\n }\n await finish()\n },\n }\n }\n\n return {\n timing,\n request(requestOptions) {\n const out: { failure: unknown; detach: TaskRequest[\"detach\"] } = {\n failure: undefined,\n async detach(entry) {\n if (!entry.command.task || closed) return undefined\n try {\n return await start(entry, requestOptions)\n } catch (error) {\n safeReport(report, error)\n out.failure = error\n throw error\n }\n },\n }\n return out\n },\n\n async get(taskId, principal) {\n const record = await readRecord(taskId, principal)\n const view: TaskView = {\n taskId: record.taskId,\n status: record.status,\n ...(record.statusMessage !== undefined ? { statusMessage: record.statusMessage } : {}),\n createdAt: record.createdAt,\n lastUpdatedAt: record.lastUpdatedAt,\n ttlMs: record.ttlMs,\n pollIntervalMs: timing.pollIntervalMs,\n }\n if (lost(record)) {\n view.status = \"failed\"\n view.error = {\n code: ProtocolErrorCode.InternalError,\n message: `Task lost: the executing process stopped (no heartbeat for ${timing.lostAfterMs}ms).`,\n data: { code: TASK_LOST },\n }\n } else if (record.status === \"input_required\" && record.inputRequests) view.inputRequests = record.inputRequests\n else if (record.status === \"completed\" && record.result) view.result = record.result\n return view\n },\n\n async update(taskId, principal, inputResponses) {\n const record = await readRecord(taskId, principal)\n if (TERMINAL.has(record.status) || lost(record)) return\n let wrote = false\n for (const [key, value] of Object.entries(inputResponses)) {\n // 모르는 키 · 형식이 아닌 답 · 이미 답한 키 = 무시\n if (record.inputRequests?.[key] === undefined || !elicitResult(value)) continue\n const stored = await storeCall(() => store.get(inputKey(taskId, key)))\n if (stored !== undefined) continue\n await storeCall(() => store.set(inputKey(taskId, key), JSON.stringify(value), { ttlMs: record.ttlMs + timing.lostAfterMs }))\n wrote = true\n }\n if (wrote) await notify(taskId, \"input\")\n },\n\n async cancel(taskId, principal) {\n const record = await readRecord(taskId, principal)\n if (TERMINAL.has(record.status) || lost(record)) return\n await storeCall(() => store.set(cancelKey(taskId), \"{}\", { ttlMs: record.ttlMs + timing.lostAfterMs }))\n await notify(taskId, \"cancel\")\n },\n\n async close() {\n closed = true\n const tasks = [...running.values()]\n if (tasks.length === 0) return\n for (const task of tasks) task.abort(new DOMException(\"Server shutting down\", \"AbortError\"))\n let timer: ReturnType<typeof setTimeout> | undefined\n await Promise.race([\n Promise.all(tasks.map((task) => task.done)),\n new Promise<void>((resolve) => (timer = setTimeout(resolve, timing.shutdownMs))),\n ])\n clearTimeout(timer)\n await Promise.all(tasks.map((task) => task.forceCancel()))\n },\n }\n}\n\n/**\n * McpServer 에 tasks/get · tasks/update · tasks/cancel 등록 (D5: 3-arg setRequestHandler, custom params schema).\n * declare = server/discover capabilities.extensions 에 확장 선언 (생성 가능할 때만). transport 연결 전에 호출\n */\nexport function installTaskHandlers(server: McpServer, runtime: TaskRuntime, principal: Principal, declare: boolean): void {\n const inner = server.server\n if (declare) inner.registerCapabilities({ extensions: { [TASKS_EXTENSION]: {} } })\n const byId = z.object({ taskId: z.string() })\n inner.setRequestHandler(\"tasks/get\", { params: byId }, async ({ taskId }) => ({ ...(await runtime.get(taskId, principal)) }))\n // inputResponses 는 SDK 가 params 에서 분리 (MRTR 예약 키) → ctx.mcpReq.inputResponses (bare 결과만)\n inner.setRequestHandler(\"tasks/update\", { params: byId }, async ({ taskId }, ctx) => {\n await runtime.update(taskId, principal, ctx.mcpReq.inputResponses ?? {})\n return {}\n })\n inner.setRequestHandler(\"tasks/cancel\", { params: byId }, async ({ taskId }) => {\n await runtime.cancel(taskId, principal)\n return {}\n })\n}\n\nfunction unknownTask(taskId: string): ProtocolError {\n return new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown task: ${taskId}`)\n}\n\nfunction bindingOf(principal: Principal): string {\n return `${principal.kind}:${principal.id}`\n}\n\nfunction parseRecord(raw: string): TaskRecord | undefined {\n const value = parseJson(raw)\n if (!isPlainObject(value) || value.v !== 1 || typeof value.taskId !== \"string\" || typeof value.status !== \"string\") return undefined\n return value as unknown as TaskRecord\n}\n\nfunction parseJson(raw: string): unknown {\n try {\n return JSON.parse(raw)\n } catch {\n return undefined\n }\n}\n\nfunction safeReport(report: (error: unknown) => void, error: unknown): void {\n try {\n report(error)\n } catch {\n // 보고는 동작을 바꾸지 않는다\n }\n}\n\nfunction defaultOnError(error: unknown): void {\n process.stderr.write(`mext: state store error: ${error instanceof Error ? error.message : String(error)}\\n`)\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/mcp/tasks.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\"\nimport { ProtocolError, ProtocolErrorCode, type McpServer } from \"@modelcontextprotocol/server\"\nimport * as z from \"zod\"\nimport type { ProgressUpdate } from \"../command.ts\"\nimport type { AskHandler, DetachedExecution } from \"../invoke.ts\"\nimport type { Principal } from \"../principal.ts\"\nimport type { RegisteredCommand, Registry } from \"../registry.ts\"\nimport { STATE_KEY_PREFIX, type MextState } from \"../state.ts\"\nimport { errorResult, valueResult, type ToolCallResult } from \"./dispatch.ts\"\nimport {\n ASK_KEY_PREFIX,\n askAnswer,\n elicitation,\n elicitResult,\n modeUnavailable,\n type ElicitationModes,\n type ElicitationRequest,\n type ElicitResultValue,\n} from \"./mrtr.ts\"\n\n/**\n * MCP tasks 확장 (io.modelcontextprotocol/tasks, §12.6). 서버 측: task 생성 (invoke detach) · tasks/get · update · cancel.\n *\n * D5: SDK 2.4.0 은 tasks 런타임이 없다 (task 메서드 = 2025-11-25 어휘, typed API 미제공). 단 3-arg setRequestHandler\n * (custom params schema) 로 tasks/get · update · cancel 을 등록할 수 있고 (era gate 통과), Mcp-Name = params.taskId 헤더 검증은\n * SDK 가 한다. tools/call 결과 resultType \"task\" 는 SDK 가 그대로 통과시킨다. 그래서 mext 가 이 파일에서 직접 구현한다.\n *\n * D2: store 키 (값 = JSON, 접두 \"mext:\", 키마다 writer 하나)\n * mext:task:<taskId> TaskRecord. writer = 실행 프로세스 (생성 · 상태 · heartbeat · 결과)\n * mext:task:<taskId>:input:<ask-N> 답 (ElicitResult). writer = tasks/update 를 받은 프로세스. 이미 있으면 무시\n * mext:task:<taskId>:cancel 취소 기록 ({}). writer = tasks/cancel 을 받은 프로세스\n * bus 채널 mext:task:<taskId> = 답 · 취소 도착 알림 ({\"type\":\"input\"|\"cancel\"}). 내용은 store 가 원본, 메시지는 깨우기만.\n * bus 없음 = 실행 프로세스가 storePollMs (1초) 마다 store 폴링. 같은 프로세스의 task = 직접 깨움.\n * store ttl: 실행 중 = ttlMs + lostAfterMs (heartbeat 마다 연장, 유실 후 failed 를 ttlMs 동안 조회), 종료 = ttlMs.\n *\n * R4: ctx.ask 의미 차이. MRTR (동기) = 라운드마다 핸들러 재실행 (ask 이전 코드 반복), task = 재실행 없이 대기\n * (ask 이전 코드 1회). 키 (ask-0 · ask-1 …) · elicitation 형식 · 답 해석 (askAnswer) · 미선언 mode = INPUT_UNAVAILABLE 은 같다.\n * 두 경로 모두에서 맞게 동작하려면 MRTR 규칙 (부작용은 ask 뒤) 을 따른다.\n */\n\nexport const TASKS_EXTENSION = \"io.modelcontextprotocol/tasks\"\n\nexport interface TaskTiming {\n /** CreateTaskResult · tasks/get 의 pollIntervalMs (클라이언트 폴링 권장 간격) */\n pollIntervalMs: number\n /** 실행 프로세스의 heartbeat (레코드 갱신) 간격 */\n heartbeatMs: number\n /** heartbeat 이 이보다 오래 없으면 tasks/get = failed (TASK_LOST) */\n lostAfterMs: number\n /** bus 없음: 실행 프로세스의 답 · 취소 store 폴링 간격 */\n storePollMs: number\n /** close (SIGTERM · SIGINT) 시 실행 중 task 정리 상한 */\n shutdownMs: number\n}\n\nexport const TASK_TIMING: Readonly<TaskTiming> = Object.freeze({\n pollIntervalMs: 2_000,\n heartbeatMs: 10_000,\n lostAfterMs: 30_000,\n storePollMs: 1_000,\n shutdownMs: 5_000,\n})\n\n/** tasks/get failed 의 error.data.code (실행 프로세스 유실) */\nexport const TASK_LOST = \"TASK_LOST\"\n\nexport type TaskStatus = \"working\" | \"input_required\" | \"completed\" | \"failed\" | \"cancelled\"\n\n/** tools/call 의 task 응답 (resultType \"task\") */\nexport interface CreateTaskResult {\n resultType: \"task\"\n taskId: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n pollIntervalMs: number\n _meta?: Record<string, unknown>\n}\n\n/** tasks/get 결과 (resultType 은 SDK 가 \"complete\" 로 채운다) */\nexport interface TaskView {\n taskId: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n pollIntervalMs: number\n /** input_required */\n inputRequests?: Record<string, ElicitationRequest>\n /** completed = 같은 요청의 동기 tools/call 결과 */\n result?: TaskResult\n /** failed (TASK_LOST) */\n error?: TaskError\n}\n\ntype TaskResult = ToolCallResult & { resultType: \"complete\"; _meta?: Record<string, unknown> }\n\ninterface TaskError {\n code: number\n message: string\n data?: Record<string, unknown>\n}\n\n/** D2: mext:task:<taskId> 의 값 */\ninterface TaskRecord {\n v: 1\n taskId: string\n /** 바인딩 \"<kind>:<id>\". 다른 주체 = 없는 task */\n principal: string\n command: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n /** epoch ms. heartbeatMs 마다 갱신 */\n heartbeatAt: number\n inputRequests?: Record<string, ElicitationRequest>\n result?: TaskResult\n}\n\nexport interface TaskRuntimeOptions {\n state: MextState\n timing?: Partial<TaskTiming>\n /** 완료 결과 _meta (동기 결과와 같은 manifestHash) */\n meta?: Record<string, unknown>\n /** store · bus 예외 보고. 기본 stderr 1줄 */\n onerror?: (error: unknown) => void\n}\n\n/** 요청 하나의 task 조건 */\nexport interface TaskRequestOptions {\n principal: Principal\n /** 생성 요청이 선언한 elicitation mode (ctx.ask 가능 여부, MRTR 과 같은 규칙) */\n modes: ElicitationModes\n /** handler.js: 응답 후 실행 유지 (플랫폼 waitUntil) */\n waitUntil?: (promise: Promise<unknown>) => void\n /** 완료 결과 _meta. 기본 = TaskRuntimeOptions.meta (호출자별 manifestHash 를 쓸 때 지정, §4 expose) */\n meta?: Record<string, unknown>\n}\n\nexport interface TaskRequest {\n /** invoke 의 detach. task 명령어가 아니면 undefined (동기) */\n detach: (entry: RegisteredCommand) => Promise<DetachedExecution | undefined>\n /** 생성 중 store · bus 예외 (있으면 요청 = -32603) */\n readonly failure: unknown\n}\n\nexport interface TaskRuntime {\n readonly timing: TaskTiming\n request(options: TaskRequestOptions): TaskRequest\n get(taskId: string, principal: Principal): Promise<TaskView>\n update(taskId: string, principal: Principal, inputResponses: Record<string, unknown>): Promise<void>\n cancel(taskId: string, principal: Principal): Promise<void>\n /** 실행 중 task 취소 → cancelled 기록 (상한 shutdownMs). 이후 새 task 없음 (동기 실행) */\n close(): Promise<void>\n}\n\n/** registry 에 task 명령어가 있는지 (선언 조건) */\nexport function hasTaskCommands(registry: Registry): boolean {\n for (const entry of registry.commands.values()) if (entry.command.task) return true\n return false\n}\n\n/** 요청 _meta 의 clientCapabilities 에 tasks 확장 선언 */\nexport function declaresTasks(clientCapabilities: unknown): boolean {\n const extensions = (clientCapabilities as { extensions?: unknown } | undefined)?.extensions\n return isPlainObject(extensions) && extensions[TASKS_EXTENSION] !== undefined\n}\n\n/**\n * HTTP: task 가 될 수 있는 tools/call 인지 (응답 = application/json, §12.6). 확장 선언 + 대상 명령어가 task 명령어.\n * 대상 = dispatcher 의 arguments.command (별칭 포함), 그 외 = 도구 이름 (command 노출)\n */\nexport function requestsTask(registry: Registry, body: unknown): boolean {\n if (!isPlainObject(body) || body.method !== \"tools/call\" || !isPlainObject(body.params)) return false\n const params = body.params\n const meta = isPlainObject(params._meta) ? params._meta : undefined\n if (!declaresTasks(meta?.[\"io.modelcontextprotocol/clientCapabilities\"])) return false\n const args = isPlainObject(params.arguments) ? params.arguments : undefined\n const target = typeof args?.command === \"string\" ? args.command : params.name\n if (typeof target !== \"string\") return false\n const id = registry.commands.has(target) ? target : registry.aliases.get(target)\n return id !== undefined && registry.commands.get(id)?.command.task !== undefined\n}\n\nconst recordKey = (taskId: string): string => `${STATE_KEY_PREFIX}task:${taskId}`\nconst inputKey = (taskId: string, key: string): string => `${recordKey(taskId)}:input:${key}`\nconst cancelKey = (taskId: string): string => `${recordKey(taskId)}:cancel`\nconst taskChannel = (taskId: string): string => `${STATE_KEY_PREFIX}task:${taskId}`\n\nconst TERMINAL: ReadonlySet<TaskStatus> = new Set([\"completed\", \"failed\", \"cancelled\"])\n\n/** 같은 프로세스에서 실행 중인 task */\ninterface RunningTask {\n /** 답 · 취소를 store 에서 다시 읽는다 */\n wake(): Promise<void>\n abort(reason: unknown): void\n /** 종료 기록 완료 */\n done: Promise<void>\n /** 아직 끝나지 않았으면 cancelled 기록 (종료 상한) */\n forceCancel(): Promise<void>\n}\n\nexport function createTaskRuntime(options: TaskRuntimeOptions): TaskRuntime {\n const { store, bus } = options.state\n const timing: TaskTiming = { ...TASK_TIMING, ...options.timing }\n const meta = options.meta ?? {}\n const report = options.onerror ?? defaultOnError\n const running = new Map<string, RunningTask>()\n let closed = false\n\n /** store · bus 호출. 예외 = 보고 + -32603 */\n const storeCall = async <T>(fn: () => Promise<T>): Promise<T> => {\n try {\n return await fn()\n } catch (error) {\n safeReport(report, error)\n throw new ProtocolError(ProtocolErrorCode.InternalError, \"State store error\")\n }\n }\n\n const readRecord = async (taskId: string, principal: Principal): Promise<TaskRecord> => {\n const raw = await storeCall(() => store.get(recordKey(taskId)))\n const record = raw === undefined ? undefined : parseRecord(raw)\n if (!record || record.taskId !== taskId || record.principal !== bindingOf(principal)) throw unknownTask(taskId)\n return record\n }\n\n const lost = (record: TaskRecord): boolean =>\n !TERMINAL.has(record.status) && Date.now() - record.heartbeatAt > timing.lostAfterMs\n\n /** 답 · 취소 도착 알림: 같은 프로세스 = 직접, 그 외 = bus (없으면 실행 프로세스가 폴링) */\n const notify = async (taskId: string, type: \"input\" | \"cancel\"): Promise<void> => {\n const local = running.get(taskId)\n if (local) {\n await local.wake()\n return\n }\n if (bus) await storeCall(() => bus.publish(taskChannel(taskId), JSON.stringify({ type })))\n }\n\n const start = async (entry: RegisteredCommand, request: TaskRequestOptions): Promise<DetachedExecution> => {\n const taskId = randomBytes(16).toString(\"base64url\")\n const created = new Date().toISOString()\n const record: TaskRecord = {\n v: 1,\n taskId,\n principal: bindingOf(request.principal),\n command: entry.id,\n status: \"working\",\n createdAt: created,\n lastUpdatedAt: created,\n ttlMs: entry.command.task!.ttlMs,\n heartbeatAt: Date.now(),\n }\n const controller = new AbortController()\n const waiters = new Map<string, (answer: ElicitResultValue) => void>()\n let finalized = false\n let resolveDone!: () => void\n const done = new Promise<void>((resolve) => (resolveDone = resolve))\n const touch = (): void => void (record.lastUpdatedAt = new Date().toISOString())\n\n // 순서 보장 · 합치기: 쓰는 중 변경 = 끝난 뒤 최신 상태로 한 번 더\n let writing: Promise<void> | undefined\n let dirty = false\n const persist = (): Promise<void> => {\n dirty = true\n writing ??= (async () => {\n try {\n while (dirty) {\n dirty = false\n const ttlMs = TERMINAL.has(record.status) ? record.ttlMs : record.ttlMs + timing.lostAfterMs\n await store.set(recordKey(taskId), JSON.stringify(record), { ttlMs })\n }\n } finally {\n writing = undefined\n }\n })()\n return writing\n }\n const persistLater = (): void => void persist().catch((error: unknown) => safeReport(report, error))\n\n const wake = async (): Promise<void> => {\n try {\n if (!controller.signal.aborted && (await store.get(cancelKey(taskId))) !== undefined) {\n controller.abort(new DOMException(\"Task cancelled\", \"AbortError\"))\n }\n for (const [key, resolve] of [...waiters]) {\n const raw = await store.get(inputKey(taskId, key))\n const answer = raw === undefined ? undefined : elicitResult(parseJson(raw))\n if (answer) resolve(answer)\n }\n } catch (error) {\n safeReport(report, error)\n }\n }\n\n let heartbeat: ReturnType<typeof setInterval> | undefined\n let poll: ReturnType<typeof setInterval> | undefined\n let unsubscribe: (() => Promise<void>) | undefined\n const stopTimers = (): void => {\n if (heartbeat !== undefined) clearInterval(heartbeat)\n if (poll !== undefined) clearInterval(poll)\n }\n\n const finish = async (): Promise<void> => {\n if (finalized) return\n finalized = true\n stopTimers()\n delete record.inputRequests\n touch()\n waiters.clear()\n try {\n await persist()\n } catch (error) {\n safeReport(report, error)\n }\n running.delete(taskId)\n try {\n await unsubscribe?.()\n } catch (error) {\n safeReport(report, error)\n }\n resolveDone()\n }\n\n let index = 0\n const ask: AskHandler = async (askRequest) => {\n const key = `${ASK_KEY_PREFIX}${index++}`\n if (!(askRequest.kind === \"url\" ? request.modes.url : request.modes.form)) throw modeUnavailable(askRequest)\n controller.signal.throwIfAborted()\n let onAbort!: () => void\n const answered = new Promise<ElicitResultValue>((resolve, reject) => {\n onAbort = () => {\n waiters.delete(key)\n reject(controller.signal.reason)\n }\n controller.signal.addEventListener(\"abort\", onAbort, { once: true })\n waiters.set(key, (answer) => {\n waiters.delete(key)\n controller.signal.removeEventListener(\"abort\", onAbort)\n resolve(answer)\n })\n })\n answered.catch(() => {})\n record.inputRequests = { ...record.inputRequests, [key]: elicitation(askRequest) }\n record.status = \"input_required\"\n touch()\n try {\n await persist()\n } catch (error) {\n waiters.delete(key)\n controller.signal.removeEventListener(\"abort\", onAbort)\n throw error\n }\n const response = await answered\n if (record.inputRequests) {\n delete record.inputRequests[key]\n if (Object.keys(record.inputRequests).length === 0) delete record.inputRequests\n }\n if (!record.inputRequests && !finalized) record.status = \"working\"\n touch()\n if (!finalized) persistLater()\n return askAnswer(askRequest, response)\n }\n\n const progress = (update: ProgressUpdate): void => {\n if (finalized) return\n record.statusMessage =\n update.message ?? (update.total !== undefined ? `${update.progress}/${update.total}` : String(update.progress))\n touch()\n persistLater()\n }\n\n const task: RunningTask = {\n wake,\n abort: (reason) => controller.abort(reason),\n done,\n async forceCancel() {\n if (finalized) return\n record.status = \"cancelled\"\n await finish()\n },\n }\n running.set(taskId, task)\n try {\n if (bus) unsubscribe = await bus.subscribe(taskChannel(taskId), () => void wake())\n // store 기록 후 응답 (tasks/get 이 바로 성공해야 한다)\n await persist()\n } catch (error) {\n running.delete(taskId)\n await unsubscribe?.().catch(() => {})\n throw error\n }\n heartbeat = setInterval(() => {\n record.heartbeatAt = Date.now()\n persistLater()\n }, timing.heartbeatMs)\n heartbeat.unref?.()\n if (!bus) {\n poll = setInterval(() => void wake(), timing.storePollMs)\n poll.unref?.()\n }\n request.waitUntil?.(done)\n\n const handle: CreateTaskResult = {\n resultType: \"task\",\n taskId,\n status: \"working\",\n createdAt: record.createdAt,\n lastUpdatedAt: record.lastUpdatedAt,\n ttlMs: record.ttlMs,\n pollIntervalMs: timing.pollIntervalMs,\n }\n return {\n handle,\n taskId,\n signal: controller.signal,\n ask,\n progress,\n async settle(outcome) {\n if (finalized) return\n if (\"error\" in outcome && controller.signal.aborted) {\n // 취소 후 예외 = cancelled. 핸들러가 끝까지 가면 (값 반환) 그 결과\n record.status = \"cancelled\"\n } else {\n record.status = \"completed\"\n const result = \"error\" in outcome ? errorResult(outcome.error) : valueResult(outcome.value)\n record.result = { ...result, resultType: \"complete\", _meta: { ...(request.meta ?? meta) } }\n }\n await finish()\n },\n }\n }\n\n return {\n timing,\n request(requestOptions) {\n const out: { failure: unknown; detach: TaskRequest[\"detach\"] } = {\n failure: undefined,\n async detach(entry) {\n if (!entry.command.task || closed) return undefined\n try {\n return await start(entry, requestOptions)\n } catch (error) {\n safeReport(report, error)\n out.failure = error\n throw error\n }\n },\n }\n return out\n },\n\n async get(taskId, principal) {\n const record = await readRecord(taskId, principal)\n const view: TaskView = {\n taskId: record.taskId,\n status: record.status,\n ...(record.statusMessage !== undefined ? { statusMessage: record.statusMessage } : {}),\n createdAt: record.createdAt,\n lastUpdatedAt: record.lastUpdatedAt,\n ttlMs: record.ttlMs,\n pollIntervalMs: timing.pollIntervalMs,\n }\n if (lost(record)) {\n view.status = \"failed\"\n view.error = {\n code: ProtocolErrorCode.InternalError,\n message: `Task lost: the executing process stopped (no heartbeat for ${timing.lostAfterMs}ms).`,\n data: { code: TASK_LOST },\n }\n } else if (record.status === \"input_required\" && record.inputRequests) view.inputRequests = record.inputRequests\n else if (record.status === \"completed\" && record.result) view.result = record.result\n return view\n },\n\n async update(taskId, principal, inputResponses) {\n const record = await readRecord(taskId, principal)\n if (TERMINAL.has(record.status) || lost(record)) return\n let wrote = false\n for (const [key, value] of Object.entries(inputResponses)) {\n // 모르는 키 · 형식이 아닌 답 · 이미 답한 키 = 무시\n if (record.inputRequests?.[key] === undefined || !elicitResult(value)) continue\n const stored = await storeCall(() => store.get(inputKey(taskId, key)))\n if (stored !== undefined) continue\n await storeCall(() => store.set(inputKey(taskId, key), JSON.stringify(value), { ttlMs: record.ttlMs + timing.lostAfterMs }))\n wrote = true\n }\n if (wrote) await notify(taskId, \"input\")\n },\n\n async cancel(taskId, principal) {\n const record = await readRecord(taskId, principal)\n if (TERMINAL.has(record.status) || lost(record)) return\n await storeCall(() => store.set(cancelKey(taskId), \"{}\", { ttlMs: record.ttlMs + timing.lostAfterMs }))\n await notify(taskId, \"cancel\")\n },\n\n async close() {\n closed = true\n const tasks = [...running.values()]\n if (tasks.length === 0) return\n for (const task of tasks) task.abort(new DOMException(\"Server shutting down\", \"AbortError\"))\n let timer: ReturnType<typeof setTimeout> | undefined\n await Promise.race([\n Promise.all(tasks.map((task) => task.done)),\n new Promise<void>((resolve) => (timer = setTimeout(resolve, timing.shutdownMs))),\n ])\n clearTimeout(timer)\n await Promise.all(tasks.map((task) => task.forceCancel()))\n },\n }\n}\n\n/**\n * McpServer 에 tasks/get · tasks/update · tasks/cancel 등록 (D5: 3-arg setRequestHandler, custom params schema).\n * declare = server/discover capabilities.extensions 에 확장 선언 (생성 가능할 때만). transport 연결 전에 호출\n */\nexport function installTaskHandlers(server: McpServer, runtime: TaskRuntime, principal: Principal, declare: boolean): void {\n const inner = server.server\n if (declare) inner.registerCapabilities({ extensions: { [TASKS_EXTENSION]: {} } })\n const byId = z.object({ taskId: z.string() })\n inner.setRequestHandler(\"tasks/get\", { params: byId }, async ({ taskId }) => ({ ...(await runtime.get(taskId, principal)) }))\n // inputResponses 는 SDK 가 params 에서 분리 (MRTR 예약 키) → ctx.mcpReq.inputResponses (bare 결과만)\n inner.setRequestHandler(\"tasks/update\", { params: byId }, async ({ taskId }, ctx) => {\n await runtime.update(taskId, principal, ctx.mcpReq.inputResponses ?? {})\n return {}\n })\n inner.setRequestHandler(\"tasks/cancel\", { params: byId }, async ({ taskId }) => {\n await runtime.cancel(taskId, principal)\n return {}\n })\n}\n\nfunction unknownTask(taskId: string): ProtocolError {\n return new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown task: ${taskId}`)\n}\n\nfunction bindingOf(principal: Principal): string {\n return `${principal.kind}:${principal.id}`\n}\n\nfunction parseRecord(raw: string): TaskRecord | undefined {\n const value = parseJson(raw)\n if (!isPlainObject(value) || value.v !== 1 || typeof value.taskId !== \"string\" || typeof value.status !== \"string\") return undefined\n return value as unknown as TaskRecord\n}\n\nfunction parseJson(raw: string): unknown {\n try {\n return JSON.parse(raw)\n } catch {\n return undefined\n }\n}\n\nfunction safeReport(report: (error: unknown) => void, error: unknown): void {\n try {\n report(error)\n } catch {\n // 보고는 동작을 바꾸지 않는다\n }\n}\n\nfunction defaultOnError(error: unknown): void {\n process.stderr.write(`mext: state store error: ${error instanceof Error ? error.message : String(error)}\\n`)\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n"]}
|
package/dist/principal.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/** 행위자 종류. auth · localPrincipal 이 정한다 */
|
|
2
|
+
export type ActorKind = "human" | "agent" | "service" | "system";
|
|
3
|
+
/** 행위자. 서버 (auth · localPrincipal) 가 정한 값만. 클라이언트 신고 값으로 정하지 않는다 */
|
|
4
|
+
export interface Actor {
|
|
5
|
+
kind: ActorKind;
|
|
6
|
+
/** 행위자 식별자 (사용자 ID · 에이전트 ID). principal.id 와 다를 수 있다 (에이전트가 사용자 계정으로 실행) */
|
|
7
|
+
id?: string;
|
|
8
|
+
}
|
|
1
9
|
/** 요청 주체. 서버가 요청마다 생성 (HTTP · CLI 원격), 로컬 · stdio = kind local */
|
|
2
10
|
export interface Principal {
|
|
3
11
|
/** "local:obov" | "user_123" | "anonymous" */
|
|
@@ -7,6 +15,13 @@ export interface Principal {
|
|
|
7
15
|
scopes: string[];
|
|
8
16
|
/** 검증된 토큰 내용. 토큰 원문은 포함하지 않는다 */
|
|
9
17
|
claims?: Record<string, unknown>;
|
|
18
|
+
/** 행위자 (ctx.caller.actor). 없음 = 미확정. mext 는 추정하지 않는다 */
|
|
19
|
+
actor?: Actor;
|
|
20
|
+
/**
|
|
21
|
+
* 논리 표면 (ctx.caller.surface). kebab-case 이름. 없음 = 어댑터 기본 (cli · mcp · stdio).
|
|
22
|
+
* 같은 POST /mcp 요청을 호출자별로 나눌 때 auth 가 정한다 (예: 웹 앱 세션 = "web")
|
|
23
|
+
*/
|
|
24
|
+
surface?: string;
|
|
10
25
|
}
|
|
11
26
|
/** 인증 없는 주체. scopes 없음 → readOnly 명령어만 */
|
|
12
27
|
export declare const ANONYMOUS: Principal;
|
|
@@ -14,3 +29,10 @@ export declare const ANONYMOUS: Principal;
|
|
|
14
29
|
export declare function localPrincipal(user?: string): Principal;
|
|
15
30
|
/** "*" = 전체 */
|
|
16
31
|
export declare function hasScope(principal: Principal, scope: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* principal.actor · surface 형식 문제. 없으면 undefined.
|
|
34
|
+
* id · kind · scopes 는 검사하지 않는다 (auth 결과를 검사하지 않던 기존 동작 유지)
|
|
35
|
+
*/
|
|
36
|
+
export declare function callerFieldsProblem(value: unknown): string | undefined;
|
|
37
|
+
/** callerFieldsProblem 이 있으면 TypeError ("<source>: principal <문제>"). source = "auth" · "localPrincipal" */
|
|
38
|
+
export declare function assertCallerFields(value: unknown, source: string): asserts value is Principal;
|
package/dist/principal.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { userInfo } from "node:os";
|
|
2
|
+
import { isSegment } from "./ids.js";
|
|
3
|
+
const ACTOR_KINDS = ["human", "agent", "service", "system"];
|
|
2
4
|
/** 인증 없는 주체. scopes 없음 → readOnly 명령어만 */
|
|
3
5
|
export const ANONYMOUS = Object.freeze({
|
|
4
6
|
id: "anonymous",
|
|
@@ -13,6 +15,33 @@ export function localPrincipal(user = osUser()) {
|
|
|
13
15
|
export function hasScope(principal, scope) {
|
|
14
16
|
return principal.scopes.includes("*") || principal.scopes.includes(scope);
|
|
15
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* principal.actor · surface 형식 문제. 없으면 undefined.
|
|
20
|
+
* id · kind · scopes 는 검사하지 않는다 (auth 결과를 검사하지 않던 기존 동작 유지)
|
|
21
|
+
*/
|
|
22
|
+
export function callerFieldsProblem(value) {
|
|
23
|
+
const p = value;
|
|
24
|
+
if (typeof p !== "object" || p === null)
|
|
25
|
+
return "must be an object ({ id, kind, scopes })";
|
|
26
|
+
if (p.surface !== undefined && (typeof p.surface !== "string" || !isSegment(p.surface))) {
|
|
27
|
+
return 'surface must be a kebab-case name (e.g. "web")';
|
|
28
|
+
}
|
|
29
|
+
if (p.actor !== undefined) {
|
|
30
|
+
const a = p.actor;
|
|
31
|
+
if (typeof a !== "object" || a === null || !ACTOR_KINDS.includes(a.kind)) {
|
|
32
|
+
return 'actor.kind must be "human", "agent", "service" or "system"';
|
|
33
|
+
}
|
|
34
|
+
if (a.id !== undefined && typeof a.id !== "string")
|
|
35
|
+
return "actor.id must be a string";
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
/** callerFieldsProblem 이 있으면 TypeError ("<source>: principal <문제>"). source = "auth" · "localPrincipal" */
|
|
40
|
+
export function assertCallerFields(value, source) {
|
|
41
|
+
const problem = callerFieldsProblem(value);
|
|
42
|
+
if (problem !== undefined)
|
|
43
|
+
throw new TypeError(`${source}: principal ${problem}`);
|
|
44
|
+
}
|
|
16
45
|
function osUser() {
|
|
17
46
|
try {
|
|
18
47
|
return userInfo().username;
|
package/dist/principal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"principal.js","sourceRoot":"","sources":["../src/principal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"principal.js","sourceRoot":"","sources":["../src/principal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAYpC,MAAM,WAAW,GAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAA;AAoB9E,0CAA0C;AAC1C,MAAM,CAAC,MAAM,SAAS,GAAc,MAAM,CAAC,MAAM,CAAC;IAChD,EAAE,EAAE,WAAW;IACf,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAwB;CACjD,CAAc,CAAA;AAEf,mFAAmF;AACnF,MAAM,UAAU,cAAc,CAAC,IAAI,GAAW,MAAM,EAAE;IACpD,OAAO,EAAE,EAAE,EAAE,SAAS,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAA;AAC9D,CAAC;AAED,eAAe;AACf,MAAM,UAAU,QAAQ,CAAC,SAAoB,EAAE,KAAa;IAC1D,OAAO,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC3E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,MAAM,CAAC,GAAG,KAAkC,CAAA;IAC5C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,0CAA0C,CAAA;IAC1F,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACxF,OAAO,gDAAgD,CAAA;IACzD,CAAC;IACD,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,CAAC,KAA8B,CAAA;QAC1C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAc,CAAC,EAAE,CAAC;YACnF,OAAO,4DAA4D,CAAA;QACrE,CAAC;QACD,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ;YAAE,OAAO,2BAA2B,CAAA;IACxF,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,kBAAkB,CAAC,KAAc,EAAE,MAAc;IAC/D,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAA;IAC1C,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,IAAI,SAAS,CAAC,GAAG,MAAM,eAAe,OAAO,EAAE,CAAC,CAAA;AACnF,CAAC;AAED,SAAS,MAAM;IACb,IAAI,CAAC;QACH,OAAO,QAAQ,EAAE,CAAC,QAAQ,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,SAAS,CAAA;IAC9D,CAAC;AACH,CAAC","sourcesContent":["import { userInfo } from \"node:os\"\nimport { isSegment } from \"./ids.ts\"\n\n/** 행위자 종류. auth · localPrincipal 이 정한다 */\nexport type ActorKind = \"human\" | \"agent\" | \"service\" | \"system\"\n\n/** 행위자. 서버 (auth · localPrincipal) 가 정한 값만. 클라이언트 신고 값으로 정하지 않는다 */\nexport interface Actor {\n kind: ActorKind\n /** 행위자 식별자 (사용자 ID · 에이전트 ID). principal.id 와 다를 수 있다 (에이전트가 사용자 계정으로 실행) */\n id?: string\n}\n\nconst ACTOR_KINDS: readonly string[] = [\"human\", \"agent\", \"service\", \"system\"]\n\n/** 요청 주체. 서버가 요청마다 생성 (HTTP · CLI 원격), 로컬 · stdio = kind local */\nexport interface Principal {\n /** \"local:obov\" | \"user_123\" | \"anonymous\" */\n id: string\n kind: \"local\" | \"token\" | \"anonymous\"\n /** \"*\" = 전체 */\n scopes: string[]\n /** 검증된 토큰 내용. 토큰 원문은 포함하지 않는다 */\n claims?: Record<string, unknown>\n /** 행위자 (ctx.caller.actor). 없음 = 미확정. mext 는 추정하지 않는다 */\n actor?: Actor\n /**\n * 논리 표면 (ctx.caller.surface). kebab-case 이름. 없음 = 어댑터 기본 (cli · mcp · stdio).\n * 같은 POST /mcp 요청을 호출자별로 나눌 때 auth 가 정한다 (예: 웹 앱 세션 = \"web\")\n */\n surface?: string\n}\n\n/** 인증 없는 주체. scopes 없음 → readOnly 명령어만 */\nexport const ANONYMOUS: Principal = Object.freeze({\n id: \"anonymous\",\n kind: \"anonymous\",\n scopes: Object.freeze([]) as unknown as string[],\n}) as Principal\n\n/** 로컬 · stdio 실행의 기본 주체: { id: \"local:<OS 사용자>\", kind: \"local\", scopes: [\"*\"] } */\nexport function localPrincipal(user: string = osUser()): Principal {\n return { id: `local:${user}`, kind: \"local\", scopes: [\"*\"] }\n}\n\n/** \"*\" = 전체 */\nexport function hasScope(principal: Principal, scope: string): boolean {\n return principal.scopes.includes(\"*\") || principal.scopes.includes(scope)\n}\n\n/**\n * principal.actor · surface 형식 문제. 없으면 undefined.\n * id · kind · scopes 는 검사하지 않는다 (auth 결과를 검사하지 않던 기존 동작 유지)\n */\nexport function callerFieldsProblem(value: unknown): string | undefined {\n const p = value as Partial<Principal> | null\n if (typeof p !== \"object\" || p === null) return \"must be an object ({ id, kind, scopes })\"\n if (p.surface !== undefined && (typeof p.surface !== \"string\" || !isSegment(p.surface))) {\n return 'surface must be a kebab-case name (e.g. \"web\")'\n }\n if (p.actor !== undefined) {\n const a = p.actor as Partial<Actor> | null\n if (typeof a !== \"object\" || a === null || !ACTOR_KINDS.includes(a.kind as string)) {\n return 'actor.kind must be \"human\", \"agent\", \"service\" or \"system\"'\n }\n if (a.id !== undefined && typeof a.id !== \"string\") return \"actor.id must be a string\"\n }\n return undefined\n}\n\n/** callerFieldsProblem 이 있으면 TypeError (\"<source>: principal <문제>\"). source = \"auth\" · \"localPrincipal\" */\nexport function assertCallerFields(value: unknown, source: string): asserts value is Principal {\n const problem = callerFieldsProblem(value)\n if (problem !== undefined) throw new TypeError(`${source}: principal ${problem}`)\n}\n\nfunction osUser(): string {\n try {\n return userInfo().username\n } catch {\n return process.env.USER ?? process.env.USERNAME ?? \"unknown\"\n }\n}\n"]}
|
package/dist/registry.d.ts
CHANGED
|
@@ -90,6 +90,11 @@ export declare function createLazyRegistry(input: {
|
|
|
90
90
|
commands: readonly LazyCommandInput[];
|
|
91
91
|
namespaces?: readonly RegistryNamespaceInput[];
|
|
92
92
|
}): Registry;
|
|
93
|
+
/**
|
|
94
|
+
* keep 을 통과한 명령어만 남긴 Registry (expose 의 표면별 보기). 별칭 · 네임스페이스를 다시 계산한다:
|
|
95
|
+
* 남은 명령어가 없는 네임스페이스는 없어지고, 남은 네임스페이스의 설명은 유지. 명령어 항목 · 자원 · 프롬프트는 원본과 같은 객체
|
|
96
|
+
*/
|
|
97
|
+
export declare function filterRegistry(registry: Registry, keep: (entry: RegisteredCommand) => boolean): Registry;
|
|
93
98
|
/** 실행 가능한 명령어. eager = entry.command, lazy = entry.load() (모듈 import) */
|
|
94
99
|
export declare function loadCommand(entry: RegisteredCommand): Promise<Command>;
|
|
95
100
|
/** 정식 ID 또는 별칭으로 명령어 찾기 */
|
package/dist/registry.js
CHANGED
|
@@ -134,6 +134,27 @@ export function createLazyRegistry(input) {
|
|
|
134
134
|
}
|
|
135
135
|
return { commands, aliases, namespaces: namespaceTable(namespaceIds, [...commands.keys()], input.namespaces) };
|
|
136
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* keep 을 통과한 명령어만 남긴 Registry (expose 의 표면별 보기). 별칭 · 네임스페이스를 다시 계산한다:
|
|
139
|
+
* 남은 명령어가 없는 네임스페이스는 없어지고, 남은 네임스페이스의 설명은 유지. 명령어 항목 · 자원 · 프롬프트는 원본과 같은 객체
|
|
140
|
+
*/
|
|
141
|
+
export function filterRegistry(registry, keep) {
|
|
142
|
+
const commands = new Map();
|
|
143
|
+
for (const [id, entry] of registry.commands)
|
|
144
|
+
if (keep(entry))
|
|
145
|
+
commands.set(id, entry);
|
|
146
|
+
const aliases = new Map();
|
|
147
|
+
for (const [alias, id] of registry.aliases)
|
|
148
|
+
if (commands.has(id))
|
|
149
|
+
aliases.set(alias, id);
|
|
150
|
+
const namespaceIds = new Set([""]);
|
|
151
|
+
for (const id of commands.keys()) {
|
|
152
|
+
for (let ns = parentNamespace(id); ns !== ""; ns = parentNamespace(ns))
|
|
153
|
+
namespaceIds.add(ns);
|
|
154
|
+
}
|
|
155
|
+
const descriptions = [...registry.namespaces.values()].flatMap((n) => (n.description === undefined ? [] : [{ id: n.id, description: n.description }]));
|
|
156
|
+
return { ...registry, commands, aliases, namespaces: namespaceTable(namespaceIds, [...commands.keys()], descriptions) };
|
|
157
|
+
}
|
|
137
158
|
/** 실행 가능한 명령어. eager = entry.command, lazy = entry.load() (모듈 import) */
|
|
138
159
|
export function loadCommand(entry) {
|
|
139
160
|
return entry.load ? entry.load() : Promise.resolve(entry.command);
|
package/dist/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import * as z from \"zod\"\nimport { isCommand, type Command } from \"./command.ts\"\nimport { MextBuildError, type BuildIssue } from \"./errors.ts\"\nimport { isSegment, parentNamespace, RESERVED_ROOT_SEGMENTS } from \"./ids.ts\"\nimport type { PromptSet } from \"./prompt.ts\"\nimport type { ResourceSet } from \"./resource.ts\"\n\nexport type JsonSchema = Record<string, unknown>\n\nexport interface RegistryCommandInput {\n /** 정식 ID. 점 구분 kebab-case 세그먼트 */\n id: string\n command: Command\n /** commands/ 기준 상대 경로 (posix). 스캔 결과에만 있음 */\n file?: string\n}\n\nexport interface RegistryNamespaceInput {\n /** \"\" = 루트 */\n id: string\n description?: string\n}\n\nexport interface RegistryInput {\n commands: readonly RegistryCommandInput[]\n namespaces?: readonly RegistryNamespaceInput[]\n}\n\nexport interface RegisteredCommand {\n id: string\n /**\n * 메타데이터 (description · 안전성 · scopes · examples · positional · aliases) 의 원본.\n * eager (createRegistry) = 실행 가능한 명령어 그대로. lazy (createLazyRegistry) = manifest 로 만든 메타데이터만\n * (input · execute 는 load() 결과에서)\n */\n command: Command\n /** lazy Registry: 명령어 모듈 import (1회 캐시) → 실행 가능한 명령어. 없음 = command 가 실행 가능. loadCommand 로 호출 */\n load?: () => Promise<Command>\n /** 별칭의 전체 ID (정렬) */\n aliases: readonly string[]\n file: string | undefined\n /** input 의 JSON Schema 2020-12 (io: input) */\n inputSchema: JsonSchema\n /** output 의 JSON Schema 2020-12 (io: output) */\n outputSchema: JsonSchema | undefined\n}\n\nexport interface NamespaceInfo {\n /** \"\" = 루트 */\n id: string\n /** _index.md 내용 */\n description: string | undefined\n /** 직속 명령어 정식 ID (정렬). index.ts 명령어 (네임스페이스와 같은 ID) 는 상위 네임스페이스에 속한다 */\n commands: readonly string[]\n /** 직속 하위 네임스페이스 ID (정렬) */\n namespaces: readonly string[]\n}\n\nexport interface Registry {\n /** 정식 ID → 명령어. ID 순 */\n readonly commands: ReadonlyMap<string, RegisteredCommand>\n /** 별칭 전체 ID → 정식 ID */\n readonly aliases: ReadonlyMap<string, string>\n /** 네임스페이스 ID → 정보. 루트 (\"\") 포함, ID 순 */\n readonly namespaces: ReadonlyMap<string, NamespaceInfo>\n /** MCP 자원 (resources/, §12.3). 없음 = 기능 없음 (capability 미선언). 명령어 Map 과 별개 */\n readonly resources?: ResourceSet\n /** MCP 프롬프트 (prompts/, §12.3). 없음 = 기능 없음 (capability 미선언). 이름 순 */\n readonly prompts?: PromptSet\n}\n\n/** 명령어 목록에서 Registry 생성. ID · 별칭 · 스키마 규칙 위반은 MextBuildError */\nexport function createRegistry(input: RegistryInput): Registry {\n const { registry, issues } = collectRegistry(input)\n if (issues.length > 0) throw new MextBuildError(issues)\n return registry\n}\n\n/**\n * createRegistry 의 수집형 (mext build 의 일괄 검증용). 던지지 않는다.\n * registry = 규칙을 통과한 명령어만, issues = 위반 전부\n */\nexport function collectRegistry(input: RegistryInput): { registry: Registry; issues: BuildIssue[] } {\n const issues: BuildIssue[] = []\n const accepted: RegistryCommandInput[] = []\n const seen = new Map<string, RegistryCommandInput>()\n\n for (const entry of input.commands) {\n const where = { id: entry.id, file: entry.file }\n if (!isCommand(entry.command)) {\n issues.push({ code: \"INVALID_COMMAND\", message: \"not a defineCommand result\", ...where })\n continue\n }\n const segments = entry.id.split(\".\")\n const bad = segments.find((s) => !isSegment(s))\n if (bad !== undefined) {\n issues.push({ code: \"INVALID_SEGMENT\", message: `segment \"${bad}\" is not kebab-case`, ...where })\n continue\n }\n if (RESERVED_ROOT_SEGMENTS.includes(segments[0]!)) {\n issues.push({ code: \"RESERVED_ID\", message: `root segment \"${segments[0]}\" is reserved`, ...where })\n continue\n }\n const prev = seen.get(entry.id)\n if (prev) {\n issues.push({ code: \"DUPLICATE_ID\", message: `duplicate ID (also ${prev.file ?? prev.id})`, ...where })\n continue\n }\n seen.set(entry.id, entry)\n accepted.push(entry)\n }\n\n // 네임스페이스 = 명령어 ID 의 모든 상위 경로\n const namespaceIds = new Set<string>([\"\"])\n for (const { id } of accepted) {\n for (let ns = parentNamespace(id); ns !== \"\"; ns = parentNamespace(ns)) namespaceIds.add(ns)\n }\n\n const aliases = new Map<string, string>()\n const aliasesOf = new Map<string, string[]>()\n for (const entry of accepted) {\n const where = { id: entry.id, file: entry.file }\n const parent = parentNamespace(entry.id)\n const own: string[] = []\n for (const alias of entry.command.aliases) {\n if (!isSegment(alias)) {\n issues.push({ code: \"INVALID_ALIAS\", message: `alias \"${alias}\" is not a kebab-case segment`, ...where })\n continue\n }\n if (parent === \"\") {\n issues.push({ code: \"INVALID_ALIAS\", message: `alias \"${alias}\": aliases are not allowed at the root`, ...where })\n continue\n }\n const full = `${parent}.${alias}`\n const owner = seen.has(full) ? full : aliases.get(full)\n if (owner !== undefined || namespaceIds.has(full)) {\n issues.push({\n code: \"DUPLICATE_ID\",\n message: `alias ${full} duplicates ${owner !== undefined ? owner : \"a namespace\"}`,\n ...where,\n })\n continue\n }\n aliases.set(full, entry.id)\n own.push(full)\n }\n aliasesOf.set(entry.id, own.sort())\n }\n\n const commands = new Map<string, RegisteredCommand>()\n for (const entry of [...accepted].sort((a, b) => compareIds(a.id, b.id))) {\n const where = { id: entry.id, file: entry.file }\n let inputSchema: JsonSchema\n let outputSchema: JsonSchema | undefined\n try {\n inputSchema = toJsonSchema(entry.command.input, \"input\")\n outputSchema = entry.command.output ? toJsonSchema(entry.command.output, \"output\") : undefined\n } catch (error) {\n issues.push({ code: \"SCHEMA_UNREPRESENTABLE\", message: errorMessage(error), ...where })\n continue\n }\n commands.set(entry.id, {\n id: entry.id,\n command: entry.command,\n aliases: aliasesOf.get(entry.id) ?? [],\n file: entry.file,\n inputSchema,\n outputSchema,\n })\n }\n\n const namespaces = namespaceTable(namespaceIds, [...commands.keys()], input.namespaces)\n return { registry: { commands, aliases, namespaces }, issues }\n}\n\n/** lazy Registry 의 명령어: manifest 메타데이터 + 모듈 로더 (규칙 검증은 mext build 가 이미 함) */\nexport interface LazyCommandInput {\n id: string\n /** 메타데이터만 있는 명령어 (input · execute 는 load 결과). RegisteredCommand.command */\n command: Command\n /** 별칭의 전체 ID */\n aliases: readonly string[]\n file?: string\n inputSchema: JsonSchema\n outputSchema?: JsonSchema\n /** 실행 시 1회 호출 (결과 캐시, 실패는 다음 호출에서 재시도) */\n load: () => Promise<Command>\n}\n\n/**\n * manifest (mext build 산출) 로 Registry 생성. 명령어 모듈을 import 하지 않는다 (mext start · handler.js).\n * help · tools/list · UNKNOWN_COMMAND · 권한 검사 = 메타데이터만, 입력 검증 · execute = loadCommand 후\n */\nexport function createLazyRegistry(input: {\n commands: readonly LazyCommandInput[]\n namespaces?: readonly RegistryNamespaceInput[]\n}): Registry {\n const commands = new Map<string, RegisteredCommand>()\n const aliases = new Map<string, string>()\n for (const entry of [...input.commands].sort((a, b) => compareIds(a.id, b.id))) {\n const load = entry.load\n let pending: Promise<Command> | undefined\n commands.set(entry.id, {\n id: entry.id,\n command: entry.command,\n aliases: [...entry.aliases].sort(),\n file: entry.file,\n inputSchema: entry.inputSchema,\n outputSchema: entry.outputSchema,\n load: () =>\n (pending ??= load().catch((error: unknown) => {\n pending = undefined\n throw error\n })),\n })\n for (const alias of entry.aliases) aliases.set(alias, entry.id)\n }\n const namespaceIds = new Set<string>([\"\"])\n for (const id of commands.keys()) {\n for (let ns = parentNamespace(id); ns !== \"\"; ns = parentNamespace(ns)) namespaceIds.add(ns)\n }\n return { commands, aliases, namespaces: namespaceTable(namespaceIds, [...commands.keys()], input.namespaces) }\n}\n\n/** 실행 가능한 명령어. eager = entry.command, lazy = entry.load() (모듈 import) */\nexport function loadCommand(entry: RegisteredCommand): Promise<Command> {\n return entry.load ? entry.load() : Promise.resolve(entry.command)\n}\n\nfunction namespaceTable(\n namespaceIds: ReadonlySet<string>,\n commandIds: readonly string[],\n inputs: readonly RegistryNamespaceInput[] | undefined,\n): Map<string, NamespaceInfo> {\n const descriptions = new Map<string, string | undefined>()\n for (const ns of inputs ?? []) descriptions.set(ns.id, ns.description)\n const namespaces = new Map<string, NamespaceInfo>()\n for (const id of [...namespaceIds].sort(compareIds)) {\n namespaces.set(id, {\n id,\n description: descriptions.get(id),\n commands: commandIds.filter((c) => parentNamespace(c) === id),\n namespaces: [...namespaceIds].filter((n) => n !== \"\" && parentNamespace(n) === id).sort(compareIds),\n })\n }\n return namespaces\n}\n\n/** 정식 ID 또는 별칭으로 명령어 찾기 */\nexport function resolveCommand(registry: Registry, id: string): RegisteredCommand | undefined {\n return registry.commands.get(id) ?? registry.commands.get(registry.aliases.get(id) ?? \"\")\n}\n\nfunction toJsonSchema(schema: z.ZodType, io: \"input\" | \"output\"): JsonSchema {\n return z.toJSONSchema(schema, { target: \"draft-2020-12\", io, unrepresentable: \"throw\" }) as JsonSchema\n}\n\nfunction compareIds(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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","sourcesContent":["import * as z from \"zod\"\nimport { isCommand, type Command } from \"./command.ts\"\nimport { MextBuildError, type BuildIssue } from \"./errors.ts\"\nimport { isSegment, parentNamespace, RESERVED_ROOT_SEGMENTS } from \"./ids.ts\"\nimport type { PromptSet } from \"./prompt.ts\"\nimport type { ResourceSet } from \"./resource.ts\"\n\nexport type JsonSchema = Record<string, unknown>\n\nexport interface RegistryCommandInput {\n /** 정식 ID. 점 구분 kebab-case 세그먼트 */\n id: string\n command: Command\n /** commands/ 기준 상대 경로 (posix). 스캔 결과에만 있음 */\n file?: string\n}\n\nexport interface RegistryNamespaceInput {\n /** \"\" = 루트 */\n id: string\n description?: string\n}\n\nexport interface RegistryInput {\n commands: readonly RegistryCommandInput[]\n namespaces?: readonly RegistryNamespaceInput[]\n}\n\nexport interface RegisteredCommand {\n id: string\n /**\n * 메타데이터 (description · 안전성 · scopes · examples · positional · aliases) 의 원본.\n * eager (createRegistry) = 실행 가능한 명령어 그대로. lazy (createLazyRegistry) = manifest 로 만든 메타데이터만\n * (input · execute 는 load() 결과에서)\n */\n command: Command\n /** lazy Registry: 명령어 모듈 import (1회 캐시) → 실행 가능한 명령어. 없음 = command 가 실행 가능. loadCommand 로 호출 */\n load?: () => Promise<Command>\n /** 별칭의 전체 ID (정렬) */\n aliases: readonly string[]\n file: string | undefined\n /** input 의 JSON Schema 2020-12 (io: input) */\n inputSchema: JsonSchema\n /** output 의 JSON Schema 2020-12 (io: output) */\n outputSchema: JsonSchema | undefined\n}\n\nexport interface NamespaceInfo {\n /** \"\" = 루트 */\n id: string\n /** _index.md 내용 */\n description: string | undefined\n /** 직속 명령어 정식 ID (정렬). index.ts 명령어 (네임스페이스와 같은 ID) 는 상위 네임스페이스에 속한다 */\n commands: readonly string[]\n /** 직속 하위 네임스페이스 ID (정렬) */\n namespaces: readonly string[]\n}\n\nexport interface Registry {\n /** 정식 ID → 명령어. ID 순 */\n readonly commands: ReadonlyMap<string, RegisteredCommand>\n /** 별칭 전체 ID → 정식 ID */\n readonly aliases: ReadonlyMap<string, string>\n /** 네임스페이스 ID → 정보. 루트 (\"\") 포함, ID 순 */\n readonly namespaces: ReadonlyMap<string, NamespaceInfo>\n /** MCP 자원 (resources/, §12.3). 없음 = 기능 없음 (capability 미선언). 명령어 Map 과 별개 */\n readonly resources?: ResourceSet\n /** MCP 프롬프트 (prompts/, §12.3). 없음 = 기능 없음 (capability 미선언). 이름 순 */\n readonly prompts?: PromptSet\n}\n\n/** 명령어 목록에서 Registry 생성. ID · 별칭 · 스키마 규칙 위반은 MextBuildError */\nexport function createRegistry(input: RegistryInput): Registry {\n const { registry, issues } = collectRegistry(input)\n if (issues.length > 0) throw new MextBuildError(issues)\n return registry\n}\n\n/**\n * createRegistry 의 수집형 (mext build 의 일괄 검증용). 던지지 않는다.\n * registry = 규칙을 통과한 명령어만, issues = 위반 전부\n */\nexport function collectRegistry(input: RegistryInput): { registry: Registry; issues: BuildIssue[] } {\n const issues: BuildIssue[] = []\n const accepted: RegistryCommandInput[] = []\n const seen = new Map<string, RegistryCommandInput>()\n\n for (const entry of input.commands) {\n const where = { id: entry.id, file: entry.file }\n if (!isCommand(entry.command)) {\n issues.push({ code: \"INVALID_COMMAND\", message: \"not a defineCommand result\", ...where })\n continue\n }\n const segments = entry.id.split(\".\")\n const bad = segments.find((s) => !isSegment(s))\n if (bad !== undefined) {\n issues.push({ code: \"INVALID_SEGMENT\", message: `segment \"${bad}\" is not kebab-case`, ...where })\n continue\n }\n if (RESERVED_ROOT_SEGMENTS.includes(segments[0]!)) {\n issues.push({ code: \"RESERVED_ID\", message: `root segment \"${segments[0]}\" is reserved`, ...where })\n continue\n }\n const prev = seen.get(entry.id)\n if (prev) {\n issues.push({ code: \"DUPLICATE_ID\", message: `duplicate ID (also ${prev.file ?? prev.id})`, ...where })\n continue\n }\n seen.set(entry.id, entry)\n accepted.push(entry)\n }\n\n // 네임스페이스 = 명령어 ID 의 모든 상위 경로\n const namespaceIds = new Set<string>([\"\"])\n for (const { id } of accepted) {\n for (let ns = parentNamespace(id); ns !== \"\"; ns = parentNamespace(ns)) namespaceIds.add(ns)\n }\n\n const aliases = new Map<string, string>()\n const aliasesOf = new Map<string, string[]>()\n for (const entry of accepted) {\n const where = { id: entry.id, file: entry.file }\n const parent = parentNamespace(entry.id)\n const own: string[] = []\n for (const alias of entry.command.aliases) {\n if (!isSegment(alias)) {\n issues.push({ code: \"INVALID_ALIAS\", message: `alias \"${alias}\" is not a kebab-case segment`, ...where })\n continue\n }\n if (parent === \"\") {\n issues.push({ code: \"INVALID_ALIAS\", message: `alias \"${alias}\": aliases are not allowed at the root`, ...where })\n continue\n }\n const full = `${parent}.${alias}`\n const owner = seen.has(full) ? full : aliases.get(full)\n if (owner !== undefined || namespaceIds.has(full)) {\n issues.push({\n code: \"DUPLICATE_ID\",\n message: `alias ${full} duplicates ${owner !== undefined ? owner : \"a namespace\"}`,\n ...where,\n })\n continue\n }\n aliases.set(full, entry.id)\n own.push(full)\n }\n aliasesOf.set(entry.id, own.sort())\n }\n\n const commands = new Map<string, RegisteredCommand>()\n for (const entry of [...accepted].sort((a, b) => compareIds(a.id, b.id))) {\n const where = { id: entry.id, file: entry.file }\n let inputSchema: JsonSchema\n let outputSchema: JsonSchema | undefined\n try {\n inputSchema = toJsonSchema(entry.command.input, \"input\")\n outputSchema = entry.command.output ? toJsonSchema(entry.command.output, \"output\") : undefined\n } catch (error) {\n issues.push({ code: \"SCHEMA_UNREPRESENTABLE\", message: errorMessage(error), ...where })\n continue\n }\n commands.set(entry.id, {\n id: entry.id,\n command: entry.command,\n aliases: aliasesOf.get(entry.id) ?? [],\n file: entry.file,\n inputSchema,\n outputSchema,\n })\n }\n\n const namespaces = namespaceTable(namespaceIds, [...commands.keys()], input.namespaces)\n return { registry: { commands, aliases, namespaces }, issues }\n}\n\n/** lazy Registry 의 명령어: manifest 메타데이터 + 모듈 로더 (규칙 검증은 mext build 가 이미 함) */\nexport interface LazyCommandInput {\n id: string\n /** 메타데이터만 있는 명령어 (input · execute 는 load 결과). RegisteredCommand.command */\n command: Command\n /** 별칭의 전체 ID */\n aliases: readonly string[]\n file?: string\n inputSchema: JsonSchema\n outputSchema?: JsonSchema\n /** 실행 시 1회 호출 (결과 캐시, 실패는 다음 호출에서 재시도) */\n load: () => Promise<Command>\n}\n\n/**\n * manifest (mext build 산출) 로 Registry 생성. 명령어 모듈을 import 하지 않는다 (mext start · handler.js).\n * help · tools/list · UNKNOWN_COMMAND · 권한 검사 = 메타데이터만, 입력 검증 · execute = loadCommand 후\n */\nexport function createLazyRegistry(input: {\n commands: readonly LazyCommandInput[]\n namespaces?: readonly RegistryNamespaceInput[]\n}): Registry {\n const commands = new Map<string, RegisteredCommand>()\n const aliases = new Map<string, string>()\n for (const entry of [...input.commands].sort((a, b) => compareIds(a.id, b.id))) {\n const load = entry.load\n let pending: Promise<Command> | undefined\n commands.set(entry.id, {\n id: entry.id,\n command: entry.command,\n aliases: [...entry.aliases].sort(),\n file: entry.file,\n inputSchema: entry.inputSchema,\n outputSchema: entry.outputSchema,\n load: () =>\n (pending ??= load().catch((error: unknown) => {\n pending = undefined\n throw error\n })),\n })\n for (const alias of entry.aliases) aliases.set(alias, entry.id)\n }\n const namespaceIds = new Set<string>([\"\"])\n for (const id of commands.keys()) {\n for (let ns = parentNamespace(id); ns !== \"\"; ns = parentNamespace(ns)) namespaceIds.add(ns)\n }\n return { commands, aliases, namespaces: namespaceTable(namespaceIds, [...commands.keys()], input.namespaces) }\n}\n\n/**\n * keep 을 통과한 명령어만 남긴 Registry (expose 의 표면별 보기). 별칭 · 네임스페이스를 다시 계산한다:\n * 남은 명령어가 없는 네임스페이스는 없어지고, 남은 네임스페이스의 설명은 유지. 명령어 항목 · 자원 · 프롬프트는 원본과 같은 객체\n */\nexport function filterRegistry(registry: Registry, keep: (entry: RegisteredCommand) => boolean): Registry {\n const commands = new Map<string, RegisteredCommand>()\n for (const [id, entry] of registry.commands) if (keep(entry)) commands.set(id, entry)\n const aliases = new Map<string, string>()\n for (const [alias, id] of registry.aliases) if (commands.has(id)) aliases.set(alias, id)\n const namespaceIds = new Set<string>([\"\"])\n for (const id of commands.keys()) {\n for (let ns = parentNamespace(id); ns !== \"\"; ns = parentNamespace(ns)) namespaceIds.add(ns)\n }\n const descriptions = [...registry.namespaces.values()].flatMap((n) => (n.description === undefined ? [] : [{ id: n.id, description: n.description }]))\n return { ...registry, commands, aliases, namespaces: namespaceTable(namespaceIds, [...commands.keys()], descriptions) }\n}\n\n/** 실행 가능한 명령어. eager = entry.command, lazy = entry.load() (모듈 import) */\nexport function loadCommand(entry: RegisteredCommand): Promise<Command> {\n return entry.load ? entry.load() : Promise.resolve(entry.command)\n}\n\nfunction namespaceTable(\n namespaceIds: ReadonlySet<string>,\n commandIds: readonly string[],\n inputs: readonly RegistryNamespaceInput[] | undefined,\n): Map<string, NamespaceInfo> {\n const descriptions = new Map<string, string | undefined>()\n for (const ns of inputs ?? []) descriptions.set(ns.id, ns.description)\n const namespaces = new Map<string, NamespaceInfo>()\n for (const id of [...namespaceIds].sort(compareIds)) {\n namespaces.set(id, {\n id,\n description: descriptions.get(id),\n commands: commandIds.filter((c) => parentNamespace(c) === id),\n namespaces: [...namespaceIds].filter((n) => n !== \"\" && parentNamespace(n) === id).sort(compareIds),\n })\n }\n return namespaces\n}\n\n/** 정식 ID 또는 별칭으로 명령어 찾기 */\nexport function resolveCommand(registry: Registry, id: string): RegisteredCommand | undefined {\n return registry.commands.get(id) ?? registry.commands.get(registry.aliases.get(id) ?? \"\")\n}\n\nfunction toJsonSchema(schema: z.ZodType, io: \"input\" | \"output\"): JsonSchema {\n return z.toJSONSchema(schema, { target: \"draft-2020-12\", io, unrepresentable: \"throw\" }) as JsonSchema\n}\n\nfunction compareIds(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n"]}
|
package/dist/remote/client.d.ts
CHANGED
|
@@ -61,6 +61,8 @@ export interface RequestOptions {
|
|
|
61
61
|
export interface CallToolOptions extends RequestOptions {
|
|
62
62
|
/** input_required 응답 처리 → 이번 라운드의 inputResponses. 없으면 RemoteInputRequiredError */
|
|
63
63
|
onInputRequired?: (request: InputRequired, round: number) => Promise<InputResponses>;
|
|
64
|
+
/** tools/call 요청 params._meta 에 실을 값 (예: 확인 표시 "dev.mext/approval"). 재시도 라운드에도 같은 값 */
|
|
65
|
+
meta?: Record<string, unknown>;
|
|
64
66
|
}
|
|
65
67
|
/** HTTP 401. challenge = WWW-Authenticate 파싱 결과, data = JSON-RPC error.data (mext 는 UNAUTHENTICATED toJSON) */
|
|
66
68
|
export declare class RemoteUnauthorizedError extends Error {
|
package/dist/remote/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VERSION } from "../version.js";
|
|
1
|
+
import { VERSION } from "../version-constant.js";
|
|
2
2
|
/**
|
|
3
3
|
* 원격 실행용 최소 MCP 클라이언트 (Streamable HTTP, 프로토콜 2026-07-28, stateless).
|
|
4
4
|
* 요청마다 POST 1회: _meta envelope (버전 · clientInfo · clientCapabilities) + MCP-Protocol-Version · Mcp-Method ·
|
|
@@ -154,8 +154,9 @@ export function createRemoteClient(options) {
|
|
|
154
154
|
const callTool = async (tool, args, opts = {}) => {
|
|
155
155
|
const headers = { "Mcp-Name": tool.name, ...paramHeaders(tool, args) };
|
|
156
156
|
let retry = {};
|
|
157
|
+
const meta = opts.meta ? { _meta: opts.meta } : {};
|
|
157
158
|
for (let round = 0;; round++) {
|
|
158
|
-
const result = await request("tools/call", { name: tool.name, arguments: args, ...retry }, opts, headers);
|
|
159
|
+
const result = await request("tools/call", { name: tool.name, arguments: args, ...retry, ...meta }, opts, headers);
|
|
159
160
|
if (result.resultType !== "input_required")
|
|
160
161
|
return result;
|
|
161
162
|
const required = {};
|