@ambitresearch/genie 1.3.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.
Files changed (301) hide show
  1. package/README.md +15 -0
  2. package/dist/auth/bearer.d.ts +49 -0
  3. package/dist/auth/bearer.d.ts.map +1 -0
  4. package/dist/auth/bearer.js +159 -0
  5. package/dist/auth/bearer.js.map +1 -0
  6. package/dist/auth/oauth/authorize.d.ts +19 -0
  7. package/dist/auth/oauth/authorize.d.ts.map +1 -0
  8. package/dist/auth/oauth/authorize.js +111 -0
  9. package/dist/auth/oauth/authorize.js.map +1 -0
  10. package/dist/auth/oauth/config.d.ts +10 -0
  11. package/dist/auth/oauth/config.d.ts.map +1 -0
  12. package/dist/auth/oauth/config.js +16 -0
  13. package/dist/auth/oauth/config.js.map +1 -0
  14. package/dist/auth/oauth/dcr.d.ts +15 -0
  15. package/dist/auth/oauth/dcr.d.ts.map +1 -0
  16. package/dist/auth/oauth/dcr.js +38 -0
  17. package/dist/auth/oauth/dcr.js.map +1 -0
  18. package/dist/auth/oauth/jwt.d.ts +13 -0
  19. package/dist/auth/oauth/jwt.d.ts.map +1 -0
  20. package/dist/auth/oauth/jwt.js +46 -0
  21. package/dist/auth/oauth/jwt.js.map +1 -0
  22. package/dist/auth/oauth/metadata.d.ts +9 -0
  23. package/dist/auth/oauth/metadata.d.ts.map +1 -0
  24. package/dist/auth/oauth/metadata.js +19 -0
  25. package/dist/auth/oauth/metadata.js.map +1 -0
  26. package/dist/auth/oauth/router.d.ts +32 -0
  27. package/dist/auth/oauth/router.d.ts.map +1 -0
  28. package/dist/auth/oauth/router.js +159 -0
  29. package/dist/auth/oauth/router.js.map +1 -0
  30. package/dist/auth/oauth/store.d.ts +55 -0
  31. package/dist/auth/oauth/store.d.ts.map +1 -0
  32. package/dist/auth/oauth/store.js +63 -0
  33. package/dist/auth/oauth/store.js.map +1 -0
  34. package/dist/auth/oauth/token.d.ts +21 -0
  35. package/dist/auth/oauth/token.d.ts.map +1 -0
  36. package/dist/auth/oauth/token.js +77 -0
  37. package/dist/auth/oauth/token.js.map +1 -0
  38. package/dist/auth/oidc/group-policy.d.ts +43 -0
  39. package/dist/auth/oidc/group-policy.d.ts.map +1 -0
  40. package/dist/auth/oidc/group-policy.js +54 -0
  41. package/dist/auth/oidc/group-policy.js.map +1 -0
  42. package/dist/auth/oidc/verifier.d.ts +42 -0
  43. package/dist/auth/oidc/verifier.d.ts.map +1 -0
  44. package/dist/auth/oidc/verifier.js +145 -0
  45. package/dist/auth/oidc/verifier.js.map +1 -0
  46. package/dist/auth/token-cli.d.ts +9 -0
  47. package/dist/auth/token-cli.d.ts.map +1 -0
  48. package/dist/auth/token-cli.js +98 -0
  49. package/dist/auth/token-cli.js.map +1 -0
  50. package/dist/cli.d.ts +3 -0
  51. package/dist/cli.d.ts.map +1 -0
  52. package/dist/cli.js +149 -0
  53. package/dist/cli.js.map +1 -0
  54. package/dist/config/redact.d.ts +20 -0
  55. package/dist/config/redact.d.ts.map +1 -0
  56. package/dist/config/redact.js +77 -0
  57. package/dist/config/redact.js.map +1 -0
  58. package/dist/config/secrets.d.ts +100 -0
  59. package/dist/config/secrets.d.ts.map +1 -0
  60. package/dist/config/secrets.js +130 -0
  61. package/dist/config/secrets.js.map +1 -0
  62. package/dist/framework/html.d.ts +103 -0
  63. package/dist/framework/html.d.ts.map +1 -0
  64. package/dist/framework/html.js +271 -0
  65. package/dist/framework/html.js.map +1 -0
  66. package/dist/framework/interface.d.ts +130 -0
  67. package/dist/framework/interface.d.ts.map +1 -0
  68. package/dist/framework/interface.js +112 -0
  69. package/dist/framework/interface.js.map +1 -0
  70. package/dist/framework/react.d.ts +133 -0
  71. package/dist/framework/react.d.ts.map +1 -0
  72. package/dist/framework/react.js +243 -0
  73. package/dist/framework/react.js.map +1 -0
  74. package/dist/framework/vue.d.ts +99 -0
  75. package/dist/framework/vue.d.ts.map +1 -0
  76. package/dist/framework/vue.js +375 -0
  77. package/dist/framework/vue.js.map +1 -0
  78. package/dist/index.d.ts +3 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +3 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/llm/client.d.ts +81 -0
  83. package/dist/llm/client.d.ts.map +1 -0
  84. package/dist/llm/client.js +141 -0
  85. package/dist/llm/client.js.map +1 -0
  86. package/dist/llm/component-response.d.ts +111 -0
  87. package/dist/llm/component-response.d.ts.map +1 -0
  88. package/dist/llm/component-response.js +167 -0
  89. package/dist/llm/component-response.js.map +1 -0
  90. package/dist/llm/generated-files.d.ts +10 -0
  91. package/dist/llm/generated-files.d.ts.map +1 -0
  92. package/dist/llm/generated-files.js +26 -0
  93. package/dist/llm/generated-files.js.map +1 -0
  94. package/dist/llm/prompts/CHANGELOG.md +70 -0
  95. package/dist/llm/prompts/generate-component.system.md +99 -0
  96. package/dist/llm/prompts/refine-component.system.md +112 -0
  97. package/dist/llm/prompts.d.ts +66 -0
  98. package/dist/llm/prompts.d.ts.map +1 -0
  99. package/dist/llm/prompts.js +78 -0
  100. package/dist/llm/prompts.js.map +1 -0
  101. package/dist/llm/retry.d.ts +183 -0
  102. package/dist/llm/retry.d.ts.map +1 -0
  103. package/dist/llm/retry.js +475 -0
  104. package/dist/llm/retry.js.map +1 -0
  105. package/dist/llm/schema.d.ts +129 -0
  106. package/dist/llm/schema.d.ts.map +1 -0
  107. package/dist/llm/schema.js +147 -0
  108. package/dist/llm/schema.js.map +1 -0
  109. package/dist/llm/validate.d.ts +107 -0
  110. package/dist/llm/validate.d.ts.map +1 -0
  111. package/dist/llm/validate.js +174 -0
  112. package/dist/llm/validate.js.map +1 -0
  113. package/dist/manifest/compiler.d.ts +112 -0
  114. package/dist/manifest/compiler.d.ts.map +1 -0
  115. package/dist/manifest/compiler.js +306 -0
  116. package/dist/manifest/compiler.js.map +1 -0
  117. package/dist/manifest/ensure.d.ts +46 -0
  118. package/dist/manifest/ensure.d.ts.map +1 -0
  119. package/dist/manifest/ensure.js +49 -0
  120. package/dist/manifest/ensure.js.map +1 -0
  121. package/dist/manifest/index.d.ts +13 -0
  122. package/dist/manifest/index.d.ts.map +1 -0
  123. package/dist/manifest/index.js +13 -0
  124. package/dist/manifest/index.js.map +1 -0
  125. package/dist/middleware/plan-guard.d.ts +167 -0
  126. package/dist/middleware/plan-guard.d.ts.map +1 -0
  127. package/dist/middleware/plan-guard.js +190 -0
  128. package/dist/middleware/plan-guard.js.map +1 -0
  129. package/dist/plans/index.d.ts +71 -0
  130. package/dist/plans/index.d.ts.map +1 -0
  131. package/dist/plans/index.js +252 -0
  132. package/dist/plans/index.js.map +1 -0
  133. package/dist/schemas/component.schema.json +114 -0
  134. package/dist/server.d.ts +96 -0
  135. package/dist/server.d.ts.map +1 -0
  136. package/dist/server.js +258 -0
  137. package/dist/server.js.map +1 -0
  138. package/dist/store/empty-manifest.d.ts +58 -0
  139. package/dist/store/empty-manifest.d.ts.map +1 -0
  140. package/dist/store/empty-manifest.js +59 -0
  141. package/dist/store/empty-manifest.js.map +1 -0
  142. package/dist/store/git-host.d.ts +120 -0
  143. package/dist/store/git-host.d.ts.map +1 -0
  144. package/dist/store/git-host.js +796 -0
  145. package/dist/store/git-host.js.map +1 -0
  146. package/dist/store/index.d.ts +5 -0
  147. package/dist/store/index.d.ts.map +1 -0
  148. package/dist/store/index.js +4 -0
  149. package/dist/store/index.js.map +1 -0
  150. package/dist/store/interface.d.ts +322 -0
  151. package/dist/store/interface.d.ts.map +1 -0
  152. package/dist/store/interface.js +100 -0
  153. package/dist/store/interface.js.map +1 -0
  154. package/dist/store/kit-files.d.ts +88 -0
  155. package/dist/store/kit-files.d.ts.map +1 -0
  156. package/dist/store/kit-files.js +199 -0
  157. package/dist/store/kit-files.js.map +1 -0
  158. package/dist/store/local.d.ts +70 -0
  159. package/dist/store/local.d.ts.map +1 -0
  160. package/dist/store/local.js +651 -0
  161. package/dist/store/local.js.map +1 -0
  162. package/dist/store/manifest.d.ts +44 -0
  163. package/dist/store/manifest.d.ts.map +1 -0
  164. package/dist/store/manifest.js +116 -0
  165. package/dist/store/manifest.js.map +1 -0
  166. package/dist/store/viewer-assets.d.ts +20 -0
  167. package/dist/store/viewer-assets.d.ts.map +1 -0
  168. package/dist/store/viewer-assets.js +118 -0
  169. package/dist/store/viewer-assets.js.map +1 -0
  170. package/dist/sync/anchor.d.ts +125 -0
  171. package/dist/sync/anchor.d.ts.map +1 -0
  172. package/dist/sync/anchor.js +210 -0
  173. package/dist/sync/anchor.js.map +1 -0
  174. package/dist/sync/index.d.ts +15 -0
  175. package/dist/sync/index.d.ts.map +1 -0
  176. package/dist/sync/index.js +15 -0
  177. package/dist/sync/index.js.map +1 -0
  178. package/dist/sync/orchestrator.d.ts +160 -0
  179. package/dist/sync/orchestrator.d.ts.map +1 -0
  180. package/dist/sync/orchestrator.js +288 -0
  181. package/dist/sync/orchestrator.js.map +1 -0
  182. package/dist/tools/bind_kit.d.ts +29 -0
  183. package/dist/tools/bind_kit.d.ts.map +1 -0
  184. package/dist/tools/bind_kit.js +70 -0
  185. package/dist/tools/bind_kit.js.map +1 -0
  186. package/dist/tools/conjure.d.ts +141 -0
  187. package/dist/tools/conjure.d.ts.map +1 -0
  188. package/dist/tools/conjure.js +655 -0
  189. package/dist/tools/conjure.js.map +1 -0
  190. package/dist/tools/conjure_screen.d.ts +174 -0
  191. package/dist/tools/conjure_screen.d.ts.map +1 -0
  192. package/dist/tools/conjure_screen.js +458 -0
  193. package/dist/tools/conjure_screen.js.map +1 -0
  194. package/dist/tools/create_kit.d.ts +32 -0
  195. package/dist/tools/create_kit.d.ts.map +1 -0
  196. package/dist/tools/create_kit.js +131 -0
  197. package/dist/tools/create_kit.js.map +1 -0
  198. package/dist/tools/create_project.d.ts +267 -0
  199. package/dist/tools/create_project.d.ts.map +1 -0
  200. package/dist/tools/create_project.js +546 -0
  201. package/dist/tools/create_project.js.map +1 -0
  202. package/dist/tools/delete_files.d.ts +93 -0
  203. package/dist/tools/delete_files.d.ts.map +1 -0
  204. package/dist/tools/delete_files.js +276 -0
  205. package/dist/tools/delete_files.js.map +1 -0
  206. package/dist/tools/delete_project.d.ts +43 -0
  207. package/dist/tools/delete_project.d.ts.map +1 -0
  208. package/dist/tools/delete_project.js +118 -0
  209. package/dist/tools/delete_project.js.map +1 -0
  210. package/dist/tools/get_kit.d.ts +28 -0
  211. package/dist/tools/get_kit.d.ts.map +1 -0
  212. package/dist/tools/get_kit.js +95 -0
  213. package/dist/tools/get_kit.js.map +1 -0
  214. package/dist/tools/get_project.d.ts +37 -0
  215. package/dist/tools/get_project.d.ts.map +1 -0
  216. package/dist/tools/get_project.js +71 -0
  217. package/dist/tools/get_project.js.map +1 -0
  218. package/dist/tools/list_components.d.ts +42 -0
  219. package/dist/tools/list_components.d.ts.map +1 -0
  220. package/dist/tools/list_components.js +125 -0
  221. package/dist/tools/list_components.js.map +1 -0
  222. package/dist/tools/list_files.d.ts +32 -0
  223. package/dist/tools/list_files.d.ts.map +1 -0
  224. package/dist/tools/list_files.js +109 -0
  225. package/dist/tools/list_files.js.map +1 -0
  226. package/dist/tools/list_kits.d.ts +14 -0
  227. package/dist/tools/list_kits.d.ts.map +1 -0
  228. package/dist/tools/list_kits.js +41 -0
  229. package/dist/tools/list_kits.js.map +1 -0
  230. package/dist/tools/list_projects.d.ts +23 -0
  231. package/dist/tools/list_projects.d.ts.map +1 -0
  232. package/dist/tools/list_projects.js +66 -0
  233. package/dist/tools/list_projects.js.map +1 -0
  234. package/dist/tools/plan.d.ts +16 -0
  235. package/dist/tools/plan.d.ts.map +1 -0
  236. package/dist/tools/plan.js +146 -0
  237. package/dist/tools/plan.js.map +1 -0
  238. package/dist/tools/preview.d.ts +289 -0
  239. package/dist/tools/preview.d.ts.map +1 -0
  240. package/dist/tools/preview.js +672 -0
  241. package/dist/tools/preview.js.map +1 -0
  242. package/dist/tools/read_file.d.ts +40 -0
  243. package/dist/tools/read_file.d.ts.map +1 -0
  244. package/dist/tools/read_file.js +114 -0
  245. package/dist/tools/read_file.js.map +1 -0
  246. package/dist/tools/refine.d.ts +220 -0
  247. package/dist/tools/refine.d.ts.map +1 -0
  248. package/dist/tools/refine.js +501 -0
  249. package/dist/tools/refine.js.map +1 -0
  250. package/dist/tools/validate.d.ts +74 -0
  251. package/dist/tools/validate.d.ts.map +1 -0
  252. package/dist/tools/validate.js +224 -0
  253. package/dist/tools/validate.js.map +1 -0
  254. package/dist/tools/write_files.d.ts +158 -0
  255. package/dist/tools/write_files.d.ts.map +1 -0
  256. package/dist/tools/write_files.js +541 -0
  257. package/dist/tools/write_files.js.map +1 -0
  258. package/dist/transport.d.ts +77 -0
  259. package/dist/transport.d.ts.map +1 -0
  260. package/dist/transport.js +448 -0
  261. package/dist/transport.js.map +1 -0
  262. package/dist/ui/card-asset-broker.d.ts +42 -0
  263. package/dist/ui/card-asset-broker.d.ts.map +1 -0
  264. package/dist/ui/card-asset-broker.js +479 -0
  265. package/dist/ui/card-asset-broker.js.map +1 -0
  266. package/dist/ui/grid-resource.d.ts +252 -0
  267. package/dist/ui/grid-resource.d.ts.map +1 -0
  268. package/dist/ui/grid-resource.js +680 -0
  269. package/dist/ui/grid-resource.js.map +1 -0
  270. package/dist/ui/viewer-static/index.html +95 -0
  271. package/dist/ui/viewer-static/viewer.css +451 -0
  272. package/dist/ui/viewer-static/viewer.js +1405 -0
  273. package/dist/validate/full-scan.d.ts +87 -0
  274. package/dist/validate/full-scan.d.ts.map +1 -0
  275. package/dist/validate/full-scan.js +299 -0
  276. package/dist/validate/full-scan.js.map +1 -0
  277. package/dist/validate/index.d.ts +15 -0
  278. package/dist/validate/index.d.ts.map +1 -0
  279. package/dist/validate/index.js +18 -0
  280. package/dist/validate/index.js.map +1 -0
  281. package/dist/validate/marker.d.ts +89 -0
  282. package/dist/validate/marker.d.ts.map +1 -0
  283. package/dist/validate/marker.js +87 -0
  284. package/dist/validate/marker.js.map +1 -0
  285. package/dist/validate/phash.d.ts +135 -0
  286. package/dist/validate/phash.d.ts.map +1 -0
  287. package/dist/validate/phash.js +307 -0
  288. package/dist/validate/phash.js.map +1 -0
  289. package/dist/validate/render.d.ts +38 -0
  290. package/dist/validate/render.d.ts.map +1 -0
  291. package/dist/validate/render.js +155 -0
  292. package/dist/validate/render.js.map +1 -0
  293. package/dist/watch/index.d.ts +12 -0
  294. package/dist/watch/index.d.ts.map +1 -0
  295. package/dist/watch/index.js +12 -0
  296. package/dist/watch/index.js.map +1 -0
  297. package/dist/watch/watcher.d.ts +65 -0
  298. package/dist/watch/watcher.d.ts.map +1 -0
  299. package/dist/watch/watcher.js +238 -0
  300. package/dist/watch/watcher.js.map +1 -0
  301. package/package.json +70 -0
@@ -0,0 +1,541 @@
1
+ /**
2
+ * MCP tool: write_files (M1-08; re-plumbed onto KitStore in M1-14a-1b / DRO-565).
3
+ *
4
+ * Writes up to 256 files per call into a KIT (the plan's `kitId` — the same
5
+ * readable surface `read_file`/`list_files`/`delete_files` see). Every `path`
6
+ * must match at least one glob in the plan's `writes`; the plan is resolved via
7
+ * `planId` against the M1-07 plan registry (`../plans/index.ts`), which must be
8
+ * live (exists + not expired).
9
+ *
10
+ * Each file is sourced from exactly one of:
11
+ * - `localPath` — resolved against the plan's `localDir` (the harness-local
12
+ * SOURCE base); the server reads the bytes directly from disk, so file
13
+ * contents never enter model context (the whole point of the localPath
14
+ * indirection). Note the split of roles: `localDir` is where uploads are
15
+ * READ FROM; the kit is where they are WRITTEN TO.
16
+ * - `data` — inline content (utf-8 or base64, per `encoding`), for content
17
+ * the caller only has in-memory (e.g. LLM-generated text).
18
+ *
19
+ * ── Store re-plumb (DRO-565) ─────────────────────────────────────────────────
20
+ * This tool used to own an fs-native rename-to-temp/rename-back transaction and
21
+ * wrote straight into `plan.localDir`. That transaction now lives behind the
22
+ * `KitStore.writeFiles(kitId, ops)` primitive (`store/interface.ts`), so the
23
+ * SAME verb runs against `LocalFsKitStore` (disk, rename transaction) or
24
+ * `GitHostKitStore` (contents-API commit on a branch) with the AC10 atomicity +
25
+ * rollback contract preserved. The tool keeps ALL plan-gating and per-file
26
+ * validation (planId, writes-glob membership, duplicate rejection, localPath
27
+ * containment + streaming decision, byte cap, encoding) and hands the store a
28
+ * resolved `WriteOp[]` — mirroring how `delete_files` keeps `deletes`-glob
29
+ * gating tool-side and calls `store.deleteFile(plan.kitId, path)`.
30
+ *
31
+ * The atomicity/streaming/rollback semantics themselves are documented on the
32
+ * `KitStore.writeFiles` primitive and its two adapters; this file is now the
33
+ * validation + wire-error-shaping layer in front of them.
34
+ */
35
+ import { stat } from "node:fs/promises";
36
+ import { isAbsolute, resolve } from "node:path";
37
+ import { z } from "zod";
38
+ import { withPlanGuard } from "../middleware/plan-guard.js";
39
+ import { getPlan, isPathInsideLocalDir, pathMatchesGlobs, PlanNotFoundError, } from "../plans/index.js";
40
+ import { RollbackIncompleteError, WriteFailedError } from "../store/interface.js";
41
+ import { isValidBase64Content } from "../store/kit-files.js";
42
+ export const WRITE_FILES_TOOL_NAME = "mcp__genie__write_files";
43
+ /** M1-08 AC3 — hard ceiling on files per call. */
44
+ export const MAX_FILES_PER_CALL = 256;
45
+ /**
46
+ * Byte-cap for a single `write_files` call's total decoded payload.
47
+ *
48
+ * RFC §17.5 flags Anthropic's exact server-side cap as unconfirmed for their
49
+ * hosted endpoint; PRD §EC-029 sets genie's own default at 16 MiB with a
50
+ * configurable ceiling. `GENIE_WRITE_BYTE_CAP` overrides the default; values
51
+ * that are non-numeric or ≤ 0 fall back to it.
52
+ */
53
+ export const DEFAULT_WRITE_BYTE_CAP = 16 * 1024 * 1024;
54
+ function resolveByteCap(env) {
55
+ const raw = env["GENIE_WRITE_BYTE_CAP"];
56
+ if (raw === undefined)
57
+ return DEFAULT_WRITE_BYTE_CAP;
58
+ const n = Number(raw);
59
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_WRITE_BYTE_CAP;
60
+ }
61
+ // ─── write_files' own error taxonomy ─────────────────────────────────────────
62
+ //
63
+ // Repo convention (see ListFilesError in tools/list_files.ts, ProjectStoreError
64
+ // in tools/create_project.ts): each tool owns its error classes colocated in
65
+ // its own file rather than a shared cross-tool errors module. The one
66
+ // plan-layer error this tool can also see — PlanNotFoundError — is imported
67
+ // from `../plans/index.ts` instead of redefined here.
68
+ /** M1-08 AC3 — more than 256 files were supplied to `write_files` in one call. */
69
+ export class TooManyFilesError extends Error {
70
+ count;
71
+ max;
72
+ code = "TooManyFilesError";
73
+ constructor(count, max) {
74
+ super(`write_files accepts at most ${max} files per call; received ${count}.`);
75
+ this.count = count;
76
+ this.max = max;
77
+ this.name = "TooManyFilesError";
78
+ }
79
+ }
80
+ /**
81
+ * Two or more files in the same call target the same `path` (Copilot review
82
+ * finding on PR #106). Without this check, `resolvedLocalPaths` — keyed by
83
+ * `file.path` — would silently drop all but the last entry's `localPath`
84
+ * (so an earlier duplicate would stage the WRONG file's bytes), and
85
+ * `writtenPaths` would list the same path twice as if two distinct files had
86
+ * been written, when in fact whichever entry committed last (an unspecified,
87
+ * input-order-dependent race between the two renames) is the only one that
88
+ * survives. Rejected up front, before any per-file validation, so partial
89
+ * ambiguity is never staged.
90
+ */
91
+ export class DuplicatePathError extends Error {
92
+ path;
93
+ code = "DuplicatePathError";
94
+ constructor(path) {
95
+ super(`Path "${path}" appears more than once in this write_files call; every path must be unique.`);
96
+ this.path = path;
97
+ this.name = "DuplicatePathError";
98
+ }
99
+ }
100
+ /**
101
+ * M1-08 AC4 — a file's `path` is rejected by the plan boundary: either it
102
+ * doesn't match any glob in the plan's `writes` (`reason: "glob"`), or it
103
+ * resolves outside the plan's `localDir` even though a glob DID match
104
+ * (`reason: "escapesLocalDir"` — e.g. an absolute path under a permissive
105
+ * `**`; see the containment check in `writeFiles`). Both failure modes share
106
+ * one error class/code (`PathOutsidePlanError`) so callers can branch on a
107
+ * single `code`, but the message and `reason` field distinguish them —
108
+ * a Copilot review finding on PR #106 flagged the message as misleadingly
109
+ * glob-specific even when the actual cause was the containment check.
110
+ */
111
+ export class PathOutsidePlanError extends Error {
112
+ path;
113
+ reason;
114
+ code = "PathOutsidePlanError";
115
+ constructor(path, reason = "glob") {
116
+ super(reason === "escapesLocalDir"
117
+ ? `Path "${path}" resolves outside the plan's localDir, even though it may match a writes pattern.`
118
+ : `Path "${path}" does not match any pattern in the plan's writes.`);
119
+ this.path = path;
120
+ this.reason = reason;
121
+ this.name = "PathOutsidePlanError";
122
+ }
123
+ }
124
+ /** M1-08 AC6 — a file's `localPath` resolves outside the plan's `localDir`. */
125
+ export class LocalPathEscapeError extends Error {
126
+ localPath;
127
+ localDir;
128
+ code = "LocalPathEscapeError";
129
+ constructor(localPath, localDir) {
130
+ super(`localPath "${localPath}" resolves outside the plan's localDir "${localDir}".`);
131
+ this.localPath = localPath;
132
+ this.localDir = localDir;
133
+ this.name = "LocalPathEscapeError";
134
+ }
135
+ }
136
+ /** M1-08 AC7 — a file set neither `localPath` nor `data`, or set both. */
137
+ export class InvalidFileInputError extends Error {
138
+ path;
139
+ code = "InvalidFileInputError";
140
+ constructor(path, reason) {
141
+ super(reason === "both"
142
+ ? `File "${path}" set both localPath and data; exactly one is required.`
143
+ : `File "${path}" set neither localPath nor data; exactly one is required.`);
144
+ this.path = path;
145
+ this.name = "InvalidFileInputError";
146
+ }
147
+ }
148
+ /** M1-08 AC7 — `data` was not valid base64 when `encoding: "base64"` was declared. */
149
+ export class InvalidEncodingError extends Error {
150
+ path;
151
+ code = "InvalidEncodingError";
152
+ constructor(path) {
153
+ super(`File "${path}" declared encoding "base64" but data is not valid base64.`);
154
+ this.path = path;
155
+ this.name = "InvalidEncodingError";
156
+ }
157
+ }
158
+ /** M1-08 AC9 — the call's total decoded byte size exceeds the configured cap. */
159
+ export class PayloadTooLargeError extends Error {
160
+ totalBytes;
161
+ maxBytes;
162
+ retryMaxFiles;
163
+ code = "PayloadTooLargeError";
164
+ constructor(totalBytes, maxBytes, retryMaxFiles) {
165
+ super(`write_files payload is ${totalBytes} bytes, exceeding the ${maxBytes} byte cap. ` +
166
+ "Halve the file count and retry.");
167
+ this.totalBytes = totalBytes;
168
+ this.maxBytes = maxBytes;
169
+ this.retryMaxFiles = retryMaxFiles;
170
+ this.name = "PayloadTooLargeError";
171
+ }
172
+ }
173
+ /**
174
+ * AC10 write-failure taxonomy now lives in the store layer (`store/interface.ts`),
175
+ * because the store owns the atomic write transaction after the DRO-565 re-plumb.
176
+ * Re-exported here so existing importers of these names from `write_files.js`
177
+ * (tests, in-process callers) keep resolving them.
178
+ */
179
+ export { RollbackIncompleteError, WriteFailedError } from "../store/interface.js";
180
+ // ─── Input/output shapes ─────────────────────────────────────────────────────
181
+ const fileInputSchema = z
182
+ .object({
183
+ path: z
184
+ .string()
185
+ .min(1)
186
+ .describe("Project-relative path to write, matched against the plan's writes globs"),
187
+ localPath: z
188
+ .string()
189
+ .min(1)
190
+ .optional()
191
+ .describe("Path on disk to read content from, resolved against the plan's localDir"),
192
+ data: z
193
+ .string()
194
+ .optional()
195
+ .describe("Inline content — utf-8 text, or base64 when encoding is base64"),
196
+ encoding: z
197
+ .enum(["utf-8", "base64"])
198
+ .optional()
199
+ .describe('Encoding of `data`. Defaults to "utf-8".'),
200
+ mimeType: z.string().optional().describe("Optional MIME type hint (not currently persisted)"),
201
+ })
202
+ .describe("A single file to write: exactly one of localPath or data must be set");
203
+ const writeFilesInputSchema = {
204
+ planId: z.string().min(1).describe("planId returned by a prior plan call"),
205
+ files: z.array(fileInputSchema).describe("Files to write (max 256 per call)"),
206
+ };
207
+ const writeFilesOutputSchema = {
208
+ writtenPaths: z.array(z.string()).describe("Paths written, in the same order as the input"),
209
+ };
210
+ /** Structured tool-error payload shape shared by every branch below. */
211
+ function toolError(payload) {
212
+ return {
213
+ isError: true,
214
+ content: [{ type: "text", text: JSON.stringify(payload) }],
215
+ };
216
+ }
217
+ /**
218
+ * Register the `mcp__genie__write_files` tool.
219
+ *
220
+ * @param server The MCP server to register against. `planId`/`writes` are
221
+ * validated against the shared M1-07 plan registry
222
+ * (`../plans/index.ts`) via the M1-13 plan-guard middleware
223
+ * (`../middleware/plan-guard.ts`) — the guard owns AC5's planId
224
+ * presence/existence/expiry checks and AC4's path-vs-`writes`-
225
+ * glob check; this file's own remaining validation covers
226
+ * per-file structural rules (duplicates, localPath containment,
227
+ * encoding, byte cap) that the guard is intentionally
228
+ * tool-agnostic about.
229
+ * @param kitStore The injected kit backend (M1-14a-1b / DRO-565). The physical
230
+ * write is `kitStore.writeFiles(plan.kitId, ops)` — the kit is
231
+ * the destination (same surface read_file/list_files see), and
232
+ * the atomic rename-transaction (LocalFs) / contents-API commit
233
+ * (GitHost) lives behind that primitive. Mirrors how
234
+ * `registerDeleteFilesTool(server, kitStore)` routes deletes.
235
+ */
236
+ export function registerWriteFilesTool(server, kitStore) {
237
+ server.registerTool(WRITE_FILES_TOOL_NAME, {
238
+ title: "Write files",
239
+ description: "Write up to 256 files per call into the plan's kit. Every path must match a " +
240
+ "glob in the plan's writes. Reads content from localPath (resolved against the " +
241
+ "plan's localDir, the local SOURCE base) so file contents never enter model " +
242
+ "context, or from inline data for in-memory content. Atomic per call — if any " +
243
+ "file fails, nothing is written. Requires a planId from mcp__genie__plan covering " +
244
+ "every path being written; call preview afterwards to show the result.",
245
+ inputSchema: writeFilesInputSchema,
246
+ outputSchema: writeFilesOutputSchema,
247
+ },
248
+ // M1-13 plan-vs-write guard (DRO-239). The middleware validates planId
249
+ // presence/existence/expiry and every file path against the plan's writes
250
+ // globs BEFORE the handler runs, so the four verbs share one identical
251
+ // plan-boundary check. Rejections surface as the canonical JSON-RPC
252
+ // `-32602` shape and are audit-logged as `plan.guard.reject`. The guard
253
+ // hands the resolved plan through in `ctx.plan`, so the handler reaches
254
+ // `plan.kitId` (write destination) and `plan.localDir` (localPath source
255
+ // base) without a second getPlan hit.
256
+ //
257
+ // The core `writeFiles(store, plan, args)` still performs the same plan
258
+ // check as defense-in-depth (a direct in-process caller — see the
259
+ // "writeFiles (core logic)" test suite — bypasses the MCP layer and this
260
+ // middleware with it), so removing the checks from the core would silently
261
+ // open a gap for those callers.
262
+ withPlanGuard({ mode: "writes" }, async (args) => {
263
+ try {
264
+ const result = await writeFiles(kitStore, args);
265
+ return {
266
+ content: [{ type: "text", text: JSON.stringify(result) }],
267
+ structuredContent: result,
268
+ };
269
+ }
270
+ catch (error) {
271
+ if (error instanceof TooManyFilesError) {
272
+ // AC3 — plain structured error; no retry-hint contract specified
273
+ // for the file-count ceiling (that's AC9's byte-cap path, below).
274
+ return toolError({
275
+ code: "TooManyFilesError",
276
+ message: error.message,
277
+ count: error.count,
278
+ max: error.max,
279
+ });
280
+ }
281
+ if (error instanceof PayloadTooLargeError) {
282
+ // AC9 — literal contract: "return HTTP-equivalent error code -32099
283
+ // with { retryWith: { maxFiles: <half> } } in data". That's the
284
+ // shape of a JSON-RPC error object ({ code, message, data }), which
285
+ // this mirrors exactly. Note this issue's AC9 and RFC §6.2's error
286
+ // taxonomy disagree on the number — the RFC assigns byte-cap
287
+ // overflow to genie.byteCapExceeded (-32031) and reserves -32099
288
+ // for genie.internal (unanticipated errors). This implements AC9's
289
+ // literal number as written (the graded contract for this issue)
290
+ // and flags the discrepancy in the PR description for the
291
+ // maintainer to reconcile.
292
+ return toolError({
293
+ code: -32099,
294
+ message: error.message,
295
+ data: {
296
+ retryWith: { maxFiles: error.retryMaxFiles },
297
+ totalBytes: error.totalBytes,
298
+ maxBytes: error.maxBytes,
299
+ },
300
+ });
301
+ }
302
+ if (error instanceof PlanNotFoundError) {
303
+ // Ordinarily unreachable at the wire level — the M1-13 plan-guard
304
+ // middleware (above) catches PlanNotFoundError first and returns
305
+ // the canonical -32602 shape. Kept as a belt-and-suspenders branch
306
+ // in case `writeFiles` throws it from a code path the middleware
307
+ // didn't traverse (e.g. a future refactor that bypasses the guard,
308
+ // or a race where a plan expires between the guard's getPlan and
309
+ // the core's getPlan). Behaviour matches shipped M1-07: same
310
+ // PlanNotFoundError for "never existed" and "expired".
311
+ return toolError({
312
+ code: "PlanNotFoundError",
313
+ message: error.message,
314
+ planId: error.planId,
315
+ });
316
+ }
317
+ if (error instanceof RollbackIncompleteError) {
318
+ // AC10's rollback guarantee could not be fully honored — this is
319
+ // more severe than a plain WriteFailedError (which promises a
320
+ // clean, fully-restored tree), so it gets its own code rather than
321
+ // being silently folded into that message.
322
+ return toolError({
323
+ code: "RollbackIncompleteError",
324
+ message: error.message,
325
+ commitError: error.commitError,
326
+ rollbackFailures: error.rollbackFailures,
327
+ });
328
+ }
329
+ if (error instanceof PathOutsidePlanError ||
330
+ error instanceof LocalPathEscapeError ||
331
+ error instanceof InvalidFileInputError ||
332
+ error instanceof InvalidEncodingError ||
333
+ error instanceof WriteFailedError ||
334
+ error instanceof DuplicatePathError) {
335
+ return toolError({ code: error.code, message: error.message, ...errorFields(error) });
336
+ }
337
+ throw error;
338
+ }
339
+ }));
340
+ }
341
+ /** Extra structured fields per own-error-type, beyond `code`/`message` (for client consumption). */
342
+ function errorFields(error) {
343
+ if (error instanceof PathOutsidePlanError)
344
+ return { path: error.path, reason: error.reason };
345
+ if (error instanceof LocalPathEscapeError)
346
+ return { localPath: error.localPath, localDir: error.localDir };
347
+ if (error instanceof InvalidFileInputError)
348
+ return { path: error.path };
349
+ if (error instanceof InvalidEncodingError)
350
+ return { path: error.path };
351
+ if (error instanceof DuplicatePathError)
352
+ return { path: error.path };
353
+ return { path: error.path, cause: error.cause }; // WriteFailedError
354
+ }
355
+ /**
356
+ * Validate + execute a `write_files` call against a resolved plan, committing
357
+ * the batch into the plan's KIT via the injected store.
358
+ *
359
+ * Order of validation (fails fast, before any write) — keep this list in
360
+ * lockstep with the code below; downstream steps assume every prior step has
361
+ * passed (e.g. the `resolvedLocalPaths` map keyed by `file.path` assumes step 3
362
+ * rejected duplicates):
363
+ * 1. AC5 — planId exists + not expired (`getPlan`, from the M1-07
364
+ * plan registry — throws `PlanNotFoundError` for either
365
+ * failure mode).
366
+ * 2. AC3 — `files.length <= 256`.
367
+ * 3. Structural — no two `files[]` entries share the same destination
368
+ * `path` (`DuplicatePathError`; Copilot review finding
369
+ * on PR #106).
370
+ * 4. AC4 — every `path` matches a plan `writes` glob.
371
+ * 5. Security — every destination `path` is kit-relative and contained
372
+ * (no absolute path, no `..`/`.` segment). Destinations
373
+ * resolve against the KIT now (not `localDir`), so this is
374
+ * a lexical containment check (`PathOutsidePlanError` with
375
+ * `reason: "escapesLocalDir"`; RFC §10 T-13). The store
376
+ * re-checks via `safePath` as defense-in-depth.
377
+ * 6. AC7 — every file sets exactly one of `localPath` / `data`.
378
+ * 7. AC6 — every `localPath` resolves inside the plan's `localDir`
379
+ * (the SOURCE base — where uploads are read from).
380
+ * 8. AC9 — total decoded payload size <= the configured byte cap.
381
+ * Only once every file in the batch passes is the batch handed to
382
+ * `store.writeFiles(plan.kitId, ops)` for the atomic commit (AC10).
383
+ *
384
+ * @param store The injected kit backend. The destination is `plan.kitId`; the
385
+ * physical atomic write (rename transaction on LocalFs / contents-API commit
386
+ * on GitHost) lives behind `store.writeFiles`, so this function is now purely
387
+ * validation + WriteOp assembly.
388
+ */
389
+ export async function writeFiles(store, args, env = process.env) {
390
+ // AC5 — planId must exist and be unexpired. Propagates PlanNotFoundError as-is.
391
+ const plan = await getPlan(args.planId);
392
+ // AC3 — file-count ceiling, before any per-file validation.
393
+ if (args.files.length > MAX_FILES_PER_CALL) {
394
+ throw new TooManyFilesError(args.files.length, MAX_FILES_PER_CALL);
395
+ }
396
+ // Structural check (Copilot review finding on PR #106): reject duplicate
397
+ // destination `path`s before any per-file validation depends on paths
398
+ // being unique. `resolvedLocalPaths` below is keyed by `file.path` — a
399
+ // second entry with the same path would silently overwrite the first's
400
+ // resolved `localPath` source, and `writtenPaths` would otherwise list the
401
+ // same path twice as if two distinct files had committed.
402
+ const seenPaths = new Set();
403
+ for (const file of args.files) {
404
+ if (seenPaths.has(file.path)) {
405
+ throw new DuplicatePathError(file.path);
406
+ }
407
+ seenPaths.add(file.path);
408
+ }
409
+ // AC4 — every path must match the plan's writes globs.
410
+ for (const file of args.files) {
411
+ if (!pathMatchesGlobs(file.path, plan.writes)) {
412
+ throw new PathOutsidePlanError(file.path);
413
+ }
414
+ }
415
+ // Security (Copilot review finding on PR #106; RFC §10 T-13 — "Path
416
+ // traversal in write_files overwrites /etc/passwd"): a glob match alone does
417
+ // NOT guarantee the destination stays inside the kit — an absolute path like
418
+ // "/etc/passwd" matches a permissive glob such as `**` under micromatch, and
419
+ // resolving it against a kit root would escape. Post-re-plumb the destination
420
+ // is the KIT (not `localDir`), and the store's `safePath` will reject an
421
+ // escape too — but we reject up front so the whole call fails before any
422
+ // WriteOp is built, keeping the all-or-nothing guarantee at the tool
423
+ // boundary. The check is now purely lexical (kit-relative, no `.`/`..`
424
+ // segment, not absolute) since the tool no longer holds a concrete kit root.
425
+ for (const file of args.files) {
426
+ if (!isKitRelativeContained(file.path)) {
427
+ throw new PathOutsidePlanError(file.path, "escapesLocalDir");
428
+ }
429
+ }
430
+ // AC7 — exactly one of localPath/data per file.
431
+ for (const file of args.files) {
432
+ const hasLocalPath = file.localPath !== undefined;
433
+ const hasData = file.data !== undefined;
434
+ if (hasLocalPath && hasData) {
435
+ throw new InvalidFileInputError(file.path, "both");
436
+ }
437
+ if (!hasLocalPath && !hasData) {
438
+ throw new InvalidFileInputError(file.path, "missing");
439
+ }
440
+ if (hasData && file.encoding === "base64" && !isValidBase64Content(file.data)) {
441
+ throw new InvalidEncodingError(file.path);
442
+ }
443
+ }
444
+ // AC6 — every localPath must resolve inside the plan's localDir (the SOURCE
445
+ // base). Resolve once up front (rather than re-resolving during the WriteOp
446
+ // build) so this check and the actual read always agree on the same absolute
447
+ // path. isPathInsideLocalDir(path, localDir) does its own resolution of
448
+ // `path` against `localDir` (correctly anchoring a relative localPath there,
449
+ // rather than against process.cwd()) — see plans/index.ts.
450
+ const resolvedLocalPaths = new Map();
451
+ for (const file of args.files) {
452
+ if (file.localPath === undefined)
453
+ continue;
454
+ if (!isPathInsideLocalDir(file.localPath, plan.localDir)) {
455
+ throw new LocalPathEscapeError(file.localPath, plan.localDir);
456
+ }
457
+ resolvedLocalPaths.set(file.path, resolve(plan.localDir, file.localPath));
458
+ }
459
+ // AC9 — total decoded byte-size cap, checked before any write lands.
460
+ const maxBytes = resolveByteCap(env);
461
+ let totalBytes = 0;
462
+ for (const file of args.files) {
463
+ if (file.data !== undefined) {
464
+ totalBytes += byteLengthOf(file.data, file.encoding ?? "utf-8");
465
+ }
466
+ else {
467
+ const localPath = resolvedLocalPaths.get(file.path);
468
+ if (localPath !== undefined) {
469
+ totalBytes += await sizeOf(localPath, file.path);
470
+ }
471
+ }
472
+ }
473
+ if (totalBytes > maxBytes) {
474
+ throw new PayloadTooLargeError(totalBytes, maxBytes, Math.max(1, Math.floor(args.files.length / 2)));
475
+ }
476
+ // Build the resolved WriteOp[] — inline `data` becomes `{ path, content }`,
477
+ // a `localPath` becomes `{ path, sourcePath }` (the store STREAMS from it, so
478
+ // a large upload never fully buffers here). Then hand the batch to the store
479
+ // for the atomic commit into the kit (AC10).
480
+ const ops = args.files.map((file) => {
481
+ if (file.localPath !== undefined) {
482
+ const sourcePath = resolvedLocalPaths.get(file.path);
483
+ if (sourcePath === undefined) {
484
+ // Unreachable: every localPath file populated the map above.
485
+ throw new WriteFailedError(file.path, "internal: unresolved localPath");
486
+ }
487
+ return { path: file.path, sourcePath };
488
+ }
489
+ return {
490
+ path: file.path,
491
+ content: decodeData(file.data, file.encoding ?? "utf-8", file.path),
492
+ };
493
+ });
494
+ return store.writeFiles(plan.kitId, ops);
495
+ }
496
+ /** Decoded byte length of inline `data`, without materializing extra copies for utf-8. */
497
+ function byteLengthOf(data, encoding) {
498
+ if (encoding === "base64") {
499
+ // Base64 expands 3 bytes -> 4 chars; strip padding for an exact count.
500
+ const padding = data.endsWith("==") ? 2 : data.endsWith("=") ? 1 : 0;
501
+ return Math.floor((data.length * 3) / 4) - padding;
502
+ }
503
+ return Buffer.byteLength(data, "utf-8");
504
+ }
505
+ async function sizeOf(localPath, publicPath) {
506
+ try {
507
+ const info = await stat(localPath);
508
+ return info.size;
509
+ }
510
+ catch (error) {
511
+ throw new WriteFailedError(publicPath, describeError(error, "source file not found"));
512
+ }
513
+ }
514
+ /**
515
+ * True if a destination `path` is a safe kit-relative path: not absolute, and
516
+ * with no `.`/`..` segment (on either separator). Post-re-plumb the destination
517
+ * is the kit (the tool holds no concrete kit root), so containment is a lexical
518
+ * check — a relative path with no dot-segment can never escape the kit root the
519
+ * store resolves it against, and an absolute path always does. The store's
520
+ * `safePath` re-verifies as defense-in-depth. Mirrors delete_files' own
521
+ * kit-relative path guard.
522
+ */
523
+ function isKitRelativeContained(path) {
524
+ if (isAbsolute(path))
525
+ return false;
526
+ return !path.split(/[/\\]/).some((seg) => seg === "." || seg === "..");
527
+ }
528
+ function decodeData(data, encoding, path) {
529
+ try {
530
+ return Buffer.from(data, encoding === "base64" ? "base64" : "utf-8");
531
+ }
532
+ catch (error) {
533
+ throw new WriteFailedError(path, describeError(error, "invalid data encoding"));
534
+ }
535
+ }
536
+ function describeError(error, fallback) {
537
+ if (error instanceof Error)
538
+ return error.message;
539
+ return fallback;
540
+ }
541
+ //# sourceMappingURL=write_files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write_files.js","sourceRoot":"","sources":["../../src/tools/write_files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEhD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EACL,OAAO,EACP,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,CAAC,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AAE/D,kDAAkD;AAClD,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvD,SAAS,cAAc,CAAC,GAAuC;IAC7D,MAAM,GAAG,GAAG,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACxC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,sBAAsB,CAAC;IACrD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC;AAClE,CAAC;AAED,gFAAgF;AAChF,EAAE;AACF,gFAAgF;AAChF,6EAA6E;AAC7E,sEAAsE;AACtE,4EAA4E;AAC5E,sDAAsD;AAEtD,kFAAkF;AAClF,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAG/B;IACA;IAHF,IAAI,GAAG,mBAAmB,CAAC;IACpC,YACW,KAAa,EACb,GAAW;QAEpB,KAAK,CAAC,+BAA+B,GAAG,6BAA6B,KAAK,GAAG,CAAC,CAAC;QAHtE,UAAK,GAAL,KAAK,CAAQ;QACb,QAAG,GAAH,GAAG,CAAQ;QAGpB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAEtB;IADZ,IAAI,GAAG,oBAAoB,CAAC;IACrC,YAAqB,IAAY;QAC/B,KAAK,CACH,SAAS,IAAI,+EAA+E,CAC7F,CAAC;QAHiB,SAAI,GAAJ,IAAI,CAAQ;QAI/B,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAGlC;IACA;IAHF,IAAI,GAAG,sBAAsB,CAAC;IACvC,YACW,IAAY,EACZ,SAAqC,MAAM;QAEpD,KAAK,CACH,MAAM,KAAK,iBAAiB;YAC1B,CAAC,CAAC,SAAS,IAAI,oFAAoF;YACnG,CAAC,CAAC,SAAS,IAAI,oDAAoD,CACtE,CAAC;QAPO,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAqC;QAOpD,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,+EAA+E;AAC/E,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAGlC;IACA;IAHF,IAAI,GAAG,sBAAsB,CAAC;IACvC,YACW,SAAiB,EACjB,QAAgB;QAEzB,KAAK,CAAC,cAAc,SAAS,2CAA2C,QAAQ,IAAI,CAAC,CAAC;QAH7E,cAAS,GAAT,SAAS,CAAQ;QACjB,aAAQ,GAAR,QAAQ,CAAQ;QAGzB,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,0EAA0E;AAC1E,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAGnC;IAFF,IAAI,GAAG,uBAAuB,CAAC;IACxC,YACW,IAAY,EACrB,MAA0B;QAE1B,KAAK,CACH,MAAM,KAAK,MAAM;YACf,CAAC,CAAC,SAAS,IAAI,yDAAyD;YACxE,CAAC,CAAC,SAAS,IAAI,4DAA4D,CAC9E,CAAC;QAPO,SAAI,GAAJ,IAAI,CAAQ;QAQrB,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AAED,sFAAsF;AACtF,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAExB;IADZ,IAAI,GAAG,sBAAsB,CAAC;IACvC,YAAqB,IAAY;QAC/B,KAAK,CAAC,SAAS,IAAI,4DAA4D,CAAC,CAAC;QAD9D,SAAI,GAAJ,IAAI,CAAQ;QAE/B,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,iFAAiF;AACjF,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAGlC;IACA;IACA;IAJF,IAAI,GAAG,sBAAsB,CAAC;IACvC,YACW,UAAkB,EAClB,QAAgB,EAChB,aAAqB;QAE9B,KAAK,CACH,0BAA0B,UAAU,yBAAyB,QAAQ,aAAa;YAChF,iCAAiC,CACpC,CAAC;QAPO,eAAU,GAAV,UAAU,CAAQ;QAClB,aAAQ,GAAR,QAAQ,CAAQ;QAChB,kBAAa,GAAb,aAAa,CAAQ;QAM9B,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED;;;;;GAKG;AACH,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAElF,gFAAgF;AAEhF,MAAM,eAAe,GAAG,CAAC;KACtB,MAAM,CAAC;IACN,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,yEAAyE,CAAC;IACtF,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,EAAE;SACV,QAAQ,CAAC,yEAAyE,CAAC;IACtF,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,gEAAgE,CAAC;IAC7E,QAAQ,EAAE,CAAC;SACR,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;SACzB,QAAQ,EAAE;SACV,QAAQ,CAAC,0CAA0C,CAAC;IACvD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mDAAmD,CAAC;CAC9F,CAAC;KACD,QAAQ,CAAC,sEAAsE,CAAC,CAAC;AAEpF,MAAM,qBAAqB,GAAG;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IAC1E,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC;CACrE,CAAC;AAEX,MAAM,sBAAsB,GAAG;IAC7B,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,+CAA+C,CAAC;CACnF,CAAC;AAeX,wEAAwE;AACxE,SAAS,SAAS,CAAC,OAAgC;IACjD,OAAO;QACL,OAAO,EAAE,IAAa;QACtB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;KACpE,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,QAAkB;IAC1E,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,KAAK,EAAE,aAAa;QACpB,WAAW,EACT,8EAA8E;YAC9E,gFAAgF;YAChF,6EAA6E;YAC7E,+EAA+E;YAC/E,mFAAmF;YACnF,uEAAuE;QACzE,WAAW,EAAE,qBAAqB;QAClC,YAAY,EAAE,sBAAsB;KACrC;IACD,uEAAuE;IACvE,0EAA0E;IAC1E,uEAAuE;IACvE,oEAAoE;IACpE,wEAAwE;IACxE,wEAAwE;IACxE,yEAAyE;IACzE,sCAAsC;IACtC,EAAE;IACF,wEAAwE;IACxE,kEAAkE;IAClE,yEAAyE;IACzE,2EAA2E;IAC3E,gCAAgC;IAChC,aAAa,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAoB,EAAE,EAAE;QAC/D,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAChD,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClE,iBAAiB,EAAE,MAAM;aAC1B,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;gBACvC,iEAAiE;gBACjE,kEAAkE;gBAClE,OAAO,SAAS,CAAC;oBACf,IAAI,EAAE,mBAAmB;oBACzB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,GAAG,EAAE,KAAK,CAAC,GAAG;iBACf,CAAC,CAAC;YACL,CAAC;YACD,IAAI,KAAK,YAAY,oBAAoB,EAAE,CAAC;gBAC1C,oEAAoE;gBACpE,gEAAgE;gBAChE,oEAAoE;gBACpE,mEAAmE;gBACnE,6DAA6D;gBAC7D,iEAAiE;gBACjE,mEAAmE;gBACnE,iEAAiE;gBACjE,0DAA0D;gBAC1D,2BAA2B;gBAC3B,OAAO,SAAS,CAAC;oBACf,IAAI,EAAE,CAAC,KAAK;oBACZ,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,IAAI,EAAE;wBACJ,SAAS,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE;wBAC5C,UAAU,EAAE,KAAK,CAAC,UAAU;wBAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;qBACzB;iBACF,CAAC,CAAC;YACL,CAAC;YACD,IAAI,KAAK,YAAY,iBAAiB,EAAE,CAAC;gBACvC,kEAAkE;gBAClE,iEAAiE;gBACjE,mEAAmE;gBACnE,iEAAiE;gBACjE,mEAAmE;gBACnE,iEAAiE;gBACjE,6DAA6D;gBAC7D,uDAAuD;gBACvD,OAAO,SAAS,CAAC;oBACf,IAAI,EAAE,mBAAmB;oBACzB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,MAAM,EAAE,KAAK,CAAC,MAAM;iBACrB,CAAC,CAAC;YACL,CAAC;YACD,IAAI,KAAK,YAAY,uBAAuB,EAAE,CAAC;gBAC7C,iEAAiE;gBACjE,8DAA8D;gBAC9D,mEAAmE;gBACnE,2CAA2C;gBAC3C,OAAO,SAAS,CAAC;oBACf,IAAI,EAAE,yBAAyB;oBAC/B,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;iBACzC,CAAC,CAAC;YACL,CAAC;YACD,IACE,KAAK,YAAY,oBAAoB;gBACrC,KAAK,YAAY,oBAAoB;gBACrC,KAAK,YAAY,qBAAqB;gBACtC,KAAK,YAAY,oBAAoB;gBACrC,KAAK,YAAY,gBAAgB;gBACjC,KAAK,YAAY,kBAAkB,EACnC,CAAC;gBACD,OAAO,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACxF,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,SAAS,WAAW,CAClB,KAMsB;IAEtB,IAAI,KAAK,YAAY,oBAAoB;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;IAC7F,IAAI,KAAK,YAAY,oBAAoB;QACvC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;IAClE,IAAI,KAAK,YAAY,qBAAqB;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IACxE,IAAI,KAAK,YAAY,oBAAoB;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IACvE,IAAI,KAAK,YAAY,kBAAkB;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IACrE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,mBAAmB;AACtE,CAAC;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAe,EACf,IAAoB,EACpB,MAA0C,OAAO,CAAC,GAAG;IAErD,gFAAgF;IAChF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAExC,4DAA4D;IAC5D,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;QAC3C,MAAM,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACrE,CAAC;IAED,yEAAyE;IACzE,sEAAsE;IACtE,uEAAuE;IACvE,uEAAuE;IACvE,2EAA2E;IAC3E,0DAA0D;IAC1D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,uDAAuD;IACvD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,6EAA6E;IAC7E,6EAA6E;IAC7E,6EAA6E;IAC7E,8EAA8E;IAC9E,yEAAyE;IACzE,yEAAyE;IACzE,qEAAqE;IACrE,uEAAuE;IACvE,6EAA6E;IAC7E,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,gDAAgD;IAChD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC;QACxC,IAAI,YAAY,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAM,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAc,CAAC,EAAE,CAAC;YACxF,MAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,4EAA4E;IAC5E,6EAA6E;IAC7E,wEAAwE;IACxE,6EAA6E;IAC7E,2DAA2D;IAC3D,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACrD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS;YAAE,SAAS;QAC3C,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChE,CAAC;QACD,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,qEAAqE;IACrE,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,UAAU,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,UAAU,IAAI,MAAM,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,UAAU,GAAG,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,oBAAoB,CAC5B,UAAU,EACV,QAAQ,EACR,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAC/C,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,8EAA8E;IAC9E,6EAA6E;IAC7E,6CAA6C;IAC7C,MAAM,GAAG,GAAc,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAW,EAAE;QACtD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,6DAA6D;gBAC7D,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,gCAAgC,CAAC,CAAC;YAC1E,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;QACzC,CAAC;QACD,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,IAAc,EAAE,IAAI,CAAC,QAAQ,IAAI,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC;SAC9E,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,0FAA0F;AAC1F,SAAS,YAAY,CAAC,IAAY,EAAE,QAA4B;IAC9D,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,uEAAuE;QACvE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC;IACrD,CAAC;IACD,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,SAAiB,EAAE,UAAkB;IACzD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,gBAAgB,CAAC,UAAU,EAAE,aAAa,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC,CAAC;IACxF,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,sBAAsB,CAAC,IAAY;IAC1C,IAAI,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,QAA4B,EAAE,IAAY;IAC1E,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,gBAAgB,CAAC,IAAI,EAAE,aAAa,CAAC,KAAK,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAClF,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,QAAgB;IACrD,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC;IACjD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,77 @@
1
+ import { type RequestListener } from "node:http";
2
+ import type { Readable, Writable } from "node:stream";
3
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { type OidcVerifier } from "./auth/oidc/verifier.js";
5
+ export type TransportKind = "stdio" | "http";
6
+ export declare function isLoopbackHost(host: string): boolean;
7
+ export declare function normalizeListenHost(host: string): string;
8
+ export declare function formatHttpEndpoint(host: string, port: number): string;
9
+ /** Register session-scoped resources that must close with their MCP server. */
10
+ export declare function registerServerDisposer(server: McpServer, disposer: () => void | Promise<void>): void;
11
+ /** Return the transport selected for a started server, if startup has begun. */
12
+ export declare function getServerTransportKind(server: McpServer): TransportKind | undefined;
13
+ /**
14
+ * Resolve which transport to use (RFC §5.2 transport multiplexer):
15
+ * 1. explicit `kind` argument (from the --transport CLI flag), else
16
+ * 2. MCP_TRANSPORT env var, else
17
+ * 3. auto-detect: a TTY on stdin means a human launched us → HTTP;
18
+ * otherwise a harness is piping JSON-RPC over stdio → stdio.
19
+ */
20
+ export declare function resolveTransport(kind?: string): TransportKind;
21
+ /**
22
+ * Resolve whether preview URLs are reachable from the MCP client. HTTP is
23
+ * conservative by default because a loopback bind can still sit behind a
24
+ * reverse proxy or tunnel; same-machine HTTP deployments must opt into local
25
+ * URLs explicitly.
26
+ */
27
+ export declare function resolvePreviewLocality(transportKind: TransportKind, locality?: string, env?: NodeJS.ProcessEnv): "local" | "remote";
28
+ export interface StreamableHttpHandlerOptions {
29
+ sessionIdleTimeoutMs?: number;
30
+ /**
31
+ * Enables static `Authorization: Bearer genie_<token>` authentication
32
+ * (M5-02, DRO-274). When it is the only configured credential source, every
33
+ * `/mcp` request must use one; when OAuth or OIDC is also configured, any
34
+ * one enabled source may authenticate the request. `/health` is exempt.
35
+ */
36
+ requireBearerAuth?: boolean;
37
+ /**
38
+ * Public issuer URL for OAuth (DRO-273 / M5-01), e.g. `http://127.0.0.1:3000`.
39
+ * When set and `OAUTH_HS256_KEY` is a valid signing key, the OAuth 2.0 +
40
+ * DCR endpoints (`/.well-known/oauth-authorization-server`, `/register`,
41
+ * `/authorize`, `/token`) are mounted on this HTTP server. OAuth is
42
+ * opt-in: omit `oauthIssuer`, or leave `OAUTH_HS256_KEY` unset, to run
43
+ * without it.
44
+ */
45
+ oauthIssuer?: string;
46
+ /**
47
+ * Pre-built OIDC relying-party verifier (M5-04, DRO-276). When supplied,
48
+ * a bearer token issued by the configured EXTERNAL OIDC provider and
49
+ * asserting membership in the required group can authenticate `/mcp` (see
50
+ * `auth/oidc/verifier.ts`). Independent of the other credential sources: a
51
+ * deployment can enable any combination, and acceptance by any one source
52
+ * authorizes the request. A token invalid for all sources gets 401; a
53
+ * valid OIDC token missing the required group gets 403 (AC6).
54
+ */
55
+ oidcVerifier?: OidcVerifier;
56
+ }
57
+ /**
58
+ * Create the stateful Streamable HTTP request handler. Each initialized client
59
+ * receives its own MCP server + transport, keyed by Mcp-Session-Id, so
60
+ * initialize-scoped capabilities never leak between clients.
61
+ */
62
+ export declare function createStreamableHttpRequestHandler(serverFactory: () => McpServer, options?: StreamableHttpHandlerOptions): RequestListener;
63
+ export interface StartOptions {
64
+ kind?: string;
65
+ port?: number;
66
+ host?: string;
67
+ /** Required for HTTP; must include every caller-added registration per session. */
68
+ serverFactory?: () => McpServer;
69
+ /** Injectable stdio streams for embedders and EOF lifecycle tests. */
70
+ stdioInput?: Readable;
71
+ stdioOutput?: Writable;
72
+ /** HTTP only — enable static `Authorization: Bearer` tokens (M5-02, DRO-274). */
73
+ requireBearerAuth?: boolean;
74
+ }
75
+ /** Start the server on the resolved transport. Returns the kind actually used. */
76
+ export declare function startTransport(server: McpServer, opts?: StartOptions): Promise<TransportKind>;
77
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGnF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,CAAC;AAE7C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAepD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrE;AAMD,+EAA+E;AAC/E,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACnC,IAAI,CAeN;AASD,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,SAAS,CAEnF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAO7D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,aAAa,EAC5B,QAAQ,CAAC,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,GAAG,QAAQ,CAOpB;AAmDD,MAAM,WAAW,4BAA4B;IAC3C,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAkCD;;;;GAIG;AACH,wBAAgB,kCAAkC,CAChD,aAAa,EAAE,MAAM,SAAS,EAC9B,OAAO,GAAE,4BAAiC,GACzC,eAAe,CAsQjB;AA+CD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,SAAS,CAAC;IAChC,sEAAsE;IACtE,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,kFAAkF;AAClF,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,aAAa,CAAC,CAmBxB"}