@obov/mext 0.5.0 → 0.7.1
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.map +1 -1
- package/dist/build.d.ts +2 -0
- package/dist/build.js +46 -5
- 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/args.js +1 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/build.js +26 -4
- 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 +27 -3
- 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.d.ts +6 -0
- package/dist/cli/dev.js +20 -8
- 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 +10 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/media.d.ts +19 -0
- package/dist/cli/media.js +77 -0
- package/dist/cli/media.js.map +1 -0
- 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 +33 -4
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/serve.d.ts +10 -0
- package/dist/cli/serve.js +114 -0
- package/dist/cli/serve.js.map +1 -0
- 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 +11 -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 +40 -3
- package/dist/client/runner.js.map +1 -1
- package/dist/client/typed.d.ts +56 -0
- package/dist/client/typed.js +526 -0
- package/dist/client/typed.js.map +1 -0
- package/dist/client/types.d.ts +225 -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 +59 -10
- package/dist/config.js +67 -7
- package/dist/config.js.map +1 -1
- package/dist/content.d.ts +65 -0
- package/dist/content.js +99 -0
- package/dist/content.js.map +1 -0
- 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 +18 -7
- package/dist/index.js +8 -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 +36 -5
- package/dist/invoke.js +162 -21
- package/dist/invoke.js.map +1 -1
- package/dist/manifest.d.ts +19 -3
- package/dist/manifest.js +5 -1
- package/dist/manifest.js.map +1 -1
- package/dist/mcp/constants.d.ts +7 -0
- package/dist/mcp/constants.js +7 -0
- package/dist/mcp/constants.js.map +1 -1
- package/dist/mcp/dispatch.d.ts +10 -4
- package/dist/mcp/dispatch.js +24 -7
- 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/host.d.ts +14 -0
- package/dist/mcp/host.js +48 -0
- package/dist/mcp/host.js.map +1 -0
- package/dist/mcp/http.d.ts +38 -7
- package/dist/mcp/http.js +199 -23
- package/dist/mcp/http.js.map +1 -1
- package/dist/mcp/index.d.ts +2 -1
- package/dist/mcp/index.js +2 -1
- package/dist/mcp/index.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 +3 -0
- package/dist/mcp/stdio.js.map +1 -1
- package/dist/mcp/tasks.d.ts +3 -1
- package/dist/mcp/tasks.js +7 -4
- 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 +26 -1
- package/dist/remote/client.js +180 -55
- package/dist/remote/client.js.map +1 -1
- package/dist/remote/index.d.ts +1 -1
- package/dist/remote/index.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/route.d.ts +40 -2
- package/dist/route.js +128 -8
- package/dist/route.js.map +1 -1
- package/dist/start.js +9 -4
- 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 +12 -2
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AA4BA,sDAAsD;AACtD,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,MAAM,CAAuB;IAEtC,YAAY,MAA6B;QACvC,KAAK,CACH,sBAAsB,MAAM,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK;YAC7E,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACzF,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AA2DD,qDAAqD;AACrD,MAAM,OAAO,SAAmD,SAAQ,KAAK;IAClE,IAAI,CAAG;IACP,OAAO,CAAqB;IAErC,YAAY,IAAO,EAAE,OAAe,EAAE,OAA4B;QAChE,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,WAAW,CAAA;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,MAAM;QACJ,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;IACpE,CAAC;CACF;AAED,MAAM,UAAU,WAAW,CAA0B,KAAc,EAAE,IAAQ;IAC3E,OAAO,KAAK,YAAY,SAAS,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;AAClF,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,eAAe,CAAC,MAAqD;IACnF,MAAM,OAAO,GAAG,MAAM,KAAK,eAAe,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,+BAA+B,CAAA;IACzG,OAAO,IAAI,SAAS,CAAC,iBAAiB,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;AAC9D,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,IAAyB;IACtE,MAAM,OAAO,GACX,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,qCAAqC,CAAC,CAAC,CAAC,GAAG,OAAO,wCAAwC,CAAA;IAC3H,OAAO,IAAI,SAAS,CAAC,gBAAgB,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;AACpE,CAAC;AAED,gDAAgD;AAChD,MAAM,CAAC,MAAM,oBAAoB,GAAsB;IACrD,iBAAiB;IACjB,kBAAkB;IAClB,iBAAiB;IACjB,mBAAmB;IACnB,mBAAmB;IACnB,gBAAgB;IAChB,iBAAiB;IACjB,kBAAkB;IAClB,aAAa;IACb,aAAa;IACb,cAAc;CACf,CAAA;AAED,MAAM,UAAU,GAAG,mBAAmB,CAAA;AAEtC;;;GAGG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAQ;IACZ,OAAO,CAAyB;IAEzC,YAAY,IAAY,EAAE,OAAe,EAAE,OAAO,GAA4B,EAAE;QAC9E,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,SAAS,CAAC,mDAAmD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjG,CAAC;QACD,IAAI,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,sBAAsB,IAAI,uBAAuB,CAAC,CAAA;QAC/G,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9E,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAA;QAC/D,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,MAAM;QACJ,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAA;IACpE,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,KAAK,YAAY,YAAY,CAAA;AACtC,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,KAAK,YAAY,SAAS,IAAI,KAAK,YAAY,YAAY,CAAA;AACpE,CAAC","sourcesContent":["export type BuildIssueCode =\n | \"COMMANDS_DIR_MISSING\"\n | \"PATH_COLLISION\"\n | \"DUPLICATE_ID\"\n | \"INVALID_SEGMENT\"\n | \"INVALID_ALIAS\"\n | \"RESERVED_ID\"\n | \"ROOT_INDEX\"\n | \"INVALID_COMMAND\"\n | \"LOAD_FAILED\"\n | \"SCHEMA_UNREPRESENTABLE\"\n | \"CLI_UNCONVERTIBLE\"\n | \"BUNDLE_FAILED\"\n | \"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"]}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { APPROVAL_META_KEY } from \"./mcp/constants.ts\"\nexport 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 | \"APPROVAL_REQUIRED\"\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 /**\n * anonymous = 인증 없는 주체의 readOnly 외 명령어 · read_only = readOnly 전용 호출 (split query) · scope = scopes 부족 ·\n * authorize = 명령어의 authorize 가드가 거부 (spec §4)\n */\n reason: \"anonymous\" | \"read_only\" | \"scope\" | \"authorize\"\n required_scopes: string[]\n held_scopes: string[]\n }\n /**\n * 사람의 승인 없이 실행할 수 없는 호출 (needsApproval · requiresConfirmation, spec §4 승인). PERMISSION_DENIED 와 달리 사람이 확인하면 실행된다.\n * unconfirmed = client 방식 표면인데 요청에 확인 표시가 없다 (확인받고 meta_key 에 { confirmed: true } 를 실어 다시 호출).\n * human_required = 이 호출자는 승인할 수 없다 (행위자가 agent · client 방식 표면에서 human 이 아님). 사람이 사람 표면에서 실행해야 한다\n */\n APPROVAL_REQUIRED: {\n command: string\n reason: \"unconfirmed\" | \"human_required\"\n /** reason unconfirmed: 확인 표시를 싣는 요청 params._meta 키 (\"dev.mext/approval\") */\n meta_key?: 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/** 승인 부족 (§4 승인). agent = 서버가 정한 행위자가 agent */\nexport function approvalRequired(\n command: string,\n reason: MextErrorDetails[\"APPROVAL_REQUIRED\"][\"reason\"],\n options: { agent?: boolean } = {},\n): MextError<\"APPROVAL_REQUIRED\"> {\n if (reason === \"unconfirmed\") {\n const key = APPROVAL_META_KEY\n return new MextError(\n \"APPROVAL_REQUIRED\",\n `${command} needs approval. Confirm with the person, then call again with _meta[\"${key}\"] = { \"confirmed\": true }.`,\n { command, reason, meta_key: key },\n )\n }\n const message = options.agent\n ? `${command} needs approval from a person. An agent cannot approve it; a person has to run it.`\n : `${command} needs approval from a person, and this caller is not identified as one.`\n return new MextError(\"APPROVAL_REQUIRED\", message, { command, reason })\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 \"APPROVAL_REQUIRED\",\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/expose.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Surface } from "./caller.ts";
|
|
2
|
+
import { type Registry } from "./registry.ts";
|
|
3
|
+
/** expose 를 쓰는 명령어가 하나라도 있는지. false = 표면과 무관하게 같은 목록 (보기 = 원본) */
|
|
4
|
+
export declare function hasExposure(registry: Registry): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* surface 에서 보이는 Registry. 숨길 명령어가 없으면 registry 그대로 (같은 객체).
|
|
7
|
+
* 같은 숨김 집합 = 같은 보기 객체 (도구 목록 · manifestHash 를 보기별로 1회 계산할 수 있다)
|
|
8
|
+
*/
|
|
9
|
+
export declare function exposedRegistry(registry: Registry, surface: Surface): Registry;
|
package/dist/expose.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { isExposedOn } from "./caller.js";
|
|
2
|
+
import { filterRegistry } from "./registry.js";
|
|
3
|
+
/**
|
|
4
|
+
* 표면별 노출 (defineCommand expose, spec §4) 의 Registry 보기.
|
|
5
|
+
* 숨긴 명령어 = 그 표면에서 없는 명령어: 보기에는 명령어 · 별칭 · (남은 명령어가 없는) 네임스페이스가 없다.
|
|
6
|
+
* help · tools/list · UNKNOWN_COMMAND (suggested · usage) · invoke 가 모두 보기를 쓰므로 없는 ID 와 구분되지 않는다.
|
|
7
|
+
* 판정 입력 = 서버가 정한 표면 (surfaceOf(principal, transport)) 만
|
|
8
|
+
*/
|
|
9
|
+
const rules = new WeakMap();
|
|
10
|
+
const views = new WeakMap();
|
|
11
|
+
/** expose 를 쓰는 명령어가 하나라도 있는지. false = 표면과 무관하게 같은 목록 (보기 = 원본) */
|
|
12
|
+
export function hasExposure(registry) {
|
|
13
|
+
let value = rules.get(registry);
|
|
14
|
+
if (value === undefined) {
|
|
15
|
+
value = false;
|
|
16
|
+
for (const entry of registry.commands.values()) {
|
|
17
|
+
if (entry.command.expose !== undefined) {
|
|
18
|
+
value = true;
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
rules.set(registry, value);
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* surface 에서 보이는 Registry. 숨길 명령어가 없으면 registry 그대로 (같은 객체).
|
|
28
|
+
* 같은 숨김 집합 = 같은 보기 객체 (도구 목록 · manifestHash 를 보기별로 1회 계산할 수 있다)
|
|
29
|
+
*/
|
|
30
|
+
export function exposedRegistry(registry, surface) {
|
|
31
|
+
if (!hasExposure(registry))
|
|
32
|
+
return registry;
|
|
33
|
+
const hidden = [];
|
|
34
|
+
for (const entry of registry.commands.values()) {
|
|
35
|
+
if (!isExposedOn(entry.command.expose, surface))
|
|
36
|
+
hidden.push(entry.id);
|
|
37
|
+
}
|
|
38
|
+
if (hidden.length === 0)
|
|
39
|
+
return registry;
|
|
40
|
+
let cache = views.get(registry);
|
|
41
|
+
if (!cache)
|
|
42
|
+
views.set(registry, (cache = new Map()));
|
|
43
|
+
const key = hidden.join("\n");
|
|
44
|
+
let view = cache.get(key);
|
|
45
|
+
if (!view) {
|
|
46
|
+
const set = new Set(hidden);
|
|
47
|
+
view = filterRegistry(registry, (entry) => !set.has(entry.id));
|
|
48
|
+
cache.set(key, view);
|
|
49
|
+
}
|
|
50
|
+
return view;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=expose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expose.js","sourceRoot":"","sources":["../src/expose.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,cAAc,EAAiB,MAAM,eAAe,CAAA;AAE7D;;;;;GAKG;AAEH,MAAM,KAAK,GAAG,IAAI,OAAO,EAAqB,CAAA;AAC9C,MAAM,KAAK,GAAG,IAAI,OAAO,EAAmC,CAAA;AAE5D,kEAAkE;AAClE,MAAM,UAAU,WAAW,CAAC,QAAkB;IAC5C,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,KAAK,GAAG,KAAK,CAAA;QACb,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACvC,KAAK,GAAG,IAAI,CAAA;gBACZ,MAAK;YACP,CAAC;QACH,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAC5B,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAkB,EAAE,OAAgB;IAClE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC3C,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QAC/C,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACxE,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAA;IACxC,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC/B,IAAI,CAAC,KAAK;QAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAA;IACpD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7B,IAAI,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACzB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;QAC3B,IAAI,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QAC9D,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IACtB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["import { isExposedOn, type Surface } from \"./caller.ts\"\nimport { filterRegistry, type Registry } from \"./registry.ts\"\n\n/**\n * 표면별 노출 (defineCommand expose, spec §4) 의 Registry 보기.\n * 숨긴 명령어 = 그 표면에서 없는 명령어: 보기에는 명령어 · 별칭 · (남은 명령어가 없는) 네임스페이스가 없다.\n * help · tools/list · UNKNOWN_COMMAND (suggested · usage) · invoke 가 모두 보기를 쓰므로 없는 ID 와 구분되지 않는다.\n * 판정 입력 = 서버가 정한 표면 (surfaceOf(principal, transport)) 만\n */\n\nconst rules = new WeakMap<Registry, boolean>()\nconst views = new WeakMap<Registry, Map<string, Registry>>()\n\n/** expose 를 쓰는 명령어가 하나라도 있는지. false = 표면과 무관하게 같은 목록 (보기 = 원본) */\nexport function hasExposure(registry: Registry): boolean {\n let value = rules.get(registry)\n if (value === undefined) {\n value = false\n for (const entry of registry.commands.values()) {\n if (entry.command.expose !== undefined) {\n value = true\n break\n }\n }\n rules.set(registry, value)\n }\n return value\n}\n\n/**\n * surface 에서 보이는 Registry. 숨길 명령어가 없으면 registry 그대로 (같은 객체).\n * 같은 숨김 집합 = 같은 보기 객체 (도구 목록 · manifestHash 를 보기별로 1회 계산할 수 있다)\n */\nexport function exposedRegistry(registry: Registry, surface: Surface): Registry {\n if (!hasExposure(registry)) return registry\n const hidden: string[] = []\n for (const entry of registry.commands.values()) {\n if (!isExposedOn(entry.command.expose, surface)) hidden.push(entry.id)\n }\n if (hidden.length === 0) return registry\n let cache = views.get(registry)\n if (!cache) views.set(registry, (cache = new Map()))\n const key = hidden.join(\"\\n\")\n let view = cache.get(key)\n if (!view) {\n const set = new Set(hidden)\n view = filterRegistry(registry, (entry) => !set.has(entry.id))\n cache.set(key, view)\n }\n return view\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
export { VERSION } from "./version.ts";
|
|
2
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";
|
|
3
|
+
export type { Ask, AskRequest, Command, CommandAudit, CommandContext, CommandDefinition, ConfirmRequest, InputRequest, InputSchema, MextApp, ProgressUpdate, TaskOptions, UrlRequest, } from "./command.ts";
|
|
4
|
+
export { audio, image, isContent, isContentResult, resourceLink, splitResult, withContent } from "./content.ts";
|
|
5
|
+
export type { AudioContent, BinaryData, Content, ContentBlock, ContentResult, ImageContent, ResourceLinkContent, ResultValue, } from "./content.ts";
|
|
4
6
|
export { collectResources, collectResourceSet, createLazyResourceSet, createResourceSet, defineResource, describeResource, isResource, loadResourceSet, matchResource, parseUriTemplate, resourceEntries, withResources, } from "./resource.ts";
|
|
5
7
|
export type { LazyResourceInput, ManifestResource, RegisteredResource, Resource, ResourceCompleteContext, ResourceCompleter, ResourceContext, ResourceDefinition, ResourceInput, ResourceListItem, ResourceSet, ResourceVariables, UriTemplatePattern, } from "./resource.ts";
|
|
6
8
|
export { collectPrompts, collectPromptSet, createLazyPromptSet, createPromptSet, definePrompt, describePrompt, isPrompt, loadPromptSet, promptArguments, withPrompts, } from "./prompt.ts";
|
|
7
9
|
export type { LazyPromptInput, ManifestPrompt, Prompt, PromptArgs, PromptArgument, PromptCompleteContext, PromptCompleter, PromptContext, PromptDefinition, PromptInput, PromptMessage, PromptResult, PromptSet, RegisteredPrompt, } from "./prompt.ts";
|
|
8
10
|
export { ANONYMOUS, hasScope, localPrincipal } from "./principal.ts";
|
|
9
|
-
export type { Principal } from "./principal.ts";
|
|
10
|
-
export {
|
|
11
|
+
export type { Actor, ActorKind, Principal } from "./principal.ts";
|
|
12
|
+
export { ANY_SURFACE, callerOf, defaultSurface, isExposedOn, surfaceOf } from "./caller.ts";
|
|
13
|
+
export type { BuiltinSurface, Caller, Exposure, ReportedClient, Surface } from "./caller.ts";
|
|
14
|
+
export { exposedRegistry, hasExposure } from "./expose.ts";
|
|
15
|
+
export { approvalModeOf, isApprovalMark } from "./approval.ts";
|
|
16
|
+
export type { ApprovalConfig, ApprovalMode, ApprovalSignal } from "./approval.ts";
|
|
17
|
+
export { auditHidden, startAudit } from "./audit.ts";
|
|
18
|
+
export type { AuditConfig, AuditContext, AuditEvent, AuditOutcome, AuditTarget, AuditTrail } from "./audit.ts";
|
|
19
|
+
export { CommandError, approvalRequired, inputDeclined, isCommandError, isMextError, MextBuildError, MextError, RESERVED_ERROR_CODES, unauthenticated, } from "./errors.ts";
|
|
11
20
|
export type { ArgumentIssue, BuildIssue, BuildIssueCode, MextErrorCode, MextErrorDetails } from "./errors.ts";
|
|
12
21
|
export { authorize, confirmationMessage, createContext, findCommand, invalidArgument, invoke, OutputValidationError, parseInput } from "./invoke.ts";
|
|
13
22
|
export type { AskHandler, AskHandlerRequest, DetachedExecution, InvokeOptions, InvokeResult } from "./invoke.ts";
|
|
14
23
|
export { findInstrumentation, INSTRUMENTATION_FILE, loadInstrumentation, loadProjectInstrumentation, } from "./instrumentation.ts";
|
|
15
|
-
export type { CommandErrorInfo, Instrumentation, InstrumentationModule, LoadInstrumentationOptions, OtelApi, Transport, } from "./instrumentation.ts";
|
|
16
|
-
export { collectRegistry, createLazyRegistry, createRegistry, loadCommand, resolveCommand } from "./registry.ts";
|
|
24
|
+
export type { CommandErrorInfo, Instrumentation, InstrumentationModule, LoadInstrumentationOptions, OtelApi, TraceIds, Transport, } from "./instrumentation.ts";
|
|
25
|
+
export { collectRegistry, createLazyRegistry, createRegistry, filterRegistry, loadCommand, resolveCommand } from "./registry.ts";
|
|
17
26
|
export type { JsonSchema, LazyCommandInput, NamespaceInfo, RegisteredCommand, Registry, RegistryCommandInput, RegistryInput, RegistryNamespaceInput, } from "./registry.ts";
|
|
18
27
|
export { collectCommands, loadRegistry, scanCommands, walkCommands } from "./scan.ts";
|
|
19
28
|
export type { ScannedFile, ScanResult } from "./scan.ts";
|
|
@@ -21,11 +30,13 @@ export { buildManifest, describeCommand, generateManifest, MANIFEST_SCHEMA_VERSI
|
|
|
21
30
|
export type { BuildManifest, BuildManifestCommand, BuildManifestResource, BuildManifestRoute, Manifest, ManifestCommand, ManifestNamespace } from "./manifest.ts";
|
|
22
31
|
export type { BuildManifestPrompt } from "./manifest.ts";
|
|
23
32
|
export { collectRoutes, loadRoutes, ROUTE_METHODS, walkRoutes } from "./route.ts";
|
|
24
|
-
export type { RouteContext, RouteEntry, RouteHandler, RouteMethod, RouteModule, ScannedRoute } from "./route.ts";
|
|
33
|
+
export type { RouteAuth, RouteContext, RouteEntry, RouteHandler, RouteMethod, RouteModule, RouteOptions, ScannedRoute } from "./route.ts";
|
|
25
34
|
export { BUILD_DIR, BUILD_MANIFEST_FILE, buildProject, HANDLER_JS, RolldownUnavailableError, SERVER_JS, START_ENTRY } from "./build.ts";
|
|
26
35
|
export type { BuildOptions, BuildResult, BuildWarning, RolldownModule, RolldownOutputItem } from "./build.ts";
|
|
27
36
|
export { formatBuildSummary, runBuild } from "./cli/build.ts";
|
|
28
37
|
export { mextVersion } from "./version.ts";
|
|
38
|
+
export { renderTypes, resolveTypesPath, TYPES_FILE, writeTypes } from "./typegen.ts";
|
|
39
|
+
export type { WriteTypesResult } from "./typegen.ts";
|
|
29
40
|
export * from "./mcp/index.ts";
|
|
30
41
|
export { CLI_BUILTIN_COMMANDS, CONFIG_FILE, createApp, defineConfig, loadConfig, resolveCommandsDir, resolveLocalPrincipal } from "./config.ts";
|
|
31
42
|
export { resolveResourcesDir } from "./config.ts";
|
|
@@ -33,7 +44,7 @@ export { resolvePromptsDir } from "./config.ts";
|
|
|
33
44
|
export { resolveRoutesDir } from "./config.ts";
|
|
34
45
|
export { memoryState } from "./state.ts";
|
|
35
46
|
export type { MemoryStateOptions, MextBus, MextState, MextStore } from "./state.ts";
|
|
36
|
-
export type { CliConfig, McpCapabilities, McpConfig, McpConnectHandler, McpConnection, MextConfig } from "./config.ts";
|
|
47
|
+
export type { CliConfig, LocalPrincipalRequest, McpCapabilities, McpConfig, McpConnectHandler, McpConnection, MextConfig } from "./config.ts";
|
|
37
48
|
export { buildCustomerCli, CLI_BIN_FILE, CLI_DIR, customerCliIssues } from "./build-cli.ts";
|
|
38
49
|
export type { BuildCustomerCliOptions, CustomerCliBuild } from "./build-cli.ts";
|
|
39
50
|
export { runCustomerCli } from "./client/main.ts";
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
export { VERSION } from "./version.js";
|
|
2
2
|
export { DEFAULT_TASK_TTL_MS, defineCommand, isCommand } from "./command.js";
|
|
3
|
+
export { audio, image, isContent, isContentResult, resourceLink, splitResult, withContent } from "./content.js";
|
|
3
4
|
export { collectResources, collectResourceSet, createLazyResourceSet, createResourceSet, defineResource, describeResource, isResource, loadResourceSet, matchResource, parseUriTemplate, resourceEntries, withResources, } from "./resource.js";
|
|
4
5
|
export { collectPrompts, collectPromptSet, createLazyPromptSet, createPromptSet, definePrompt, describePrompt, isPrompt, loadPromptSet, promptArguments, withPrompts, } from "./prompt.js";
|
|
5
6
|
export { ANONYMOUS, hasScope, localPrincipal } from "./principal.js";
|
|
6
|
-
export {
|
|
7
|
+
export { ANY_SURFACE, callerOf, defaultSurface, isExposedOn, surfaceOf } from "./caller.js";
|
|
8
|
+
export { exposedRegistry, hasExposure } from "./expose.js";
|
|
9
|
+
export { approvalModeOf, isApprovalMark } from "./approval.js";
|
|
10
|
+
export { auditHidden, startAudit } from "./audit.js";
|
|
11
|
+
export { CommandError, approvalRequired, inputDeclined, isCommandError, isMextError, MextBuildError, MextError, RESERVED_ERROR_CODES, unauthenticated, } from "./errors.js";
|
|
7
12
|
export { authorize, confirmationMessage, createContext, findCommand, invalidArgument, invoke, OutputValidationError, parseInput } from "./invoke.js";
|
|
8
13
|
export { findInstrumentation, INSTRUMENTATION_FILE, loadInstrumentation, loadProjectInstrumentation, } from "./instrumentation.js";
|
|
9
|
-
export { collectRegistry, createLazyRegistry, createRegistry, loadCommand, resolveCommand } from "./registry.js";
|
|
14
|
+
export { collectRegistry, createLazyRegistry, createRegistry, filterRegistry, loadCommand, resolveCommand } from "./registry.js";
|
|
10
15
|
export { collectCommands, loadRegistry, scanCommands, walkCommands } from "./scan.js";
|
|
11
16
|
export { buildManifest, describeCommand, generateManifest, MANIFEST_SCHEMA_VERSION, manifestHash } from "./manifest.js";
|
|
12
17
|
export { collectRoutes, loadRoutes, ROUTE_METHODS, walkRoutes } from "./route.js";
|
|
13
18
|
export { BUILD_DIR, BUILD_MANIFEST_FILE, buildProject, HANDLER_JS, RolldownUnavailableError, SERVER_JS, START_ENTRY } from "./build.js";
|
|
14
19
|
export { formatBuildSummary, runBuild } from "./cli/build.js";
|
|
15
20
|
export { mextVersion } from "./version.js";
|
|
21
|
+
export { renderTypes, resolveTypesPath, TYPES_FILE, writeTypes } from "./typegen.js";
|
|
16
22
|
export * from "./mcp/index.js";
|
|
17
23
|
export { CLI_BUILTIN_COMMANDS, CONFIG_FILE, createApp, defineConfig, loadConfig, resolveCommandsDir, resolveLocalPrincipal } from "./config.js";
|
|
18
24
|
export { resolveResourcesDir } from "./config.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAgB5E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAW/G,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,aAAa,GACd,MAAM,eAAe,CAAA;AAgBtB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,aAAa,EACb,eAAe,EACf,WAAW,GACZ,MAAM,aAAa,CAAA;AAiBpB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE3F,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAE9D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEpD,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,eAAe,GAChB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAEpJ,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAA;AAU7B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAWhI,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAErF,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAGvH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEjF,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,YAAY,EAAE,UAAU,EAAE,wBAAwB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAEvI,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEpF,cAAc,gBAAgB,CAAA;AAC9B,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAC/I,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAGxC,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAE3F,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAE9C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAGnD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAE/H,OAAO,EACL,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAE9F,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,cAAc,mBAAmB,CAAA;AACjC,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA","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 CommandAudit,\n CommandContext,\n CommandDefinition,\n ConfirmRequest,\n InputRequest,\n InputSchema,\n MextApp,\n ProgressUpdate,\n TaskOptions,\n UrlRequest,\n} from \"./command.ts\"\nexport { audio, image, isContent, isContentResult, resourceLink, splitResult, withContent } from \"./content.ts\"\nexport type {\n AudioContent,\n BinaryData,\n Content,\n ContentBlock,\n ContentResult,\n ImageContent,\n ResourceLinkContent,\n ResultValue,\n} from \"./content.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 { Actor, ActorKind, Principal } from \"./principal.ts\"\nexport { ANY_SURFACE, callerOf, defaultSurface, isExposedOn, surfaceOf } from \"./caller.ts\"\nexport type { BuiltinSurface, Caller, Exposure, ReportedClient, Surface } from \"./caller.ts\"\nexport { exposedRegistry, hasExposure } from \"./expose.ts\"\nexport { approvalModeOf, isApprovalMark } from \"./approval.ts\"\nexport type { ApprovalConfig, ApprovalMode, ApprovalSignal } from \"./approval.ts\"\nexport { auditHidden, startAudit } from \"./audit.ts\"\nexport type { AuditConfig, AuditContext, AuditEvent, AuditOutcome, AuditTarget, AuditTrail } from \"./audit.ts\"\nexport {\n CommandError,\n approvalRequired,\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 TraceIds,\n Transport,\n} from \"./instrumentation.ts\"\nexport { collectRegistry, createLazyRegistry, createRegistry, filterRegistry, 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 { RouteAuth, RouteContext, RouteEntry, RouteHandler, RouteMethod, RouteModule, RouteOptions, 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 { renderTypes, resolveTypesPath, TYPES_FILE, writeTypes } from \"./typegen.ts\"\nexport type { WriteTypesResult } from \"./typegen.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, LocalPrincipalRequest, 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"]}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { AuditEvent } from "../audit.ts";
|
|
2
|
+
import { type Failure } from "./compare.ts";
|
|
3
|
+
import type { Inspector } from "./inspector.ts";
|
|
4
|
+
/**
|
|
5
|
+
* 에이전트 plugin 계약 (specs/inspector.md §7): 에이전트에게 말로 지시하고, 서버에 남은 감사 이벤트로 판정한다.
|
|
6
|
+
* inspector 는 에이전트 종류를 모른다. 에이전트별 연결 방법은 AgentClient 를 만드는 모듈 (plugin) 안에만 있다
|
|
7
|
+
*/
|
|
8
|
+
/** 에이전트 쪽에서 일어난 일. 판정에는 쓰지 않는다 (판정 = 서버의 감사 이벤트). idle · error 만 단계의 끝을 정한다 */
|
|
9
|
+
export type AgentEvent =
|
|
10
|
+
/** 에이전트가 한 말 */
|
|
11
|
+
{
|
|
12
|
+
type: "text";
|
|
13
|
+
text: string;
|
|
14
|
+
}
|
|
15
|
+
/** 에이전트 쪽에서 본 도구 호출 (선택) */
|
|
16
|
+
| {
|
|
17
|
+
type: "tool";
|
|
18
|
+
name: string;
|
|
19
|
+
input?: unknown;
|
|
20
|
+
output?: unknown;
|
|
21
|
+
ok?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** 보낸 지시의 처리를 마쳤다 (더 올 호출이 없다). plugin 이 반드시 알린다 */
|
|
24
|
+
| {
|
|
25
|
+
type: "idle";
|
|
26
|
+
}
|
|
27
|
+
/** 연결 끊김 · 에이전트 실행 실패 */
|
|
28
|
+
| {
|
|
29
|
+
type: "error";
|
|
30
|
+
message: string;
|
|
31
|
+
};
|
|
32
|
+
export interface AgentMessage {
|
|
33
|
+
text: string;
|
|
34
|
+
}
|
|
35
|
+
export interface AgentClient {
|
|
36
|
+
/** 표시 이름 (결과 · 로그) */
|
|
37
|
+
readonly name?: string;
|
|
38
|
+
/** 연결하고 지시를 받을 수 있는지 확인. 실패 = throw (사람이 읽을 이유) */
|
|
39
|
+
connect(options?: {
|
|
40
|
+
signal?: AbortSignal;
|
|
41
|
+
}): Promise<void>;
|
|
42
|
+
/** 지시 하나를 보낸다. 전달이 확인되면 끝난다 (에이전트의 일이 끝나기를 기다리지 않는다) */
|
|
43
|
+
send(message: AgentMessage): Promise<void>;
|
|
44
|
+
/** 반환 = 해제 */
|
|
45
|
+
onEvent(listener: (event: AgentEvent) => void): () => void;
|
|
46
|
+
close?(): Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
/** --agent 모듈의 default export: AgentClient, 또는 그것을 만드는 함수 */
|
|
49
|
+
export type AgentPlugin = AgentClient | ((context: AgentPluginContext) => AgentClient | Promise<AgentClient>);
|
|
50
|
+
export interface AgentPluginContext {
|
|
51
|
+
cwd: string;
|
|
52
|
+
env: Record<string, string | undefined>;
|
|
53
|
+
}
|
|
54
|
+
export declare function isAgentClient(value: unknown): value is AgentClient;
|
|
55
|
+
/** agent 단계의 기대 (각 항목 = 감사 이벤트의 일부) */
|
|
56
|
+
export interface AgentExpect {
|
|
57
|
+
/** 순서대로 있어야 하는 이벤트 (사이에 다른 이벤트가 있어도 된다) */
|
|
58
|
+
audit?: Record<string, unknown>[];
|
|
59
|
+
/** 있으면 안 되는 이벤트 */
|
|
60
|
+
none?: Record<string, unknown>[];
|
|
61
|
+
}
|
|
62
|
+
export interface AgentToolCall {
|
|
63
|
+
name: string;
|
|
64
|
+
input?: unknown;
|
|
65
|
+
output?: unknown;
|
|
66
|
+
ok?: boolean;
|
|
67
|
+
}
|
|
68
|
+
export interface AgentObservation {
|
|
69
|
+
/** idle 까지 갔는가 (false = timeout · error · 취소) */
|
|
70
|
+
ok: boolean;
|
|
71
|
+
/** ok 아님 = 이유 ("timeout" · error 이벤트의 메시지 · "cancelled") */
|
|
72
|
+
problem?: string;
|
|
73
|
+
/** 보낸 지시문 */
|
|
74
|
+
instruction: string;
|
|
75
|
+
/** 관찰 구간에 온 이 에이전트의 감사 이벤트 (오래된 것부터) */
|
|
76
|
+
events: AuditEvent[];
|
|
77
|
+
/** 에이전트가 한 말 */
|
|
78
|
+
messages: string[];
|
|
79
|
+
/** 에이전트 쪽에서 본 도구 호출 */
|
|
80
|
+
tools: AgentToolCall[];
|
|
81
|
+
}
|
|
82
|
+
export declare const AGENT_TIMEOUT_MS = 120000;
|
|
83
|
+
/** idle 뒤 늦게 오는 감사 이벤트를 기다리는 시간 */
|
|
84
|
+
export declare const AGENT_SETTLE_MS = 500;
|
|
85
|
+
export interface InstructOptions {
|
|
86
|
+
text: string;
|
|
87
|
+
/** 이 에이전트의 호출을 가려내는 조건 (이벤트의 일부) */
|
|
88
|
+
from?: Record<string, unknown>;
|
|
89
|
+
timeoutMs?: number;
|
|
90
|
+
settleMs?: number;
|
|
91
|
+
signal?: AbortSignal;
|
|
92
|
+
}
|
|
93
|
+
/** connect 한 번 (같은 AgentClient 로 여러 번 불러도). 실패하면 다음 호출이 다시 시도한다 */
|
|
94
|
+
export declare function connectAgent(agent: AgentClient, signal?: AbortSignal): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* 지시 하나를 보내고 idle 까지 서버의 감사 이벤트를 모은다.
|
|
97
|
+
* 관찰 = send 직전부터 idle (+ settleMs) 까지 온 이벤트 중 inspector 자신의 호출 (trace ID) 이 아니고 from 에 맞는 것.
|
|
98
|
+
* 시작 시각 (at) 이 send 보다 이른 이벤트는 뺀다: 감사 출처가 연결할 때 다시 보내 주는 예전 이벤트 (서버와 시계가 같다고 본다)
|
|
99
|
+
*/
|
|
100
|
+
export declare function instructAgent(inspector: Inspector, agent: AgentClient, options: InstructOptions): Promise<AgentObservation>;
|
|
101
|
+
/** 기대와 관찰한 이벤트 비교. 못 찾은 audit 항목 · 걸린 none 항목 = failures */
|
|
102
|
+
export declare function checkAudit(expect: AgentExpect | undefined, events: readonly AuditEvent[], failures: Failure[]): void;
|
|
103
|
+
/** 실패 항목에 싣는 이벤트 요약 (입력 · 요약문 제외) */
|
|
104
|
+
export declare function summarizeAudit(event: AuditEvent): Record<string, unknown>;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { matches } from "./compare.js";
|
|
2
|
+
export function isAgentClient(value) {
|
|
3
|
+
if (typeof value !== "object" || value === null)
|
|
4
|
+
return false;
|
|
5
|
+
const v = value;
|
|
6
|
+
return typeof v.connect === "function" && typeof v.send === "function" && typeof v.onEvent === "function";
|
|
7
|
+
}
|
|
8
|
+
export const AGENT_TIMEOUT_MS = 120_000;
|
|
9
|
+
/** idle 뒤 늦게 오는 감사 이벤트를 기다리는 시간 */
|
|
10
|
+
export const AGENT_SETTLE_MS = 500;
|
|
11
|
+
const connections = new WeakMap();
|
|
12
|
+
/** connect 한 번 (같은 AgentClient 로 여러 번 불러도). 실패하면 다음 호출이 다시 시도한다 */
|
|
13
|
+
export function connectAgent(agent, signal) {
|
|
14
|
+
let connected = connections.get(agent);
|
|
15
|
+
if (!connected) {
|
|
16
|
+
connected = agent.connect(signal ? { signal } : {});
|
|
17
|
+
connections.set(agent, connected);
|
|
18
|
+
connected.catch(() => connections.delete(agent));
|
|
19
|
+
}
|
|
20
|
+
return connected;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 지시 하나를 보내고 idle 까지 서버의 감사 이벤트를 모은다.
|
|
24
|
+
* 관찰 = send 직전부터 idle (+ settleMs) 까지 온 이벤트 중 inspector 자신의 호출 (trace ID) 이 아니고 from 에 맞는 것.
|
|
25
|
+
* 시작 시각 (at) 이 send 보다 이른 이벤트는 뺀다: 감사 출처가 연결할 때 다시 보내 주는 예전 이벤트 (서버와 시계가 같다고 본다)
|
|
26
|
+
*/
|
|
27
|
+
export async function instructAgent(inspector, agent, options) {
|
|
28
|
+
const started = Date.now();
|
|
29
|
+
const received = [];
|
|
30
|
+
const messages = [];
|
|
31
|
+
const tools = [];
|
|
32
|
+
let finish = () => { };
|
|
33
|
+
const finished = new Promise((resolve) => (finish = resolve));
|
|
34
|
+
const stopAudit = inspector.subscribe((event) => {
|
|
35
|
+
if (event.type === "audit")
|
|
36
|
+
received.push(event.event);
|
|
37
|
+
});
|
|
38
|
+
const stopAgent = agent.onEvent((event) => {
|
|
39
|
+
if (event.type === "text")
|
|
40
|
+
messages.push(event.text);
|
|
41
|
+
else if (event.type === "tool") {
|
|
42
|
+
const { type: _type, ...call } = event;
|
|
43
|
+
tools.push(call);
|
|
44
|
+
}
|
|
45
|
+
else if (event.type === "idle")
|
|
46
|
+
finish(undefined);
|
|
47
|
+
else if (event.type === "error")
|
|
48
|
+
finish(event.message);
|
|
49
|
+
});
|
|
50
|
+
const timer = setTimeout(() => finish("timeout"), options.timeoutMs ?? AGENT_TIMEOUT_MS);
|
|
51
|
+
const onAbort = () => finish("cancelled");
|
|
52
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
53
|
+
if (options.signal?.aborted)
|
|
54
|
+
finish("cancelled");
|
|
55
|
+
let problem;
|
|
56
|
+
try {
|
|
57
|
+
try {
|
|
58
|
+
await agent.send({ text: options.text });
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
finish(`send failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
62
|
+
}
|
|
63
|
+
problem = await finished;
|
|
64
|
+
// 감사 이벤트는 호출보다 늦게 올 수 있다 (감사 출처의 전달 지연)
|
|
65
|
+
if (problem === undefined)
|
|
66
|
+
await new Promise((resolve) => setTimeout(resolve, options.settleMs ?? AGENT_SETTLE_MS));
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
69
|
+
clearTimeout(timer);
|
|
70
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
71
|
+
stopAgent();
|
|
72
|
+
stopAudit();
|
|
73
|
+
}
|
|
74
|
+
const own = new Set(inspector.history().map((record) => record.traceId));
|
|
75
|
+
const events = received.filter((event) => {
|
|
76
|
+
if (event.traceId !== undefined && own.has(event.traceId))
|
|
77
|
+
return false;
|
|
78
|
+
const at = Date.parse(event.at);
|
|
79
|
+
if (Number.isFinite(at) && at < started)
|
|
80
|
+
return false;
|
|
81
|
+
return options.from === undefined || matches(options.from, event);
|
|
82
|
+
});
|
|
83
|
+
// 에이전트가 한 말 · 도구 호출에 프로필의 비밀 값이 섞여 있으면 가린다 (감사 이벤트는 받을 때 이미 가렸다)
|
|
84
|
+
return inspector.redact({
|
|
85
|
+
ok: problem === undefined,
|
|
86
|
+
...(problem !== undefined ? { problem } : {}),
|
|
87
|
+
instruction: options.text,
|
|
88
|
+
events,
|
|
89
|
+
messages,
|
|
90
|
+
tools,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/** 기대와 관찰한 이벤트 비교. 못 찾은 audit 항목 · 걸린 none 항목 = failures */
|
|
94
|
+
export function checkAudit(expect, events, failures) {
|
|
95
|
+
let next = 0;
|
|
96
|
+
for (const [i, pattern] of (expect?.audit ?? []).entries()) {
|
|
97
|
+
const found = events.findIndex((event, index) => index >= next && matches(pattern, event));
|
|
98
|
+
if (found >= 0) {
|
|
99
|
+
next = found + 1;
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
// 같은 명령어의 이벤트를 보여 준다 (무엇이 달랐는지). 순서만 틀린 경우도 여기에 나온다
|
|
103
|
+
const same = typeof pattern.command === "string" ? events.filter((event) => event.command === pattern.command) : events;
|
|
104
|
+
failures.push({ path: `audit.${i}`, expected: pattern, actual: same.map(summarizeAudit) });
|
|
105
|
+
}
|
|
106
|
+
for (const [i, pattern] of (expect?.none ?? []).entries()) {
|
|
107
|
+
const hit = events.find((event) => matches(pattern, event));
|
|
108
|
+
if (hit)
|
|
109
|
+
failures.push({ path: `none.${i}`, expected: pattern, actual: summarizeAudit(hit) });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/** 실패 항목에 싣는 이벤트 요약 (입력 · 요약문 제외) */
|
|
113
|
+
export function summarizeAudit(event) {
|
|
114
|
+
return {
|
|
115
|
+
command: event.command,
|
|
116
|
+
outcome: event.outcome,
|
|
117
|
+
...(event.error ? { error: event.error.code } : {}),
|
|
118
|
+
surface: event.surface,
|
|
119
|
+
...(event.actor ? { actor: event.actor } : {}),
|
|
120
|
+
...(event.client ? { client: event.client.name } : {}),
|
|
121
|
+
...(event.approval ? { approval: event.approval } : {}),
|
|
122
|
+
at: event.at,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/inspect/agent.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuditEvent } from \"../audit.ts\"\nimport { matches, type Failure } from \"./compare.ts\"\nimport type { Inspector } from \"./inspector.ts\"\n\n/**\n * 에이전트 plugin 계약 (specs/inspector.md §7): 에이전트에게 말로 지시하고, 서버에 남은 감사 이벤트로 판정한다.\n * inspector 는 에이전트 종류를 모른다. 에이전트별 연결 방법은 AgentClient 를 만드는 모듈 (plugin) 안에만 있다\n */\n\n/** 에이전트 쪽에서 일어난 일. 판정에는 쓰지 않는다 (판정 = 서버의 감사 이벤트). idle · error 만 단계의 끝을 정한다 */\nexport type AgentEvent =\n /** 에이전트가 한 말 */\n | { type: \"text\"; text: string }\n /** 에이전트 쪽에서 본 도구 호출 (선택) */\n | { type: \"tool\"; name: string; input?: unknown; output?: unknown; ok?: boolean }\n /** 보낸 지시의 처리를 마쳤다 (더 올 호출이 없다). plugin 이 반드시 알린다 */\n | { type: \"idle\" }\n /** 연결 끊김 · 에이전트 실행 실패 */\n | { type: \"error\"; message: string }\n\nexport interface AgentMessage {\n text: string\n}\n\nexport interface AgentClient {\n /** 표시 이름 (결과 · 로그) */\n readonly name?: string\n /** 연결하고 지시를 받을 수 있는지 확인. 실패 = throw (사람이 읽을 이유) */\n connect(options?: { signal?: AbortSignal }): Promise<void>\n /** 지시 하나를 보낸다. 전달이 확인되면 끝난다 (에이전트의 일이 끝나기를 기다리지 않는다) */\n send(message: AgentMessage): Promise<void>\n /** 반환 = 해제 */\n onEvent(listener: (event: AgentEvent) => void): () => void\n close?(): Promise<void>\n}\n\n/** --agent 모듈의 default export: AgentClient, 또는 그것을 만드는 함수 */\nexport type AgentPlugin = AgentClient | ((context: AgentPluginContext) => AgentClient | Promise<AgentClient>)\n\nexport interface AgentPluginContext {\n cwd: string\n env: Record<string, string | undefined>\n}\n\nexport function isAgentClient(value: unknown): value is AgentClient {\n if (typeof value !== \"object\" || value === null) return false\n const v = value as Record<string, unknown>\n return typeof v.connect === \"function\" && typeof v.send === \"function\" && typeof v.onEvent === \"function\"\n}\n\n/** agent 단계의 기대 (각 항목 = 감사 이벤트의 일부) */\nexport interface AgentExpect {\n /** 순서대로 있어야 하는 이벤트 (사이에 다른 이벤트가 있어도 된다) */\n audit?: Record<string, unknown>[]\n /** 있으면 안 되는 이벤트 */\n none?: Record<string, unknown>[]\n}\n\nexport interface AgentToolCall {\n name: string\n input?: unknown\n output?: unknown\n ok?: boolean\n}\n\nexport interface AgentObservation {\n /** idle 까지 갔는가 (false = timeout · error · 취소) */\n ok: boolean\n /** ok 아님 = 이유 (\"timeout\" · error 이벤트의 메시지 · \"cancelled\") */\n problem?: string\n /** 보낸 지시문 */\n instruction: string\n /** 관찰 구간에 온 이 에이전트의 감사 이벤트 (오래된 것부터) */\n events: AuditEvent[]\n /** 에이전트가 한 말 */\n messages: string[]\n /** 에이전트 쪽에서 본 도구 호출 */\n tools: AgentToolCall[]\n}\n\nexport const AGENT_TIMEOUT_MS = 120_000\n/** idle 뒤 늦게 오는 감사 이벤트를 기다리는 시간 */\nexport const AGENT_SETTLE_MS = 500\n\nexport interface InstructOptions {\n text: string\n /** 이 에이전트의 호출을 가려내는 조건 (이벤트의 일부) */\n from?: Record<string, unknown>\n timeoutMs?: number\n settleMs?: number\n signal?: AbortSignal\n}\n\nconst connections = new WeakMap<AgentClient, Promise<void>>()\n\n/** connect 한 번 (같은 AgentClient 로 여러 번 불러도). 실패하면 다음 호출이 다시 시도한다 */\nexport function connectAgent(agent: AgentClient, signal?: AbortSignal): Promise<void> {\n let connected = connections.get(agent)\n if (!connected) {\n connected = agent.connect(signal ? { signal } : {})\n connections.set(agent, connected)\n connected.catch(() => connections.delete(agent))\n }\n return connected\n}\n\n/**\n * 지시 하나를 보내고 idle 까지 서버의 감사 이벤트를 모은다.\n * 관찰 = send 직전부터 idle (+ settleMs) 까지 온 이벤트 중 inspector 자신의 호출 (trace ID) 이 아니고 from 에 맞는 것.\n * 시작 시각 (at) 이 send 보다 이른 이벤트는 뺀다: 감사 출처가 연결할 때 다시 보내 주는 예전 이벤트 (서버와 시계가 같다고 본다)\n */\nexport async function instructAgent(inspector: Inspector, agent: AgentClient, options: InstructOptions): Promise<AgentObservation> {\n const started = Date.now()\n const received: AuditEvent[] = []\n const messages: string[] = []\n const tools: AgentToolCall[] = []\n let finish: (problem: string | undefined) => void = () => {}\n const finished = new Promise<string | undefined>((resolve) => (finish = resolve))\n const stopAudit = inspector.subscribe((event) => {\n if (event.type === \"audit\") received.push(event.event)\n })\n const stopAgent = agent.onEvent((event) => {\n if (event.type === \"text\") messages.push(event.text)\n else if (event.type === \"tool\") {\n const { type: _type, ...call } = event\n tools.push(call)\n } else if (event.type === \"idle\") finish(undefined)\n else if (event.type === \"error\") finish(event.message)\n })\n const timer = setTimeout(() => finish(\"timeout\"), options.timeoutMs ?? AGENT_TIMEOUT_MS)\n const onAbort = (): void => finish(\"cancelled\")\n options.signal?.addEventListener(\"abort\", onAbort, { once: true })\n if (options.signal?.aborted) finish(\"cancelled\")\n let problem: string | undefined\n try {\n try {\n await agent.send({ text: options.text })\n } catch (error) {\n finish(`send failed: ${error instanceof Error ? error.message : String(error)}`)\n }\n problem = await finished\n // 감사 이벤트는 호출보다 늦게 올 수 있다 (감사 출처의 전달 지연)\n if (problem === undefined) await new Promise((resolve) => setTimeout(resolve, options.settleMs ?? AGENT_SETTLE_MS))\n } finally {\n clearTimeout(timer)\n options.signal?.removeEventListener(\"abort\", onAbort)\n stopAgent()\n stopAudit()\n }\n const own = new Set(inspector.history().map((record) => record.traceId))\n const events = received.filter((event) => {\n if (event.traceId !== undefined && own.has(event.traceId)) return false\n const at = Date.parse(event.at)\n if (Number.isFinite(at) && at < started) return false\n return options.from === undefined || matches(options.from, event)\n })\n // 에이전트가 한 말 · 도구 호출에 프로필의 비밀 값이 섞여 있으면 가린다 (감사 이벤트는 받을 때 이미 가렸다)\n return inspector.redact({\n ok: problem === undefined,\n ...(problem !== undefined ? { problem } : {}),\n instruction: options.text,\n events,\n messages,\n tools,\n })\n}\n\n/** 기대와 관찰한 이벤트 비교. 못 찾은 audit 항목 · 걸린 none 항목 = failures */\nexport function checkAudit(expect: AgentExpect | undefined, events: readonly AuditEvent[], failures: Failure[]): void {\n let next = 0\n for (const [i, pattern] of (expect?.audit ?? []).entries()) {\n const found = events.findIndex((event, index) => index >= next && matches(pattern, event))\n if (found >= 0) {\n next = found + 1\n continue\n }\n // 같은 명령어의 이벤트를 보여 준다 (무엇이 달랐는지). 순서만 틀린 경우도 여기에 나온다\n const same = typeof pattern.command === \"string\" ? events.filter((event) => event.command === pattern.command) : events\n failures.push({ path: `audit.${i}`, expected: pattern, actual: same.map(summarizeAudit) })\n }\n for (const [i, pattern] of (expect?.none ?? []).entries()) {\n const hit = events.find((event) => matches(pattern, event))\n if (hit) failures.push({ path: `none.${i}`, expected: pattern, actual: summarizeAudit(hit) })\n }\n}\n\n/** 실패 항목에 싣는 이벤트 요약 (입력 · 요약문 제외) */\nexport function summarizeAudit(event: AuditEvent): Record<string, unknown> {\n return {\n command: event.command,\n outcome: event.outcome,\n ...(event.error ? { error: event.error.code } : {}),\n surface: event.surface,\n ...(event.actor ? { actor: event.actor } : {}),\n ...(event.client ? { client: event.client.name } : {}),\n ...(event.approval ? { approval: event.approval } : {}),\n at: event.at,\n }\n}\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { AuditEvent } from "../audit.ts";
|
|
2
|
+
/**
|
|
3
|
+
* 감사 출처 (specs/inspector.md §6): 서버의 감사 이벤트 (mext.md §11.1) 를 Inspector 로 잇는다.
|
|
4
|
+
* mext dev = 감사 tap 의 endpoint (mext.md §10). 그 외 = 호출 코드가 출처를 만들어 연결한다
|
|
5
|
+
*/
|
|
6
|
+
export interface AuditSource {
|
|
7
|
+
/** 이벤트마다 listener 호출. 반환 = 구독 해제 */
|
|
8
|
+
subscribe(listener: (event: AuditEvent) => void): () => void;
|
|
9
|
+
}
|
|
10
|
+
/** 같은 프로세스의 서버와 잇는 출처: mext.config.ts · startMcpHttpServer 의 audit.sink 에 push 를 넘긴다 */
|
|
11
|
+
export interface AuditChannel extends AuditSource {
|
|
12
|
+
push(event: AuditEvent): void;
|
|
13
|
+
}
|
|
14
|
+
export declare function auditChannel(): AuditChannel;
|
|
15
|
+
export interface DevAuditCredentials {
|
|
16
|
+
/** mext dev 의 MCP 엔드포인트 (lock 의 url) */
|
|
17
|
+
url: string;
|
|
18
|
+
/** lock 의 auditToken */
|
|
19
|
+
token: string;
|
|
20
|
+
}
|
|
21
|
+
export interface DevAuditSourceOptions {
|
|
22
|
+
/** 연결할 때마다 읽는다 (mext dev 를 다시 시작하면 토큰이 바뀐다). undefined = 실행 중인 dev 없음 → 잠시 뒤 다시 */
|
|
23
|
+
credentials: DevAuditCredentials | (() => DevAuditCredentials | undefined);
|
|
24
|
+
fetch?: typeof fetch;
|
|
25
|
+
/** 다시 연결하기 전 대기 (기본 500ms, 실패가 이어지면 5초까지 늘어난다) */
|
|
26
|
+
retryMs?: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* mext dev 의 감사 tap endpoint 를 읽는 출처. 구독자가 있는 동안 연결 하나를 유지하고, 끊기면 ?after 로 이어 받는다.
|
|
30
|
+
* 토큰은 Authorization 헤더로만 보낸다 (출력하지 않는다)
|
|
31
|
+
*/
|
|
32
|
+
export declare function devAuditSource(options: DevAuditSourceOptions): AuditSource;
|
|
33
|
+
export type AuditAvailability = {
|
|
34
|
+
available: true;
|
|
35
|
+
source: AuditSource;
|
|
36
|
+
} | {
|
|
37
|
+
available: false;
|
|
38
|
+
reason: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* 대상 서버의 감사 출처. 대상이 이 프로젝트의 mext dev (대상 URL = .mext/dev/lock 의 url) 일 때만 자동 연결.
|
|
42
|
+
* 그 외 = 사용 불가 + 이유 (프로그램 API 로 출처를 직접 연결할 수 있다)
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveAudit(target: {
|
|
45
|
+
url: string;
|
|
46
|
+
}, cwd: string): AuditAvailability;
|