@obov/mext 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build.js +67 -4
- package/dist/build.js.map +1 -1
- package/dist/cli/ask-url.d.ts +16 -0
- package/dist/cli/ask-url.js +27 -0
- package/dist/cli/ask-url.js.map +1 -0
- package/dist/cli/build.js +7 -1
- package/dist/cli/build.js.map +1 -1
- package/dist/cli/dev-server.d.ts +7 -1
- package/dist/cli/dev-server.js +15 -2
- package/dist/cli/dev-server.js.map +1 -1
- package/dist/cli/dev.js +22 -7
- package/dist/cli/dev.js.map +1 -1
- package/dist/cli/login.d.ts +5 -0
- package/dist/cli/login.js +11 -7
- package/dist/cli/login.js.map +1 -1
- package/dist/cli/logout.js +4 -6
- package/dist/cli/logout.js.map +1 -1
- package/dist/cli/output.d.ts +1 -1
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/run.js +7 -3
- package/dist/cli/run.js.map +1 -1
- package/dist/client/cache.d.ts +14 -4
- package/dist/client/cache.js +10 -3
- package/dist/client/cache.js.map +1 -1
- package/dist/client/main.js +11 -10
- package/dist/client/main.js.map +1 -1
- package/dist/client/manifest.d.ts +13 -1
- package/dist/client/manifest.js +43 -0
- package/dist/client/manifest.js.map +1 -1
- package/dist/client/runner.d.ts +3 -1
- package/dist/client/runner.js +80 -19
- package/dist/client/runner.js.map +1 -1
- package/dist/client/task.d.ts +47 -0
- package/dist/client/task.js +126 -0
- package/dist/client/task.js.map +1 -0
- package/dist/command.d.ts +30 -3
- package/dist/command.js +16 -0
- package/dist/command.js.map +1 -1
- package/dist/config.d.ts +40 -6
- package/dist/config.js +57 -8
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +3 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +17 -5
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/dist/instrumentation.d.ts +14 -2
- package/dist/instrumentation.js +12 -4
- package/dist/instrumentation.js.map +1 -1
- package/dist/invoke.d.ts +38 -0
- package/dist/invoke.js +72 -3
- package/dist/invoke.js.map +1 -1
- package/dist/local-bin.js +5 -3
- package/dist/local-bin.js.map +1 -1
- package/dist/manifest.d.ts +48 -3
- package/dist/manifest.js +14 -3
- package/dist/manifest.js.map +1 -1
- package/dist/mcp/constants.d.ts +4 -0
- package/dist/mcp/constants.js +4 -0
- package/dist/mcp/constants.js.map +1 -1
- package/dist/mcp/dispatch.d.ts +21 -7
- package/dist/mcp/dispatch.js +42 -7
- package/dist/mcp/dispatch.js.map +1 -1
- package/dist/mcp/http.d.ts +23 -5
- package/dist/mcp/http.js +64 -9
- package/dist/mcp/http.js.map +1 -1
- package/dist/mcp/index.d.ts +14 -6
- package/dist/mcp/index.js +7 -3
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/mrtr.d.ts +40 -8
- package/dist/mcp/mrtr.js +32 -11
- package/dist/mcp/mrtr.js.map +1 -1
- package/dist/mcp/prompts.d.ts +25 -0
- package/dist/mcp/prompts.js +164 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/resources.d.ts +48 -0
- package/dist/mcp/resources.js +142 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/server.d.ts +30 -5
- package/dist/mcp/server.js +143 -16
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/stdio.d.ts +5 -0
- package/dist/mcp/stdio.js +16 -3
- package/dist/mcp/stdio.js.map +1 -1
- package/dist/mcp/subscriptions.d.ts +61 -0
- package/dist/mcp/subscriptions.js +188 -0
- package/dist/mcp/subscriptions.js.map +1 -0
- package/dist/mcp/tasks.d.ts +127 -0
- package/dist/mcp/tasks.js +448 -0
- package/dist/mcp/tasks.js.map +1 -0
- package/dist/module-files.d.ts +24 -0
- package/dist/module-files.js +97 -0
- package/dist/module-files.js.map +1 -0
- package/dist/prompt.d.ts +133 -0
- package/dist/prompt.js +222 -0
- package/dist/prompt.js.map +1 -0
- package/dist/registry.d.ts +6 -0
- package/dist/registry.js.map +1 -1
- package/dist/remote/client.d.ts +17 -1
- package/dist/remote/client.js +18 -2
- package/dist/remote/client.js.map +1 -1
- package/dist/resource.d.ts +169 -0
- package/dist/resource.js +301 -0
- package/dist/resource.js.map +1 -0
- package/dist/route.d.ts +71 -0
- package/dist/route.js +280 -0
- package/dist/route.js.map +1 -0
- package/dist/start.d.ts +14 -3
- package/dist/start.js +76 -11
- package/dist/start.js.map +1 -1
- package/dist/state.d.ts +38 -0
- package/dist/state.js +98 -0
- package/dist/state.js.map +1 -0
- package/package.json +1 -1
package/dist/command.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as z from \"zod\"\nimport type { Principal } from \"./principal.ts\"\n\n/**\n * 도입 프로젝트가 declaration merging 으로 채우는 ctx.app 타입.\n *\n * declare module \"@obov/mext\" { interface MextApp { db: Db } }\n */\nexport interface MextApp {}\n\nexport interface ProgressUpdate {\n progress: number\n total?: number\n message?: string\n}\n\nexport interface ConfirmRequest {\n kind: \"confirm\"\n message: string\n}\n\nexport interface InputRequest<S extends z.ZodObject = z.ZodObject> {\n kind: \"input\"\n message: string\n schema: S\n}\n\n/** URL 모드 (spec §12.4). 제3자 인가 · API 키 · 결제처럼 클라이언트를 거치면 안 되는 입력. url = http(s) 절대 URL */\nexport interface UrlRequest {\n kind: \"url\"\n message: string\n url: string\n}\n\nexport type AskRequest = ConfirmRequest | InputRequest | UrlRequest\n\n/** ctx.ask. confirm = boolean, input = schema 로 검증된 값, url = boolean (accept = URL 열기 동의. 완료 의미 아님) */\nexport interface Ask {\n (request: ConfirmRequest): Promise<boolean>\n (request: UrlRequest): Promise<boolean>\n <S extends z.ZodObject>(request: InputRequest<S>): Promise<z.output<S>>\n}\n\nexport interface CommandContext {\n principal: Principal\n signal: AbortSignal\n progress(update: ProgressUpdate): void\n ask: Ask\n app: MextApp\n /**\n * 자원 갱신 알림 (§12.5) → 구독 중인 subscriptions/listen 스트림에 notifications/resources/updated.\n * state 없음 · 구독 없음 · 로컬 CLI 실행 = no-op. bus 발행 실패 = stderr 1줄 (거부하지 않음)\n */\n resourceUpdated(uri: string): Promise<void>\n}\n\nexport type InputSchema = z.ZodObject\n\ntype InputKey<I extends InputSchema> = keyof z.input<I> & string\n\nexport interface CommandDefinition<I extends InputSchema, R> {\n /** 필수. help · MCP 설명의 원본 */\n description: string\n /** 필수. 최상위 z.object */\n input: I\n /** 선택. MCP outputSchema 의 원본 (tools: \"command\"). 있으면 모든 어댑터가 반환값을 검증 (실패 = EXECUTION_ERROR) */\n output?: z.ZodType\n readOnly?: boolean\n destructive?: boolean\n requiresConfirmation?: boolean\n /** 실행에 필요한 scopes. 전부 보유해야 실행 */\n scopes?: readonly string[]\n examples?: readonly z.input<I>[]\n /** CLI positional 인자로 받을 input 키 순서 */\n positional?: readonly InputKey<I>[]\n /** 같은 네임스페이스 안 kebab-case 세그먼트. commands/users/get.ts 의 \"fetch\" → users.fetch */\n aliases?: readonly string[]\n /**\n * 장시간 명령어. 조건 (state.store · 클라이언트 선언) 이 맞으면 MCP tasks 확장으로 실행 (§12.6).\n * true = 기본 ttlMs (DEFAULT_TASK_TTL_MS). ttlMs = 종료 후 tasks/get 으로 조회할 수 있는 시간\n */\n task?: boolean | { ttlMs: number }\n execute(input: z.output<I>, ctx: CommandContext): R | Promise<R>\n}\n\n/** task 명령어의 기본 ttlMs (1시간) */\nexport const DEFAULT_TASK_TTL_MS = 3_600_000\n\n/** defineCommand 의 task 정규형 */\nexport interface TaskOptions {\n ttlMs: number\n}\n\nexport const COMMAND: unique symbol = Symbol.for(\"@obov/mext/command\") as never\n\nexport interface Command<I extends InputSchema = InputSchema, R = unknown> {\n readonly [COMMAND]: true\n readonly description: string\n readonly input: I\n readonly output: z.ZodType | undefined\n readonly readOnly: boolean\n readonly destructive: boolean\n readonly requiresConfirmation: boolean\n readonly scopes: readonly string[]\n readonly examples: readonly z.input<I>[]\n readonly positional: readonly string[]\n readonly aliases: readonly string[]\n /** task 명령어 (§12.6). 없음 = 항상 동기 */\n readonly task?: TaskOptions\n execute(input: z.output<I>, ctx: CommandContext): R | Promise<R>\n}\n\nexport function defineCommand<I extends InputSchema, R>(definition: CommandDefinition<I, R>): Command<I, R> {\n const d = definition as Partial<CommandDefinition<I, R>>\n if (typeof d.description !== \"string\" || d.description.trim() === \"\") {\n throw new TypeError(\"defineCommand: description must be a non-empty string\")\n }\n if (!isObjectSchema(d.input)) {\n throw new TypeError(\"defineCommand: input must be a top-level z.object schema\")\n }\n if (typeof d.execute !== \"function\") {\n throw new TypeError(\"defineCommand: execute must be a function\")\n }\n const shapeKeys = Object.keys(d.input.shape)\n for (const key of d.positional ?? []) {\n if (!shapeKeys.includes(key)) {\n throw new TypeError(`defineCommand: positional \"${key}\" is not an input key`)\n }\n }\n const task = taskOptions(d.task)\n const execute = d.execute\n return Object.freeze({\n [COMMAND]: true as const,\n description: d.description,\n input: d.input,\n output: d.output,\n readOnly: d.readOnly === true,\n destructive: d.destructive === true,\n requiresConfirmation: d.requiresConfirmation === true,\n scopes: Object.freeze([...(d.scopes ?? [])]),\n examples: Object.freeze([...(d.examples ?? [])]),\n positional: Object.freeze([...(d.positional ?? [])]),\n aliases: Object.freeze([...(d.aliases ?? [])]),\n ...(task ? { task } : {}),\n execute(input: z.output<I>, ctx: CommandContext) {\n return execute.call(definition, input, ctx)\n },\n })\n}\n\n/** task: true | { ttlMs } → TaskOptions. false · undefined = 없음, 그 외 = TypeError */\nfunction taskOptions(value: unknown): TaskOptions | undefined {\n if (value === undefined || value === false) return undefined\n if (value === true) return Object.freeze({ ttlMs: DEFAULT_TASK_TTL_MS })\n const ttlMs = (value as { ttlMs?: unknown } | null)?.ttlMs\n if (typeof value !== \"object\" || !Number.isSafeInteger(ttlMs) || (ttlMs as number) <= 0) {\n throw new TypeError(\"defineCommand: task must be true or { ttlMs: <positive integer> }\")\n }\n return Object.freeze({ ttlMs: ttlMs as number })\n}\n\nexport function isCommand(value: unknown): value is Command {\n return typeof value === \"object\" && value !== null && (value as Record<symbol, unknown>)[COMMAND] === true\n}\n\nfunction isObjectSchema(value: unknown): value is InputSchema {\n const def = (value as { _zod?: { def?: { type?: unknown } } } | undefined)?._zod?.def\n return def?.type === \"object\" && typeof (value as { safeParseAsync?: unknown }).safeParseAsync === \"function\"\n}\n"]}
|
package/dist/config.d.ts
CHANGED
|
@@ -2,18 +2,23 @@ import type { CliErrorFormatter } from "./cli/output.ts";
|
|
|
2
2
|
import type { MextApp } from "./command.ts";
|
|
3
3
|
import type { OAuthResourceOptions } from "./mcp/http.ts";
|
|
4
4
|
import { type Principal } from "./principal.ts";
|
|
5
|
+
import { type MextState } from "./state.ts";
|
|
5
6
|
/** mext.config.ts 의 default export */
|
|
6
7
|
export interface MextConfig {
|
|
7
8
|
/** 명령어 폴더. 설정 파일 위치 (cwd) 기준. 기본 "commands" */
|
|
8
9
|
commandsDir?: string;
|
|
10
|
+
/** MCP 자원 폴더 (§12.3). 설정 파일 위치 (cwd) 기준. 기본 "resources". 폴더 없음 = 자원 없음 */
|
|
11
|
+
resourcesDir?: string;
|
|
12
|
+
/** MCP 프롬프트 폴더 (§12.3). 설정 파일 위치 (cwd) 기준. 기본 "prompts". 폴더 없음 = 프롬프트 없음 */
|
|
13
|
+
promptsDir?: string;
|
|
9
14
|
/** ctx.app 팩토리. 실행 프로세스당 1회 */
|
|
10
15
|
app?: () => MextApp | Promise<MextApp>;
|
|
11
16
|
/** HTTP 전용. 요청마다 Authorization 헤더로 주체 생성. 잘못된 토큰 = unauthenticated() throw */
|
|
12
17
|
auth?: (req: {
|
|
13
18
|
authorization: string | undefined;
|
|
14
19
|
}) => Principal | Promise<Principal>;
|
|
15
|
-
/** MCP 노출 방식. 기본 "execute" */
|
|
16
|
-
tools?: "execute" | "split";
|
|
20
|
+
/** MCP 노출 방식. 기본 "execute". command = 명령어별 도구 (§12.2) */
|
|
21
|
+
tools?: "execute" | "split" | "command";
|
|
17
22
|
server?: {
|
|
18
23
|
host?: string;
|
|
19
24
|
port?: number;
|
|
@@ -27,6 +32,18 @@ export interface MextConfig {
|
|
|
27
32
|
cli?: CliConfig;
|
|
28
33
|
/** MCP 서버 선언 (serverInfo.name · instructions · capabilities) · stdio 서버 발신 알림 (§6) */
|
|
29
34
|
mcp?: McpConfig;
|
|
35
|
+
/**
|
|
36
|
+
* 서버 비밀 (32바이트 이상). MRTR requestState 서명 키 (§12.1). 미지정 = MEXT_SECRET 환경변수, 둘 다 없으면 프로세스별 임의 키.
|
|
37
|
+
* 다중 인스턴스 · 재시작을 넘는 ctx.ask 재시도에 필요
|
|
38
|
+
*/
|
|
39
|
+
secret?: string;
|
|
40
|
+
/**
|
|
41
|
+
* 도입 프로젝트가 주입하는 저장소 · 메시지 버스 (§12.1). 없으면 stateless.
|
|
42
|
+
* 단일 프로세스 = memoryState(), 다중 인스턴스 = 도입 프로젝트가 구현한 { store, bus }
|
|
43
|
+
*/
|
|
44
|
+
state?: MextState;
|
|
45
|
+
/** HTTP 경로 폴더 (§12.4). 설정 파일 위치 (cwd) 기준. 기본 "routes". 폴더 없음 = route 없음 */
|
|
46
|
+
routesDir?: string;
|
|
30
47
|
}
|
|
31
48
|
/** mext.config.ts 의 mcp (§6 서버 선언 · 서버 발신 알림) */
|
|
32
49
|
export interface McpConfig {
|
|
@@ -87,6 +104,10 @@ export interface CliConfig {
|
|
|
87
104
|
local?: boolean;
|
|
88
105
|
}
|
|
89
106
|
export declare const CONFIG_FILE = "mext.config.ts";
|
|
107
|
+
/** secret 최소 길이 (바이트, HMAC-SHA256 키) */
|
|
108
|
+
export declare const SECRET_MIN_BYTES = 32;
|
|
109
|
+
/** secret 환경변수 */
|
|
110
|
+
export declare const SECRET_ENV = "MEXT_SECRET";
|
|
90
111
|
/** 고객 CLI 의 내장 명령 (루트 세그먼트로 쓸 수 없음) */
|
|
91
112
|
export declare const CLI_BUILTIN_COMMANDS: readonly string[];
|
|
92
113
|
/** 로컬 bin (cli.local) 의 내장 명령 */
|
|
@@ -97,16 +118,29 @@ export declare function defineConfig(config: MextConfig): MextConfig;
|
|
|
97
118
|
export declare function loadConfig(cwd?: string): Promise<MextConfig>;
|
|
98
119
|
/** commands/ 절대 경로 */
|
|
99
120
|
export declare function resolveCommandsDir(cwd: string, config: MextConfig): string;
|
|
121
|
+
/** resources/ 절대 경로 */
|
|
122
|
+
export declare function resolveResourcesDir(cwd: string, config: MextConfig): string;
|
|
123
|
+
/** prompts/ 절대 경로 */
|
|
124
|
+
export declare function resolvePromptsDir(cwd: string, config: MextConfig): string;
|
|
125
|
+
/** routes/ 절대 경로 */
|
|
126
|
+
export declare function resolveRoutesDir(cwd: string, config: MextConfig): string;
|
|
100
127
|
/** 로컬 실행 주체: config.localPrincipal (값 · 함수) 또는 localPrincipal() */
|
|
101
128
|
export declare function resolveLocalPrincipal(config: MextConfig): Promise<Principal>;
|
|
102
|
-
/**
|
|
103
|
-
|
|
129
|
+
/**
|
|
130
|
+
* 서버 비밀: config.secret > MEXT_SECRET > undefined (프로세스별 임의 키).
|
|
131
|
+
* 환경변수 값이 짧으면 TypeError (config.secret 은 설정 로드 시 검사)
|
|
132
|
+
*/
|
|
133
|
+
export declare function resolveSecret(config: MextConfig, env?: Record<string, string | undefined>): string | undefined;
|
|
134
|
+
/** 서버 선언 (모든 transport): config.mcp 의 name · instructions · capabilities + secret (requestStateKey) + state. onConnect 는 stdio 만 따로 */
|
|
135
|
+
export declare function mcpDeclarations(config: MextConfig, env?: Record<string, string | undefined>): {
|
|
104
136
|
name?: string;
|
|
105
137
|
instructions?: string;
|
|
106
138
|
capabilities?: McpCapabilities;
|
|
139
|
+
requestStateKey?: string;
|
|
140
|
+
state?: MextState;
|
|
107
141
|
};
|
|
108
|
-
/**
|
|
109
|
-
export declare function mcpStdioDeclarations(config: MextConfig): ReturnType<typeof mcpDeclarations> & {
|
|
142
|
+
/** stdio 옵션 = 선언 + onConnect */
|
|
143
|
+
export declare function mcpStdioDeclarations(config: MextConfig, env?: Record<string, string | undefined>): ReturnType<typeof mcpDeclarations> & {
|
|
110
144
|
onConnect?: McpConnectHandler;
|
|
111
145
|
era?: "auto" | "legacy";
|
|
112
146
|
};
|
package/dist/config.js
CHANGED
|
@@ -11,8 +11,13 @@ import { join, resolve } from "node:path";
|
|
|
11
11
|
import { pathToFileURL } from "node:url";
|
|
12
12
|
import { isSegment } from "./ids.js";
|
|
13
13
|
import { localPrincipal } from "./principal.js";
|
|
14
|
+
import { stateProblem } from "./state.js";
|
|
14
15
|
export const CONFIG_FILE = "mext.config.ts";
|
|
15
|
-
const CONFIG_KEYS = ["commandsDir", "app", "auth", "tools", "server", "oauth", "localPrincipal", "cli", "mcp"];
|
|
16
|
+
const CONFIG_KEYS = ["commandsDir", "app", "auth", "tools", "server", "oauth", "localPrincipal", "cli", "mcp", "secret", "state", "resourcesDir", "routesDir", "promptsDir"];
|
|
17
|
+
/** secret 최소 길이 (바이트, HMAC-SHA256 키) */
|
|
18
|
+
export const SECRET_MIN_BYTES = 32;
|
|
19
|
+
/** secret 환경변수 */
|
|
20
|
+
export const SECRET_ENV = "MEXT_SECRET";
|
|
16
21
|
const MCP_KEYS = ["name", "instructions", "capabilities", "onConnect", "stdioEra"];
|
|
17
22
|
const CLI_KEYS = ["bin", "url", "packageName", "version", "manifest", "errors", "local"];
|
|
18
23
|
/** 고객 CLI 의 내장 명령 (루트 세그먼트로 쓸 수 없음) */
|
|
@@ -35,6 +40,18 @@ export async function loadConfig(cwd = process.cwd()) {
|
|
|
35
40
|
export function resolveCommandsDir(cwd, config) {
|
|
36
41
|
return resolve(cwd, config.commandsDir ?? "commands");
|
|
37
42
|
}
|
|
43
|
+
/** resources/ 절대 경로 */
|
|
44
|
+
export function resolveResourcesDir(cwd, config) {
|
|
45
|
+
return resolve(cwd, config.resourcesDir ?? "resources");
|
|
46
|
+
}
|
|
47
|
+
/** prompts/ 절대 경로 */
|
|
48
|
+
export function resolvePromptsDir(cwd, config) {
|
|
49
|
+
return resolve(cwd, config.promptsDir ?? "prompts");
|
|
50
|
+
}
|
|
51
|
+
/** routes/ 절대 경로 */
|
|
52
|
+
export function resolveRoutesDir(cwd, config) {
|
|
53
|
+
return resolve(cwd, config.routesDir ?? "routes");
|
|
54
|
+
}
|
|
38
55
|
/** 로컬 실행 주체: config.localPrincipal (값 · 함수) 또는 localPrincipal() */
|
|
39
56
|
export async function resolveLocalPrincipal(config) {
|
|
40
57
|
const p = config.localPrincipal;
|
|
@@ -42,19 +59,36 @@ export async function resolveLocalPrincipal(config) {
|
|
|
42
59
|
return localPrincipal();
|
|
43
60
|
return typeof p === "function" ? await p() : p;
|
|
44
61
|
}
|
|
45
|
-
/**
|
|
46
|
-
|
|
62
|
+
/**
|
|
63
|
+
* 서버 비밀: config.secret > MEXT_SECRET > undefined (프로세스별 임의 키).
|
|
64
|
+
* 환경변수 값이 짧으면 TypeError (config.secret 은 설정 로드 시 검사)
|
|
65
|
+
*/
|
|
66
|
+
export function resolveSecret(config, env = process.env) {
|
|
67
|
+
if (config.secret !== undefined)
|
|
68
|
+
return config.secret;
|
|
69
|
+
const value = env[SECRET_ENV];
|
|
70
|
+
if (value === undefined || value === "")
|
|
71
|
+
return undefined;
|
|
72
|
+
if (Buffer.byteLength(value) < SECRET_MIN_BYTES)
|
|
73
|
+
throw new TypeError(`${SECRET_ENV} must be at least ${SECRET_MIN_BYTES} bytes`);
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
/** 서버 선언 (모든 transport): config.mcp 의 name · instructions · capabilities + secret (requestStateKey) + state. onConnect 는 stdio 만 따로 */
|
|
77
|
+
export function mcpDeclarations(config, env = process.env) {
|
|
47
78
|
const mcp = config.mcp;
|
|
79
|
+
const secret = resolveSecret(config, env);
|
|
48
80
|
return {
|
|
49
81
|
...(mcp?.name !== undefined ? { name: mcp.name } : {}),
|
|
50
82
|
...(mcp?.instructions !== undefined ? { instructions: mcp.instructions } : {}),
|
|
51
83
|
...(mcp?.capabilities !== undefined ? { capabilities: mcp.capabilities } : {}),
|
|
84
|
+
...(secret !== undefined ? { requestStateKey: secret } : {}),
|
|
85
|
+
...(config.state !== undefined ? { state: config.state } : {}),
|
|
52
86
|
};
|
|
53
87
|
}
|
|
54
|
-
/**
|
|
55
|
-
export function mcpStdioDeclarations(config) {
|
|
88
|
+
/** stdio 옵션 = 선언 + onConnect */
|
|
89
|
+
export function mcpStdioDeclarations(config, env = process.env) {
|
|
56
90
|
return {
|
|
57
|
-
...mcpDeclarations(config),
|
|
91
|
+
...mcpDeclarations(config, env),
|
|
58
92
|
...(config.mcp?.onConnect ? { onConnect: config.mcp.onConnect } : {}),
|
|
59
93
|
...(config.mcp?.stdioEra ? { era: config.mcp.stdioEra } : {}),
|
|
60
94
|
};
|
|
@@ -92,12 +126,19 @@ function validateConfig(value) {
|
|
|
92
126
|
fail(`unknown key${unknown.length === 1 ? "" : "s"}: ${unknown.join(", ")}`);
|
|
93
127
|
if (c.commandsDir !== undefined && typeof c.commandsDir !== "string")
|
|
94
128
|
fail("commandsDir must be a string");
|
|
129
|
+
if (c.resourcesDir !== undefined && typeof c.resourcesDir !== "string")
|
|
130
|
+
fail("resourcesDir must be a string");
|
|
131
|
+
if (c.routesDir !== undefined && typeof c.routesDir !== "string")
|
|
132
|
+
fail("routesDir must be a string");
|
|
133
|
+
if (c.promptsDir !== undefined && typeof c.promptsDir !== "string")
|
|
134
|
+
fail("promptsDir must be a string");
|
|
95
135
|
if (c.app !== undefined && typeof c.app !== "function")
|
|
96
136
|
fail("app must be a function");
|
|
97
137
|
if (c.auth !== undefined && typeof c.auth !== "function")
|
|
98
138
|
fail("auth must be a function");
|
|
99
|
-
if (c.tools !== undefined && c.tools !== "execute" && c.tools !== "split")
|
|
100
|
-
fail('tools must be "execute" or "
|
|
139
|
+
if (c.tools !== undefined && c.tools !== "execute" && c.tools !== "split" && c.tools !== "command") {
|
|
140
|
+
fail('tools must be "execute", "split" or "command"');
|
|
141
|
+
}
|
|
101
142
|
if (c.server !== undefined && (typeof c.server !== "object" || c.server === null))
|
|
102
143
|
fail("server must be an object");
|
|
103
144
|
if (c.oauth !== undefined) {
|
|
@@ -110,6 +151,14 @@ function validateConfig(value) {
|
|
|
110
151
|
if (lp !== undefined && typeof lp !== "function" && !isPrincipal(lp)) {
|
|
111
152
|
fail("localPrincipal must be a Principal ({ id, kind, scopes }) or a function");
|
|
112
153
|
}
|
|
154
|
+
if (c.secret !== undefined && (typeof c.secret !== "string" || Buffer.byteLength(c.secret) < SECRET_MIN_BYTES)) {
|
|
155
|
+
fail(`secret must be a string of at least ${SECRET_MIN_BYTES} bytes`);
|
|
156
|
+
}
|
|
157
|
+
if (c.state !== undefined) {
|
|
158
|
+
const problem = stateProblem(c.state);
|
|
159
|
+
if (problem !== undefined)
|
|
160
|
+
fail(problem);
|
|
161
|
+
}
|
|
113
162
|
if (c.cli !== undefined)
|
|
114
163
|
validateCli(c.cli, fail);
|
|
115
164
|
if (c.mcp !== undefined)
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\"\nimport { join, resolve } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport type { CliErrorFormatter } from \"./cli/output.ts\"\nimport type { MextApp } from \"./command.ts\"\nimport { isSegment } from \"./ids.ts\"\nimport type { OAuthResourceOptions } from \"./mcp/http.ts\"\nimport { localPrincipal, type Principal } from \"./principal.ts\"\n\n/** mext.config.ts 의 default export */\nexport interface MextConfig {\n /** 명령어 폴더. 설정 파일 위치 (cwd) 기준. 기본 \"commands\" */\n commandsDir?: string\n /** ctx.app 팩토리. 실행 프로세스당 1회 */\n app?: () => MextApp | Promise<MextApp>\n /** HTTP 전용. 요청마다 Authorization 헤더로 주체 생성. 잘못된 토큰 = unauthenticated() throw */\n auth?: (req: { authorization: string | undefined }) => Principal | Promise<Principal>\n /** MCP 노출 방식. 기본 \"execute\" */\n tools?: \"execute\" | \"split\"\n server?: { host?: string; port?: number; allowedOrigins?: string[] }\n /** HTTP 전용. OAuth 보호 자원 메타데이터 (인가 서버 위치). mext login · MCP 클라이언트의 discovery */\n oauth?: OAuthResourceOptions\n /** 로컬 실행 (mext run · stdio) 주체. 기본 localPrincipal() */\n localPrincipal?: Principal | (() => Principal | Promise<Principal>)\n /** 고객 CLI (mext build → .mext/cli/). 없으면 고객 CLI 를 만들지 않는다 */\n cli?: CliConfig\n /** MCP 서버 선언 (serverInfo.name · instructions · capabilities) · stdio 서버 발신 알림 (§6) */\n mcp?: McpConfig\n}\n\n/** mext.config.ts 의 mcp (§6 서버 선언 · 서버 발신 알림) */\nexport interface McpConfig {\n /** serverInfo.name. 기본 \"mext\" */\n name?: string\n /** initialize · server/discover 결과 instructions */\n instructions?: string\n /** 서버 capabilities 에 병합. experimental 만 (예: { experimental: { \"claude/channel\": {} } }) */\n capabilities?: McpCapabilities\n /**\n * stdio 전용. 연결 하나에 1회 (2025 = notifications/initialized 후, 2026-07-28 = 연결 직후).\n * 반환 함수 = 연결 종료 시 cleanup. HTTP 는 stateless 라 호출하지 않는다\n */\n onConnect?: McpConnectHandler\n /**\n * stdio 프로토콜. auto = 2026-07-28 · 2025 모두, legacy = 2025 만 (server/discover 거부).\n * Claude Code channel 은 2025 연결에서만 알림을 전달. 기본 = experimental[\"claude/channel\"] 선언 시 legacy, 그 외 auto\n */\n stdioEra?: \"auto\" | \"legacy\"\n}\n\nexport interface McpCapabilities {\n experimental?: Record<string, object>\n}\n\n/** stdio 연결. notify = 요청과 무관한 서버 발신 알림 */\nexport interface McpConnection {\n /** 협상된 프로토콜 era */\n readonly era: \"legacy\" | \"modern\"\n /** 연결 종료 후 호출 = reject */\n notify(method: string, params?: Record<string, unknown>): Promise<void>\n /**\n * 클라이언트 발신 알림 수신 (예: notifications/claude/channel/permission_request).\n * SDK 가 처리하는 사양 알림 (initialized · cancelled 등) 은 대상 아님. 같은 method 재등록 = 교체. 반환 = 해제\n */\n onNotification(method: string, handler: (params: Record<string, unknown>) => void | Promise<void>): () => void\n}\n\nexport type McpConnectHandler = (\n conn: McpConnection,\n) => void | (() => void | Promise<void>) | Promise<void | (() => void | Promise<void>)>\n\n/** mext.config.ts 의 cli (§5 고객 CLI 설정) */\nexport interface CliConfig {\n /** 실행 파일 이름 (kebab-case). 환경변수 접두 (MYAPP_TOKEN · MYAPP_URL) · 설정 폴더 (~/.config/<bin>) */\n bin: string\n /** 서버 MCP 엔드포인트 (http(s)). 실행 시 <BIN>_URL 환경변수가 있으면 그 값. local 이면 없음 */\n url?: string\n /** npm 패키지 이름. 기본 = bin */\n packageName?: string\n /** 고객 CLI 버전 (--version · clientInfo). 기본 = 도입 프로젝트 package.json version */\n version?: string\n /** true = 번들 형태 (내장 manifest, 기본), false = 범용 형태 (help · 스키마를 서버에서 조회) */\n manifest?: boolean\n /**\n * 오류 출력 · exit code 커스텀 모듈 (도입 프로젝트 루트 기준 경로). default export = CliErrorFormatter.\n * 고객 CLI bin.js 에 번들, mext run (로컬) 이 import. @obov/mext 는 타입만 import (값 import = 번들 포함)\n */\n errors?: string\n /**\n * true = 로컬 bin (§5). mext build → .mext/bin.js (핸들러를 사용자 PC 에서 실행, .mext/cli/ 없음).\n * 도입 프로젝트 package.json bin { \"<bin>\": \".mext/bin.js\" }. url · packageName · manifest 와 함께 쓸 수 없음\n */\n local?: boolean\n}\n\nexport const CONFIG_FILE = \"mext.config.ts\"\n\nconst CONFIG_KEYS: readonly string[] = [\"commandsDir\", \"app\", \"auth\", \"tools\", \"server\", \"oauth\", \"localPrincipal\", \"cli\", \"mcp\"]\nconst MCP_KEYS: readonly string[] = [\"name\", \"instructions\", \"capabilities\", \"onConnect\", \"stdioEra\"]\nconst CLI_KEYS: readonly string[] = [\"bin\", \"url\", \"packageName\", \"version\", \"manifest\", \"errors\", \"local\"]\n/** 고객 CLI 의 내장 명령 (루트 세그먼트로 쓸 수 없음) */\nexport const CLI_BUILTIN_COMMANDS: readonly string[] = [\"help\", \"login\", \"logout\", \"mcp\"]\n/** 로컬 bin (cli.local) 의 내장 명령 */\nexport const LOCAL_BIN_BUILTIN_COMMANDS: readonly string[] = [\"help\", \"mcp\"]\n\n/** 타입 도우미. 값은 그대로 반환 */\nexport function defineConfig(config: MextConfig): MextConfig {\n return config\n}\n\n/** cwd 의 mext.config.ts 를 import. 없으면 {}. 형식이 틀리면 TypeError (모르는 키 포함) */\nexport async function loadConfig(cwd: string = process.cwd()): Promise<MextConfig> {\n const file = join(resolve(cwd), CONFIG_FILE)\n if (!existsSync(file)) return {}\n const mod = (await import(pathToFileURL(file).href)) as { default?: unknown }\n return validateConfig(mod.default)\n}\n\n/** commands/ 절대 경로 */\nexport function resolveCommandsDir(cwd: string, config: MextConfig): string {\n return resolve(cwd, config.commandsDir ?? \"commands\")\n}\n\n/** 로컬 실행 주체: config.localPrincipal (값 · 함수) 또는 localPrincipal() */\nexport async function resolveLocalPrincipal(config: MextConfig): Promise<Principal> {\n const p = config.localPrincipal\n if (p === undefined) return localPrincipal()\n return typeof p === \"function\" ? await p() : p\n}\n\n/** config.mcp 의 서버 선언 (모든 transport). onConnect 는 stdio 만 따로 전달 */\nexport function mcpDeclarations(config: MextConfig): { name?: string; instructions?: string; capabilities?: McpCapabilities } {\n const mcp = config.mcp\n return {\n ...(mcp?.name !== undefined ? { name: mcp.name } : {}),\n ...(mcp?.instructions !== undefined ? { instructions: mcp.instructions } : {}),\n ...(mcp?.capabilities !== undefined ? { capabilities: mcp.capabilities } : {}),\n }\n}\n\n/** config.mcp 의 stdio 옵션 = 선언 + onConnect */\nexport function mcpStdioDeclarations(\n config: MextConfig,\n): ReturnType<typeof mcpDeclarations> & { onConnect?: McpConnectHandler; era?: \"auto\" | \"legacy\" } {\n return {\n ...mcpDeclarations(config),\n ...(config.mcp?.onConnect ? { onConnect: config.mcp.onConnect } : {}),\n ...(config.mcp?.stdioEra ? { era: config.mcp.stdioEra } : {}),\n }\n}\n\n/** cli.errors 절대 경로 (없으면 undefined) */\nexport function resolveCliErrorsPath(cwd: string, config: MextConfig): string | undefined {\n return config.cli?.errors === undefined ? undefined : resolve(cwd, config.cli.errors)\n}\n\n/** cli.errors 모듈의 default export (함수). 파일 없음 · default 가 함수 아님 = TypeError */\nexport async function loadCliErrorFormatter(cwd: string, config: MextConfig): Promise<CliErrorFormatter | undefined> {\n const file = resolveCliErrorsPath(cwd, config)\n if (file === undefined) return undefined\n if (!existsSync(file)) throw new TypeError(`${CONFIG_FILE}: cli.errors file not found: ${config.cli!.errors}`)\n const mod = (await import(pathToFileURL(file).href)) as { default?: unknown }\n if (typeof mod.default !== \"function\") throw new TypeError(`${config.cli!.errors}: default export must be a function (CliErrorFormatter)`)\n return mod.default as CliErrorFormatter\n}\n\n/** ctx.app: config.app() 또는 {} */\nexport async function createApp(config: MextConfig): Promise<MextApp> {\n return config.app ? await config.app() : ({} as MextApp)\n}\n\nfunction validateConfig(value: unknown): MextConfig {\n const fail = (message: string): never => {\n throw new TypeError(`${CONFIG_FILE}: ${message}`)\n }\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return fail(\"default export must be an object (export default defineConfig({ ... }))\")\n }\n const c = value as Record<string, unknown>\n const unknown = Object.keys(c).filter((k) => !CONFIG_KEYS.includes(k))\n if (unknown.length > 0) fail(`unknown key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`)\n if (c.commandsDir !== undefined && typeof c.commandsDir !== \"string\") fail(\"commandsDir must be a string\")\n if (c.app !== undefined && typeof c.app !== \"function\") fail(\"app must be a function\")\n if (c.auth !== undefined && typeof c.auth !== \"function\") fail(\"auth must be a function\")\n if (c.tools !== undefined && c.tools !== \"execute\" && c.tools !== \"split\") fail('tools must be \"execute\" or \"split\"')\n if (c.server !== undefined && (typeof c.server !== \"object\" || c.server === null)) fail(\"server must be an object\")\n if (c.oauth !== undefined) {\n const o = c.oauth as { authorizationServers?: unknown } | null\n if (typeof o !== \"object\" || o === null || !Array.isArray(o.authorizationServers) || o.authorizationServers.length === 0) {\n fail(\"oauth.authorizationServers must be a non-empty array of URLs\")\n }\n }\n const lp = c.localPrincipal\n if (lp !== undefined && typeof lp !== \"function\" && !isPrincipal(lp)) {\n fail(\"localPrincipal must be a Principal ({ id, kind, scopes }) or a function\")\n }\n if (c.cli !== undefined) validateCli(c.cli, fail)\n if (c.mcp !== undefined) validateMcp(c.mcp, fail)\n return c as MextConfig\n}\n\nfunction validateMcp(value: unknown, fail: (message: string) => never): void {\n if (!isPlainObject(value)) fail(\"mcp must be an object\")\n const mcp = value as Record<string, unknown>\n const unknown = Object.keys(mcp).filter((k) => !MCP_KEYS.includes(k))\n if (unknown.length > 0) fail(`unknown mcp key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`)\n if (mcp.name !== undefined && (typeof mcp.name !== \"string\" || mcp.name.trim() === \"\")) fail(\"mcp.name must be a non-empty string\")\n if (mcp.instructions !== undefined && typeof mcp.instructions !== \"string\") fail(\"mcp.instructions must be a string\")\n if (mcp.onConnect !== undefined && typeof mcp.onConnect !== \"function\") fail(\"mcp.onConnect must be a function\")\n if (mcp.stdioEra !== undefined && mcp.stdioEra !== \"auto\" && mcp.stdioEra !== \"legacy\") fail('mcp.stdioEra must be \"auto\" or \"legacy\"')\n if (mcp.capabilities !== undefined) {\n if (!isPlainObject(mcp.capabilities)) fail(\"mcp.capabilities must be an object ({ experimental })\")\n const caps = mcp.capabilities as Record<string, unknown>\n const other = Object.keys(caps).filter((k) => k !== \"experimental\")\n if (other.length > 0) fail(`mcp.capabilities supports only experimental (got ${other.join(\", \")})`)\n const exp = caps.experimental\n if (exp !== undefined) {\n if (!isPlainObject(exp)) fail(\"mcp.capabilities.experimental must be an object\")\n for (const [key, v] of Object.entries(exp as Record<string, unknown>)) {\n if (!isPlainObject(v)) fail(`mcp.capabilities.experimental[\"${key}\"] must be an object`)\n }\n }\n }\n}\n\nfunction isPlainObject(value: unknown): boolean {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction validateCli(value: unknown, fail: (message: string) => never): void {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) fail(\"cli must be an object ({ bin, url })\")\n const cli = value as Record<string, unknown>\n const unknown = Object.keys(cli).filter((k) => !CLI_KEYS.includes(k))\n if (unknown.length > 0) fail(`unknown cli key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`)\n if (typeof cli.bin !== \"string\" || !isSegment(cli.bin)) fail('cli.bin must be a kebab-case name (e.g. \"myapp\")')\n if (cli.local !== undefined && typeof cli.local !== \"boolean\") fail(\"cli.local must be a boolean\")\n if (cli.local === true) {\n const remoteOnly = [\"url\", \"packageName\", \"manifest\"].filter((k) => cli[k] !== undefined)\n if (remoteOnly.length > 0) fail(`cli.local cannot be combined with ${remoteOnly.map((k) => `cli.${k}`).join(\", \")} (local bin runs handlers, no server)`)\n } else if (typeof cli.url !== \"string\" || !isHttpUrl(cli.url)) {\n fail(\"cli.url must be an http(s) URL of the MCP endpoint (or set cli.local: true for a local bin)\")\n }\n if (cli.packageName !== undefined && (typeof cli.packageName !== \"string\" || !NPM_NAME.test(cli.packageName))) {\n fail('cli.packageName must be an npm package name (e.g. \"@example/myapp-cli\")')\n }\n if (cli.version !== undefined && (typeof cli.version !== \"string\" || cli.version.trim() === \"\")) {\n fail(\"cli.version must be a non-empty string\")\n }\n if (cli.manifest !== undefined && typeof cli.manifest !== \"boolean\") fail(\"cli.manifest must be a boolean\")\n if (cli.errors !== undefined && (typeof cli.errors !== \"string\" || cli.errors.trim() === \"\")) {\n fail('cli.errors must be a module path (e.g. \"./cli-errors.ts\")')\n }\n}\n\n/** npm 패키지 이름 (소문자 · scope 선택) */\nconst NPM_NAME = /^(?:@[a-z0-9][a-z0-9._~-]*\\/)?[a-z0-9][a-z0-9._~-]*$/\n\nfunction isHttpUrl(value: string): boolean {\n if (!/^https?:\\/\\//i.test(value)) return false\n try {\n new URL(value)\n return true\n } catch {\n return false\n }\n}\n\nfunction isPrincipal(value: unknown): value is Principal {\n const p = value as Partial<Principal> | null\n return (\n typeof p === \"object\" &&\n p !== null &&\n typeof p.id === \"string\" &&\n (p.kind === \"local\" || p.kind === \"token\" || p.kind === \"anonymous\") &&\n Array.isArray(p.scopes)\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\"\nimport { join, resolve } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport type { CliErrorFormatter } from \"./cli/output.ts\"\nimport type { MextApp } from \"./command.ts\"\nimport { isSegment } from \"./ids.ts\"\nimport type { OAuthResourceOptions } from \"./mcp/http.ts\"\nimport { localPrincipal, type Principal } from \"./principal.ts\"\nimport { stateProblem, type MextState } from \"./state.ts\"\n\n/** mext.config.ts 의 default export */\nexport interface MextConfig {\n /** 명령어 폴더. 설정 파일 위치 (cwd) 기준. 기본 \"commands\" */\n commandsDir?: string\n /** MCP 자원 폴더 (§12.3). 설정 파일 위치 (cwd) 기준. 기본 \"resources\". 폴더 없음 = 자원 없음 */\n resourcesDir?: string\n /** MCP 프롬프트 폴더 (§12.3). 설정 파일 위치 (cwd) 기준. 기본 \"prompts\". 폴더 없음 = 프롬프트 없음 */\n promptsDir?: string\n /** ctx.app 팩토리. 실행 프로세스당 1회 */\n app?: () => MextApp | Promise<MextApp>\n /** HTTP 전용. 요청마다 Authorization 헤더로 주체 생성. 잘못된 토큰 = unauthenticated() throw */\n auth?: (req: { authorization: string | undefined }) => Principal | Promise<Principal>\n /** MCP 노출 방식. 기본 \"execute\". command = 명령어별 도구 (§12.2) */\n tools?: \"execute\" | \"split\" | \"command\"\n server?: { host?: string; port?: number; allowedOrigins?: string[] }\n /** HTTP 전용. OAuth 보호 자원 메타데이터 (인가 서버 위치). mext login · MCP 클라이언트의 discovery */\n oauth?: OAuthResourceOptions\n /** 로컬 실행 (mext run · stdio) 주체. 기본 localPrincipal() */\n localPrincipal?: Principal | (() => Principal | Promise<Principal>)\n /** 고객 CLI (mext build → .mext/cli/). 없으면 고객 CLI 를 만들지 않는다 */\n cli?: CliConfig\n /** MCP 서버 선언 (serverInfo.name · instructions · capabilities) · stdio 서버 발신 알림 (§6) */\n mcp?: McpConfig\n /**\n * 서버 비밀 (32바이트 이상). MRTR requestState 서명 키 (§12.1). 미지정 = MEXT_SECRET 환경변수, 둘 다 없으면 프로세스별 임의 키.\n * 다중 인스턴스 · 재시작을 넘는 ctx.ask 재시도에 필요\n */\n secret?: string\n /**\n * 도입 프로젝트가 주입하는 저장소 · 메시지 버스 (§12.1). 없으면 stateless.\n * 단일 프로세스 = memoryState(), 다중 인스턴스 = 도입 프로젝트가 구현한 { store, bus }\n */\n state?: MextState\n /** HTTP 경로 폴더 (§12.4). 설정 파일 위치 (cwd) 기준. 기본 \"routes\". 폴더 없음 = route 없음 */\n routesDir?: string\n}\n\n/** mext.config.ts 의 mcp (§6 서버 선언 · 서버 발신 알림) */\nexport interface McpConfig {\n /** serverInfo.name. 기본 \"mext\" */\n name?: string\n /** initialize · server/discover 결과 instructions */\n instructions?: string\n /** 서버 capabilities 에 병합. experimental 만 (예: { experimental: { \"claude/channel\": {} } }) */\n capabilities?: McpCapabilities\n /**\n * stdio 전용. 연결 하나에 1회 (2025 = notifications/initialized 후, 2026-07-28 = 연결 직후).\n * 반환 함수 = 연결 종료 시 cleanup. HTTP 는 stateless 라 호출하지 않는다\n */\n onConnect?: McpConnectHandler\n /**\n * stdio 프로토콜. auto = 2026-07-28 · 2025 모두, legacy = 2025 만 (server/discover 거부).\n * Claude Code channel 은 2025 연결에서만 알림을 전달. 기본 = experimental[\"claude/channel\"] 선언 시 legacy, 그 외 auto\n */\n stdioEra?: \"auto\" | \"legacy\"\n}\n\nexport interface McpCapabilities {\n experimental?: Record<string, object>\n}\n\n/** stdio 연결. notify = 요청과 무관한 서버 발신 알림 */\nexport interface McpConnection {\n /** 협상된 프로토콜 era */\n readonly era: \"legacy\" | \"modern\"\n /** 연결 종료 후 호출 = reject */\n notify(method: string, params?: Record<string, unknown>): Promise<void>\n /**\n * 클라이언트 발신 알림 수신 (예: notifications/claude/channel/permission_request).\n * SDK 가 처리하는 사양 알림 (initialized · cancelled 등) 은 대상 아님. 같은 method 재등록 = 교체. 반환 = 해제\n */\n onNotification(method: string, handler: (params: Record<string, unknown>) => void | Promise<void>): () => void\n}\n\nexport type McpConnectHandler = (\n conn: McpConnection,\n) => void | (() => void | Promise<void>) | Promise<void | (() => void | Promise<void>)>\n\n/** mext.config.ts 의 cli (§5 고객 CLI 설정) */\nexport interface CliConfig {\n /** 실행 파일 이름 (kebab-case). 환경변수 접두 (MYAPP_TOKEN · MYAPP_URL) · 설정 폴더 (~/.config/<bin>) */\n bin: string\n /** 서버 MCP 엔드포인트 (http(s)). 실행 시 <BIN>_URL 환경변수가 있으면 그 값. local 이면 없음 */\n url?: string\n /** npm 패키지 이름. 기본 = bin */\n packageName?: string\n /** 고객 CLI 버전 (--version · clientInfo). 기본 = 도입 프로젝트 package.json version */\n version?: string\n /** true = 번들 형태 (내장 manifest, 기본), false = 범용 형태 (help · 스키마를 서버에서 조회) */\n manifest?: boolean\n /**\n * 오류 출력 · exit code 커스텀 모듈 (도입 프로젝트 루트 기준 경로). default export = CliErrorFormatter.\n * 고객 CLI bin.js 에 번들, mext run (로컬) 이 import. @obov/mext 는 타입만 import (값 import = 번들 포함)\n */\n errors?: string\n /**\n * true = 로컬 bin (§5). mext build → .mext/bin.js (핸들러를 사용자 PC 에서 실행, .mext/cli/ 없음).\n * 도입 프로젝트 package.json bin { \"<bin>\": \".mext/bin.js\" }. url · packageName · manifest 와 함께 쓸 수 없음\n */\n local?: boolean\n}\n\nexport const CONFIG_FILE = \"mext.config.ts\"\n\nconst CONFIG_KEYS: readonly string[] = [\"commandsDir\", \"app\", \"auth\", \"tools\", \"server\", \"oauth\", \"localPrincipal\", \"cli\", \"mcp\", \"secret\", \"state\", \"resourcesDir\", \"routesDir\", \"promptsDir\"]\n\n/** secret 최소 길이 (바이트, HMAC-SHA256 키) */\nexport const SECRET_MIN_BYTES = 32\n/** secret 환경변수 */\nexport const SECRET_ENV = \"MEXT_SECRET\"\nconst MCP_KEYS: readonly string[] = [\"name\", \"instructions\", \"capabilities\", \"onConnect\", \"stdioEra\"]\nconst CLI_KEYS: readonly string[] = [\"bin\", \"url\", \"packageName\", \"version\", \"manifest\", \"errors\", \"local\"]\n/** 고객 CLI 의 내장 명령 (루트 세그먼트로 쓸 수 없음) */\nexport const CLI_BUILTIN_COMMANDS: readonly string[] = [\"help\", \"login\", \"logout\", \"mcp\"]\n/** 로컬 bin (cli.local) 의 내장 명령 */\nexport const LOCAL_BIN_BUILTIN_COMMANDS: readonly string[] = [\"help\", \"mcp\"]\n\n/** 타입 도우미. 값은 그대로 반환 */\nexport function defineConfig(config: MextConfig): MextConfig {\n return config\n}\n\n/** cwd 의 mext.config.ts 를 import. 없으면 {}. 형식이 틀리면 TypeError (모르는 키 포함) */\nexport async function loadConfig(cwd: string = process.cwd()): Promise<MextConfig> {\n const file = join(resolve(cwd), CONFIG_FILE)\n if (!existsSync(file)) return {}\n const mod = (await import(pathToFileURL(file).href)) as { default?: unknown }\n return validateConfig(mod.default)\n}\n\n/** commands/ 절대 경로 */\nexport function resolveCommandsDir(cwd: string, config: MextConfig): string {\n return resolve(cwd, config.commandsDir ?? \"commands\")\n}\n\n/** resources/ 절대 경로 */\nexport function resolveResourcesDir(cwd: string, config: MextConfig): string {\n return resolve(cwd, config.resourcesDir ?? \"resources\")\n}\n\n/** prompts/ 절대 경로 */\nexport function resolvePromptsDir(cwd: string, config: MextConfig): string {\n return resolve(cwd, config.promptsDir ?? \"prompts\")\n}\n\n/** routes/ 절대 경로 */\nexport function resolveRoutesDir(cwd: string, config: MextConfig): string {\n return resolve(cwd, config.routesDir ?? \"routes\")\n}\n\n/** 로컬 실행 주체: config.localPrincipal (값 · 함수) 또는 localPrincipal() */\nexport async function resolveLocalPrincipal(config: MextConfig): Promise<Principal> {\n const p = config.localPrincipal\n if (p === undefined) return localPrincipal()\n return typeof p === \"function\" ? await p() : p\n}\n\n/**\n * 서버 비밀: config.secret > MEXT_SECRET > undefined (프로세스별 임의 키).\n * 환경변수 값이 짧으면 TypeError (config.secret 은 설정 로드 시 검사)\n */\nexport function resolveSecret(config: MextConfig, env: Record<string, string | undefined> = process.env): string | undefined {\n if (config.secret !== undefined) return config.secret\n const value = env[SECRET_ENV]\n if (value === undefined || value === \"\") return undefined\n if (Buffer.byteLength(value) < SECRET_MIN_BYTES) throw new TypeError(`${SECRET_ENV} must be at least ${SECRET_MIN_BYTES} bytes`)\n return value\n}\n\n/** 서버 선언 (모든 transport): config.mcp 의 name · instructions · capabilities + secret (requestStateKey) + state. onConnect 는 stdio 만 따로 */\nexport function mcpDeclarations(\n config: MextConfig,\n env: Record<string, string | undefined> = process.env,\n): { name?: string; instructions?: string; capabilities?: McpCapabilities; requestStateKey?: string; state?: MextState } {\n const mcp = config.mcp\n const secret = resolveSecret(config, env)\n return {\n ...(mcp?.name !== undefined ? { name: mcp.name } : {}),\n ...(mcp?.instructions !== undefined ? { instructions: mcp.instructions } : {}),\n ...(mcp?.capabilities !== undefined ? { capabilities: mcp.capabilities } : {}),\n ...(secret !== undefined ? { requestStateKey: secret } : {}),\n ...(config.state !== undefined ? { state: config.state } : {}),\n }\n}\n\n/** stdio 옵션 = 선언 + onConnect */\nexport function mcpStdioDeclarations(\n config: MextConfig,\n env: Record<string, string | undefined> = process.env,\n): ReturnType<typeof mcpDeclarations> & { onConnect?: McpConnectHandler; era?: \"auto\" | \"legacy\" } {\n return {\n ...mcpDeclarations(config, env),\n ...(config.mcp?.onConnect ? { onConnect: config.mcp.onConnect } : {}),\n ...(config.mcp?.stdioEra ? { era: config.mcp.stdioEra } : {}),\n }\n}\n\n/** cli.errors 절대 경로 (없으면 undefined) */\nexport function resolveCliErrorsPath(cwd: string, config: MextConfig): string | undefined {\n return config.cli?.errors === undefined ? undefined : resolve(cwd, config.cli.errors)\n}\n\n/** cli.errors 모듈의 default export (함수). 파일 없음 · default 가 함수 아님 = TypeError */\nexport async function loadCliErrorFormatter(cwd: string, config: MextConfig): Promise<CliErrorFormatter | undefined> {\n const file = resolveCliErrorsPath(cwd, config)\n if (file === undefined) return undefined\n if (!existsSync(file)) throw new TypeError(`${CONFIG_FILE}: cli.errors file not found: ${config.cli!.errors}`)\n const mod = (await import(pathToFileURL(file).href)) as { default?: unknown }\n if (typeof mod.default !== \"function\") throw new TypeError(`${config.cli!.errors}: default export must be a function (CliErrorFormatter)`)\n return mod.default as CliErrorFormatter\n}\n\n/** ctx.app: config.app() 또는 {} */\nexport async function createApp(config: MextConfig): Promise<MextApp> {\n return config.app ? await config.app() : ({} as MextApp)\n}\n\nfunction validateConfig(value: unknown): MextConfig {\n const fail = (message: string): never => {\n throw new TypeError(`${CONFIG_FILE}: ${message}`)\n }\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return fail(\"default export must be an object (export default defineConfig({ ... }))\")\n }\n const c = value as Record<string, unknown>\n const unknown = Object.keys(c).filter((k) => !CONFIG_KEYS.includes(k))\n if (unknown.length > 0) fail(`unknown key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`)\n if (c.commandsDir !== undefined && typeof c.commandsDir !== \"string\") fail(\"commandsDir must be a string\")\n if (c.resourcesDir !== undefined && typeof c.resourcesDir !== \"string\") fail(\"resourcesDir must be a string\")\n if (c.routesDir !== undefined && typeof c.routesDir !== \"string\") fail(\"routesDir must be a string\")\n if (c.promptsDir !== undefined && typeof c.promptsDir !== \"string\") fail(\"promptsDir must be a string\")\n if (c.app !== undefined && typeof c.app !== \"function\") fail(\"app must be a function\")\n if (c.auth !== undefined && typeof c.auth !== \"function\") fail(\"auth must be a function\")\n if (c.tools !== undefined && c.tools !== \"execute\" && c.tools !== \"split\" && c.tools !== \"command\") {\n fail('tools must be \"execute\", \"split\" or \"command\"')\n }\n if (c.server !== undefined && (typeof c.server !== \"object\" || c.server === null)) fail(\"server must be an object\")\n if (c.oauth !== undefined) {\n const o = c.oauth as { authorizationServers?: unknown } | null\n if (typeof o !== \"object\" || o === null || !Array.isArray(o.authorizationServers) || o.authorizationServers.length === 0) {\n fail(\"oauth.authorizationServers must be a non-empty array of URLs\")\n }\n }\n const lp = c.localPrincipal\n if (lp !== undefined && typeof lp !== \"function\" && !isPrincipal(lp)) {\n fail(\"localPrincipal must be a Principal ({ id, kind, scopes }) or a function\")\n }\n if (c.secret !== undefined && (typeof c.secret !== \"string\" || Buffer.byteLength(c.secret) < SECRET_MIN_BYTES)) {\n fail(`secret must be a string of at least ${SECRET_MIN_BYTES} bytes`)\n }\n if (c.state !== undefined) {\n const problem = stateProblem(c.state)\n if (problem !== undefined) fail(problem)\n }\n if (c.cli !== undefined) validateCli(c.cli, fail)\n if (c.mcp !== undefined) validateMcp(c.mcp, fail)\n return c as MextConfig\n}\n\nfunction validateMcp(value: unknown, fail: (message: string) => never): void {\n if (!isPlainObject(value)) fail(\"mcp must be an object\")\n const mcp = value as Record<string, unknown>\n const unknown = Object.keys(mcp).filter((k) => !MCP_KEYS.includes(k))\n if (unknown.length > 0) fail(`unknown mcp key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`)\n if (mcp.name !== undefined && (typeof mcp.name !== \"string\" || mcp.name.trim() === \"\")) fail(\"mcp.name must be a non-empty string\")\n if (mcp.instructions !== undefined && typeof mcp.instructions !== \"string\") fail(\"mcp.instructions must be a string\")\n if (mcp.onConnect !== undefined && typeof mcp.onConnect !== \"function\") fail(\"mcp.onConnect must be a function\")\n if (mcp.stdioEra !== undefined && mcp.stdioEra !== \"auto\" && mcp.stdioEra !== \"legacy\") fail('mcp.stdioEra must be \"auto\" or \"legacy\"')\n if (mcp.capabilities !== undefined) {\n if (!isPlainObject(mcp.capabilities)) fail(\"mcp.capabilities must be an object ({ experimental })\")\n const caps = mcp.capabilities as Record<string, unknown>\n const other = Object.keys(caps).filter((k) => k !== \"experimental\")\n if (other.length > 0) fail(`mcp.capabilities supports only experimental (got ${other.join(\", \")})`)\n const exp = caps.experimental\n if (exp !== undefined) {\n if (!isPlainObject(exp)) fail(\"mcp.capabilities.experimental must be an object\")\n for (const [key, v] of Object.entries(exp as Record<string, unknown>)) {\n if (!isPlainObject(v)) fail(`mcp.capabilities.experimental[\"${key}\"] must be an object`)\n }\n }\n }\n}\n\nfunction isPlainObject(value: unknown): boolean {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction validateCli(value: unknown, fail: (message: string) => never): void {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) fail(\"cli must be an object ({ bin, url })\")\n const cli = value as Record<string, unknown>\n const unknown = Object.keys(cli).filter((k) => !CLI_KEYS.includes(k))\n if (unknown.length > 0) fail(`unknown cli key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`)\n if (typeof cli.bin !== \"string\" || !isSegment(cli.bin)) fail('cli.bin must be a kebab-case name (e.g. \"myapp\")')\n if (cli.local !== undefined && typeof cli.local !== \"boolean\") fail(\"cli.local must be a boolean\")\n if (cli.local === true) {\n const remoteOnly = [\"url\", \"packageName\", \"manifest\"].filter((k) => cli[k] !== undefined)\n if (remoteOnly.length > 0) fail(`cli.local cannot be combined with ${remoteOnly.map((k) => `cli.${k}`).join(\", \")} (local bin runs handlers, no server)`)\n } else if (typeof cli.url !== \"string\" || !isHttpUrl(cli.url)) {\n fail(\"cli.url must be an http(s) URL of the MCP endpoint (or set cli.local: true for a local bin)\")\n }\n if (cli.packageName !== undefined && (typeof cli.packageName !== \"string\" || !NPM_NAME.test(cli.packageName))) {\n fail('cli.packageName must be an npm package name (e.g. \"@example/myapp-cli\")')\n }\n if (cli.version !== undefined && (typeof cli.version !== \"string\" || cli.version.trim() === \"\")) {\n fail(\"cli.version must be a non-empty string\")\n }\n if (cli.manifest !== undefined && typeof cli.manifest !== \"boolean\") fail(\"cli.manifest must be a boolean\")\n if (cli.errors !== undefined && (typeof cli.errors !== \"string\" || cli.errors.trim() === \"\")) {\n fail('cli.errors must be a module path (e.g. \"./cli-errors.ts\")')\n }\n}\n\n/** npm 패키지 이름 (소문자 · scope 선택) */\nconst NPM_NAME = /^(?:@[a-z0-9][a-z0-9._~-]*\\/)?[a-z0-9][a-z0-9._~-]*$/\n\nfunction isHttpUrl(value: string): boolean {\n if (!/^https?:\\/\\//i.test(value)) return false\n try {\n new URL(value)\n return true\n } catch {\n return false\n }\n}\n\nfunction isPrincipal(value: unknown): value is Principal {\n const p = value as Partial<Principal> | null\n return (\n typeof p === \"object\" &&\n p !== null &&\n typeof p.id === \"string\" &&\n (p.kind === \"local\" || p.kind === \"token\" || p.kind === \"anonymous\") &&\n Array.isArray(p.scopes)\n )\n}\n"]}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type BuildIssueCode = "COMMANDS_DIR_MISSING" | "PATH_COLLISION" | "DUPLICATE_ID" | "INVALID_SEGMENT" | "INVALID_ALIAS" | "RESERVED_ID" | "ROOT_INDEX" | "INVALID_COMMAND" | "LOAD_FAILED" | "SCHEMA_UNREPRESENTABLE" | "CLI_UNCONVERTIBLE" | "BUNDLE_FAILED" | "INVALID_CONFIG";
|
|
1
|
+
export type BuildIssueCode = "COMMANDS_DIR_MISSING" | "PATH_COLLISION" | "DUPLICATE_ID" | "INVALID_SEGMENT" | "INVALID_ALIAS" | "RESERVED_ID" | "ROOT_INDEX" | "INVALID_COMMAND" | "LOAD_FAILED" | "SCHEMA_UNREPRESENTABLE" | "CLI_UNCONVERTIBLE" | "BUNDLE_FAILED" | "INVALID_CONFIG" | "INVALID_RESOURCE" | "INVALID_PROMPT" | "ROUTE_CONFLICT" | "DUPLICATE_ROUTE" | "INVALID_ROUTE";
|
|
2
2
|
export interface BuildIssue {
|
|
3
3
|
code: BuildIssueCode;
|
|
4
4
|
message: string;
|
|
@@ -50,6 +50,8 @@ export interface MextErrorDetails {
|
|
|
50
50
|
/** ctx.ask 를 처리할 수 없는 실행 환경 (TTY 없는 CLI 등) */
|
|
51
51
|
INPUT_UNAVAILABLE: {
|
|
52
52
|
command: string;
|
|
53
|
+
/** url 요청 (ctx.ask kind url) 의 URL. 사용자가 직접 열고 다시 실행 */
|
|
54
|
+
url?: string;
|
|
53
55
|
};
|
|
54
56
|
/** ctx.ask 거절 · 취소. confirm = requiresConfirmation 확인 거절 (실행 안 함), input = 입력 요청 거절 */
|
|
55
57
|
INPUT_DECLINED: {
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["export type BuildIssueCode =\n | \"COMMANDS_DIR_MISSING\"\n | \"PATH_COLLISION\"\n | \"DUPLICATE_ID\"\n | \"INVALID_SEGMENT\"\n | \"INVALID_ALIAS\"\n | \"RESERVED_ID\"\n | \"ROOT_INDEX\"\n | \"INVALID_COMMAND\"\n | \"LOAD_FAILED\"\n | \"SCHEMA_UNREPRESENTABLE\"\n | \"CLI_UNCONVERTIBLE\"\n | \"BUNDLE_FAILED\"\n | \"INVALID_CONFIG\"\n | \"INVALID_RESOURCE\"\n | \"INVALID_PROMPT\"\n | \"ROUTE_CONFLICT\"\n | \"DUPLICATE_ROUTE\"\n | \"INVALID_ROUTE\"\n\nexport interface BuildIssue {\n code: BuildIssueCode\n message: string\n /** commands/ 기준 상대 경로 (posix) */\n file?: string\n id?: string\n}\n\n/** 스캔 · Registry 생성의 빌드 오류. 발견한 문제를 모두 모아 한 번에 던진다 */\nexport class MextBuildError extends Error {\n readonly issues: readonly BuildIssue[]\n\n constructor(issues: readonly BuildIssue[]) {\n super(\n `mext build failed (${issues.length} issue${issues.length === 1 ? \"\" : \"s\"})\\n` +\n issues.map((i) => ` ${i.code}${i.file ? ` ${i.file}` : \"\"}: ${i.message}`).join(\"\\n\"),\n )\n this.name = \"MextBuildError\"\n this.issues = issues\n }\n}\n\nexport type MextErrorCode =\n | \"UNKNOWN_COMMAND\"\n | \"INVALID_ARGUMENT\"\n | \"UNAUTHENTICATED\"\n | \"PERMISSION_DENIED\"\n | \"INPUT_UNAVAILABLE\"\n | \"INPUT_DECLINED\"\n\nexport interface ArgumentIssue {\n /** 점 구분 경로. \"\" = 입력 전체 */\n path: string\n code: string\n message: string\n}\n\nexport interface MextErrorDetails {\n UNKNOWN_COMMAND: {\n command: string\n /** 유사 정식 ID (가까운 순) */\n suggested: string[]\n /** 다음에 볼 help 대상. \"help\" (루트) · \"help users\" (네임스페이스) */\n usage: string\n }\n INVALID_ARGUMENT: {\n command: string\n /** 원본 입력에 없는 필수 필드 경로 */\n missing_fields: string[]\n issues: ArgumentIssue[]\n /** input JSON Schema 2020-12 */\n expected_schema: Record<string, unknown>\n examples: unknown[]\n }\n UNAUTHENTICATED: {\n reason: \"missing_token\" | \"invalid_token\"\n /** CLI 원격 실행: 토큰 발급 명령 (mext login --url <url>) */\n login?: string\n }\n PERMISSION_DENIED: {\n command: string\n /** anonymous = 인증 없는 주체의 readOnly 외 명령어 · read_only = readOnly 전용 호출 (split query) · scope = scopes 부족 */\n reason: \"anonymous\" | \"read_only\" | \"scope\"\n required_scopes: string[]\n held_scopes: string[]\n }\n /** ctx.ask 를 처리할 수 없는 실행 환경 (TTY 없는 CLI 등) */\n INPUT_UNAVAILABLE: {\n command: string\n /** url 요청 (ctx.ask kind url) 의 URL. 사용자가 직접 열고 다시 실행 */\n url?: string\n }\n /** ctx.ask 거절 · 취소. confirm = requiresConfirmation 확인 거절 (실행 안 함), input = 입력 요청 거절 */\n INPUT_DECLINED: {\n command: string\n kind: \"confirm\" | \"input\"\n }\n}\n\n/** 구조화 오류. 어댑터는 code 로 분기하고 toJSON() 을 응답 본문으로 쓴다 */\nexport class MextError<C extends MextErrorCode = MextErrorCode> extends Error {\n readonly code: C\n readonly details: MextErrorDetails[C]\n\n constructor(code: C, message: string, details: MextErrorDetails[C]) {\n super(message)\n this.name = \"MextError\"\n this.code = code\n this.details = details\n }\n\n toJSON(): { code: C; message: string } & MextErrorDetails[C] {\n return { code: this.code, message: this.message, ...this.details }\n }\n}\n\nexport function isMextError<C extends MextErrorCode>(error: unknown, code?: C): error is MextError<C> {\n return error instanceof MextError && (code === undefined || error.code === code)\n}\n\n/** auth 단계에서 어댑터가 던지는 오류. anonymous 로 낮추지 않는다 */\nexport function unauthenticated(reason: MextErrorDetails[\"UNAUTHENTICATED\"][\"reason\"]): MextError<\"UNAUTHENTICATED\"> {\n const message = reason === \"missing_token\" ? \"Authentication required.\" : \"Invalid authentication token.\"\n return new MextError(\"UNAUTHENTICATED\", message, { reason })\n}\n\n/** ctx.ask 거절. AskHandler 가 input 요청 거절 · 취소에 던진다. invoke 는 requiresConfirmation 확인 거절에 던진다 */\nexport function inputDeclined(command: string, kind: \"confirm\" | \"input\"): MextError<\"INPUT_DECLINED\"> {\n const message =\n kind === \"confirm\" ? `${command} was not confirmed and did not run.` : `${command} requested input, but it was declined.`\n return new MextError(\"INPUT_DECLINED\", message, { command, kind })\n}\n\n/** mext 가 쓰는 오류 code. CommandError 로 만들 수 없다 */\nexport const RESERVED_ERROR_CODES: readonly string[] = [\n \"UNKNOWN_COMMAND\",\n \"INVALID_ARGUMENT\",\n \"UNAUTHENTICATED\",\n \"PERMISSION_DENIED\",\n \"INPUT_UNAVAILABLE\",\n \"INPUT_DECLINED\",\n \"EXECUTION_ERROR\",\n \"EXECUTION_FAILED\",\n \"INTERRUPTED\",\n \"BUILD_ERROR\",\n \"REMOTE_ERROR\",\n]\n\nconst ERROR_CODE = /^[A-Z][A-Z0-9_]*$/\n\n/**\n * 핸들러 정의 오류 (§4). 응답 본문 = { code, message, ...details } (MCP structuredContent.error · CLI --json).\n * code = 대문자 스네이크, mext 예약 code 불가 (TypeError). onCommandError 에 보고하지 않는다 (의도된 오류)\n */\nexport class CommandError extends Error {\n readonly code: string\n readonly details: Record<string, unknown>\n\n constructor(code: string, message: string, details: Record<string, unknown> = {}) {\n if (typeof code !== \"string\" || !ERROR_CODE.test(code)) {\n throw new TypeError(`CommandError code must be UPPER_SNAKE_CASE (got ${JSON.stringify(code)})`)\n }\n if (RESERVED_ERROR_CODES.includes(code)) throw new TypeError(`CommandError code \"${code}\" is reserved by mext`)\n if (typeof details !== \"object\" || details === null || Array.isArray(details)) {\n throw new TypeError(\"CommandError details must be an object\")\n }\n super(message)\n this.name = \"CommandError\"\n this.code = code\n this.details = details\n }\n\n toJSON(): { code: string; message: string } & Record<string, unknown> {\n return { ...this.details, code: this.code, message: this.message }\n }\n}\n\nexport function isCommandError(error: unknown): error is CommandError {\n return error instanceof CommandError\n}\n\n/** 응답 본문으로 그대로 보내는 오류 (MextError · CommandError) */\nexport function isDeclaredError(error: unknown): error is MextError | CommandError {\n return error instanceof MextError || error instanceof CommandError\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
export { VERSION } from "./version.ts";
|
|
2
|
-
export { defineCommand, isCommand } from "./command.ts";
|
|
3
|
-
export type { Ask, AskRequest, Command, CommandContext, CommandDefinition, ConfirmRequest, InputRequest, InputSchema, MextApp, ProgressUpdate, } from "./command.ts";
|
|
2
|
+
export { DEFAULT_TASK_TTL_MS, defineCommand, isCommand } from "./command.ts";
|
|
3
|
+
export type { Ask, AskRequest, Command, CommandContext, CommandDefinition, ConfirmRequest, InputRequest, InputSchema, MextApp, ProgressUpdate, TaskOptions, UrlRequest, } from "./command.ts";
|
|
4
|
+
export { collectResources, collectResourceSet, createLazyResourceSet, createResourceSet, defineResource, describeResource, isResource, loadResourceSet, matchResource, parseUriTemplate, resourceEntries, withResources, } from "./resource.ts";
|
|
5
|
+
export type { LazyResourceInput, ManifestResource, RegisteredResource, Resource, ResourceCompleteContext, ResourceCompleter, ResourceContext, ResourceDefinition, ResourceInput, ResourceListItem, ResourceSet, ResourceVariables, UriTemplatePattern, } from "./resource.ts";
|
|
6
|
+
export { collectPrompts, collectPromptSet, createLazyPromptSet, createPromptSet, definePrompt, describePrompt, isPrompt, loadPromptSet, promptArguments, withPrompts, } from "./prompt.ts";
|
|
7
|
+
export type { LazyPromptInput, ManifestPrompt, Prompt, PromptArgs, PromptArgument, PromptCompleteContext, PromptCompleter, PromptContext, PromptDefinition, PromptInput, PromptMessage, PromptResult, PromptSet, RegisteredPrompt, } from "./prompt.ts";
|
|
4
8
|
export { ANONYMOUS, hasScope, localPrincipal } from "./principal.ts";
|
|
5
9
|
export type { Principal } from "./principal.ts";
|
|
6
10
|
export { CommandError, inputDeclined, isCommandError, isMextError, MextBuildError, MextError, RESERVED_ERROR_CODES, unauthenticated, } from "./errors.ts";
|
|
7
11
|
export type { ArgumentIssue, BuildIssue, BuildIssueCode, MextErrorCode, MextErrorDetails } from "./errors.ts";
|
|
8
|
-
export { authorize, confirmationMessage, createContext, findCommand, invoke, parseInput } from "./invoke.ts";
|
|
9
|
-
export type { AskHandler, AskHandlerRequest, InvokeOptions, InvokeResult } from "./invoke.ts";
|
|
12
|
+
export { authorize, confirmationMessage, createContext, findCommand, invalidArgument, invoke, OutputValidationError, parseInput } from "./invoke.ts";
|
|
13
|
+
export type { AskHandler, AskHandlerRequest, DetachedExecution, InvokeOptions, InvokeResult } from "./invoke.ts";
|
|
10
14
|
export { findInstrumentation, INSTRUMENTATION_FILE, loadInstrumentation, loadProjectInstrumentation, } from "./instrumentation.ts";
|
|
11
15
|
export type { CommandErrorInfo, Instrumentation, InstrumentationModule, LoadInstrumentationOptions, OtelApi, Transport, } from "./instrumentation.ts";
|
|
12
16
|
export { collectRegistry, createLazyRegistry, createRegistry, loadCommand, resolveCommand } from "./registry.ts";
|
|
@@ -14,13 +18,21 @@ export type { JsonSchema, LazyCommandInput, NamespaceInfo, RegisteredCommand, Re
|
|
|
14
18
|
export { collectCommands, loadRegistry, scanCommands, walkCommands } from "./scan.ts";
|
|
15
19
|
export type { ScannedFile, ScanResult } from "./scan.ts";
|
|
16
20
|
export { buildManifest, describeCommand, generateManifest, MANIFEST_SCHEMA_VERSION, manifestHash } from "./manifest.ts";
|
|
17
|
-
export type { BuildManifest, BuildManifestCommand, Manifest, ManifestCommand, ManifestNamespace } from "./manifest.ts";
|
|
21
|
+
export type { BuildManifest, BuildManifestCommand, BuildManifestResource, BuildManifestRoute, Manifest, ManifestCommand, ManifestNamespace } from "./manifest.ts";
|
|
22
|
+
export type { BuildManifestPrompt } from "./manifest.ts";
|
|
23
|
+
export { collectRoutes, loadRoutes, ROUTE_METHODS, walkRoutes } from "./route.ts";
|
|
24
|
+
export type { RouteContext, RouteEntry, RouteHandler, RouteMethod, RouteModule, ScannedRoute } from "./route.ts";
|
|
18
25
|
export { BUILD_DIR, BUILD_MANIFEST_FILE, buildProject, HANDLER_JS, RolldownUnavailableError, SERVER_JS, START_ENTRY } from "./build.ts";
|
|
19
26
|
export type { BuildOptions, BuildResult, BuildWarning, RolldownModule, RolldownOutputItem } from "./build.ts";
|
|
20
27
|
export { formatBuildSummary, runBuild } from "./cli/build.ts";
|
|
21
28
|
export { mextVersion } from "./version.ts";
|
|
22
29
|
export * from "./mcp/index.ts";
|
|
23
30
|
export { CLI_BUILTIN_COMMANDS, CONFIG_FILE, createApp, defineConfig, loadConfig, resolveCommandsDir, resolveLocalPrincipal } from "./config.ts";
|
|
31
|
+
export { resolveResourcesDir } from "./config.ts";
|
|
32
|
+
export { resolvePromptsDir } from "./config.ts";
|
|
33
|
+
export { resolveRoutesDir } from "./config.ts";
|
|
34
|
+
export { memoryState } from "./state.ts";
|
|
35
|
+
export type { MemoryStateOptions, MextBus, MextState, MextStore } from "./state.ts";
|
|
24
36
|
export type { CliConfig, McpCapabilities, McpConfig, McpConnectHandler, McpConnection, MextConfig } from "./config.ts";
|
|
25
37
|
export { buildCustomerCli, CLI_BIN_FILE, CLI_DIR, customerCliIssues } from "./build-cli.ts";
|
|
26
38
|
export type { BuildCustomerCliOptions, CustomerCliBuild } from "./build-cli.ts";
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
export { VERSION } from "./version.js";
|
|
2
|
-
export { defineCommand, isCommand } from "./command.js";
|
|
2
|
+
export { DEFAULT_TASK_TTL_MS, defineCommand, isCommand } from "./command.js";
|
|
3
|
+
export { collectResources, collectResourceSet, createLazyResourceSet, createResourceSet, defineResource, describeResource, isResource, loadResourceSet, matchResource, parseUriTemplate, resourceEntries, withResources, } from "./resource.js";
|
|
4
|
+
export { collectPrompts, collectPromptSet, createLazyPromptSet, createPromptSet, definePrompt, describePrompt, isPrompt, loadPromptSet, promptArguments, withPrompts, } from "./prompt.js";
|
|
3
5
|
export { ANONYMOUS, hasScope, localPrincipal } from "./principal.js";
|
|
4
6
|
export { CommandError, inputDeclined, isCommandError, isMextError, MextBuildError, MextError, RESERVED_ERROR_CODES, unauthenticated, } from "./errors.js";
|
|
5
|
-
export { authorize, confirmationMessage, createContext, findCommand, invoke, parseInput } from "./invoke.js";
|
|
7
|
+
export { authorize, confirmationMessage, createContext, findCommand, invalidArgument, invoke, OutputValidationError, parseInput } from "./invoke.js";
|
|
6
8
|
export { findInstrumentation, INSTRUMENTATION_FILE, loadInstrumentation, loadProjectInstrumentation, } from "./instrumentation.js";
|
|
7
9
|
export { collectRegistry, createLazyRegistry, createRegistry, loadCommand, resolveCommand } from "./registry.js";
|
|
8
10
|
export { collectCommands, loadRegistry, scanCommands, walkCommands } from "./scan.js";
|
|
9
11
|
export { buildManifest, describeCommand, generateManifest, MANIFEST_SCHEMA_VERSION, manifestHash } from "./manifest.js";
|
|
12
|
+
export { collectRoutes, loadRoutes, ROUTE_METHODS, walkRoutes } from "./route.js";
|
|
10
13
|
export { BUILD_DIR, BUILD_MANIFEST_FILE, buildProject, HANDLER_JS, RolldownUnavailableError, SERVER_JS, START_ENTRY } from "./build.js";
|
|
11
14
|
export { formatBuildSummary, runBuild } from "./cli/build.js";
|
|
12
15
|
export { mextVersion } from "./version.js";
|
|
13
16
|
export * from "./mcp/index.js";
|
|
14
17
|
export { CLI_BUILTIN_COMMANDS, CONFIG_FILE, createApp, defineConfig, loadConfig, resolveCommandsDir, resolveLocalPrincipal } from "./config.js";
|
|
18
|
+
export { resolveResourcesDir } from "./config.js";
|
|
19
|
+
export { resolvePromptsDir } from "./config.js";
|
|
20
|
+
export { resolveRoutesDir } from "./config.js";
|
|
21
|
+
export { memoryState } from "./state.js";
|
|
15
22
|
export { buildCustomerCli, CLI_BIN_FILE, CLI_DIR, customerCliIssues } from "./build-cli.js";
|
|
16
23
|
export { runCustomerCli } from "./client/main.js";
|
|
17
24
|
export { clientManifest, manifestHelp } from "./client/manifest.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { VERSION } from \"./version.ts\"\n\nexport { DEFAULT_TASK_TTL_MS, defineCommand, isCommand } from \"./command.ts\"\nexport type {\n Ask,\n AskRequest,\n Command,\n CommandContext,\n CommandDefinition,\n ConfirmRequest,\n InputRequest,\n InputSchema,\n MextApp,\n ProgressUpdate,\n TaskOptions,\n UrlRequest,\n} from \"./command.ts\"\nexport {\n collectResources,\n collectResourceSet,\n createLazyResourceSet,\n createResourceSet,\n defineResource,\n describeResource,\n isResource,\n loadResourceSet,\n matchResource,\n parseUriTemplate,\n resourceEntries,\n withResources,\n} from \"./resource.ts\"\nexport type {\n LazyResourceInput,\n ManifestResource,\n RegisteredResource,\n Resource,\n ResourceCompleteContext,\n ResourceCompleter,\n ResourceContext,\n ResourceDefinition,\n ResourceInput,\n ResourceListItem,\n ResourceSet,\n ResourceVariables,\n UriTemplatePattern,\n} from \"./resource.ts\"\nexport {\n collectPrompts,\n collectPromptSet,\n createLazyPromptSet,\n createPromptSet,\n definePrompt,\n describePrompt,\n isPrompt,\n loadPromptSet,\n promptArguments,\n withPrompts,\n} from \"./prompt.ts\"\nexport type {\n LazyPromptInput,\n ManifestPrompt,\n Prompt,\n PromptArgs,\n PromptArgument,\n PromptCompleteContext,\n PromptCompleter,\n PromptContext,\n PromptDefinition,\n PromptInput,\n PromptMessage,\n PromptResult,\n PromptSet,\n RegisteredPrompt,\n} from \"./prompt.ts\"\nexport { ANONYMOUS, hasScope, localPrincipal } from \"./principal.ts\"\nexport type { Principal } from \"./principal.ts\"\nexport {\n CommandError,\n inputDeclined,\n isCommandError,\n isMextError,\n MextBuildError,\n MextError,\n RESERVED_ERROR_CODES,\n unauthenticated,\n} from \"./errors.ts\"\nexport type { ArgumentIssue, BuildIssue, BuildIssueCode, MextErrorCode, MextErrorDetails } from \"./errors.ts\"\nexport { authorize, confirmationMessage, createContext, findCommand, invalidArgument, invoke, OutputValidationError, parseInput } from \"./invoke.ts\"\nexport type { AskHandler, AskHandlerRequest, DetachedExecution, InvokeOptions, InvokeResult } from \"./invoke.ts\"\nexport {\n findInstrumentation,\n INSTRUMENTATION_FILE,\n loadInstrumentation,\n loadProjectInstrumentation,\n} from \"./instrumentation.ts\"\nexport type {\n CommandErrorInfo,\n Instrumentation,\n InstrumentationModule,\n LoadInstrumentationOptions,\n OtelApi,\n Transport,\n} from \"./instrumentation.ts\"\nexport { collectRegistry, createLazyRegistry, createRegistry, loadCommand, resolveCommand } from \"./registry.ts\"\nexport type {\n JsonSchema,\n LazyCommandInput,\n NamespaceInfo,\n RegisteredCommand,\n Registry,\n RegistryCommandInput,\n RegistryInput,\n RegistryNamespaceInput,\n} from \"./registry.ts\"\nexport { collectCommands, loadRegistry, scanCommands, walkCommands } from \"./scan.ts\"\nexport type { ScannedFile, ScanResult } from \"./scan.ts\"\nexport { buildManifest, describeCommand, generateManifest, MANIFEST_SCHEMA_VERSION, manifestHash } from \"./manifest.ts\"\nexport type { BuildManifest, BuildManifestCommand, BuildManifestResource, BuildManifestRoute, Manifest, ManifestCommand, ManifestNamespace } from \"./manifest.ts\"\nexport type { BuildManifestPrompt } from \"./manifest.ts\"\nexport { collectRoutes, loadRoutes, ROUTE_METHODS, walkRoutes } from \"./route.ts\"\nexport type { RouteContext, RouteEntry, RouteHandler, RouteMethod, RouteModule, ScannedRoute } from \"./route.ts\"\nexport { BUILD_DIR, BUILD_MANIFEST_FILE, buildProject, HANDLER_JS, RolldownUnavailableError, SERVER_JS, START_ENTRY } from \"./build.ts\"\nexport type { BuildOptions, BuildResult, BuildWarning, RolldownModule, RolldownOutputItem } from \"./build.ts\"\nexport { formatBuildSummary, runBuild } from \"./cli/build.ts\"\nexport { mextVersion } from \"./version.ts\"\nexport * from \"./mcp/index.ts\"\nexport { CLI_BUILTIN_COMMANDS, CONFIG_FILE, createApp, defineConfig, loadConfig, resolveCommandsDir, resolveLocalPrincipal } from \"./config.ts\"\nexport { resolveResourcesDir } from \"./config.ts\"\nexport { resolvePromptsDir } from \"./config.ts\"\nexport { resolveRoutesDir } from \"./config.ts\"\nexport { memoryState } from \"./state.ts\"\nexport type { MemoryStateOptions, MextBus, MextState, MextStore } from \"./state.ts\"\nexport type { CliConfig, McpCapabilities, McpConfig, McpConnectHandler, McpConnection, MextConfig } from \"./config.ts\"\nexport { buildCustomerCli, CLI_BIN_FILE, CLI_DIR, customerCliIssues } from \"./build-cli.ts\"\nexport type { BuildCustomerCliOptions, CustomerCliBuild } from \"./build-cli.ts\"\nexport { runCustomerCli } from \"./client/main.ts\"\nexport type { CustomerCliConfig } from \"./client/main.ts\"\nexport { clientManifest, manifestHelp } from \"./client/manifest.ts\"\nexport type { ClientManifest, ClientManifestCommand } from \"./client/manifest.ts\"\nexport { runRemote } from \"./client/runner.ts\"\nexport type { HelpSource, RemoteRunOptions } from \"./client/runner.ts\"\nexport { runCli, SUBCOMMANDS } from \"./cli/main.ts\"\nexport type { CliSubcommand } from \"./cli/main.ts\"\nexport type { CliIo, CliWriter } from \"./cli/io.ts\"\nexport { analyzeInput, assertCliConvertible, cliBuildIssues, cliSpec, parseArgs, RESERVED_FLAGS, toKebab } from \"./cli/args.ts\"\nexport type { CliField, CliSpec, FieldKind, ParseArgsOptions, ParsedArgs, Primitive, ScalarKind } from \"./cli/args.ts\"\nexport {\n cliPath,\n formatInvocation,\n renderCommandHelp,\n renderHelp,\n renderNamespaceHelp,\n resolveHelpTarget,\n} from \"./cli/help.ts\"\nexport type { HelpOptions, HelpTarget } from \"./cli/help.ts\"\nexport { errorJson, exitCodeOf, formatError, formatJson, formatResult } from \"./cli/output.ts\"\nexport type { CliErrorFormatter, CliErrorInfo, CliErrorOutput } from \"./cli/output.ts\"\nexport { loginCommand, resolveServerUrl } from \"./cli/login.ts\"\nexport type { AuthCommandOptions } from \"./cli/login.ts\"\nexport { logoutCommand } from \"./cli/logout.ts\"\nexport * from \"./remote/index.ts\"\nexport { cliSpecFromJsonSchema, defineCliSpec } from \"./cli/args.ts\"\n"]}
|
|
@@ -8,8 +8,12 @@ export declare const INSTRUMENTATION_FILE = "instrumentation.ts";
|
|
|
8
8
|
/** 핸들러를 실행한 어댑터. 원격 CLI 는 핸들러를 실행하지 않으므로 없다 */
|
|
9
9
|
export type Transport = "http" | "stdio" | "local";
|
|
10
10
|
export interface CommandErrorInfo {
|
|
11
|
-
/** 정식 명령어 ID */
|
|
11
|
+
/** 정식 명령어 ID. 자원 핸들러 (read · list · complete) 오류 = 자원 uri (템플릿 원문), 프롬프트 핸들러 오류 = 프롬프트 이름 */
|
|
12
12
|
command: string;
|
|
13
|
+
/** 자원 핸들러 오류일 때 자원 uri (템플릿 원문, §12.3) */
|
|
14
|
+
resource?: string;
|
|
15
|
+
/** 프롬프트 핸들러 (render · complete) 오류일 때 프롬프트 이름 (§12.3) */
|
|
16
|
+
prompt?: string;
|
|
13
17
|
transport: Transport;
|
|
14
18
|
/** scopes · claims 는 넘기지 않는다 */
|
|
15
19
|
principal: {
|
|
@@ -89,9 +93,17 @@ export interface ObserveOptions {
|
|
|
89
93
|
* 취소 (signal abort · MRTR 대기) = status 없음.
|
|
90
94
|
*/
|
|
91
95
|
export declare function observeCommand<T>(command: string, options: ObserveOptions, signal: () => AbortSignal | undefined, fn: () => Promise<T>): Promise<T>;
|
|
96
|
+
/**
|
|
97
|
+
* observeCommand 의 일반형 (자원 = `mext.resource <uri 템플릿>`, §12.3).
|
|
98
|
+
* attributes 에 mext.transport · mext.principal.kind 를 더한다. 실패 · 취소 처리는 observeCommand 와 같다
|
|
99
|
+
*/
|
|
100
|
+
export declare function observeSpan<T>(name: string, attributes: Record<string, string>, options: ObserveOptions, signal: () => AbortSignal | undefined, fn: () => Promise<T>): Promise<T>;
|
|
92
101
|
/**
|
|
93
102
|
* 핸들러 예외 → onCommandError (await). MextError · CommandError · 취소 · MRTR 대기는 보고하지 않는다.
|
|
94
103
|
* onCommandError 자체의 예외 = onerror (기본 stderr), 호출자에게 전파하지 않는다.
|
|
95
104
|
*/
|
|
96
|
-
export declare function reportCommandError(error: unknown, command: string, options: ObserveOptions, signal: AbortSignal | undefined
|
|
105
|
+
export declare function reportCommandError(error: unknown, command: string, options: ObserveOptions, signal: AbortSignal | undefined, extra?: {
|
|
106
|
+
resource?: string;
|
|
107
|
+
prompt?: string;
|
|
108
|
+
}): Promise<void>;
|
|
97
109
|
export {};
|