@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,501 @@
1
+ import { createTwoFilesPatch } from "diff";
2
+ import { z } from "zod";
3
+ import {} from "../llm/schema.js";
4
+ import { REFINE_COMPONENT_SYSTEM_PROMPT_FILE, loadPrompt, } from "../llm/prompts.js";
5
+ // The shared request/validate/retry harness (M2-03/M2-04) — the same Ajv
6
+ // validate, response_format envelope, retry-feedback wording, and two-attempt
7
+ // loop `conjure` uses (AC6).
8
+ import { appendRetryFeedback, logStderr, runComponentGeneration, } from "../llm/component-response.js";
9
+ // Value import (not type-only): `retry.ts` has no import-time side effects —
10
+ // unlike `client.ts`, it never touches `GENIE_LLM_*` env or constructs
11
+ // anything eagerly at module load — so wrapping `defaultChatCompletion`
12
+ // below in `withRetry` is safe to do statically (same reasoning as
13
+ // `conjure.ts`; DRO-253 / DRO-618: `refine` shares the exact same gap
14
+ // conjure had — `withRetry` existed but no production call site applied it).
15
+ import { withRetry } from "../llm/retry.js";
16
+ import { normalizeGeneratedFiles, validateGeneratedBinaryContent, } from "../llm/generated-files.js";
17
+ import { KIT_ID_PATTERN } from "./get_kit.js";
18
+ export const REFINE_TOOL_NAME = "mcp__genie__refine";
19
+ /** Default model routing alias — the same one `conjure` uses (M2-05). Resolved
20
+ * to a concrete provider model by the configured endpoint/gateway. Defined
21
+ * locally to keep `refine` decoupled from `conjure`'s module. */
22
+ export const DEFAULT_MODEL = "design-default";
23
+ /** PascalCase component-name shape — identical to `COMPONENT_SCHEMA`'s
24
+ * `componentName` pattern, so an id `refine` accepts is one `conjure` could have
25
+ * produced. */
26
+ export const COMPONENT_NAME_PATTERN = /^[A-Z][A-Za-z0-9]{1,63}$/;
27
+ /** Directory prefix every kit component's files live under. */
28
+ const COMPONENTS_ROOT = "components";
29
+ // ── Input schema (AC2) ────────────────────────────────────────────────────────
30
+ //
31
+ // { kitId, componentName, instruction, region?: { x, y, w, h }, model? }
32
+ // (research §3.1). `region` bounds mirror COMPONENT_SCHEMA's viewport limits
33
+ // (≤4096) so a canvas selection can't request an absurd crop; `w`/`h` are ≥1
34
+ // (a zero-area rect is not a selection). `model` defaults like `conjure`.
35
+ const regionSchema = z
36
+ .object({
37
+ x: z.number().int().min(0).max(4096),
38
+ y: z.number().int().min(0).max(4096),
39
+ w: z.number().int().min(1).max(4096),
40
+ h: z.number().int().min(1).max(4096),
41
+ })
42
+ .strict();
43
+ const refineInputShape = {
44
+ kitId: z
45
+ .string()
46
+ .regex(KIT_ID_PATTERN, "kitId must be a 3-64 character slug of lowercase letters, numbers, and hyphens."),
47
+ componentName: z
48
+ .string()
49
+ .regex(COMPONENT_NAME_PATTERN, "componentName must be PascalCase, 2-64 chars (e.g. Button)."),
50
+ instruction: z.string().min(1).max(8192),
51
+ region: regionSchema.optional(),
52
+ model: z.string().min(1).max(128).default(DEFAULT_MODEL),
53
+ };
54
+ const refineArgsSchema = z.object(refineInputShape).strict();
55
+ /** Typed failure surfaced to the tool boundary (mapped to an MCP error result).
56
+ * `ERR_COMPONENT_NOT_FOUND` — no files for `componentName` in the kit (or the
57
+ * kit itself is absent); `ERR_LLM_OUTPUT_INVALID` — the model did not return a
58
+ * schema-valid component after the retry (same code `conjure` throws). */
59
+ export class RefineError extends Error {
60
+ code;
61
+ details;
62
+ constructor(code, message, details) {
63
+ super(message);
64
+ this.code = code;
65
+ this.details = details;
66
+ this.name = "RefineError";
67
+ }
68
+ }
69
+ // ── Default (production) chat impl: lazy client import (same as conjure) ───────
70
+ /**
71
+ * Default `chat` seam: dynamically imports the M2-01 client on first call, so
72
+ * building the server never eagerly triggers `MissingLLMConfigError` (see module
73
+ * header). A real `refine` call in a properly-configured deployment resolves
74
+ * this to `withRetry(createChatCompletion)` (M2-06, DRO-253) — every
75
+ * production LLM call this tool makes is retry/backoff-wrapped by default,
76
+ * same as `conjure`; callers (and tests, via `deps.chat`) never need to
77
+ * remember to apply the wrapper themselves.
78
+ *
79
+ * `withRetry` is called fresh on every invocation rather than wrapped once at
80
+ * module scope: the module-scope `createChatCompletion` binding doesn't exist
81
+ * until the dynamic import resolves, and re-wrapping a plain async function
82
+ * is cheap (no state beyond reading `GENIE_LLM_RETRY_MAX` from `process.env`
83
+ * per call, matching `conjure.ts`'s identical seam).
84
+ */
85
+ const defaultChatCompletion = async (input) => {
86
+ const { createChatCompletion } = await import("../llm/client.js");
87
+ return withRetry(createChatCompletion)(input);
88
+ };
89
+ /** Load Playwright at runtime, or `null` if it is not installed. The non-literal
90
+ * specifier keeps `tsc` from resolving the (non-dependency) module at build. */
91
+ async function importPlaywright() {
92
+ const specifier = "playwright";
93
+ try {
94
+ return (await import(specifier));
95
+ }
96
+ catch (error) {
97
+ logStderr({
98
+ event: "refine.region.unavailable",
99
+ reason: "playwright-not-installed",
100
+ error: String(error),
101
+ });
102
+ return null;
103
+ }
104
+ }
105
+ /**
106
+ * Default cropper (AC7): render the preview HTML in headless Chromium and
107
+ * screenshot the region rect, returning it as a PNG data URL for vision input.
108
+ * Degrades gracefully — if Playwright is absent, or launch/render/screenshot
109
+ * fails, it logs and returns `{ dataUrl: null }` so `refine` continues without
110
+ * the image rather than failing the whole call over an optional enhancement.
111
+ */
112
+ export const defaultRegionCropper = {
113
+ async crop({ html, region, viewport }) {
114
+ const pw = await importPlaywright();
115
+ if (!pw)
116
+ return { dataUrl: null };
117
+ let browser;
118
+ try {
119
+ // `--no-sandbox` so it runs in restricted CI/container environments.
120
+ browser = await pw.chromium.launch({ args: ["--no-sandbox"] });
121
+ const page = await browser.newPage({ viewport });
122
+ // `load` (not `networkidle`): an embedded-CSP preview has no network to go
123
+ // idle on (`default-src 'none'`), so waiting for idle would just add the
124
+ // default timeout to every crop.
125
+ await page.setContent(html, { waitUntil: "load" });
126
+ const buf = await page.screenshot({
127
+ clip: { x: region.x, y: region.y, width: region.w, height: region.h },
128
+ });
129
+ return { dataUrl: `data:image/png;base64,${buf.toString("base64")}` };
130
+ }
131
+ catch (error) {
132
+ logStderr({ event: "refine.region.error", error: String(error) });
133
+ return { dataUrl: null };
134
+ }
135
+ finally {
136
+ if (browser)
137
+ await browser.close();
138
+ }
139
+ },
140
+ };
141
+ // ── File discovery (AC3) ──────────────────────────────────────────────────────
142
+ /**
143
+ * Split a kit-relative path into its `components/<group>/<Name>/…` parts, or
144
+ * `null` if it is not a component file. Used to find every file belonging to
145
+ * `componentName` and to read its group off the first match.
146
+ */
147
+ function parseComponentPath(path) {
148
+ const parts = path.split("/");
149
+ if (parts.length < 4 || parts[0] !== COMPONENTS_ROOT)
150
+ return null;
151
+ return { group: parts[1], name: parts[2], rest: parts.slice(3).join("/") };
152
+ }
153
+ /**
154
+ * Load every file of `componentName` from the kit (AC3): `listFiles` to discover
155
+ * the set, then `readFile` per file (one call each, as the AC specifies). The
156
+ * group is derived from the matched paths — a component's directory names it.
157
+ * Throws `RefineError("ERR_COMPONENT_NOT_FOUND")` when nothing matches (a missing
158
+ * kit surfaces the same way: no files, nothing to refine).
159
+ */
160
+ async function loadComponentFiles(kitStore, kitId, componentName) {
161
+ let entries;
162
+ try {
163
+ entries = await kitStore.listFiles(kitId);
164
+ }
165
+ catch (error) {
166
+ // A missing kit (NotFoundError) is just "nothing to refine" — one clear code.
167
+ throw new RefineError("ERR_COMPONENT_NOT_FOUND", `Could not load component "${componentName}" from kit "${kitId}": ${String(error?.message ?? error)}`, { kitId, componentName });
168
+ }
169
+ // Match files whose 3rd path segment is exactly the component name. Sort by
170
+ // path so group derivation and file order are deterministic.
171
+ const matches = entries
172
+ .map((e) => ({ path: e.path, parsed: parseComponentPath(e.path) }))
173
+ .filter((m) => m.parsed !== null && m.parsed.name === componentName)
174
+ .sort((a, b) => a.path.localeCompare(b.path));
175
+ if (matches.length === 0) {
176
+ throw new RefineError("ERR_COMPONENT_NOT_FOUND", `No component named "${componentName}" was found in kit "${kitId}". ` +
177
+ `Expected files under ${COMPONENTS_ROOT}/<group>/${componentName}/.`, { kitId, componentName });
178
+ }
179
+ // A component lives in ONE group; take it from the first match and keep only
180
+ // that group's files (guards the pathological case of two same-named dirs).
181
+ const group = matches[0].parsed.group;
182
+ const inGroup = matches.filter((m) => m.parsed.group === group);
183
+ const files = await Promise.all(inGroup.map(async ({ path }) => {
184
+ const read = await kitStore.readFile(kitId, path);
185
+ return { path, content: read.content, encoding: read.encoding, mimeType: read.mimeType };
186
+ }));
187
+ return { group, files };
188
+ }
189
+ // ── Preview + viewport helpers (AC4/AC7) ──────────────────────────────────────
190
+ /** The `<Name>.html` preview file among the loaded set, if present. */
191
+ function findPreview(files, componentName) {
192
+ const suffix = `/${componentName}/${componentName}.html`;
193
+ return files.find((f) => f.path.endsWith(suffix));
194
+ }
195
+ /**
196
+ * Choose a render viewport for the crop that (a) is at least the component's
197
+ * natural preview size (read from `meta.json`'s `viewport` when available, so the
198
+ * layout matches how the card really renders) and (b) is big enough to contain
199
+ * the requested region. Falls back to a sensible default when there is no
200
+ * parseable meta.
201
+ */
202
+ export function deriveRenderViewport(files, region) {
203
+ const DEFAULT = { width: 400, height: 300 };
204
+ const meta = files.find((f) => f.path.endsWith("/meta.json"));
205
+ let base = DEFAULT;
206
+ if (meta) {
207
+ try {
208
+ const parsed = JSON.parse(meta.content);
209
+ const w = parsed.viewport?.width;
210
+ const h = parsed.viewport?.height;
211
+ if (typeof w === "number" && typeof h === "number" && w > 0 && h > 0) {
212
+ base = { width: w, height: h };
213
+ }
214
+ }
215
+ catch {
216
+ // Non-JSON / unexpected meta → keep the default. Best-effort only.
217
+ }
218
+ }
219
+ return {
220
+ width: Math.max(base.width, region.x + region.w),
221
+ height: Math.max(base.height, region.y + region.h),
222
+ };
223
+ }
224
+ // ── Prompt / message assembly (AC4) ───────────────────────────────────────────
225
+ /** True for files we inline verbatim into the prompt. Binary (base64) files are
226
+ * summarized rather than dumped as base64 into the context. */
227
+ function isTextFile(file) {
228
+ return file.encoding !== "base64";
229
+ }
230
+ /** Build the natural-language user instruction block (everything except the
231
+ * optional vision crop image, attached separately). */
232
+ function buildUserText(args, group, files, cropAttached) {
233
+ const lines = [
234
+ "## Instruction",
235
+ args.instruction,
236
+ "",
237
+ "## Component",
238
+ `Name: ${args.componentName}`,
239
+ `Group: ${group}`,
240
+ ];
241
+ if (args.region) {
242
+ const { x, y, w, h } = args.region;
243
+ lines.push("", "## Region (canvas selection)", `The instruction targets this rectangle of the preview, in the preview's own ` +
244
+ `pixel coordinates: x=${x}, y=${y}, width=${w}, height=${h}.`);
245
+ lines.push(cropAttached
246
+ ? "A cropped screenshot of that region is attached as a reference image — " +
247
+ "focus your edit on the element(s) it shows and leave the rest unchanged."
248
+ : "(A rendered crop of that region could not be produced; identify which " +
249
+ "element sits at those coordinates from the preview markup below.)");
250
+ }
251
+ lines.push("", "## Current files", "Apply only the instruction. Return every file below (updated where the edit " +
252
+ "touches it, unchanged otherwise); do not rename the component or drop files.");
253
+ for (const file of files) {
254
+ lines.push("", `### File: ${file.path} (${file.mimeType})`);
255
+ lines.push(isTextFile(file) ? file.content : `[binary file, ${file.encoding} — omitted]`);
256
+ }
257
+ return lines.join("\n");
258
+ }
259
+ /**
260
+ * Assemble the messages for one attempt (AC4). System prompt is message 0; the
261
+ * user message carries the instruction + current files, and — when a region crop
262
+ * was produced — becomes a content-parts array with a vision `image_url` part
263
+ * (the same shape `conjure` uses for its reference image). `retry` appends the
264
+ * shared validation-feedback block on the single retry (AC6).
265
+ */
266
+ function buildMessages(systemPrompt, args, group, files, cropDataUrl, retry) {
267
+ let userText = buildUserText(args, group, files, cropDataUrl !== null);
268
+ if (retry)
269
+ userText = appendRetryFeedback(userText, retry);
270
+ const userContent = cropDataUrl
271
+ ? [
272
+ { type: "text", text: userText },
273
+ { type: "image_url", image_url: { url: cropDataUrl } },
274
+ ]
275
+ : userText;
276
+ return [
277
+ { role: "system", content: systemPrompt },
278
+ { role: "user", content: userContent },
279
+ ];
280
+ }
281
+ // ── Unified diff (AC5) ────────────────────────────────────────────────────────
282
+ /**
283
+ * Build a git-style unified diff from the original file set to the updated one,
284
+ * matched by path. Only CHANGED files contribute a hunk (unchanged files are
285
+ * omitted so the diff shows exactly what the refinement did); added/removed
286
+ * files diff against `/dev/null`. Informational only — `files` is authoritative.
287
+ */
288
+ export function buildUnifiedDiff(originals, updated) {
289
+ const paths = new Set([...originals.keys(), ...updated.keys()]);
290
+ const sorted = [...paths].sort((a, b) => a.localeCompare(b));
291
+ const parts = [];
292
+ for (const path of sorted) {
293
+ const before = originals.get(path) ?? "";
294
+ const after = updated.get(path) ?? "";
295
+ if (before === after)
296
+ continue;
297
+ parts.push(createTwoFilesPatch(originals.has(path) ? `a/${path}` : "/dev/null", updated.has(path) ? `b/${path}` : "/dev/null", before, after));
298
+ }
299
+ return parts.join("\n");
300
+ }
301
+ // ── Core ──────────────────────────────────────────────────────────────────────
302
+ /**
303
+ * Refine one existing component. Flow: load current files (AC3) → optionally
304
+ * render a region crop (AC4/AC7) → run the shared request/validate/retry loop
305
+ * with the diff-mode prompt (AC6) → compute the unified diff (AC5) → return
306
+ * `{ diff, files, … }` and log a per-call line (AC8).
307
+ */
308
+ export async function refine(deps, args) {
309
+ const parsed = refineArgsSchema.parse(args);
310
+ const chat = deps.chat ?? defaultChatCompletion;
311
+ const cropper = deps.cropper ?? defaultRegionCropper;
312
+ const systemPrompt = (deps.loadSystemPrompt ?? (() => loadPrompt(REFINE_COMPONENT_SYSTEM_PROMPT_FILE)))();
313
+ const startedAt = performance.now();
314
+ const hasRegion = parsed.region !== undefined;
315
+ // AC3 — load the component's current files from the kit.
316
+ const { group, files: originalFiles } = await loadComponentFiles(deps.kitStore, parsed.kitId, parsed.componentName);
317
+ const originalBinaryPaths = new Set(originalFiles.filter((file) => !isTextFile(file)).map((file) => file.path));
318
+ // AC4/AC7 — if a region was given, try to render a crop of it for vision input.
319
+ let cropDataUrl = null;
320
+ if (parsed.region) {
321
+ const preview = findPreview(originalFiles, parsed.componentName);
322
+ if (preview && isTextFile(preview)) {
323
+ const viewport = deriveRenderViewport(originalFiles, parsed.region);
324
+ const { dataUrl } = await cropper.crop({
325
+ html: preview.content,
326
+ region: parsed.region,
327
+ viewport,
328
+ });
329
+ cropDataUrl = dataUrl;
330
+ }
331
+ else {
332
+ // No preview to render — the coordinates still reach the prompt as text.
333
+ logStderr({
334
+ event: "refine.region.no_preview",
335
+ componentName: parsed.componentName,
336
+ kitId: parsed.kitId,
337
+ });
338
+ }
339
+ }
340
+ // AC6 — shared request/validate/retry-once loop (same as conjure).
341
+ const { outcome, usage, attempts } = await runComponentGeneration({
342
+ chat,
343
+ model: parsed.model,
344
+ validateGeneratedComponent: (component) => validateGeneratedBinaryContent(component, originalBinaryPaths),
345
+ buildMessages: (retry) => buildMessages(systemPrompt.text, parsed, group, originalFiles, cropDataUrl, retry),
346
+ });
347
+ const latencyMs = Math.round(performance.now() - startedAt);
348
+ if (!outcome.ok) {
349
+ logStderr({
350
+ event: "refine",
351
+ ok: false,
352
+ componentName: parsed.componentName,
353
+ hasRegion,
354
+ model: parsed.model,
355
+ promptTokens: usage.promptTokens,
356
+ completionTokens: usage.completionTokens,
357
+ latencyMs,
358
+ promptVersion: systemPrompt.version,
359
+ attempts,
360
+ });
361
+ throw new RefineError("ERR_LLM_OUTPUT_INVALID", `The model did not return a schema-valid component after ${attempts} attempt(s). ` +
362
+ `Last validation error:\n${outcome.reason}`, { attempts, reason: outcome.reason });
363
+ }
364
+ const component = outcome.component;
365
+ // Binary (base64) originals are never sent to the model (they can't be inlined
366
+ // as prompt text — see buildUserText), so the model cannot echo them back. If
367
+ // we returned `component.files` as-is, any binary asset in the component
368
+ // directory would be silently DROPPED from the returned set and the diff would
369
+ // misreport it as deleted (diffed against /dev/null) — a refine round-trip
370
+ // would lose it (Copilot review, PR #127). So carry every original binary file
371
+ // forward into the result, even if the model fabricates the same path. Because
372
+ // that file is byte-identical on both sides, `buildUnifiedDiff`'s
373
+ // `before === after` check omits it automatically.
374
+ //
375
+ // Deliberate consequence (Copilot review, PR #128): because omission of a
376
+ // binary can't be distinguished from "the model never saw it", this carry-
377
+ // forward means `refine` cannot DELETE a binary asset — omission always
378
+ // resurrects it. That is intentional for v1: `refine` is an *edit* verb whose
379
+ // prompt explicitly says "don't drop files", and the kit's own system prompt
380
+ // steers components toward inline SVG / `data:` URIs rather than binary assets
381
+ // in the first place. Removing a binary from a component is the job of the
382
+ // dedicated, plan-gated `delete_files` / `write_files` verbs, not a side effect
383
+ // of a natural-language refine instruction. If a future version needs
384
+ // refine-driven binary deletion, it would take an explicit keep/delete marker
385
+ // protocol (the model returns the path with a sentinel the tool resolves to the
386
+ // original bytes, and true omission then means delete) — out of scope here.
387
+ // A model-supplied entry for an ORIGINAL binary path cannot be trusted: the
388
+ // prompt exposed only a placeholder, never those bytes. Preserve the original
389
+ // until a future explicit binary replacement/delete protocol exists. New
390
+ // binary paths are still allowed when their returned content validates.
391
+ const returnedFiles = normalizeGeneratedFiles(component.files).filter((file) => !originalBinaryPaths.has(file.path));
392
+ const carriedBinaries = originalFiles
393
+ .filter((f) => !isTextFile(f))
394
+ .map((f) => ({
395
+ path: f.path,
396
+ content: f.content,
397
+ mimeType: f.mimeType,
398
+ encoding: "base64",
399
+ }));
400
+ const files = [...returnedFiles, ...carriedBinaries];
401
+ // AC5 — unified diff (informational) from originals → updated, by path. Built
402
+ // from the merged `files` so carried-forward binaries (identical on both sides)
403
+ // are excluded, while genuine text edits still surface.
404
+ const originalsByPath = new Map(originalFiles.map((f) => [f.path, f.content]));
405
+ const updatedByPath = new Map(files.map((f) => [f.path, f.content]));
406
+ const diff = buildUnifiedDiff(originalsByPath, updatedByPath);
407
+ // AC8 — per-call structured log.
408
+ logStderr({
409
+ event: "refine",
410
+ ok: true,
411
+ componentName: component.componentName,
412
+ hasRegion,
413
+ model: parsed.model,
414
+ promptTokens: usage.promptTokens,
415
+ completionTokens: usage.completionTokens,
416
+ latencyMs,
417
+ promptVersion: systemPrompt.version,
418
+ attempts,
419
+ });
420
+ return {
421
+ componentName: component.componentName,
422
+ group: component.group,
423
+ diff,
424
+ files,
425
+ manifestEntry: component.manifestEntry,
426
+ usage,
427
+ };
428
+ }
429
+ // ── MCP registration ──────────────────────────────────────────────────────────
430
+ const refineOutputShape = {
431
+ componentName: z.string(),
432
+ group: z.string(),
433
+ diff: z.string(),
434
+ files: z.array(z
435
+ .object({
436
+ path: z.string(),
437
+ content: z.string(),
438
+ mimeType: z.string(),
439
+ encoding: z.enum(["utf-8", "base64"]),
440
+ })
441
+ .strict()),
442
+ manifestEntry: z
443
+ .object({
444
+ viewport: z.object({ width: z.number(), height: z.number() }).strict(),
445
+ subtitle: z.string().optional(),
446
+ tags: z.array(z.string()).optional(),
447
+ })
448
+ .strict(),
449
+ usage: z
450
+ .object({
451
+ promptTokens: z.number().int().min(0),
452
+ completionTokens: z.number().int().min(0),
453
+ totalTokens: z.number().int().min(0),
454
+ })
455
+ .strict(),
456
+ };
457
+ export function registerRefineTool(server, deps) {
458
+ server.registerTool(REFINE_TOOL_NAME, {
459
+ title: "Refine component",
460
+ description: "Iterate on an existing component in a UI kit. Takes a free-form instruction " +
461
+ '(e.g. "make the border radius softer") and an optional region { x, y, w, h } rect ' +
462
+ 'for a canvas-style "fix this element" edit, and returns a unified diff plus the full ' +
463
+ "updated files (the files are the source of truth; the diff is informational). Loads the " +
464
+ "component's current source from the kit, validates the model's reply against " +
465
+ "COMPONENT_SCHEMA (retried once on a validation failure), and — when a region is given — " +
466
+ "attaches a rendered crop of it as a visual reference. Reach for this to adjust a " +
467
+ "component already written to the kit (typically after conjure → write_files → preview); " +
468
+ "`design-default` is the valid gateway routing alias. Persist the returned files via " +
469
+ "plan, mapping each {path, content, mimeType, encoding} to write_files " +
470
+ "{path, data: content, mimeType, encoding}, before previewing.",
471
+ inputSchema: refineInputShape,
472
+ outputSchema: refineOutputShape,
473
+ }, async (args) => {
474
+ try {
475
+ const result = await refine(deps, args);
476
+ return {
477
+ content: [{ type: "text", text: JSON.stringify(result) }],
478
+ structuredContent: result,
479
+ };
480
+ }
481
+ catch (error) {
482
+ if (error instanceof RefineError) {
483
+ return {
484
+ isError: true,
485
+ content: [
486
+ {
487
+ type: "text",
488
+ text: JSON.stringify({
489
+ code: error.code,
490
+ message: error.message,
491
+ ...(error.details ? { details: error.details } : {}),
492
+ }),
493
+ },
494
+ ],
495
+ };
496
+ }
497
+ throw error;
498
+ }
499
+ });
500
+ }
501
+ //# sourceMappingURL=refine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refine.js","sourceRoot":"","sources":["../../src/tools/refine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { z } from "zod";
2
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { Registry } from "prom-client";
4
+ import { type FullScanKitStore, type FullScanResult, type Renderer } from "../validate/index.js";
5
+ /** Input schema for validate (counter-persistence facet). */
6
+ declare const countsSchema: z.ZodObject<{
7
+ total: z.ZodNumber;
8
+ bad: z.ZodNumber;
9
+ thin: z.ZodNumber;
10
+ variantsIdentical: z.ZodNumber;
11
+ iterations: z.ZodNumber;
12
+ }, z.core.$strip>;
13
+ type ValidateCounts = z.infer<typeof countsSchema>;
14
+ /**
15
+ * Prometheus metrics registry and counters.
16
+ * Exposed as a module singleton so M6-01 can register it with the HTTP endpoint.
17
+ */
18
+ export declare const metricsRegistry: Registry<"text/plain; version=0.0.4; charset=utf-8">;
19
+ /**
20
+ * Persist validation counts to a timestamped JSON report file.
21
+ *
22
+ * @param reportsDir - Directory where reports are stored (.genie/reports)
23
+ * @param kitId - Kit identifier
24
+ * @param counts - Validation counts to persist
25
+ * @returns The path to the created report file
26
+ */
27
+ export declare function persistReport(reportsDir: string, kitId: string, counts: ValidateCounts): Promise<string>;
28
+ /**
29
+ * Emit Prometheus metrics for the given validation counts.
30
+ *
31
+ * @param kitId - Kit identifier (used as metric label)
32
+ * @param counts - Validation counts to emit
33
+ */
34
+ export declare function emitMetrics(kitId: string, counts: ValidateCounts): void;
35
+ /**
36
+ * Derive the M1-12 counter shape from a full-scan result (AC8: the full-scan
37
+ * facet persists its run via the SAME `persistReport`/`emitMetrics` path as the
38
+ * counter facet). `iterations` is 1 — a single scan pass — and the four
39
+ * validation dimensions come straight off the scan. `bad` is the scan's own
40
+ * literal sum (`markerMissing + thin + variantsIdentical`).
41
+ */
42
+ export declare function countsFromScan(result: FullScanResult): ValidateCounts;
43
+ /** Options for {@link registerValidate}. */
44
+ export interface RegisterValidateOptions {
45
+ /** Where the counter facet + full-scan facet persist their JSON reports.
46
+ * Defaults to `GENIE_REPORTS_DIR` / `.genie/reports`. */
47
+ reportsDir?: string;
48
+ /**
49
+ * The kit read-port the full-scan facet walks (`listFiles`/`readFile`). When
50
+ * omitted, the full-scan facet is unavailable and a no-`counts` call returns a
51
+ * typed error — the counter-persistence facet still works standalone (so a
52
+ * deployment that only uses telemetry needs no store wired here). `server.ts`
53
+ * passes the shared `kitStore`.
54
+ */
55
+ kitStore?: FullScanKitStore;
56
+ /**
57
+ * Factory for the one headless renderer the full-scan facet reuses across a
58
+ * scan (AC7). Defaults to {@link createDefaultRenderer} (lazy Playwright,
59
+ * `null` when unavailable → the scan degrades to marker-only). Injectable so
60
+ * tests supply a stub and never launch a browser.
61
+ */
62
+ createRenderer?: () => Promise<Renderer | null>;
63
+ }
64
+ /**
65
+ * Register the `mcp__genie__validate` tool on the given MCP server (both
66
+ * facets — see the module header).
67
+ *
68
+ * Backward-compatible call shape: `registerValidate(server, reportsDir?)` still
69
+ * works (the M1-12 wiring), and `registerValidate(server, options)` opts into
70
+ * the full-scan facet by supplying a `kitStore`.
71
+ */
72
+ export declare function registerValidate(server: McpServer, reportsDirOrOptions?: string | RegisterValidateOptions): void;
73
+ export {};
74
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"AA8BA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACd,MAAM,sBAAsB,CAAC;AAE9B,6DAA6D;AAC7D,QAAA,MAAM,YAAY;;;;;;iBAMhB,CAAC;AAuBH,KAAK,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,eAAe,sDAAiB,CAAC;AAqC9C;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAMvE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAQrE;AAED,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC;6DACyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;CACjD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,mBAAmB,CAAC,EAAE,MAAM,GAAG,uBAAuB,GACrD,IAAI,CAuFN"}