@obov/mext 0.4.0 โ†’ 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/dist/approval.d.ts +33 -0
  2. package/dist/approval.js +36 -0
  3. package/dist/approval.js.map +1 -0
  4. package/dist/audit.d.ts +123 -0
  5. package/dist/audit.js +221 -0
  6. package/dist/audit.js.map +1 -0
  7. package/dist/build-cli.d.ts +1 -0
  8. package/dist/build-cli.js +2 -1
  9. package/dist/build-cli.js.map +1 -1
  10. package/dist/build.d.ts +2 -0
  11. package/dist/build.js +30 -3
  12. package/dist/build.js.map +1 -1
  13. package/dist/caller.d.ts +53 -0
  14. package/dist/caller.js +51 -0
  15. package/dist/caller.js.map +1 -0
  16. package/dist/cli/build.js +6 -3
  17. package/dist/cli/build.js.map +1 -1
  18. package/dist/cli/dev-audit.d.ts +25 -0
  19. package/dist/cli/dev-audit.js +84 -0
  20. package/dist/cli/dev-audit.js.map +1 -0
  21. package/dist/cli/dev-lock.d.ts +3 -1
  22. package/dist/cli/dev-lock.js +12 -5
  23. package/dist/cli/dev-lock.js.map +1 -1
  24. package/dist/cli/dev-server.d.ts +9 -0
  25. package/dist/cli/dev-server.js +24 -1
  26. package/dist/cli/dev-server.js.map +1 -1
  27. package/dist/cli/dev-tap.d.ts +20 -0
  28. package/dist/cli/dev-tap.js +70 -0
  29. package/dist/cli/dev-tap.js.map +1 -0
  30. package/dist/cli/dev.js +16 -4
  31. package/dist/cli/dev.js.map +1 -1
  32. package/dist/cli/help.js +2 -0
  33. package/dist/cli/help.js.map +1 -1
  34. package/dist/cli/inspect.d.ts +7 -0
  35. package/dist/cli/inspect.js +699 -0
  36. package/dist/cli/inspect.js.map +1 -0
  37. package/dist/cli/main.js +8 -0
  38. package/dist/cli/main.js.map +1 -1
  39. package/dist/cli/output.d.ts +1 -1
  40. package/dist/cli/output.js +3 -2
  41. package/dist/cli/output.js.map +1 -1
  42. package/dist/cli/run.js +28 -4
  43. package/dist/cli/run.js.map +1 -1
  44. package/dist/cli/types.d.ts +9 -0
  45. package/dist/cli/types.js +77 -0
  46. package/dist/cli/types.js.map +1 -0
  47. package/dist/client/index.d.ts +10 -0
  48. package/dist/client/index.js +7 -0
  49. package/dist/client/index.js.map +1 -0
  50. package/dist/client/manifest.js +6 -2
  51. package/dist/client/manifest.js.map +1 -1
  52. package/dist/client/runner.js +37 -3
  53. package/dist/client/runner.js.map +1 -1
  54. package/dist/client/typed.d.ts +54 -0
  55. package/dist/client/typed.js +490 -0
  56. package/dist/client/typed.js.map +1 -0
  57. package/dist/client/types.d.ts +196 -0
  58. package/dist/client/types.js +2 -0
  59. package/dist/client/types.js.map +1 -0
  60. package/dist/command.d.ts +61 -5
  61. package/dist/command.js +42 -1
  62. package/dist/command.js.map +1 -1
  63. package/dist/config.d.ts +42 -10
  64. package/dist/config.js +32 -7
  65. package/dist/config.js.map +1 -1
  66. package/dist/errors.d.ts +21 -3
  67. package/dist/errors.js +13 -0
  68. package/dist/errors.js.map +1 -1
  69. package/dist/expose.d.ts +9 -0
  70. package/dist/expose.js +52 -0
  71. package/dist/expose.js.map +1 -0
  72. package/dist/index.d.ts +15 -6
  73. package/dist/index.js +7 -2
  74. package/dist/index.js.map +1 -1
  75. package/dist/inspect/agent.d.ts +104 -0
  76. package/dist/inspect/agent.js +125 -0
  77. package/dist/inspect/agent.js.map +1 -0
  78. package/dist/inspect/audit.d.ts +46 -0
  79. package/dist/inspect/audit.js +133 -0
  80. package/dist/inspect/audit.js.map +1 -0
  81. package/dist/inspect/compare.d.ts +12 -0
  82. package/dist/inspect/compare.js +31 -0
  83. package/dist/inspect/compare.js.map +1 -0
  84. package/dist/inspect/index.d.ts +17 -0
  85. package/dist/inspect/index.js +12 -0
  86. package/dist/inspect/index.js.map +1 -0
  87. package/dist/inspect/inspector.d.ts +168 -0
  88. package/dist/inspect/inspector.js +392 -0
  89. package/dist/inspect/inspector.js.map +1 -0
  90. package/dist/inspect/profiles.d.ts +95 -0
  91. package/dist/inspect/profiles.js +235 -0
  92. package/dist/inspect/profiles.js.map +1 -0
  93. package/dist/inspect/scenario.d.ts +126 -0
  94. package/dist/inspect/scenario.js +555 -0
  95. package/dist/inspect/scenario.js.map +1 -0
  96. package/dist/inspect/ui-server.d.ts +31 -0
  97. package/dist/inspect/ui-server.js +378 -0
  98. package/dist/inspect/ui-server.js.map +1 -0
  99. package/dist/inspect/ui.html +917 -0
  100. package/dist/instrumentation.d.ts +13 -2
  101. package/dist/instrumentation.js +11 -1
  102. package/dist/instrumentation.js.map +1 -1
  103. package/dist/invoke.d.ts +32 -5
  104. package/dist/invoke.js +150 -16
  105. package/dist/invoke.js.map +1 -1
  106. package/dist/manifest.d.ts +13 -2
  107. package/dist/manifest.js +5 -1
  108. package/dist/manifest.js.map +1 -1
  109. package/dist/mcp/constants.d.ts +5 -0
  110. package/dist/mcp/constants.js +5 -0
  111. package/dist/mcp/constants.js.map +1 -1
  112. package/dist/mcp/dispatch.d.ts +1 -1
  113. package/dist/mcp/dispatch.js +14 -3
  114. package/dist/mcp/dispatch.js.map +1 -1
  115. package/dist/mcp/help.d.ts +2 -0
  116. package/dist/mcp/help.js +6 -1
  117. package/dist/mcp/help.js.map +1 -1
  118. package/dist/mcp/http.d.ts +16 -2
  119. package/dist/mcp/http.js +76 -7
  120. package/dist/mcp/http.js.map +1 -1
  121. package/dist/mcp/index.d.ts +1 -1
  122. package/dist/mcp/index.js +1 -1
  123. package/dist/mcp/index.js.map +1 -1
  124. package/dist/mcp/install.d.ts +1 -1
  125. package/dist/mcp/install.js +3 -2
  126. package/dist/mcp/install.js.map +1 -1
  127. package/dist/mcp/server.d.ts +12 -1
  128. package/dist/mcp/server.js +63 -17
  129. package/dist/mcp/server.js.map +1 -1
  130. package/dist/mcp/stdio.d.ts +4 -0
  131. package/dist/mcp/stdio.js +28 -0
  132. package/dist/mcp/stdio.js.map +1 -1
  133. package/dist/mcp/tasks.d.ts +3 -1
  134. package/dist/mcp/tasks.js +6 -3
  135. package/dist/mcp/tasks.js.map +1 -1
  136. package/dist/principal.d.ts +22 -0
  137. package/dist/principal.js +29 -0
  138. package/dist/principal.js.map +1 -1
  139. package/dist/registry.d.ts +5 -0
  140. package/dist/registry.js +21 -0
  141. package/dist/registry.js.map +1 -1
  142. package/dist/remote/client.d.ts +2 -0
  143. package/dist/remote/client.js +3 -2
  144. package/dist/remote/client.js.map +1 -1
  145. package/dist/remote/oauth.d.ts +1 -1
  146. package/dist/remote/oauth.js +1 -1
  147. package/dist/remote/oauth.js.map +1 -1
  148. package/dist/runtime.d.ts +10 -0
  149. package/dist/runtime.js +11 -0
  150. package/dist/runtime.js.map +1 -0
  151. package/dist/start.js +6 -2
  152. package/dist/start.js.map +1 -1
  153. package/dist/suggest.js +1 -1
  154. package/dist/suggest.js.map +1 -1
  155. package/dist/typegen.d.ts +27 -0
  156. package/dist/typegen.js +62 -0
  157. package/dist/typegen.js.map +1 -0
  158. package/dist/version-constant.d.ts +5 -0
  159. package/dist/version-constant.js +6 -0
  160. package/dist/version-constant.js.map +1 -0
  161. package/dist/version.d.ts +1 -2
  162. package/dist/version.js +1 -2
  163. package/dist/version.js.map +1 -1
  164. package/package.json +14 -3
@@ -0,0 +1,33 @@
1
+ import { type Surface } from "./caller.ts";
2
+ /**
3
+ * ์Šน์ธ (defineCommand needsApproval ยท requiresConfirmation, spec ยง4 ์Šน์ธ).
4
+ * ์Šน์ธ์ด ํ•„์š”ํ•œ ํ˜ธ์ถœ์„ ๋ˆ„๊ฐ€ ์‚ฌ๋žŒ์—๊ฒŒ ํ™•์ธ๋ฐ›๋Š”์ง€ = ํ‘œ๋ฉด๋งˆ๋‹ค ํ•œ ๊ณณ:
5
+ * ask mext ๊ฐ€ ctx.ask confirm ์œผ๋กœ ๋ฌป๋Š”๋‹ค (CLI ํ”„๋กฌํ”„ํŠธ ยท --yes, MCP = MRTR). ๊ธฐ๋ณธ
6
+ * client ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ž๊ธฐ ํ™”๋ฉด์—์„œ ํ™•์ธ๋ฐ›๊ณ  ์š”์ฒญ์— ํ™•์ธ ํ‘œ์‹œ๋ฅผ ์‹ฃ๋Š”๋‹ค. mext ๋Š” ๋ฌป์ง€ ์•Š๋Š”๋‹ค
7
+ */
8
+ export type ApprovalMode = "ask" | "client";
9
+ /** mext.config.ts ์˜ approval */
10
+ export interface ApprovalConfig {
11
+ /**
12
+ * ํ‘œ๋ฉด๋ณ„ ํ™•์ธ ๋ฐฉ์‹. ํ‚ค = ๋…ผ๋ฆฌ ํ‘œ๋ฉด (ctx.caller.surface ์™€ ๊ฐ™์€ ๊ฐ’) ๋˜๋Š” "*" (์ ์ง€ ์•Š์€ ํ‘œ๋ฉด ์ „๋ถ€). ์ ์ง€ ์•Š์€ ํ‘œ๋ฉด = "ask".
13
+ * client = ์š”์ฒญ _meta["dev.mext/approval"] = { confirmed: true } + ์„œ๋ฒ„๊ฐ€ ์ •ํ•œ ํ–‰์œ„์ž๊ฐ€ human ์ผ ๋•Œ๋งŒ ํ†ต๊ณผ
14
+ */
15
+ surfaces?: {
16
+ readonly [surface: string]: ApprovalMode | undefined;
17
+ };
18
+ }
19
+ /** ๊ฐ์‚ฌ ์ด๋ฒคํŠธ์˜ ์Šน์ธ ์‹ ํ˜ธ (AuditEvent.approval). ๋ˆ„๊ฐ€ ยท ์–ด๋А ํ‘œ๋ฉด = ๊ฐ™์€ ์ด๋ฒคํŠธ์˜ actor ยท principal ยท surface */
20
+ export interface ApprovalSignal {
21
+ /** ์ด๋ฒˆ ํ˜ธ์ถœ์— ์Šน์ธ์ด ํ•„์š”ํ–ˆ๋Š”์ง€ (needsApproval ์กฐ๊ฑด์‹ ๊ฒฐ๊ณผ. ์˜ˆ์™ธ ยท boolean ์•„๋‹Œ ๊ฐ’ = true) */
22
+ required: boolean;
23
+ /** required: ๊ทธ ํ‘œ๋ฉด์˜ ํ™•์ธ ๋ฐฉ์‹ */
24
+ method?: ApprovalMode;
25
+ /** required: ํ™•์ธ๋จ. ask = ctx.ask ์Šน์ธ (ํ”„๋กฌํ”„ํŠธ ยท --yes ยท MRTR accept), client = ์š”์ฒญ์˜ ํ™•์ธ ํ‘œ์‹œ๋ฅผ ์ธ์ • */
26
+ confirmed?: boolean;
27
+ }
28
+ /** ํ‘œ๋ฉด์˜ ํ™•์ธ ๋ฐฉ์‹: surfaces[surface] โ†’ surfaces["*"] โ†’ "ask" */
29
+ export declare function approvalModeOf(config: ApprovalConfig | undefined, surface: Surface): ApprovalMode;
30
+ /** ์š”์ฒญ _meta ์˜ ํ™•์ธ ํ‘œ์‹œ ๊ฐ’์ธ์ง€: { confirmed: true }. ๋‹ค๋ฅธ ํ‚ค๋Š” ๋ฌด์‹œ (์˜ˆ์•ฝ) */
31
+ export declare function isApprovalMark(value: unknown): boolean;
32
+ /** mext.config.ts ์˜ approval ํ˜•์‹ ๋ฌธ์ œ. ์—†์œผ๋ฉด undefined */
33
+ export declare function approvalConfigProblem(value: unknown): string | undefined;
@@ -0,0 +1,36 @@
1
+ import { ANY_SURFACE } from "./caller.js";
2
+ import { isSegment } from "./ids.js";
3
+ /** ํ‘œ๋ฉด์˜ ํ™•์ธ ๋ฐฉ์‹: surfaces[surface] โ†’ surfaces["*"] โ†’ "ask" */
4
+ export function approvalModeOf(config, surface) {
5
+ const surfaces = config?.surfaces;
6
+ if (!surfaces)
7
+ return "ask";
8
+ const own = Object.hasOwn(surfaces, surface) ? surfaces[surface] : undefined;
9
+ return own ?? (Object.hasOwn(surfaces, ANY_SURFACE) ? surfaces[ANY_SURFACE] : undefined) ?? "ask";
10
+ }
11
+ /** ์š”์ฒญ _meta ์˜ ํ™•์ธ ํ‘œ์‹œ ๊ฐ’์ธ์ง€: { confirmed: true }. ๋‹ค๋ฅธ ํ‚ค๋Š” ๋ฌด์‹œ (์˜ˆ์•ฝ) */
12
+ export function isApprovalMark(value) {
13
+ return typeof value === "object" && value !== null && !Array.isArray(value) && value.confirmed === true;
14
+ }
15
+ /** mext.config.ts ์˜ approval ํ˜•์‹ ๋ฌธ์ œ. ์—†์œผ๋ฉด undefined */
16
+ export function approvalConfigProblem(value) {
17
+ if (typeof value !== "object" || value === null || Array.isArray(value))
18
+ return "approval must be an object ({ surfaces })";
19
+ const a = value;
20
+ const unknown = Object.keys(a).filter((k) => k !== "surfaces");
21
+ if (unknown.length > 0)
22
+ return `unknown approval key${unknown.length === 1 ? "" : "s"}: ${unknown.join(", ")}`;
23
+ if (a.surfaces === undefined)
24
+ return undefined;
25
+ if (typeof a.surfaces !== "object" || a.surfaces === null || Array.isArray(a.surfaces)) {
26
+ return 'approval.surfaces must be an object (e.g. { web: "client" })';
27
+ }
28
+ for (const [surface, mode] of Object.entries(a.surfaces)) {
29
+ if (surface !== ANY_SURFACE && !isSegment(surface))
30
+ return `approval.surfaces key "${surface}" must be a surface name (kebab-case) or "*"`;
31
+ if (mode !== "ask" && mode !== "client")
32
+ return `approval.surfaces.${surface} must be "ask" or "client"`;
33
+ }
34
+ return undefined;
35
+ }
36
+ //# sourceMappingURL=approval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.js","sourceRoot":"","sources":["../src/approval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAgB,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AA6BpC,2DAA2D;AAC3D,MAAM,UAAU,cAAc,CAAC,MAAkC,EAAE,OAAgB;IACjF,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,CAAA;IACjC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC5E,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,CAAA;AACnG,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAK,KAAiC,CAAC,SAAS,KAAK,IAAI,CAAA;AACtI,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,2CAA2C,CAAA;IAC3H,MAAM,CAAC,GAAG,KAAgC,CAAA;IAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,CAAA;IAC9D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,uBAAuB,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;IAC9G,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC9C,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvF,OAAO,8DAA8D,CAAA;IACvE,CAAC;IACD,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzD,IAAI,OAAO,KAAK,WAAW,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YAAE,OAAO,0BAA0B,OAAO,8CAA8C,CAAA;QAC1I,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,qBAAqB,OAAO,4BAA4B,CAAA;IAC1G,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC","sourcesContent":["import { ANY_SURFACE, type Surface } from \"./caller.ts\"\nimport { isSegment } from \"./ids.ts\"\n\n/**\n * ์Šน์ธ (defineCommand needsApproval ยท requiresConfirmation, spec ยง4 ์Šน์ธ).\n * ์Šน์ธ์ด ํ•„์š”ํ•œ ํ˜ธ์ถœ์„ ๋ˆ„๊ฐ€ ์‚ฌ๋žŒ์—๊ฒŒ ํ™•์ธ๋ฐ›๋Š”์ง€ = ํ‘œ๋ฉด๋งˆ๋‹ค ํ•œ ๊ณณ:\n * ask mext ๊ฐ€ ctx.ask confirm ์œผ๋กœ ๋ฌป๋Š”๋‹ค (CLI ํ”„๋กฌํ”„ํŠธ ยท --yes, MCP = MRTR). ๊ธฐ๋ณธ\n * client ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ž๊ธฐ ํ™”๋ฉด์—์„œ ํ™•์ธ๋ฐ›๊ณ  ์š”์ฒญ์— ํ™•์ธ ํ‘œ์‹œ๋ฅผ ์‹ฃ๋Š”๋‹ค. mext ๋Š” ๋ฌป์ง€ ์•Š๋Š”๋‹ค\n */\nexport type ApprovalMode = \"ask\" | \"client\"\n\n/** mext.config.ts ์˜ approval */\nexport interface ApprovalConfig {\n /**\n * ํ‘œ๋ฉด๋ณ„ ํ™•์ธ ๋ฐฉ์‹. ํ‚ค = ๋…ผ๋ฆฌ ํ‘œ๋ฉด (ctx.caller.surface ์™€ ๊ฐ™์€ ๊ฐ’) ๋˜๋Š” \"*\" (์ ์ง€ ์•Š์€ ํ‘œ๋ฉด ์ „๋ถ€). ์ ์ง€ ์•Š์€ ํ‘œ๋ฉด = \"ask\".\n * client = ์š”์ฒญ _meta[\"dev.mext/approval\"] = { confirmed: true } + ์„œ๋ฒ„๊ฐ€ ์ •ํ•œ ํ–‰์œ„์ž๊ฐ€ human ์ผ ๋•Œ๋งŒ ํ†ต๊ณผ\n */\n surfaces?: { readonly [surface: string]: ApprovalMode | undefined }\n}\n\n/** ๊ฐ์‚ฌ ์ด๋ฒคํŠธ์˜ ์Šน์ธ ์‹ ํ˜ธ (AuditEvent.approval). ๋ˆ„๊ฐ€ ยท ์–ด๋А ํ‘œ๋ฉด = ๊ฐ™์€ ์ด๋ฒคํŠธ์˜ actor ยท principal ยท surface */\nexport interface ApprovalSignal {\n /** ์ด๋ฒˆ ํ˜ธ์ถœ์— ์Šน์ธ์ด ํ•„์š”ํ–ˆ๋Š”์ง€ (needsApproval ์กฐ๊ฑด์‹ ๊ฒฐ๊ณผ. ์˜ˆ์™ธ ยท boolean ์•„๋‹Œ ๊ฐ’ = true) */\n required: boolean\n /** required: ๊ทธ ํ‘œ๋ฉด์˜ ํ™•์ธ ๋ฐฉ์‹ */\n method?: ApprovalMode\n /** required: ํ™•์ธ๋จ. ask = ctx.ask ์Šน์ธ (ํ”„๋กฌํ”„ํŠธ ยท --yes ยท MRTR accept), client = ์š”์ฒญ์˜ ํ™•์ธ ํ‘œ์‹œ๋ฅผ ์ธ์ • */\n confirmed?: boolean\n}\n\n/** ํ‘œ๋ฉด์˜ ํ™•์ธ ๋ฐฉ์‹: surfaces[surface] โ†’ surfaces[\"*\"] โ†’ \"ask\" */\nexport function approvalModeOf(config: ApprovalConfig | undefined, surface: Surface): ApprovalMode {\n const surfaces = config?.surfaces\n if (!surfaces) return \"ask\"\n const own = Object.hasOwn(surfaces, surface) ? surfaces[surface] : undefined\n return own ?? (Object.hasOwn(surfaces, ANY_SURFACE) ? surfaces[ANY_SURFACE] : undefined) ?? \"ask\"\n}\n\n/** ์š”์ฒญ _meta ์˜ ํ™•์ธ ํ‘œ์‹œ ๊ฐ’์ธ์ง€: { confirmed: true }. ๋‹ค๋ฅธ ํ‚ค๋Š” ๋ฌด์‹œ (์˜ˆ์•ฝ) */\nexport function isApprovalMark(value: unknown): boolean {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) && (value as { confirmed?: unknown }).confirmed === true\n}\n\n/** mext.config.ts ์˜ approval ํ˜•์‹ ๋ฌธ์ œ. ์—†์œผ๋ฉด undefined */\nexport function approvalConfigProblem(value: unknown): string | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return \"approval must be an object ({ surfaces })\"\n const a = value as Record<string, unknown>\n const unknown = Object.keys(a).filter((k) => k !== \"surfaces\")\n if (unknown.length > 0) return `unknown approval key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`\n if (a.surfaces === undefined) return undefined\n if (typeof a.surfaces !== \"object\" || a.surfaces === null || Array.isArray(a.surfaces)) {\n return 'approval.surfaces must be an object (e.g. { web: \"client\" })'\n }\n for (const [surface, mode] of Object.entries(a.surfaces)) {\n if (surface !== ANY_SURFACE && !isSegment(surface)) return `approval.surfaces key \"${surface}\" must be a surface name (kebab-case) or \"*\"`\n if (mode !== \"ask\" && mode !== \"client\") return `approval.surfaces.${surface} must be \"ask\" or \"client\"`\n }\n return undefined\n}\n"]}
@@ -0,0 +1,123 @@
1
+ import type { ApprovalSignal } from "./approval.ts";
2
+ import { type ReportedClient, type Surface } from "./caller.ts";
3
+ import type { Command } from "./command.ts";
4
+ import type { TraceIds, Transport } from "./instrumentation.ts";
5
+ import type { Actor, Principal } from "./principal.ts";
6
+ import type { RegisteredCommand } from "./registry.ts";
7
+ /**
8
+ * ๊ฐ์‚ฌ (spec ยง11.1). invoke ๊ฒฝ๊ณ„์—์„œ ํ˜ธ์ถœ 1๊ฑด = AuditEvent 1๊ฑด์„ config.audit.sink ๋กœ ๋„˜๊ธด๋‹ค.
9
+ * mext ๋Š” ์ €์žฅ์†Œ์— ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค. sink ๋ฏธ์„ค์ • = startAudit ๊ฐ€ undefined (์ด๋ฒคํŠธ ยท ์ธก์ • ์—†์Œ).
10
+ * span (ยง11) ๊ณผ ๋‹ฌ๋ฆฌ ํ‘œ๋ณธ์ด ์•„๋‹ˆ๋‹ค: ๋Œ€์ƒ ๋ช…๋ น์–ด์˜ ๋ชจ๋“  ํ˜ธ์ถœ์„ sink ์— ๋„˜๊ธด๋‹ค
11
+ */
12
+ /** mext.config.ts ์˜ audit */
13
+ export interface AuditConfig {
14
+ /** ์ด๋ฒคํŠธ 1๊ฑด ์ „๋‹ฌ. ์‘๋‹ต ์ „์— await ํ•œ๋‹ค. ์˜ˆ์™ธ = onerror (์‘๋‹ต ๋ถˆ๋ณ€) */
15
+ sink: (event: AuditEvent) => unknown;
16
+ /** readOnly ๋ช…๋ น์–ด๋„ ๊ธฐ๋ก. ๊ธฐ๋ณธ false = ๋ณ€๊ฒฝ ๋ช…๋ น์–ด๋งŒ */
17
+ includeReadOnly?: boolean;
18
+ /**
19
+ * expose (ยง4) ๋กœ ์ˆจ๊ธด ๋ช…๋ น์–ด๋ฅผ ๊ทธ ํ‘œ๋ฉด์—์„œ ํ˜ธ์ถœํ•˜๋ ค ํ•œ ์‹œ๋„๋„ ๊ธฐ๋ก (outcome "hidden", ์ž…๋ ฅ ์—†์Œ). ๊ธฐ๋ณธ false.
20
+ * ํ˜ธ์ถœ์ž๊ฐ€ ๋ฐ›๋Š” ์‘๋‹ต์€ ๊ธฐ๋ก ์—ฌ๋ถ€์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ์—†๋Š” ๋ช…๋ น์–ด์™€ ๊ฐ™๋‹ค. ์‹ค์ œ๋กœ ์—†๋Š” ID ๋Š” ๊ธฐ๋กํ•˜์ง€ ์•Š๋Š”๋‹ค
21
+ */
22
+ includeHidden?: boolean;
23
+ /** false = ์ž…๋ ฅ์„ ๊ธฐ๋กํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ธฐ๋ณธ true (๋ช…๋ น์–ด audit.input ์œผ๋กœ ๊ฐ€๋ฆผ) */
24
+ input?: boolean;
25
+ /** sink ยท ๋ช…๋ น์–ด audit ํ•จ์ˆ˜ (target ยท summary ยท input) ์˜ ์˜ˆ์™ธ ๋ณด๊ณ . ๊ธฐ๋ณธ stderr 1์ค„ */
26
+ onerror?: (error: unknown) => void;
27
+ }
28
+ /** hidden = expose ๋กœ ์ˆจ๊ธด ๋ช…๋ น์–ด์˜ ํ˜ธ์ถœ ์‹œ๋„ (includeHidden). ์‹คํ–‰ ยท ๊ถŒํ•œ ํŒ์ • ์ „์ด๋ผ denied ์™€ ๊ตฌ๋ถ„ํ•œ๋‹ค */
29
+ export type AuditOutcome = "success" | "error" | "denied" | "hidden";
30
+ /** ๋Œ€์ƒ. type ยท id ์™ธ ๊ฐ’ (๋ฒ„์ „ ํ•ด์‹œ ๋“ฑ) ์„ ์ž์œ ๋กญ๊ฒŒ ์‹ฃ๋Š”๋‹ค */
31
+ export interface AuditTarget {
32
+ type: string;
33
+ id?: string;
34
+ [key: string]: unknown;
35
+ }
36
+ export interface AuditEvent {
37
+ /** ์ •์‹ ๋ช…๋ น์–ด ID (๋ณ„์นญ์œผ๋กœ ํ˜ธ์ถœํ•ด๋„) */
38
+ command: string;
39
+ readOnly: boolean;
40
+ /** ์‹œ์ž‘ ์‹œ๊ฐ (ISO 8601) */
41
+ at: string;
42
+ /** ์ข…๋ฃŒ๊นŒ์ง€ (ms). task = ๋ถ„๋ฆฌ ์‹คํ–‰ ์ข…๋ฃŒ๊นŒ์ง€. hidden = 0 */
43
+ durationMs: number;
44
+ /** ctx.caller.surface ์™€ ๊ฐ™์€ ๊ฐ’: ์„œ๋ฒ„๊ฐ€ ์ •ํ•œ ๋…ผ๋ฆฌ ํ‘œ๋ฉด */
45
+ surface: Surface;
46
+ /** ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•œ ์–ด๋Œ‘ํ„ฐ */
47
+ transport: Transport;
48
+ /** ์„œ๋ฒ„ (auth ยท localPrincipal) ๊ฐ€ ์ •ํ•œ ํ–‰์œ„์ž. ์—†์Œ = ๋ฏธํ™•์ • */
49
+ actor?: Actor;
50
+ /** ์ž๊ฐ€ ์‹ ๊ณ  clientInfo. ๊ฒ€์ฆ๋˜์ง€ ์•Š์€ ๊ฐ’ */
51
+ client?: ReportedClient;
52
+ /** scopes ยท claims ยท ํ† ํฐ์€ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค */
53
+ principal: {
54
+ id: string;
55
+ kind: Principal["kind"];
56
+ };
57
+ outcome: AuditOutcome;
58
+ /** error ยท denied ์˜ code (MextError ยท CommandError code ยท EXECUTION_ERROR ยท INTERRUPTED) ยท message */
59
+ error?: {
60
+ code: string;
61
+ message: string;
62
+ };
63
+ /**
64
+ * ์Šน์ธ ์‹ ํ˜ธ (ยง4 ์Šน์ธ). ์Šน์ธ ๋Œ€์ƒ ๋ช…๋ น์–ด (needsApproval ยท requiresConfirmation) ์˜ ์Šน์ธ ํŒ์ •๊นŒ์ง€ ๊ฐ„ ํ˜ธ์ถœ์—๋งŒ ์žˆ๋‹ค.
65
+ * ๋ˆ„๊ฐ€ ยท ์–ด๋А ํ‘œ๋ฉด = ์ด ์ด๋ฒคํŠธ์˜ actor ยท principal ยท surface
66
+ */
67
+ approval?: ApprovalSignal;
68
+ /** ๊ฒ€์ฆ๋œ ์ž…๋ ฅ (๋ช…๋ น์–ด audit.input ์œผ๋กœ ๊ฐ€๋ฆฐ ๊ฐ’). ์ž…๋ ฅ ๊ฒ€์ฆ ์ „ ๊ฑฐ๋ถ€ ยท hidden ยท ๊ธฐ๋ก์„ ๋ˆ ๊ฒฝ์šฐ = ์—†์Œ */
69
+ input?: unknown;
70
+ target?: AuditTarget;
71
+ summary?: string;
72
+ traceId?: string;
73
+ spanId?: string;
74
+ /** ๋ถ„๋ฆฌ ์‹คํ–‰ (tasks ํ™•์žฅ) ์˜ taskId */
75
+ taskId?: string;
76
+ }
77
+ /** ์ทจ์†Œ (ctx.signal abort ํ›„ ์˜ˆ์™ธ) ์˜ error.code */
78
+ export declare const AUDIT_INTERRUPTED = "INTERRUPTED";
79
+ /** startAudit ์˜ ์ž…๋ ฅ (InvokeOptions ์˜ ๋ถ€๋ถ„) */
80
+ export interface AuditContext {
81
+ audit?: AuditConfig;
82
+ principal: Principal;
83
+ transport?: Transport;
84
+ client?: ReportedClient;
85
+ /** W3C trace context carrier. span ์ด ์—†์„ ๋•Œ traceparent ์˜ traceId */
86
+ traceContext?: Record<string, unknown>;
87
+ }
88
+ /** ํ˜ธ์ถœ 1๊ฑด์˜ ๊ธฐ๋ก. finish ยท skip ์ค‘ ๋จผ์ € ์˜จ ๊ฒƒ๋งŒ ์ ์šฉ (์ด๋ฒคํŠธ๋Š” ๋งŽ์•„์•ผ 1๊ฑด) */
89
+ export interface AuditTrail {
90
+ /** ์ž…๋ ฅ ๊ฒ€์ฆ ํ†ต๊ณผ. ๋ช…๋ น์–ด audit ์˜ต์…˜ (target ยท summary) ์„ ์“ธ ์ˆ˜ ์žˆ๊ณ , ๊ฐ€๋ฆฐ ์ž…๋ ฅ์„ ์ด ์‹œ์ ์— ๊ณ„์‚ฐ */
91
+ validated(command: Command, input: Record<string, unknown>): void;
92
+ /** span ์˜ traceId ยท spanId (observeCommand ๊ฐ€ ๋„˜๊ธด๋‹ค) */
93
+ trace(ids: TraceIds | undefined): void;
94
+ /** ๋ถ„๋ฆฌ ์‹คํ–‰ (task) */
95
+ task(taskId: string | undefined): void;
96
+ /** ์Šน์ธ ํŒ์ • ยท ํ™•์ธ ๊ฒฐ๊ณผ (๋งˆ์ง€๋ง‰ ๊ฐ’์ด ์ด๋ฒคํŠธ์— ์‹ค๋ฆฐ๋‹ค) */
97
+ approval(signal: ApprovalSignal): void;
98
+ /** ๊ธฐ๋กํ•˜์ง€ ์•Š๊ณ  ๋ (์ž…๋ ฅ ๊ฒ€์ฆ ์‹คํŒจ ยท MRTR ์ž…๋ ฅ ๋Œ€๊ธฐ ๋ผ์šด๋“œ) */
99
+ skip(): void;
100
+ /** ์ข…๋ฃŒ โ†’ ์ด๋ฒคํŠธ ์ „๋‹ฌ (sink await). aborted = ctx.signal ์ทจ์†Œ ์—ฌ๋ถ€. ๊ฑฐ๋ถ€ํ•˜์ง€ ์•Š๋Š”๋‹ค */
101
+ finish(result: {
102
+ value: unknown;
103
+ } | {
104
+ error: unknown;
105
+ }, aborted: boolean): Promise<void>;
106
+ }
107
+ /**
108
+ * ํ˜ธ์ถœ 1๊ฑด์˜ ๊ฐ์‚ฌ ์‹œ์ž‘. sink ์—†์Œ ยท ๋Œ€์ƒ ์•„๋‹˜ (readOnly ์ธ๋ฐ includeReadOnly ์•„๋‹˜) = undefined.
109
+ * entry.command ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋งŒ ์“ด๋‹ค (lazy Registry = ๋ชจ๋“ˆ import ์ „์—๋„ ํ˜ธ์ถœ ๊ฐ€๋Šฅ)
110
+ */
111
+ export declare function startAudit(entry: RegisteredCommand, context: AuditContext): AuditTrail | undefined;
112
+ /**
113
+ * expose ๋กœ ์ˆจ๊ธด ๋ช…๋ น์–ด์˜ ํ˜ธ์ถœ ์‹œ๋„ 1๊ฑด (config.audit.includeHidden, spec ยง11.1). entry = ์ˆจ๊ธด ๋ช…๋ น์–ด (ํ˜ธ์ถœ์ž๊ฐ€ ํŒ์ •ํ•ด์„œ ๋„˜๊ธด๋‹ค).
114
+ * ์ž…๋ ฅ ยท ์˜ค๋ฅ˜ ยท target ยท summary ์—†์Œ (๊ฒ€์ฆ ์ „ ์ž…๋ ฅ์—๋Š” ๊ฐ€๋ฆผ ๊ทœ์น™์„ ์ ์šฉํ•  ์ˆ˜ ์—†๋‹ค). readOnly ๋ช…๋ น์–ด๋„ ๊ธฐ๋กํ•œ๋‹ค.
115
+ * sink ํ˜ธ์ถœ = ๋‹ค์Œ macrotask (์‘๋‹ต ์ฒ˜๋ฆฌ๊ฐ€ ๋จผ์ € ์ง„ํ–‰๋œ๋‹ค). ๋ฐ˜ํ™˜ = ์ „๋‹ฌ ์™„๋ฃŒ (๊ฑฐ๋ถ€ํ•˜์ง€ ์•Š๋Š”๋‹ค):
116
+ * ์‘๋‹ต ์‹œ๊ฐ„์œผ๋กœ ์ˆจ๊ธด ๋ช…๋ น์–ด๊ฐ€ ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š๊ฒŒ MCP ์–ด๋Œ‘ํ„ฐ๋Š” ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ , ๋กœ์ปฌ CLI ๋Š” ์ข…๋ฃŒ ์ „์— await ํ•œ๋‹ค.
117
+ * includeHidden ์ด ์•„๋‹ˆ๋ฉด undefined (์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค)
118
+ */
119
+ export declare function auditHidden(entry: RegisteredCommand, context: AuditContext): Promise<void> | undefined;
120
+ /** defineCommand ์˜ audit ํ˜•์‹ ๋ฌธ์ œ. ์—†์œผ๋ฉด undefined */
121
+ export declare function commandAuditProblem(value: unknown): string | undefined;
122
+ /** mext.config.ts ์˜ audit ํ˜•์‹ ๋ฌธ์ œ. ์—†์œผ๋ฉด undefined */
123
+ export declare function auditConfigProblem(value: unknown): string | undefined;
package/dist/audit.js ADDED
@@ -0,0 +1,221 @@
1
+ import { callerOf } from "./caller.js";
2
+ import { isDeclaredError, isMextError } from "./errors.js";
3
+ /** ์ทจ์†Œ (ctx.signal abort ํ›„ ์˜ˆ์™ธ) ์˜ error.code */
4
+ export const AUDIT_INTERRUPTED = "INTERRUPTED";
5
+ /**
6
+ * ํ˜ธ์ถœ 1๊ฑด์˜ ๊ฐ์‚ฌ ์‹œ์ž‘. sink ์—†์Œ ยท ๋Œ€์ƒ ์•„๋‹˜ (readOnly ์ธ๋ฐ includeReadOnly ์•„๋‹˜) = undefined.
7
+ * entry.command ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋งŒ ์“ด๋‹ค (lazy Registry = ๋ชจ๋“ˆ import ์ „์—๋„ ํ˜ธ์ถœ ๊ฐ€๋Šฅ)
8
+ */
9
+ export function startAudit(entry, context) {
10
+ const config = context.audit;
11
+ if (!config)
12
+ return undefined;
13
+ const readOnly = entry.command.readOnly;
14
+ if (readOnly && config.includeReadOnly !== true)
15
+ return undefined;
16
+ const at = new Date().toISOString();
17
+ const started = performance.now();
18
+ let done = false;
19
+ let command;
20
+ let input;
21
+ let validatedInput = {};
22
+ let trace;
23
+ let taskId;
24
+ let approval;
25
+ return {
26
+ validated(loaded, value) {
27
+ command = loaded;
28
+ validatedInput = value;
29
+ const option = loaded.audit?.input;
30
+ if (config.input === false || option === false)
31
+ return;
32
+ if (typeof option !== "function")
33
+ input = { value };
34
+ // input ํ•จ์ˆ˜ ์˜ˆ์™ธ = ์ž…๋ ฅ ์—†์ด ๊ธฐ๋ก (๊ฐ€๋ฆฌ์ง€ ์•Š์€ ๊ฐ’์œผ๋กœ ๋Œ€์ฒดํ•˜์ง€ ์•Š๋Š”๋‹ค)
35
+ else
36
+ guarded(config, () => void (input = { value: option(value) }));
37
+ },
38
+ trace(ids) {
39
+ trace = ids;
40
+ },
41
+ task(id) {
42
+ taskId = id;
43
+ },
44
+ approval(signal) {
45
+ approval = signal;
46
+ },
47
+ skip() {
48
+ done = true;
49
+ },
50
+ async finish(result, aborted) {
51
+ if (done)
52
+ return;
53
+ done = true;
54
+ const value = "value" in result ? result.value : undefined;
55
+ const event = {
56
+ command: entry.id,
57
+ readOnly,
58
+ at,
59
+ durationMs: Math.max(0, Math.round(performance.now() - started)),
60
+ ...callerFields(context),
61
+ ..."error" in result ? failure(result.error, aborted) : { outcome: "success" },
62
+ ...(approval ? { approval } : {}),
63
+ ...(input ? { input: input.value } : {}),
64
+ };
65
+ const options = command?.audit;
66
+ if (options?.target) {
67
+ guarded(config, () => {
68
+ const target = options.target(validatedInput, value);
69
+ if (isTarget(target))
70
+ event.target = target;
71
+ });
72
+ }
73
+ if (options?.summary !== undefined) {
74
+ guarded(config, () => {
75
+ const summary = typeof options.summary === "function" ? options.summary(validatedInput, value) : options.summary;
76
+ if (typeof summary === "string")
77
+ event.summary = summary;
78
+ });
79
+ }
80
+ const ids = trace ?? traceparentIds(context.traceContext);
81
+ if (ids?.traceId !== undefined)
82
+ event.traceId = ids.traceId;
83
+ if (ids?.spanId !== undefined)
84
+ event.spanId = ids.spanId;
85
+ if (taskId !== undefined)
86
+ event.taskId = taskId;
87
+ await deliver(config, event);
88
+ },
89
+ };
90
+ }
91
+ /** ์ด๋ฒคํŠธ์˜ ํ˜ธ์ถœ์ž ํ•„๋“œ (ctx.caller ์™€ ๊ฐ™์€ ๊ณ„์‚ฐ) */
92
+ function callerFields(context) {
93
+ const caller = callerOf(context.principal, context.transport ?? "local", context.client);
94
+ return {
95
+ surface: caller.surface,
96
+ transport: caller.transport,
97
+ ...(caller.actor !== undefined ? { actor: caller.actor } : {}),
98
+ ...(caller.client !== undefined ? { client: caller.client } : {}),
99
+ principal: { id: context.principal.id, kind: context.principal.kind },
100
+ };
101
+ }
102
+ /**
103
+ * expose ๋กœ ์ˆจ๊ธด ๋ช…๋ น์–ด์˜ ํ˜ธ์ถœ ์‹œ๋„ 1๊ฑด (config.audit.includeHidden, spec ยง11.1). entry = ์ˆจ๊ธด ๋ช…๋ น์–ด (ํ˜ธ์ถœ์ž๊ฐ€ ํŒ์ •ํ•ด์„œ ๋„˜๊ธด๋‹ค).
104
+ * ์ž…๋ ฅ ยท ์˜ค๋ฅ˜ ยท target ยท summary ์—†์Œ (๊ฒ€์ฆ ์ „ ์ž…๋ ฅ์—๋Š” ๊ฐ€๋ฆผ ๊ทœ์น™์„ ์ ์šฉํ•  ์ˆ˜ ์—†๋‹ค). readOnly ๋ช…๋ น์–ด๋„ ๊ธฐ๋กํ•œ๋‹ค.
105
+ * sink ํ˜ธ์ถœ = ๋‹ค์Œ macrotask (์‘๋‹ต ์ฒ˜๋ฆฌ๊ฐ€ ๋จผ์ € ์ง„ํ–‰๋œ๋‹ค). ๋ฐ˜ํ™˜ = ์ „๋‹ฌ ์™„๋ฃŒ (๊ฑฐ๋ถ€ํ•˜์ง€ ์•Š๋Š”๋‹ค):
106
+ * ์‘๋‹ต ์‹œ๊ฐ„์œผ๋กœ ์ˆจ๊ธด ๋ช…๋ น์–ด๊ฐ€ ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š๊ฒŒ MCP ์–ด๋Œ‘ํ„ฐ๋Š” ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ , ๋กœ์ปฌ CLI ๋Š” ์ข…๋ฃŒ ์ „์— await ํ•œ๋‹ค.
107
+ * includeHidden ์ด ์•„๋‹ˆ๋ฉด undefined (์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค)
108
+ */
109
+ export function auditHidden(entry, context) {
110
+ const config = context.audit;
111
+ if (config?.includeHidden !== true)
112
+ return undefined;
113
+ const event = {
114
+ command: entry.id,
115
+ readOnly: entry.command.readOnly,
116
+ at: new Date().toISOString(),
117
+ durationMs: 0,
118
+ ...callerFields(context),
119
+ outcome: "hidden",
120
+ };
121
+ const ids = traceparentIds(context.traceContext);
122
+ if (ids?.traceId !== undefined)
123
+ event.traceId = ids.traceId;
124
+ return new Promise((resolve) => setTimeout(() => resolve(deliver(config, event)), 0));
125
+ }
126
+ /**
127
+ * sink ์ „๋‹ฌ. sink ์˜ˆ์™ธ ์ •์ฑ… (spec ยง11.1 sink ์‹คํŒจ, ๊ฒฐ์ •): onerror ๋ณด๊ณ  ํ›„ ์‚ผํ‚จ๋‹ค = ์‘๋‹ต ๋ถˆ๋ณ€ (onCommandError ์™€ ๊ฐ™์€ ์›์น™).
128
+ * ๊ฐ์‚ฌ๋Š” ์‹คํ–‰ ํ›„ ๊ธฐ๋ก์ด๋ผ ์—ฌ๊ธฐ์„œ ์‹คํŒจํ•ด๋„ ์‹คํ–‰์€ ์ด๋ฏธ ๋๋‚ฌ๋‹ค. ์ •์ฑ…์€ ์ด ํ•จ์ˆ˜ ํ•œ ๊ณณ์— ์žˆ๋‹ค
129
+ */
130
+ async function deliver(config, event) {
131
+ try {
132
+ await config.sink(event);
133
+ }
134
+ catch (error) {
135
+ report(config, error);
136
+ }
137
+ }
138
+ /** ๋ช…๋ น์–ด audit ํ•จ์ˆ˜ (target ยท summary ยท input) ์‹คํ–‰. ์˜ˆ์™ธ = onerror, ๊ทธ ํ•„๋“œ ์—†์ด ๊ณ„์† */
139
+ function guarded(config, fn) {
140
+ try {
141
+ fn();
142
+ }
143
+ catch (error) {
144
+ report(config, error);
145
+ }
146
+ }
147
+ function report(config, error) {
148
+ try {
149
+ ;
150
+ (config.onerror ?? defaultOnError)(error);
151
+ }
152
+ catch {
153
+ // ๋ณด๊ณ ๋Š” ์‘๋‹ต์„ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค
154
+ }
155
+ }
156
+ function defaultOnError(error) {
157
+ const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
158
+ process.stderr.write(`mext: audit threw: ${message}\n`);
159
+ }
160
+ /**
161
+ * ์˜ˆ์™ธ โ†’ outcome ยท error. ๊ฑฐ๋ถ€ = PERMISSION_DENIED ยท INPUT_DECLINED ยท APPROVAL_REQUIRED. ๊ทธ ์™ธ = error:
162
+ * ์ทจ์†Œ ํ›„ ์˜ˆ์™ธ = INTERRUPTED, MextError ยท CommandError = ๊ทธ code, ๋‚˜๋จธ์ง€ = EXECUTION_ERROR (์‘๋‹ต๊ณผ ๊ฐ™์€ code ยท message)
163
+ */
164
+ function failure(error, aborted) {
165
+ if (isMextError(error, "PERMISSION_DENIED") || isMextError(error, "INPUT_DECLINED") || isMextError(error, "APPROVAL_REQUIRED")) {
166
+ return { outcome: "denied", error: { code: error.code, message: error.message } };
167
+ }
168
+ if (aborted)
169
+ return { outcome: "error", error: { code: AUDIT_INTERRUPTED, message: "Cancelled before completion." } };
170
+ if (isDeclaredError(error))
171
+ return { outcome: "error", error: { code: error.code, message: error.message } };
172
+ return { outcome: "error", error: { code: "EXECUTION_ERROR", message: error instanceof Error ? error.message : String(error) } };
173
+ }
174
+ function isTarget(value) {
175
+ return typeof value === "object" && value !== null && typeof value.type === "string";
176
+ }
177
+ /** traceparent ("00-<traceId 32 hex>-<parent 16 hex>-<flags>") ์˜ traceId. ํ˜ธ์ถœ ์ชฝ span ์ด๋ผ spanId ๋Š” ์“ฐ์ง€ ์•Š๋Š”๋‹ค */
178
+ function traceparentIds(carrier) {
179
+ const value = carrier?.traceparent;
180
+ const match = typeof value === "string" ? /^[0-9a-f]{2}-([0-9a-f]{32})-[0-9a-f]{16}-[0-9a-f]{2}/.exec(value) : null;
181
+ return match && !/^0+$/.test(match[1]) ? { traceId: match[1] } : undefined;
182
+ }
183
+ /** defineCommand ์˜ audit ํ˜•์‹ ๋ฌธ์ œ. ์—†์œผ๋ฉด undefined */
184
+ export function commandAuditProblem(value) {
185
+ if (typeof value !== "object" || value === null || Array.isArray(value))
186
+ return "audit must be an object ({ target, summary, input })";
187
+ const a = value;
188
+ const unknown = Object.keys(a).filter((k) => k !== "target" && k !== "summary" && k !== "input");
189
+ if (unknown.length > 0)
190
+ return `unknown audit key${unknown.length === 1 ? "" : "s"}: ${unknown.join(", ")}`;
191
+ if (a.target !== undefined && typeof a.target !== "function")
192
+ return "audit.target must be a function";
193
+ if (a.summary !== undefined && typeof a.summary !== "string" && typeof a.summary !== "function") {
194
+ return "audit.summary must be a string or a function";
195
+ }
196
+ if (a.input !== undefined && typeof a.input !== "boolean" && typeof a.input !== "function") {
197
+ return "audit.input must be false or a function";
198
+ }
199
+ return undefined;
200
+ }
201
+ /** mext.config.ts ์˜ audit ํ˜•์‹ ๋ฌธ์ œ. ์—†์œผ๋ฉด undefined */
202
+ export function auditConfigProblem(value) {
203
+ if (typeof value !== "object" || value === null || Array.isArray(value))
204
+ return "audit must be an object ({ sink })";
205
+ const a = value;
206
+ const unknown = Object.keys(a).filter((k) => !["sink", "includeReadOnly", "includeHidden", "input", "onerror"].includes(k));
207
+ if (unknown.length > 0)
208
+ return `unknown audit key${unknown.length === 1 ? "" : "s"}: ${unknown.join(", ")}`;
209
+ if (typeof a.sink !== "function")
210
+ return "audit.sink must be a function";
211
+ if (a.includeReadOnly !== undefined && typeof a.includeReadOnly !== "boolean")
212
+ return "audit.includeReadOnly must be a boolean";
213
+ if (a.includeHidden !== undefined && typeof a.includeHidden !== "boolean")
214
+ return "audit.includeHidden must be a boolean";
215
+ if (a.input !== undefined && typeof a.input !== "boolean")
216
+ return "audit.input must be a boolean";
217
+ if (a.onerror !== undefined && typeof a.onerror !== "function")
218
+ return "audit.onerror must be a function";
219
+ return undefined;
220
+ }
221
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApprovalSignal } from \"./approval.ts\"\nimport { callerOf, type ReportedClient, type Surface } from \"./caller.ts\"\nimport type { Command } from \"./command.ts\"\nimport { isDeclaredError, isMextError } from \"./errors.ts\"\nimport type { TraceIds, Transport } from \"./instrumentation.ts\"\nimport type { Actor, Principal } from \"./principal.ts\"\nimport type { RegisteredCommand } from \"./registry.ts\"\n\n/**\n * ๊ฐ์‚ฌ (spec ยง11.1). invoke ๊ฒฝ๊ณ„์—์„œ ํ˜ธ์ถœ 1๊ฑด = AuditEvent 1๊ฑด์„ config.audit.sink ๋กœ ๋„˜๊ธด๋‹ค.\n * mext ๋Š” ์ €์žฅ์†Œ์— ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค. sink ๋ฏธ์„ค์ • = startAudit ๊ฐ€ undefined (์ด๋ฒคํŠธ ยท ์ธก์ • ์—†์Œ).\n * span (ยง11) ๊ณผ ๋‹ฌ๋ฆฌ ํ‘œ๋ณธ์ด ์•„๋‹ˆ๋‹ค: ๋Œ€์ƒ ๋ช…๋ น์–ด์˜ ๋ชจ๋“  ํ˜ธ์ถœ์„ sink ์— ๋„˜๊ธด๋‹ค\n */\n\n/** mext.config.ts ์˜ audit */\nexport interface AuditConfig {\n /** ์ด๋ฒคํŠธ 1๊ฑด ์ „๋‹ฌ. ์‘๋‹ต ์ „์— await ํ•œ๋‹ค. ์˜ˆ์™ธ = onerror (์‘๋‹ต ๋ถˆ๋ณ€) */\n sink: (event: AuditEvent) => unknown\n /** readOnly ๋ช…๋ น์–ด๋„ ๊ธฐ๋ก. ๊ธฐ๋ณธ false = ๋ณ€๊ฒฝ ๋ช…๋ น์–ด๋งŒ */\n includeReadOnly?: boolean\n /**\n * expose (ยง4) ๋กœ ์ˆจ๊ธด ๋ช…๋ น์–ด๋ฅผ ๊ทธ ํ‘œ๋ฉด์—์„œ ํ˜ธ์ถœํ•˜๋ ค ํ•œ ์‹œ๋„๋„ ๊ธฐ๋ก (outcome \"hidden\", ์ž…๋ ฅ ์—†์Œ). ๊ธฐ๋ณธ false.\n * ํ˜ธ์ถœ์ž๊ฐ€ ๋ฐ›๋Š” ์‘๋‹ต์€ ๊ธฐ๋ก ์—ฌ๋ถ€์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ ์—†๋Š” ๋ช…๋ น์–ด์™€ ๊ฐ™๋‹ค. ์‹ค์ œ๋กœ ์—†๋Š” ID ๋Š” ๊ธฐ๋กํ•˜์ง€ ์•Š๋Š”๋‹ค\n */\n includeHidden?: boolean\n /** false = ์ž…๋ ฅ์„ ๊ธฐ๋กํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ธฐ๋ณธ true (๋ช…๋ น์–ด audit.input ์œผ๋กœ ๊ฐ€๋ฆผ) */\n input?: boolean\n /** sink ยท ๋ช…๋ น์–ด audit ํ•จ์ˆ˜ (target ยท summary ยท input) ์˜ ์˜ˆ์™ธ ๋ณด๊ณ . ๊ธฐ๋ณธ stderr 1์ค„ */\n onerror?: (error: unknown) => void\n}\n\n/** hidden = expose ๋กœ ์ˆจ๊ธด ๋ช…๋ น์–ด์˜ ํ˜ธ์ถœ ์‹œ๋„ (includeHidden). ์‹คํ–‰ ยท ๊ถŒํ•œ ํŒ์ • ์ „์ด๋ผ denied ์™€ ๊ตฌ๋ถ„ํ•œ๋‹ค */\nexport type AuditOutcome = \"success\" | \"error\" | \"denied\" | \"hidden\"\n\n/** ๋Œ€์ƒ. type ยท id ์™ธ ๊ฐ’ (๋ฒ„์ „ ํ•ด์‹œ ๋“ฑ) ์„ ์ž์œ ๋กญ๊ฒŒ ์‹ฃ๋Š”๋‹ค */\nexport interface AuditTarget {\n type: string\n id?: string\n [key: string]: unknown\n}\n\nexport interface AuditEvent {\n /** ์ •์‹ ๋ช…๋ น์–ด ID (๋ณ„์นญ์œผ๋กœ ํ˜ธ์ถœํ•ด๋„) */\n command: string\n readOnly: boolean\n /** ์‹œ์ž‘ ์‹œ๊ฐ (ISO 8601) */\n at: string\n /** ์ข…๋ฃŒ๊นŒ์ง€ (ms). task = ๋ถ„๋ฆฌ ์‹คํ–‰ ์ข…๋ฃŒ๊นŒ์ง€. hidden = 0 */\n durationMs: number\n /** ctx.caller.surface ์™€ ๊ฐ™์€ ๊ฐ’: ์„œ๋ฒ„๊ฐ€ ์ •ํ•œ ๋…ผ๋ฆฌ ํ‘œ๋ฉด */\n surface: Surface\n /** ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•œ ์–ด๋Œ‘ํ„ฐ */\n transport: Transport\n /** ์„œ๋ฒ„ (auth ยท localPrincipal) ๊ฐ€ ์ •ํ•œ ํ–‰์œ„์ž. ์—†์Œ = ๋ฏธํ™•์ • */\n actor?: Actor\n /** ์ž๊ฐ€ ์‹ ๊ณ  clientInfo. ๊ฒ€์ฆ๋˜์ง€ ์•Š์€ ๊ฐ’ */\n client?: ReportedClient\n /** scopes ยท claims ยท ํ† ํฐ์€ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค */\n principal: { id: string; kind: Principal[\"kind\"] }\n outcome: AuditOutcome\n /** error ยท denied ์˜ code (MextError ยท CommandError code ยท EXECUTION_ERROR ยท INTERRUPTED) ยท message */\n error?: { code: string; message: string }\n /**\n * ์Šน์ธ ์‹ ํ˜ธ (ยง4 ์Šน์ธ). ์Šน์ธ ๋Œ€์ƒ ๋ช…๋ น์–ด (needsApproval ยท requiresConfirmation) ์˜ ์Šน์ธ ํŒ์ •๊นŒ์ง€ ๊ฐ„ ํ˜ธ์ถœ์—๋งŒ ์žˆ๋‹ค.\n * ๋ˆ„๊ฐ€ ยท ์–ด๋А ํ‘œ๋ฉด = ์ด ์ด๋ฒคํŠธ์˜ actor ยท principal ยท surface\n */\n approval?: ApprovalSignal\n /** ๊ฒ€์ฆ๋œ ์ž…๋ ฅ (๋ช…๋ น์–ด audit.input ์œผ๋กœ ๊ฐ€๋ฆฐ ๊ฐ’). ์ž…๋ ฅ ๊ฒ€์ฆ ์ „ ๊ฑฐ๋ถ€ ยท hidden ยท ๊ธฐ๋ก์„ ๋ˆ ๊ฒฝ์šฐ = ์—†์Œ */\n input?: unknown\n target?: AuditTarget\n summary?: string\n traceId?: string\n spanId?: string\n /** ๋ถ„๋ฆฌ ์‹คํ–‰ (tasks ํ™•์žฅ) ์˜ taskId */\n taskId?: string\n}\n\n/** ์ทจ์†Œ (ctx.signal abort ํ›„ ์˜ˆ์™ธ) ์˜ error.code */\nexport const AUDIT_INTERRUPTED = \"INTERRUPTED\"\n\n/** startAudit ์˜ ์ž…๋ ฅ (InvokeOptions ์˜ ๋ถ€๋ถ„) */\nexport interface AuditContext {\n audit?: AuditConfig\n principal: Principal\n transport?: Transport\n client?: ReportedClient\n /** W3C trace context carrier. span ์ด ์—†์„ ๋•Œ traceparent ์˜ traceId */\n traceContext?: Record<string, unknown>\n}\n\n/** ํ˜ธ์ถœ 1๊ฑด์˜ ๊ธฐ๋ก. finish ยท skip ์ค‘ ๋จผ์ € ์˜จ ๊ฒƒ๋งŒ ์ ์šฉ (์ด๋ฒคํŠธ๋Š” ๋งŽ์•„์•ผ 1๊ฑด) */\nexport interface AuditTrail {\n /** ์ž…๋ ฅ ๊ฒ€์ฆ ํ†ต๊ณผ. ๋ช…๋ น์–ด audit ์˜ต์…˜ (target ยท summary) ์„ ์“ธ ์ˆ˜ ์žˆ๊ณ , ๊ฐ€๋ฆฐ ์ž…๋ ฅ์„ ์ด ์‹œ์ ์— ๊ณ„์‚ฐ */\n validated(command: Command, input: Record<string, unknown>): void\n /** span ์˜ traceId ยท spanId (observeCommand ๊ฐ€ ๋„˜๊ธด๋‹ค) */\n trace(ids: TraceIds | undefined): void\n /** ๋ถ„๋ฆฌ ์‹คํ–‰ (task) */\n task(taskId: string | undefined): void\n /** ์Šน์ธ ํŒ์ • ยท ํ™•์ธ ๊ฒฐ๊ณผ (๋งˆ์ง€๋ง‰ ๊ฐ’์ด ์ด๋ฒคํŠธ์— ์‹ค๋ฆฐ๋‹ค) */\n approval(signal: ApprovalSignal): void\n /** ๊ธฐ๋กํ•˜์ง€ ์•Š๊ณ  ๋ (์ž…๋ ฅ ๊ฒ€์ฆ ์‹คํŒจ ยท MRTR ์ž…๋ ฅ ๋Œ€๊ธฐ ๋ผ์šด๋“œ) */\n skip(): void\n /** ์ข…๋ฃŒ โ†’ ์ด๋ฒคํŠธ ์ „๋‹ฌ (sink await). aborted = ctx.signal ์ทจ์†Œ ์—ฌ๋ถ€. ๊ฑฐ๋ถ€ํ•˜์ง€ ์•Š๋Š”๋‹ค */\n finish(result: { value: unknown } | { error: unknown }, aborted: boolean): Promise<void>\n}\n\n/**\n * ํ˜ธ์ถœ 1๊ฑด์˜ ๊ฐ์‚ฌ ์‹œ์ž‘. sink ์—†์Œ ยท ๋Œ€์ƒ ์•„๋‹˜ (readOnly ์ธ๋ฐ includeReadOnly ์•„๋‹˜) = undefined.\n * entry.command ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋งŒ ์“ด๋‹ค (lazy Registry = ๋ชจ๋“ˆ import ์ „์—๋„ ํ˜ธ์ถœ ๊ฐ€๋Šฅ)\n */\nexport function startAudit(entry: RegisteredCommand, context: AuditContext): AuditTrail | undefined {\n const config = context.audit\n if (!config) return undefined\n const readOnly = entry.command.readOnly\n if (readOnly && config.includeReadOnly !== true) return undefined\n const at = new Date().toISOString()\n const started = performance.now()\n let done = false\n let command: Command | undefined\n let input: { value: unknown } | undefined\n let validatedInput: Record<string, unknown> = {}\n let trace: TraceIds | undefined\n let taskId: string | undefined\n let approval: ApprovalSignal | undefined\n return {\n validated(loaded, value) {\n command = loaded\n validatedInput = value\n const option = loaded.audit?.input\n if (config.input === false || option === false) return\n if (typeof option !== \"function\") input = { value }\n // input ํ•จ์ˆ˜ ์˜ˆ์™ธ = ์ž…๋ ฅ ์—†์ด ๊ธฐ๋ก (๊ฐ€๋ฆฌ์ง€ ์•Š์€ ๊ฐ’์œผ๋กœ ๋Œ€์ฒดํ•˜์ง€ ์•Š๋Š”๋‹ค)\n else guarded(config, () => void (input = { value: option(value) }))\n },\n trace(ids) {\n trace = ids\n },\n task(id) {\n taskId = id\n },\n approval(signal) {\n approval = signal\n },\n skip() {\n done = true\n },\n async finish(result, aborted) {\n if (done) return\n done = true\n const value = \"value\" in result ? result.value : undefined\n const event: AuditEvent = {\n command: entry.id,\n readOnly,\n at,\n durationMs: Math.max(0, Math.round(performance.now() - started)),\n ...callerFields(context),\n ...\"error\" in result ? failure(result.error, aborted) : { outcome: \"success\" as const },\n ...(approval ? { approval } : {}),\n ...(input ? { input: input.value } : {}),\n }\n const options = command?.audit\n if (options?.target) {\n guarded(config, () => {\n const target = options.target!(validatedInput, value)\n if (isTarget(target)) event.target = target\n })\n }\n if (options?.summary !== undefined) {\n guarded(config, () => {\n const summary = typeof options.summary === \"function\" ? options.summary(validatedInput, value) : options.summary\n if (typeof summary === \"string\") event.summary = summary\n })\n }\n const ids = trace ?? traceparentIds(context.traceContext)\n if (ids?.traceId !== undefined) event.traceId = ids.traceId\n if (ids?.spanId !== undefined) event.spanId = ids.spanId\n if (taskId !== undefined) event.taskId = taskId\n await deliver(config, event)\n },\n }\n}\n\n/** ์ด๋ฒคํŠธ์˜ ํ˜ธ์ถœ์ž ํ•„๋“œ (ctx.caller ์™€ ๊ฐ™์€ ๊ณ„์‚ฐ) */\nfunction callerFields(context: AuditContext): Pick<AuditEvent, \"surface\" | \"transport\" | \"actor\" | \"client\" | \"principal\"> {\n const caller = callerOf(context.principal, context.transport ?? \"local\", context.client)\n return {\n surface: caller.surface,\n transport: caller.transport,\n ...(caller.actor !== undefined ? { actor: caller.actor } : {}),\n ...(caller.client !== undefined ? { client: caller.client } : {}),\n principal: { id: context.principal.id, kind: context.principal.kind },\n }\n}\n\n/**\n * expose ๋กœ ์ˆจ๊ธด ๋ช…๋ น์–ด์˜ ํ˜ธ์ถœ ์‹œ๋„ 1๊ฑด (config.audit.includeHidden, spec ยง11.1). entry = ์ˆจ๊ธด ๋ช…๋ น์–ด (ํ˜ธ์ถœ์ž๊ฐ€ ํŒ์ •ํ•ด์„œ ๋„˜๊ธด๋‹ค).\n * ์ž…๋ ฅ ยท ์˜ค๋ฅ˜ ยท target ยท summary ์—†์Œ (๊ฒ€์ฆ ์ „ ์ž…๋ ฅ์—๋Š” ๊ฐ€๋ฆผ ๊ทœ์น™์„ ์ ์šฉํ•  ์ˆ˜ ์—†๋‹ค). readOnly ๋ช…๋ น์–ด๋„ ๊ธฐ๋กํ•œ๋‹ค.\n * sink ํ˜ธ์ถœ = ๋‹ค์Œ macrotask (์‘๋‹ต ์ฒ˜๋ฆฌ๊ฐ€ ๋จผ์ € ์ง„ํ–‰๋œ๋‹ค). ๋ฐ˜ํ™˜ = ์ „๋‹ฌ ์™„๋ฃŒ (๊ฑฐ๋ถ€ํ•˜์ง€ ์•Š๋Š”๋‹ค):\n * ์‘๋‹ต ์‹œ๊ฐ„์œผ๋กœ ์ˆจ๊ธด ๋ช…๋ น์–ด๊ฐ€ ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š๊ฒŒ MCP ์–ด๋Œ‘ํ„ฐ๋Š” ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ , ๋กœ์ปฌ CLI ๋Š” ์ข…๋ฃŒ ์ „์— await ํ•œ๋‹ค.\n * includeHidden ์ด ์•„๋‹ˆ๋ฉด undefined (์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค)\n */\nexport function auditHidden(entry: RegisteredCommand, context: AuditContext): Promise<void> | undefined {\n const config = context.audit\n if (config?.includeHidden !== true) return undefined\n const event: AuditEvent = {\n command: entry.id,\n readOnly: entry.command.readOnly,\n at: new Date().toISOString(),\n durationMs: 0,\n ...callerFields(context),\n outcome: \"hidden\",\n }\n const ids = traceparentIds(context.traceContext)\n if (ids?.traceId !== undefined) event.traceId = ids.traceId\n return new Promise<void>((resolve) => setTimeout(() => resolve(deliver(config, event)), 0))\n}\n\n/**\n * sink ์ „๋‹ฌ. sink ์˜ˆ์™ธ ์ •์ฑ… (spec ยง11.1 sink ์‹คํŒจ, ๊ฒฐ์ •): onerror ๋ณด๊ณ  ํ›„ ์‚ผํ‚จ๋‹ค = ์‘๋‹ต ๋ถˆ๋ณ€ (onCommandError ์™€ ๊ฐ™์€ ์›์น™).\n * ๊ฐ์‚ฌ๋Š” ์‹คํ–‰ ํ›„ ๊ธฐ๋ก์ด๋ผ ์—ฌ๊ธฐ์„œ ์‹คํŒจํ•ด๋„ ์‹คํ–‰์€ ์ด๋ฏธ ๋๋‚ฌ๋‹ค. ์ •์ฑ…์€ ์ด ํ•จ์ˆ˜ ํ•œ ๊ณณ์— ์žˆ๋‹ค\n */\nasync function deliver(config: AuditConfig, event: AuditEvent): Promise<void> {\n try {\n await config.sink(event)\n } catch (error) {\n report(config, error)\n }\n}\n\n/** ๋ช…๋ น์–ด audit ํ•จ์ˆ˜ (target ยท summary ยท input) ์‹คํ–‰. ์˜ˆ์™ธ = onerror, ๊ทธ ํ•„๋“œ ์—†์ด ๊ณ„์† */\nfunction guarded(config: AuditConfig, fn: () => void): void {\n try {\n fn()\n } catch (error) {\n report(config, error)\n }\n}\n\nfunction report(config: AuditConfig, error: unknown): void {\n try {\n ;(config.onerror ?? defaultOnError)(error)\n } catch {\n // ๋ณด๊ณ ๋Š” ์‘๋‹ต์„ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค\n }\n}\n\nfunction defaultOnError(error: unknown): void {\n const message = error instanceof Error ? (error.stack ?? error.message) : String(error)\n process.stderr.write(`mext: audit threw: ${message}\\n`)\n}\n\n/**\n * ์˜ˆ์™ธ โ†’ outcome ยท error. ๊ฑฐ๋ถ€ = PERMISSION_DENIED ยท INPUT_DECLINED ยท APPROVAL_REQUIRED. ๊ทธ ์™ธ = error:\n * ์ทจ์†Œ ํ›„ ์˜ˆ์™ธ = INTERRUPTED, MextError ยท CommandError = ๊ทธ code, ๋‚˜๋จธ์ง€ = EXECUTION_ERROR (์‘๋‹ต๊ณผ ๊ฐ™์€ code ยท message)\n */\nfunction failure(error: unknown, aborted: boolean): Pick<AuditEvent, \"outcome\" | \"error\"> {\n if (isMextError(error, \"PERMISSION_DENIED\") || isMextError(error, \"INPUT_DECLINED\") || isMextError(error, \"APPROVAL_REQUIRED\")) {\n return { outcome: \"denied\", error: { code: error.code, message: error.message } }\n }\n if (aborted) return { outcome: \"error\", error: { code: AUDIT_INTERRUPTED, message: \"Cancelled before completion.\" } }\n if (isDeclaredError(error)) return { outcome: \"error\", error: { code: error.code, message: error.message } }\n return { outcome: \"error\", error: { code: \"EXECUTION_ERROR\", message: error instanceof Error ? error.message : String(error) } }\n}\n\nfunction isTarget(value: unknown): value is AuditTarget {\n return typeof value === \"object\" && value !== null && typeof (value as { type?: unknown }).type === \"string\"\n}\n\n/** traceparent (\"00-<traceId 32 hex>-<parent 16 hex>-<flags>\") ์˜ traceId. ํ˜ธ์ถœ ์ชฝ span ์ด๋ผ spanId ๋Š” ์“ฐ์ง€ ์•Š๋Š”๋‹ค */\nfunction traceparentIds(carrier: Record<string, unknown> | undefined): TraceIds | undefined {\n const value = carrier?.traceparent\n const match = typeof value === \"string\" ? /^[0-9a-f]{2}-([0-9a-f]{32})-[0-9a-f]{16}-[0-9a-f]{2}/.exec(value) : null\n return match && !/^0+$/.test(match[1]!) ? { traceId: match[1]! } : undefined\n}\n\n/** defineCommand ์˜ audit ํ˜•์‹ ๋ฌธ์ œ. ์—†์œผ๋ฉด undefined */\nexport function commandAuditProblem(value: unknown): string | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return \"audit must be an object ({ target, summary, input })\"\n const a = value as Record<string, unknown>\n const unknown = Object.keys(a).filter((k) => k !== \"target\" && k !== \"summary\" && k !== \"input\")\n if (unknown.length > 0) return `unknown audit key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`\n if (a.target !== undefined && typeof a.target !== \"function\") return \"audit.target must be a function\"\n if (a.summary !== undefined && typeof a.summary !== \"string\" && typeof a.summary !== \"function\") {\n return \"audit.summary must be a string or a function\"\n }\n if (a.input !== undefined && typeof a.input !== \"boolean\" && typeof a.input !== \"function\") {\n return \"audit.input must be false or a function\"\n }\n return undefined\n}\n\n/** mext.config.ts ์˜ audit ํ˜•์‹ ๋ฌธ์ œ. ์—†์œผ๋ฉด undefined */\nexport function auditConfigProblem(value: unknown): string | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return \"audit must be an object ({ sink })\"\n const a = value as Record<string, unknown>\n const unknown = Object.keys(a).filter((k) => ![\"sink\", \"includeReadOnly\", \"includeHidden\", \"input\", \"onerror\"].includes(k))\n if (unknown.length > 0) return `unknown audit key${unknown.length === 1 ? \"\" : \"s\"}: ${unknown.join(\", \")}`\n if (typeof a.sink !== \"function\") return \"audit.sink must be a function\"\n if (a.includeReadOnly !== undefined && typeof a.includeReadOnly !== \"boolean\") return \"audit.includeReadOnly must be a boolean\"\n if (a.includeHidden !== undefined && typeof a.includeHidden !== \"boolean\") return \"audit.includeHidden must be a boolean\"\n if (a.input !== undefined && typeof a.input !== \"boolean\") return \"audit.input must be a boolean\"\n if (a.onerror !== undefined && typeof a.onerror !== \"function\") return \"audit.onerror must be a function\"\n return undefined\n}\n"]}
@@ -34,6 +34,7 @@ export interface BuildCustomerCliOptions {
34
34
  /** .mext/ ์ ˆ๋Œ€ ๊ฒฝ๋กœ */
35
35
  outDir: string;
36
36
  cli: CliConfig;
37
+ /** ๊ณ ๊ฐ CLI ์— ๋‚ด์žฅํ•  manifest ยท manifestHash. expose ์‚ฌ์šฉ ์‹œ = mcp ํ‘œ๋ฉด์—์„œ ๋ณด์ด๋Š” ๋ช…๋ น์–ด ๊ธฐ์ค€ (ยง4) */
37
38
  manifest: BuildManifest;
38
39
  }
39
40
  export declare function buildCustomerCli(options: BuildCustomerCliOptions): Promise<CustomerCliBuild>;
package/dist/build-cli.js CHANGED
@@ -5,6 +5,7 @@ import { fileURLToPath } from "node:url";
5
5
  import { clientManifest } from "./client/manifest.js";
6
6
  import { CLI_BUILTIN_COMMANDS, LOCAL_BIN_BUILTIN_COMMANDS } from "./config.js";
7
7
  import { MextBuildError } from "./errors.js";
8
+ import { BUN_ENGINE } from "./runtime.js";
8
9
  import { envPrefix } from "./remote/credentials.js";
9
10
  /**
10
11
  * ๊ณ ๊ฐ CLI ํŒจํ‚ค์ง€ (.mext/cli/, ยง5). mext build ๊ฐ€ config.cli ๊ฐ€ ์žˆ์„ ๋•Œ ํ˜ธ์ถœ.
@@ -117,7 +118,7 @@ export async function buildCustomerCli(options) {
117
118
  type: "module",
118
119
  bin: { [cli.bin]: `./${CLI_BIN_FILE}` },
119
120
  files: [CLI_BIN_FILE],
120
- engines: { node: CLI_NODE_ENGINE },
121
+ engines: { node: CLI_NODE_ENGINE, bun: BUN_ENGINE },
121
122
  };
122
123
  writeFileSync(join(dir, "package.json"), `${JSON.stringify(pkg, null, 2)}\n`);
123
124
  writeFileSync(join(dir, "README.md"), readme(cli.bin, url, packageName));
@@ -1 +1 @@
1
- {"version":3,"file":"build-cli.js","sourceRoot":"","sources":["../src/build-cli.ts"],"names":[],"mappings":"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","sourcesContent":["import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\"\nimport { isBuiltin } from \"node:module\"\nimport { join, resolve } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport type { RolldownModule, RolldownOutputItem } from \"./build.ts\"\nimport { clientManifest } from \"./client/manifest.ts\"\nimport type { CustomerCliConfig } from \"./client/main.ts\"\nimport { CLI_BUILTIN_COMMANDS, LOCAL_BIN_BUILTIN_COMMANDS, type CliConfig } from \"./config.ts\"\nimport { MextBuildError, type BuildIssue } from \"./errors.ts\"\nimport type { BuildManifest } from \"./manifest.ts\"\nimport type { Registry } from \"./registry.ts\"\nimport { envPrefix } from \"./remote/credentials.ts\"\n\n/**\n * ๊ณ ๊ฐ CLI ํŒจํ‚ค์ง€ (.mext/cli/, ยง5). mext build ๊ฐ€ config.cli ๊ฐ€ ์žˆ์„ ๋•Œ ํ˜ธ์ถœ.\n * bin.js = client/main.ts (๊ณ ๊ฐ CLI ๋Ÿฐํƒ€์ž„) + ์ธ๋ผ์ธ ์„ค์ • (CustomerCliConfig) ์˜ rolldown ๋‹จ์ผ ๋ฒˆ๋“ค. ์™ธ๋ถ€ = Node ๋‚ด์žฅ๋งŒ\n * (์˜์กด์„ฑ ์ „๋ถ€ ๋ฒˆ๋“ค โ†’ package.json dependencies ์—†์Œ). ๋Ÿฐํƒ€์ž„์€ Zod ยท MCP ์„œ๋ฒ„ SDK ยท ํ•ธ๋“ค๋Ÿฌ ยท ์Šค์บ” ยท ๋นŒ๋“œ ์ฝ”๋“œ๋ฅผ import ํ•˜์ง€ ์•Š๋Š”๋‹ค\n */\n\n/** .mext/ ์•„๋ž˜ ๊ณ ๊ฐ CLI ํด๋” */\nexport const CLI_DIR = \"cli\"\nexport const CLI_BIN_FILE = \"bin.js\"\n/** ๊ณ ๊ฐ CLI package.json engines.node (๋ฒˆ๋“ค target node22, ํƒ€์ž… ์ œ๊ฑฐ ๋ถˆํ•„์š”) */\nexport const CLI_NODE_ENGINE = \">=22\"\n\n/** ๊ณ ๊ฐ CLI ๋Ÿฐํƒ€์ž„ ์—”ํŠธ๋ฆฌ (src = .ts, dist = .js: ์ด ํŒŒ์ผ๊ณผ ๊ฐ™์€ ํ™•์žฅ์ž) */\nconst RUNTIME_ENTRY = fileURLToPath(new URL(`./client/main${import.meta.url.slice(import.meta.url.lastIndexOf(\".\"))}`, import.meta.url))\nconst ENTRY_ID = \"\\0mext-customer-cli\"\n\nexport interface CustomerCliBuild {\n /** ์ ˆ๋Œ€ ๊ฒฝ๋กœ (.mext/cli) */\n dir: string\n bin: string\n packageName: string\n version: string\n form: \"bundled\" | \"universal\"\n /** .mext/cli ๊ธฐ์ค€ ์ƒ์„ฑ ํŒŒ์ผ (์ •๋ ฌ) */\n files: string[]\n /** bin.js ๋ฐ”์ดํŠธ */\n size: number\n}\n\n/** cli ์„ค์ •์ด ์žˆ์„ ๋•Œ ๋ฃจํŠธ ์„ธ๊ทธ๋จผํŠธ๊ฐ€ ๊ณ ๊ฐ CLI ๋‚ด์žฅ ๋ช…๋ น (login ยท logout ยท mcp, ๋กœ์ปฌ bin = help ยท mcp) ๊ณผ ๊ฒน์น˜๋ฉด RESERVED_ID */\nexport function customerCliIssues(cli: CliConfig | undefined, registry: Registry): BuildIssue[] {\n if (!cli) return []\n const builtins = cli.local === true ? LOCAL_BIN_BUILTIN_COMMANDS : CLI_BUILTIN_COMMANDS\n // ๋ฃจํŠธ ๋ณ„์นญ์€ Registry ๊ฐ€ ๊ธˆ์ง€ํ•˜๋ฏ€๋กœ ๋ฃจํŠธ ๋ช…๋ น์–ด ยท ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋งŒ ๋ณธ๋‹ค\n const root = registry.namespaces.get(\"\")\n const ids = new Set([...(root?.commands ?? []), ...(root?.namespaces ?? [])])\n return [...ids]\n .filter((id) => builtins.includes(id))\n .sort()\n .map((id) => {\n const file = registry.commands.get(id)?.file\n return {\n code: \"RESERVED_ID\",\n message: `\"${id}\" is a built-in command of the customer CLI (${cli.bin} ${id}). Rename it or remove cli from mext.config.ts`,\n id,\n ...(file !== undefined ? { file } : {}),\n }\n })\n}\n\nexport interface BuildCustomerCliOptions {\n rolldown: RolldownModule\n /** ๋„์ž… ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ (package.json version) */\n cwd: string\n /** .mext/ ์ ˆ๋Œ€ ๊ฒฝ๋กœ */\n outDir: string\n cli: CliConfig\n manifest: BuildManifest\n}\n\nexport async function buildCustomerCli(options: BuildCustomerCliOptions): Promise<CustomerCliBuild> {\n const { cli, manifest } = options\n if (cli.url === undefined) throw new Error(\"mext build: customer CLI requires cli.url\")\n const url = cli.url\n const dir = join(options.outDir, CLI_DIR)\n mkdirSync(dir, { recursive: true })\n const version = cli.version ?? projectVersion(options.cwd) ?? \"0.0.0\"\n const packageName = cli.packageName ?? cli.bin\n const bundled = cli.manifest !== false\n const config: CustomerCliConfig = {\n bin: cli.bin,\n url,\n version,\n packageName,\n mextVersion: manifest.mextVersion,\n manifestHash: manifest.manifestHash,\n ...(bundled ? { manifest: clientManifest(manifest) } : {}),\n }\n const errorsFile = cli.errors === undefined ? undefined : resolve(options.cwd, cli.errors)\n if (errorsFile !== undefined && !existsSync(errorsFile)) {\n throw new MextBuildError([{ code: \"INVALID_CONFIG\", message: `cli.errors file not found: ${cli.errors}` }])\n }\n const entry = [\n `import { main } from ${JSON.stringify(RUNTIME_ENTRY)}`,\n ...(errorsFile !== undefined ? [`import formatError from ${JSON.stringify(errorsFile)}`] : []),\n \"\",\n errorsFile !== undefined\n ? `await main(${JSON.stringify(config)}, { formatError })`\n : `await main(${JSON.stringify(config)})`,\n \"\",\n ].join(\"\\n\")\n\n let output: readonly RolldownOutputItem[]\n try {\n ;({ output } = await options.rolldown.build({\n cwd: options.cwd,\n input: { bin: ENTRY_ID },\n platform: \"node\",\n external: (id: string): boolean => id.startsWith(\"node:\") || isBuiltin(id),\n plugins: [\n {\n name: \"mext-customer-cli\",\n resolveId: (id: string) => (id === ENTRY_ID ? ENTRY_ID : null),\n load: (id: string) => (id === ENTRY_ID ? entry : null),\n },\n ],\n transform: { target: \"node22\" },\n logLevel: \"warn\",\n output: {\n dir,\n format: \"esm\",\n entryFileNames: CLI_BIN_FILE,\n banner: \"#!/usr/bin/env node\",\n codeSplitting: false,\n sourcemap: false,\n },\n }))\n } catch (error) {\n throw new MextBuildError([\n { code: \"BUNDLE_FAILED\", message: `customer CLI: ${error instanceof Error ? error.message : String(error)}` },\n ])\n }\n const emitted = output.map((o) => o.fileName)\n if (emitted.length !== 1 || emitted[0] !== CLI_BIN_FILE) {\n throw new Error(`mext build: customer CLI bundle must be a single ${CLI_BIN_FILE} (got ${emitted.join(\", \")})`)\n }\n const binPath = join(dir, CLI_BIN_FILE)\n chmodSync(binPath, 0o755)\n\n const pkg = {\n name: packageName,\n version,\n description: `Command-line client for ${url}`,\n type: \"module\",\n bin: { [cli.bin]: `./${CLI_BIN_FILE}` },\n files: [CLI_BIN_FILE],\n engines: { node: CLI_NODE_ENGINE },\n }\n writeFileSync(join(dir, \"package.json\"), `${JSON.stringify(pkg, null, 2)}\\n`)\n writeFileSync(join(dir, \"README.md\"), readme(cli.bin, url, packageName))\n\n return {\n dir,\n bin: cli.bin,\n packageName,\n version,\n form: bundled ? \"bundled\" : \"universal\",\n files: [CLI_BIN_FILE, \"README.md\", \"package.json\"],\n size: statSync(binPath).size,\n }\n}\n\nexport function projectVersion(cwd: string): string | undefined {\n try {\n const pkg = JSON.parse(readFileSync(join(cwd, \"package.json\"), \"utf8\")) as { version?: unknown }\n return typeof pkg.version === \"string\" && pkg.version !== \"\" ? pkg.version : undefined\n } catch {\n return undefined\n }\n}\n\nfunction readme(bin: string, url: string, packageName: string): string {\n const prefix = envPrefix(bin)\n return [\n `# ${packageName}`,\n \"\",\n `Command-line client for ${url}. Generated by mext build.`,\n \"\",\n \"```sh\",\n `npm install -g ${packageName}`,\n `${bin} login # log in (browser, device code, or --with-token)`,\n `${bin} help # commands`,\n `${bin} <namespace> <command> --help`,\n `${bin} mcp install # MCP client registration commands`,\n `${bin} logout`,\n \"```\",\n \"\",\n \"Environment:\",\n \"\",\n `- \\`${prefix}_TOKEN\\`: API token (used instead of the stored login)`,\n `- \\`${prefix}_URL\\`: server URL (default: ${url})`,\n `- \\`${prefix}_NO_KEYRING=1\\`: store the token in \\`~/.config/${bin}/credentials.json\\` instead of the OS keychain`,\n `- \\`${prefix}_CACHE_DIR\\`: server schema cache folder (default: \\`\\${XDG_CACHE_HOME:-~/.cache}/${bin}\\`)`,\n \"\",\n \"Exit codes: 0 success ยท 1 error ยท 2 invalid arguments or unknown command ยท 77 authentication or permission ยท 130 interrupted.\",\n \"\",\n ].join(\"\\n\")\n}\n"]}
1
+ {"version":3,"file":"build-cli.js","sourceRoot":"","sources":["../src/build-cli.ts"],"names":[],"mappings":"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","sourcesContent":["import { chmodSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\"\nimport { isBuiltin } from \"node:module\"\nimport { join, resolve } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport type { RolldownModule, RolldownOutputItem } from \"./build.ts\"\nimport { clientManifest } from \"./client/manifest.ts\"\nimport type { CustomerCliConfig } from \"./client/main.ts\"\nimport { CLI_BUILTIN_COMMANDS, LOCAL_BIN_BUILTIN_COMMANDS, type CliConfig } from \"./config.ts\"\nimport { MextBuildError, type BuildIssue } from \"./errors.ts\"\nimport type { BuildManifest } from \"./manifest.ts\"\nimport type { Registry } from \"./registry.ts\"\nimport { BUN_ENGINE } from \"./runtime.ts\"\nimport { envPrefix } from \"./remote/credentials.ts\"\n\n/**\n * ๊ณ ๊ฐ CLI ํŒจํ‚ค์ง€ (.mext/cli/, ยง5). mext build ๊ฐ€ config.cli ๊ฐ€ ์žˆ์„ ๋•Œ ํ˜ธ์ถœ.\n * bin.js = client/main.ts (๊ณ ๊ฐ CLI ๋Ÿฐํƒ€์ž„) + ์ธ๋ผ์ธ ์„ค์ • (CustomerCliConfig) ์˜ rolldown ๋‹จ์ผ ๋ฒˆ๋“ค. ์™ธ๋ถ€ = Node ๋‚ด์žฅ๋งŒ\n * (์˜์กด์„ฑ ์ „๋ถ€ ๋ฒˆ๋“ค โ†’ package.json dependencies ์—†์Œ). ๋Ÿฐํƒ€์ž„์€ Zod ยท MCP ์„œ๋ฒ„ SDK ยท ํ•ธ๋“ค๋Ÿฌ ยท ์Šค์บ” ยท ๋นŒ๋“œ ์ฝ”๋“œ๋ฅผ import ํ•˜์ง€ ์•Š๋Š”๋‹ค\n */\n\n/** .mext/ ์•„๋ž˜ ๊ณ ๊ฐ CLI ํด๋” */\nexport const CLI_DIR = \"cli\"\nexport const CLI_BIN_FILE = \"bin.js\"\n/** ๊ณ ๊ฐ CLI package.json engines.node (๋ฒˆ๋“ค target node22, ํƒ€์ž… ์ œ๊ฑฐ ๋ถˆํ•„์š”) */\nexport const CLI_NODE_ENGINE = \">=22\"\n\n/** ๊ณ ๊ฐ CLI ๋Ÿฐํƒ€์ž„ ์—”ํŠธ๋ฆฌ (src = .ts, dist = .js: ์ด ํŒŒ์ผ๊ณผ ๊ฐ™์€ ํ™•์žฅ์ž) */\nconst RUNTIME_ENTRY = fileURLToPath(new URL(`./client/main${import.meta.url.slice(import.meta.url.lastIndexOf(\".\"))}`, import.meta.url))\nconst ENTRY_ID = \"\\0mext-customer-cli\"\n\nexport interface CustomerCliBuild {\n /** ์ ˆ๋Œ€ ๊ฒฝ๋กœ (.mext/cli) */\n dir: string\n bin: string\n packageName: string\n version: string\n form: \"bundled\" | \"universal\"\n /** .mext/cli ๊ธฐ์ค€ ์ƒ์„ฑ ํŒŒ์ผ (์ •๋ ฌ) */\n files: string[]\n /** bin.js ๋ฐ”์ดํŠธ */\n size: number\n}\n\n/** cli ์„ค์ •์ด ์žˆ์„ ๋•Œ ๋ฃจํŠธ ์„ธ๊ทธ๋จผํŠธ๊ฐ€ ๊ณ ๊ฐ CLI ๋‚ด์žฅ ๋ช…๋ น (login ยท logout ยท mcp, ๋กœ์ปฌ bin = help ยท mcp) ๊ณผ ๊ฒน์น˜๋ฉด RESERVED_ID */\nexport function customerCliIssues(cli: CliConfig | undefined, registry: Registry): BuildIssue[] {\n if (!cli) return []\n const builtins = cli.local === true ? LOCAL_BIN_BUILTIN_COMMANDS : CLI_BUILTIN_COMMANDS\n // ๋ฃจํŠธ ๋ณ„์นญ์€ Registry ๊ฐ€ ๊ธˆ์ง€ํ•˜๋ฏ€๋กœ ๋ฃจํŠธ ๋ช…๋ น์–ด ยท ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋งŒ ๋ณธ๋‹ค\n const root = registry.namespaces.get(\"\")\n const ids = new Set([...(root?.commands ?? []), ...(root?.namespaces ?? [])])\n return [...ids]\n .filter((id) => builtins.includes(id))\n .sort()\n .map((id) => {\n const file = registry.commands.get(id)?.file\n return {\n code: \"RESERVED_ID\",\n message: `\"${id}\" is a built-in command of the customer CLI (${cli.bin} ${id}). Rename it or remove cli from mext.config.ts`,\n id,\n ...(file !== undefined ? { file } : {}),\n }\n })\n}\n\nexport interface BuildCustomerCliOptions {\n rolldown: RolldownModule\n /** ๋„์ž… ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ (package.json version) */\n cwd: string\n /** .mext/ ์ ˆ๋Œ€ ๊ฒฝ๋กœ */\n outDir: string\n cli: CliConfig\n /** ๊ณ ๊ฐ CLI ์— ๋‚ด์žฅํ•  manifest ยท manifestHash. expose ์‚ฌ์šฉ ์‹œ = mcp ํ‘œ๋ฉด์—์„œ ๋ณด์ด๋Š” ๋ช…๋ น์–ด ๊ธฐ์ค€ (ยง4) */\n manifest: BuildManifest\n}\n\nexport async function buildCustomerCli(options: BuildCustomerCliOptions): Promise<CustomerCliBuild> {\n const { cli, manifest } = options\n if (cli.url === undefined) throw new Error(\"mext build: customer CLI requires cli.url\")\n const url = cli.url\n const dir = join(options.outDir, CLI_DIR)\n mkdirSync(dir, { recursive: true })\n const version = cli.version ?? projectVersion(options.cwd) ?? \"0.0.0\"\n const packageName = cli.packageName ?? cli.bin\n const bundled = cli.manifest !== false\n const config: CustomerCliConfig = {\n bin: cli.bin,\n url,\n version,\n packageName,\n mextVersion: manifest.mextVersion,\n manifestHash: manifest.manifestHash,\n ...(bundled ? { manifest: clientManifest(manifest) } : {}),\n }\n const errorsFile = cli.errors === undefined ? undefined : resolve(options.cwd, cli.errors)\n if (errorsFile !== undefined && !existsSync(errorsFile)) {\n throw new MextBuildError([{ code: \"INVALID_CONFIG\", message: `cli.errors file not found: ${cli.errors}` }])\n }\n const entry = [\n `import { main } from ${JSON.stringify(RUNTIME_ENTRY)}`,\n ...(errorsFile !== undefined ? [`import formatError from ${JSON.stringify(errorsFile)}`] : []),\n \"\",\n errorsFile !== undefined\n ? `await main(${JSON.stringify(config)}, { formatError })`\n : `await main(${JSON.stringify(config)})`,\n \"\",\n ].join(\"\\n\")\n\n let output: readonly RolldownOutputItem[]\n try {\n ;({ output } = await options.rolldown.build({\n cwd: options.cwd,\n input: { bin: ENTRY_ID },\n platform: \"node\",\n external: (id: string): boolean => id.startsWith(\"node:\") || isBuiltin(id),\n plugins: [\n {\n name: \"mext-customer-cli\",\n resolveId: (id: string) => (id === ENTRY_ID ? ENTRY_ID : null),\n load: (id: string) => (id === ENTRY_ID ? entry : null),\n },\n ],\n transform: { target: \"node22\" },\n logLevel: \"warn\",\n output: {\n dir,\n format: \"esm\",\n entryFileNames: CLI_BIN_FILE,\n banner: \"#!/usr/bin/env node\",\n codeSplitting: false,\n sourcemap: false,\n },\n }))\n } catch (error) {\n throw new MextBuildError([\n { code: \"BUNDLE_FAILED\", message: `customer CLI: ${error instanceof Error ? error.message : String(error)}` },\n ])\n }\n const emitted = output.map((o) => o.fileName)\n if (emitted.length !== 1 || emitted[0] !== CLI_BIN_FILE) {\n throw new Error(`mext build: customer CLI bundle must be a single ${CLI_BIN_FILE} (got ${emitted.join(\", \")})`)\n }\n const binPath = join(dir, CLI_BIN_FILE)\n chmodSync(binPath, 0o755)\n\n const pkg = {\n name: packageName,\n version,\n description: `Command-line client for ${url}`,\n type: \"module\",\n bin: { [cli.bin]: `./${CLI_BIN_FILE}` },\n files: [CLI_BIN_FILE],\n engines: { node: CLI_NODE_ENGINE, bun: BUN_ENGINE },\n }\n writeFileSync(join(dir, \"package.json\"), `${JSON.stringify(pkg, null, 2)}\\n`)\n writeFileSync(join(dir, \"README.md\"), readme(cli.bin, url, packageName))\n\n return {\n dir,\n bin: cli.bin,\n packageName,\n version,\n form: bundled ? \"bundled\" : \"universal\",\n files: [CLI_BIN_FILE, \"README.md\", \"package.json\"],\n size: statSync(binPath).size,\n }\n}\n\nexport function projectVersion(cwd: string): string | undefined {\n try {\n const pkg = JSON.parse(readFileSync(join(cwd, \"package.json\"), \"utf8\")) as { version?: unknown }\n return typeof pkg.version === \"string\" && pkg.version !== \"\" ? pkg.version : undefined\n } catch {\n return undefined\n }\n}\n\nfunction readme(bin: string, url: string, packageName: string): string {\n const prefix = envPrefix(bin)\n return [\n `# ${packageName}`,\n \"\",\n `Command-line client for ${url}. Generated by mext build.`,\n \"\",\n \"```sh\",\n `npm install -g ${packageName}`,\n `${bin} login # log in (browser, device code, or --with-token)`,\n `${bin} help # commands`,\n `${bin} <namespace> <command> --help`,\n `${bin} mcp install # MCP client registration commands`,\n `${bin} logout`,\n \"```\",\n \"\",\n \"Environment:\",\n \"\",\n `- \\`${prefix}_TOKEN\\`: API token (used instead of the stored login)`,\n `- \\`${prefix}_URL\\`: server URL (default: ${url})`,\n `- \\`${prefix}_NO_KEYRING=1\\`: store the token in \\`~/.config/${bin}/credentials.json\\` instead of the OS keychain`,\n `- \\`${prefix}_CACHE_DIR\\`: server schema cache folder (default: \\`\\${XDG_CACHE_HOME:-~/.cache}/${bin}\\`)`,\n \"\",\n \"Exit codes: 0 success ยท 1 error ยท 2 invalid arguments or unknown command ยท 77 authentication or permission ยท 130 interrupted.\",\n \"\",\n ].join(\"\\n\")\n}\n"]}
package/dist/build.d.ts CHANGED
@@ -53,6 +53,8 @@ export interface BuildResult {
53
53
  bin: string;
54
54
  version: string;
55
55
  };
56
+ /** ๋ช…๋ น์–ด ํƒ€์ž… ์ƒ์„ฑ ํŒŒ์ผ (config.types ๊ฐ€ ์žˆ์„ ๋•Œ, specs/client.md ยง4). ์ ˆ๋Œ€ ๊ฒฝ๋กœ */
57
+ types?: string;
56
58
  }
57
59
  /** rolldown ์„ ์ฐพ์„ ์ˆ˜ ์—†์Œ. message ์— ์„ค์น˜ ๋ช…๋ น */
58
60
  export declare class RolldownUnavailableError extends Error {