claude-exode-mcp 7.5.7 → 7.5.8

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 (173) hide show
  1. package/MCP_DOCUMENTATION.md +1 -0
  2. package/SKILL.md +10 -0
  3. package/examples/aurum-product-page.exode +3208 -0
  4. package/examples/bell-ring-icon.exode +1 -0
  5. package/examples/drift-kinetic-type.exode +770 -0
  6. package/examples/earbuds-product.exode +214 -0
  7. package/examples/energy-flow.exode +1736 -0
  8. package/examples/flux-hero.exode +223 -0
  9. package/examples/gooey-toggle.exode +214 -0
  10. package/examples/gravity-well.exode +3113 -0
  11. package/examples/heart-icon.exode +1 -0
  12. package/examples/hologram-temple.exode +8100 -0
  13. package/examples/jarful-app.exode +1 -0
  14. package/examples/kip-character-rig.exode +1 -0
  15. package/examples/low-tide-tilt.exode +2216 -0
  16. package/examples/manifest.json +352 -0
  17. package/examples/swipe-stack-carousel.exode +4048 -0
  18. package/examples/tokyo-neon-weather.exode +470 -0
  19. package/examples/typographic-collapse.exode +1578 -0
  20. package/examples/void-product-ad.exode +1269 -0
  21. package/examples/wire-globe-card.exode +580 -0
  22. package/index.d.ts +41 -1
  23. package/index.js +2553 -2407
  24. package/package.json +4 -2
  25. package/render-runtime/exode-runtime.js +20 -20
  26. package/skills/creative-motion/SKILL.md +10 -0
  27. package/skills/creative-motion/recipes/character-rig.js +104 -0
  28. package/skills/creative-motion/recipes/dashboard.js +120 -0
  29. package/skills/creative-motion/recipes/game-arcade.js +203 -0
  30. package/skills/creative-motion/recipes/hero-physics.js +65 -0
  31. package/skills/creative-motion/recipes/pricing.js +88 -0
  32. package/skills/creative-motion/recipes/title-sequence.js +62 -0
  33. package/skills/creative-motion/references/apps.md +37 -0
  34. package/skills/creative-motion/references/gotchas.md +80 -0
  35. package/skills/creative-motion/references/native-layers.md +60 -0
  36. package/skills/creative-motion/references/quality.md +54 -0
  37. package/src/__tests__/buildKit.test.ts +127 -0
  38. package/src/__tests__/effectKnobs.test.ts +162 -0
  39. package/src/__tests__/nativeLayers.test.ts +178 -0
  40. package/src/buildKit.d.ts +301 -0
  41. package/src/buildKit.d.ts.map +1 -0
  42. package/src/buildKit.js +559 -0
  43. package/src/buildKit.js.map +1 -0
  44. package/src/buildKit.ts +520 -0
  45. package/src/compiler.d.ts +4 -0
  46. package/src/compiler.d.ts.map +1 -1
  47. package/src/compiler.js +21 -45
  48. package/src/compiler.js.map +1 -1
  49. package/src/compiler.ts +22 -51
  50. package/src/critique.d.ts +8 -0
  51. package/src/critique.d.ts.map +1 -0
  52. package/src/critique.js +348 -0
  53. package/src/critique.js.map +1 -0
  54. package/src/critique.ts +239 -0
  55. package/src/effectKnobs.d.ts +72 -0
  56. package/src/effectKnobs.d.ts.map +1 -0
  57. package/src/effectKnobs.js +541 -0
  58. package/src/effectKnobs.js.map +1 -0
  59. package/src/effectKnobs.ts +445 -0
  60. package/src/effectOptimizer.d.ts +18 -0
  61. package/src/effectOptimizer.d.ts.map +1 -0
  62. package/src/effectOptimizer.js +125 -0
  63. package/src/effectOptimizer.js.map +1 -0
  64. package/src/effectOptimizer.ts +104 -0
  65. package/src/engine/layout.js +1 -1
  66. package/src/engine/layout.js.map +1 -1
  67. package/src/engine/layout.ts +1 -1
  68. package/src/examples.d.ts +30 -0
  69. package/src/examples.d.ts.map +1 -0
  70. package/src/examples.js +168 -0
  71. package/src/examples.js.map +1 -0
  72. package/src/examples.ts +151 -0
  73. package/src/handlers/artboardHandlers.d.ts.map +1 -1
  74. package/src/handlers/artboardHandlers.js +45 -10
  75. package/src/handlers/artboardHandlers.js.map +1 -1
  76. package/src/handlers/artboardHandlers.ts +43 -12
  77. package/src/handlers/buildHandlers.d.ts +2 -0
  78. package/src/handlers/buildHandlers.d.ts.map +1 -0
  79. package/src/handlers/buildHandlers.js +86 -0
  80. package/src/handlers/buildHandlers.js.map +1 -0
  81. package/src/handlers/buildHandlers.ts +76 -0
  82. package/src/handlers/compilerHandlers.d.ts.map +1 -1
  83. package/src/handlers/compilerHandlers.js +32 -2
  84. package/src/handlers/compilerHandlers.js.map +1 -1
  85. package/src/handlers/compilerHandlers.ts +31 -2
  86. package/src/handlers/exampleHandlers.d.ts +2 -0
  87. package/src/handlers/exampleHandlers.d.ts.map +1 -0
  88. package/src/handlers/exampleHandlers.js +81 -0
  89. package/src/handlers/exampleHandlers.js.map +1 -0
  90. package/src/handlers/exampleHandlers.ts +76 -0
  91. package/src/handlers/renderHandlers.d.ts.map +1 -1
  92. package/src/handlers/renderHandlers.js +100 -2
  93. package/src/handlers/renderHandlers.js.map +1 -1
  94. package/src/handlers/renderHandlers.ts +90 -2
  95. package/src/handlers/scaffoldHandlers.d.ts.map +1 -1
  96. package/src/handlers/scaffoldHandlers.js +3 -0
  97. package/src/handlers/scaffoldHandlers.js.map +1 -1
  98. package/src/handlers/scaffoldHandlers.ts +2 -0
  99. package/src/handlers/widgetHandlers.js +1 -1
  100. package/src/handlers/widgetHandlers.js.map +1 -1
  101. package/src/handlers/widgetHandlers.ts +1 -1
  102. package/src/lottie/convert.d.ts +16 -0
  103. package/src/lottie/convert.d.ts.map +1 -0
  104. package/src/lottie/convert.js +1225 -0
  105. package/src/lottie/convert.js.map +1 -0
  106. package/src/lottie/convert.ts +1134 -0
  107. package/src/lottie/evaluate.d.ts +48 -0
  108. package/src/lottie/evaluate.d.ts.map +1 -0
  109. package/src/lottie/evaluate.js +174 -0
  110. package/src/lottie/evaluate.js.map +1 -0
  111. package/src/lottie/evaluate.ts +184 -0
  112. package/src/nativeLayers.d.ts +76 -0
  113. package/src/nativeLayers.d.ts.map +1 -0
  114. package/src/nativeLayers.js +404 -0
  115. package/src/nativeLayers.js.map +1 -0
  116. package/src/nativeLayers.ts +339 -0
  117. package/src/render/motionBrief.d.ts.map +1 -1
  118. package/src/render/motionBrief.js +4 -0
  119. package/src/render/motionBrief.js.map +1 -1
  120. package/src/render/motionBrief.ts +4 -0
  121. package/src/render/videoRenderer.d.ts.map +1 -1
  122. package/src/render/videoRenderer.js +5 -2
  123. package/src/render/videoRenderer.js.map +1 -1
  124. package/src/render/videoRenderer.ts +5 -2
  125. package/src/rive/convert.d.ts +17 -0
  126. package/src/rive/convert.d.ts.map +1 -0
  127. package/src/rive/convert.js +1779 -0
  128. package/src/rive/convert.js.map +1 -0
  129. package/src/rive/convert.ts +1492 -0
  130. package/src/rive/font.d.ts +13 -0
  131. package/src/rive/font.d.ts.map +1 -0
  132. package/src/rive/font.js +154 -0
  133. package/src/rive/font.js.map +1 -0
  134. package/src/rive/font.ts +132 -0
  135. package/src/rive/layout.d.ts +20 -0
  136. package/src/rive/layout.d.ts.map +1 -0
  137. package/src/rive/layout.js +145 -0
  138. package/src/rive/layout.js.map +1 -0
  139. package/src/rive/layout.ts +140 -0
  140. package/src/rive/reader.d.ts +32 -0
  141. package/src/rive/reader.d.ts.map +1 -0
  142. package/src/rive/reader.js +172 -0
  143. package/src/rive/reader.js.map +1 -0
  144. package/src/rive/reader.ts +160 -0
  145. package/src/rive/schema.generated.d.ts +9 -0
  146. package/src/rive/schema.generated.d.ts.map +1 -0
  147. package/src/rive/schema.generated.js +13 -0
  148. package/src/rive/schema.generated.js.map +1 -0
  149. package/src/rive/schema.generated.ts +13 -0
  150. package/src/schema.d.ts +5 -0
  151. package/src/schema.d.ts.map +1 -1
  152. package/src/schema.js +5 -0
  153. package/src/schema.js.map +1 -1
  154. package/src/schema.ts +6 -0
  155. package/src/serverInstructions.d.ts +2 -0
  156. package/src/serverInstructions.d.ts.map +1 -0
  157. package/src/serverInstructions.js +22 -0
  158. package/src/serverInstructions.js.map +1 -0
  159. package/src/serverInstructions.ts +21 -0
  160. package/src/sseServer.d.ts +2 -0
  161. package/src/sseServer.d.ts.map +1 -0
  162. package/src/sseServer.js +165 -0
  163. package/src/sseServer.js.map +1 -0
  164. package/src/sseServer.ts +189 -0
  165. package/src/utils.d.ts.map +1 -1
  166. package/src/utils.js +23 -1
  167. package/src/utils.js.map +1 -1
  168. package/src/utils.ts +13 -1
  169. package/src/widgets.d.ts +26 -0
  170. package/src/widgets.d.ts.map +1 -1
  171. package/src/widgets.js +89 -45
  172. package/src/widgets.js.map +1 -1
  173. package/src/widgets.ts +88 -45
@@ -3,8 +3,8 @@ import { enforceArtboardQuota, readArtboard, writeArtboard } from '../utils.js';
3
3
  import { resolve } from 'path';
4
4
  import { writeFileSync, readFileSync } from 'fs';
5
5
  import { reportError, WORKSPACE_ROOT, validateArgs } from '../utils.js';
6
- import { GenerateHeroArgsSchema, CssToExodeArgsSchema, LottieToExodeArgsSchema } from '../schema.js';
7
- import { compileHero, listPalettes, listLayouts, listPrograms, getStyleCatalog, compileCssToExode, compileLottieToExode } from '../compiler.js';
6
+ import { GenerateHeroArgsSchema, CssToExodeArgsSchema, LottieToExodeArgsSchema, RiveToExodeArgsSchema } from '../schema.js';
7
+ import { compileHero, listPalettes, listLayouts, listPrograms, getStyleCatalog, compileCssToExode, compileLottieToExode, compileRiveToExode } from '../compiler.js';
8
8
  import type { FramerHeroSpec } from '../compiler.js';
9
9
 
10
10
  export async function handleCompilerTool(name: string, args: any) {
@@ -161,6 +161,35 @@ export async function handleCompilerTool(name: string, args: any) {
161
161
  return reportError(`lottie_to_exode failed: ${e.message}`);
162
162
  }
163
163
  }
164
+ case 'rive_to_exode': {
165
+ try {
166
+ const v = validateArgs(RiveToExodeArgsSchema, args, name);
167
+ const bytes = new Uint8Array(readFileSync(resolve(WORKSPACE_ROOT, v.rivPath)));
168
+ const { artboard, validation } = compileRiveToExode(bytes, v.artboard);
169
+ const outPath = resolveSafePath(v.outputPath);
170
+ writeFileSync(outPath, JSON.stringify(artboard, null, 2));
171
+ return {
172
+ content: [
173
+ {
174
+ type: "text",
175
+ text: JSON.stringify({
176
+ success: true,
177
+ message: `Rive file converted to Exode artboard at ${v.outputPath}`,
178
+ artboard: artboard.name,
179
+ availableArtboards: artboard.source?.artboards,
180
+ objectCount: artboard.objects.length,
181
+ animationCount: artboard.animations.length,
182
+ stateMachineLayers: artboard.stateMachine.layers.length,
183
+ validationScore: validation.score,
184
+ warnings: validation.riveWarnings,
185
+ }, null, 2),
186
+ },
187
+ ],
188
+ };
189
+ } catch (e: any) {
190
+ return reportError(`rive_to_exode failed: ${e.message}`);
191
+ }
192
+ }
164
193
  case "import_css": {
165
194
  try {
166
195
  const { cssPath, cssContent, targetArtboardPath } = args;
@@ -0,0 +1,2 @@
1
+ export declare function handleExampleTool(name: string, args: any): Promise<any>;
2
+ //# sourceMappingURL=exampleHandlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exampleHandlers.d.ts","sourceRoot":"","sources":["exampleHandlers.ts"],"names":[],"mappings":"AAcA,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CA6D7E"}
@@ -0,0 +1,81 @@
1
+ // list_examples / get_example: the curated reference library (src/examples.ts).
2
+ import { copyFileSync, existsSync, mkdirSync, readFileSync } from 'fs';
3
+ import { dirname, join } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { resolveSafePath } from '../security.js';
6
+ import { reportError } from '../utils.js';
7
+ import { collectEffects, examplesDir, loadManifest, outlineExode, searchExamples } from '../examples.js';
8
+ import { readdirSync } from 'fs';
9
+ import { skillDir } from '../render/motionBrief.js';
10
+ const HERE = dirname(fileURLToPath(import.meta.url));
11
+ const FULL_LIMIT_KB = 400;
12
+ const EFFECT_LIMIT = 24000;
13
+ export async function handleExampleTool(name, args) {
14
+ if (name !== 'list_examples' && name !== 'get_example' && name !== 'get_recipe')
15
+ return null;
16
+ try {
17
+ if (name === 'get_recipe') {
18
+ const dir = join(skillDir(HERE), 'recipes');
19
+ const files = readdirSync(dir).filter((f) => f.endsWith('.js')).sort();
20
+ const describe = (f) => { const src = readFileSync(join(dir, f), 'utf8'); const m = src.match(/\/\*([\s\S]*?)\*\//); return { id: f.replace(/\.js$/, ''), src, about: (m?.[1] || '').replace(/^\s*RECIPE:\s*\S+\s*/, '').replace(/\s+/g, ' ').trim() }; };
21
+ const all = files.map(describe);
22
+ if (!args?.name)
23
+ return { content: [{ type: 'text', text: `Recipes (complete, tested build_from_script scripts; adapt the settings at the top, keep the structure):\n\n${all.map((r) => `• ${r.id}: ${r.about}`).join('\n\n')}\n\nget_recipe { name } returns the script.` }] };
24
+ const r = all.find((x) => x.id === args.name);
25
+ if (!r)
26
+ return reportError(`Unknown recipe "${args.name}". Recipes: ${all.map((x) => x.id).join(', ')}`);
27
+ return { content: [{ type: 'text', text: `${r.src}\n\n/* NEXT: change the settings at the top (brand, copy, palette, items) to fit the brief; keep the layout maths, beats and helpers. Run it with build_from_script, fix what the design check flags, look at the sheet, rerun. */` }] };
28
+ }
29
+ const dir = examplesDir(HERE);
30
+ const all = loadManifest(dir);
31
+ if (name === 'list_examples') {
32
+ const list = searchExamples(all, { kind: args?.kind, query: args?.query });
33
+ const kinds = [...new Set(all.map((e) => e.kind))].join(', ');
34
+ if (!list.length)
35
+ return { content: [{ type: 'text', text: `No example matches. Kinds: ${kinds}. Call list_examples with no arguments to see all ${all.length}.` }] };
36
+ const lines = list.map((e) => `• ${e.id} [${e.kind}] ${e.title} (${e.width}×${e.height}, ${e.background}, ${e.sizeKB} KB)\n tags: ${e.tags.join(', ')}\n study: ${e.study}`);
37
+ return { content: [{ type: 'text', text: `${list.length} of ${all.length} reference pieces (kinds: ${kinds}).\n\n${lines.join('\n\n')}\n\nNext: get_example { id, mode: "outline" } for the 1–2 closest. Copy their structure and craft, never their subject, palette or layout.` }] };
38
+ }
39
+ const ex = all.find((e) => e.id === args?.id);
40
+ if (!ex)
41
+ return reportError(`Unknown example "${args?.id}". Ids: ${all.map((e) => e.id).join(', ')}`);
42
+ const file = join(dir, ex.file);
43
+ const raw = readFileSync(file, 'utf8');
44
+ const doc = JSON.parse(raw);
45
+ const mode = String(args?.mode || 'outline');
46
+ const head = `${ex.title} [${ex.kind}]\nWhy study it: ${ex.study}\n`;
47
+ if (mode === 'outline') {
48
+ return { content: [{ type: 'text', text: `${head}\n${outlineExode(doc, { maxObjects: args?.maxObjects })}` }] };
49
+ }
50
+ if (mode === 'effects') {
51
+ const fx = collectEffects(doc);
52
+ if (!fx.length)
53
+ return { content: [{ type: 'text', text: `${head}\nThis piece has no effect code: everything is native objects, keyframes and the state machine (see mode "outline").` }] };
54
+ const parts = fx.map((f, i) => {
55
+ const code = f.code.length > EFFECT_LIMIT ? `${f.code.slice(0, EFFECT_LIMIT)}\n/* … ${f.code.length - EFFECT_LIMIT} more chars; use mode "copy" and read the file for the rest */` : f.code;
56
+ return `── Effect ${i + 1}/${fx.length} on "${f.object}" (${f.name}, ${f.code.length} chars)\n${code}`;
57
+ });
58
+ return { content: [{ type: 'text', text: `${head}\n${parts.join('\n\n')}` }] };
59
+ }
60
+ if (mode === 'full') {
61
+ const kb = Math.round(raw.length / 1024);
62
+ if (kb > FULL_LIMIT_KB)
63
+ return reportError(`${ex.id} is ${kb} KB, too big to return inline. Use mode "outline"/"effects", or mode "copy" with destPath and read_artboard the copy.`);
64
+ return { content: [{ type: 'text', text: raw }] };
65
+ }
66
+ if (mode === 'copy') {
67
+ const dest = String(args?.destPath || `examples/${ex.file}`);
68
+ const full = resolveSafePath(dest);
69
+ if (existsSync(full) && !args?.overwrite)
70
+ return reportError(`${dest} already exists. Pass overwrite: true or another destPath.`);
71
+ mkdirSync(dirname(full), { recursive: true });
72
+ copyFileSync(file, full);
73
+ return { content: [{ type: 'text', text: `Copied ${ex.id} to ${dest}. Open it with read_artboard, preview it with preview_frames, or use it as a starting point (rename layers and replace the subject; don't ship it unchanged).` }] };
74
+ }
75
+ return reportError(`Unknown mode "${mode}". Modes: outline, effects, full, copy.`);
76
+ }
77
+ catch (e) {
78
+ return reportError(`${name} failed: ${e.message}`);
79
+ }
80
+ }
81
+ //# sourceMappingURL=exampleHandlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exampleHandlers.js","sourceRoot":"","sources":["exampleHandlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ // list_examples / get_example: the curated reference library (src/examples.ts).
2
+ import { copyFileSync, existsSync, mkdirSync, readFileSync } from 'fs';
3
+ import { dirname, join } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { resolveSafePath } from '../security.js';
6
+ import { reportError } from '../utils.js';
7
+ import { collectEffects, examplesDir, loadManifest, outlineExode, searchExamples } from '../examples.js';
8
+ import { readdirSync } from 'fs';
9
+ import { skillDir } from '../render/motionBrief.js';
10
+
11
+ const HERE = dirname(fileURLToPath(import.meta.url));
12
+ const FULL_LIMIT_KB = 400;
13
+ const EFFECT_LIMIT = 24000;
14
+
15
+ export async function handleExampleTool(name: string, args: any): Promise<any> {
16
+ if (name !== 'list_examples' && name !== 'get_example' && name !== 'get_recipe') return null;
17
+ try {
18
+ if (name === 'get_recipe') {
19
+ const dir = join(skillDir(HERE), 'recipes');
20
+ const files = readdirSync(dir).filter((f) => f.endsWith('.js')).sort();
21
+ const describe = (f: string) => { const src = readFileSync(join(dir, f), 'utf8'); const m = src.match(/\/\*([\s\S]*?)\*\//); return { id: f.replace(/\.js$/, ''), src, about: (m?.[1] || '').replace(/^\s*RECIPE:\s*\S+\s*/, '').replace(/\s+/g, ' ').trim() }; };
22
+ const all = files.map(describe);
23
+ if (!args?.name) return { content: [{ type: 'text', text: `Recipes (complete, tested build_from_script scripts; adapt the settings at the top, keep the structure):\n\n${all.map((r) => `• ${r.id}: ${r.about}`).join('\n\n')}\n\nget_recipe { name } returns the script.` }] };
24
+ const r = all.find((x) => x.id === args.name);
25
+ if (!r) return reportError(`Unknown recipe "${args.name}". Recipes: ${all.map((x) => x.id).join(', ')}`);
26
+ return { content: [{ type: 'text', text: `${r.src}\n\n/* NEXT: change the settings at the top (brand, copy, palette, items) to fit the brief; keep the layout maths, beats and helpers. Run it with build_from_script, fix what the design check flags, look at the sheet, rerun. */` }] };
27
+ }
28
+ const dir = examplesDir(HERE);
29
+ const all = loadManifest(dir);
30
+
31
+ if (name === 'list_examples') {
32
+ const list = searchExamples(all, { kind: args?.kind, query: args?.query });
33
+ const kinds = [...new Set(all.map((e) => e.kind))].join(', ');
34
+ if (!list.length) return { content: [{ type: 'text', text: `No example matches. Kinds: ${kinds}. Call list_examples with no arguments to see all ${all.length}.` }] };
35
+ const lines = list.map((e) => `• ${e.id} [${e.kind}] ${e.title} (${e.width}×${e.height}, ${e.background}, ${e.sizeKB} KB)\n tags: ${e.tags.join(', ')}\n study: ${e.study}`);
36
+ return { content: [{ type: 'text', text: `${list.length} of ${all.length} reference pieces (kinds: ${kinds}).\n\n${lines.join('\n\n')}\n\nNext: get_example { id, mode: "outline" } for the 1–2 closest. Copy their structure and craft, never their subject, palette or layout.` }] };
37
+ }
38
+
39
+ const ex = all.find((e) => e.id === args?.id);
40
+ if (!ex) return reportError(`Unknown example "${args?.id}". Ids: ${all.map((e) => e.id).join(', ')}`);
41
+ const file = join(dir, ex.file);
42
+ const raw = readFileSync(file, 'utf8');
43
+ const doc = JSON.parse(raw);
44
+ const mode = String(args?.mode || 'outline');
45
+ const head = `${ex.title} [${ex.kind}]\nWhy study it: ${ex.study}\n`;
46
+
47
+ if (mode === 'outline') {
48
+ return { content: [{ type: 'text', text: `${head}\n${outlineExode(doc, { maxObjects: args?.maxObjects })}` }] };
49
+ }
50
+ if (mode === 'effects') {
51
+ const fx = collectEffects(doc);
52
+ if (!fx.length) return { content: [{ type: 'text', text: `${head}\nThis piece has no effect code: everything is native objects, keyframes and the state machine (see mode "outline").` }] };
53
+ const parts = fx.map((f, i) => {
54
+ const code = f.code.length > EFFECT_LIMIT ? `${f.code.slice(0, EFFECT_LIMIT)}\n/* … ${f.code.length - EFFECT_LIMIT} more chars; use mode "copy" and read the file for the rest */` : f.code;
55
+ return `── Effect ${i + 1}/${fx.length} on "${f.object}" (${f.name}, ${f.code.length} chars)\n${code}`;
56
+ });
57
+ return { content: [{ type: 'text', text: `${head}\n${parts.join('\n\n')}` }] };
58
+ }
59
+ if (mode === 'full') {
60
+ const kb = Math.round(raw.length / 1024);
61
+ if (kb > FULL_LIMIT_KB) return reportError(`${ex.id} is ${kb} KB, too big to return inline. Use mode "outline"/"effects", or mode "copy" with destPath and read_artboard the copy.`);
62
+ return { content: [{ type: 'text', text: raw }] };
63
+ }
64
+ if (mode === 'copy') {
65
+ const dest = String(args?.destPath || `examples/${ex.file}`);
66
+ const full = resolveSafePath(dest);
67
+ if (existsSync(full) && !args?.overwrite) return reportError(`${dest} already exists. Pass overwrite: true or another destPath.`);
68
+ mkdirSync(dirname(full), { recursive: true });
69
+ copyFileSync(file, full);
70
+ return { content: [{ type: 'text', text: `Copied ${ex.id} to ${dest}. Open it with read_artboard, preview it with preview_frames, or use it as a starting point (rename layers and replace the subject; don't ship it unchanged).` }] };
71
+ }
72
+ return reportError(`Unknown mode "${mode}". Modes: outline, effects, full, copy.`);
73
+ } catch (e: any) {
74
+ return reportError(`${name} failed: ${e.message}`);
75
+ }
76
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"renderHandlers.d.ts","sourceRoot":"","sources":["renderHandlers.ts"],"names":[],"mappings":"AA6EA,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAsM5E"}
1
+ {"version":3,"file":"renderHandlers.d.ts","sourceRoot":"","sources":["renderHandlers.ts"],"names":[],"mappings":"AAgFA,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CA2R5E"}
@@ -10,6 +10,9 @@ import { readArtboard, reportError, writeArtboard, WORKSPACE_ROOT } from '../uti
10
10
  import { previewFrames, renderVideo, parsePointer } from '../render/videoRenderer.js';
11
11
  import { formatBrief, rollMotionBrief, skillDir, SKILL_TOPICS } from '../render/motionBrief.js';
12
12
  import { splitScreenPath } from '../screens.js';
13
+ import { optimizeEffectsInDoc } from '../effectOptimizer.js';
14
+ import { bakeNativeLayers, nativeLayerChecks, NATIVE_KIT_JS, refreshGroupMirrors, logicGroups, logicLayoutChecks } from '../nativeLayers.js';
15
+ import { tmpdir } from 'os';
13
16
  const HERE = dirname(fileURLToPath(import.meta.url));
14
17
  function sceneArgs(args) {
15
18
  const o = { input: resolveSafePath(args.path) };
@@ -153,12 +156,88 @@ export async function handleRenderTool(name, args) {
153
156
  return reportError(`export_webpage failed: ${e.message}`);
154
157
  }
155
158
  }
159
+ case 'bake_native_layers': {
160
+ try {
161
+ if (args.kit)
162
+ return { content: [{ type: 'text', text: `Paste this kit once into the effect code (all layers that share the script):\n\n${NATIVE_KIT_JS}` }] };
163
+ const artboard = readArtboard(String(args.path));
164
+ const reports = bakeNativeLayers(artboard, { effectIds: Array.isArray(args.effectIds) ? args.effectIds.map(String) : undefined });
165
+ if (!args.dryRun)
166
+ writeArtboard(String(args.path), artboard);
167
+ const lines = [`${args.dryRun ? 'Would bake' : 'Baked'} native layers in ${basename(String(args.path).split('#')[0])}:`];
168
+ for (const r of reports) {
169
+ lines.push(`- ${r.effect}: ${r.groups} groups, ${r.layers} Path layers, ${r.segments} segments (tight frames, placed just below the effect).`);
170
+ for (const w of r.warnings)
171
+ lines.push(` ! ${w}`);
172
+ }
173
+ for (const m of nativeLayerChecks(artboard))
174
+ lines.push(`! ${m}`);
175
+ lines.push('NATIVE_ORG (frame centres) was written into every effect that uses it, and the engineKey input added.', 'Next: preview_frames (with a pointer script for drags/clicks) to confirm motion and interaction match the effect, then lock background layers.', 'Re-run this tool whenever nativeBake() changes (new parts, renamed parts). It replaces the previous bake.');
176
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
177
+ }
178
+ catch (e) {
179
+ return reportError(`bake_native_layers failed: ${e.message}`);
180
+ }
181
+ }
182
+ case 'mirror_group_effects': {
183
+ try {
184
+ const artboard = readArtboard(String(args.path));
185
+ const wanted = Array.isArray(args.groups) && args.groups.length ? args.groups.map(String) : logicGroups(artboard).map((g) => g.id);
186
+ const changed = refreshGroupMirrors(artboard, wanted);
187
+ if (!args.dryRun)
188
+ writeArtboard(String(args.path), artboard);
189
+ const lines = [changed.length ? `${args.dryRun ? 'Would add or refresh' : 'Added or refreshed'} the group effect on: ${changed.join(', ')}.` : 'Group effects already match their pieces.',
190
+ 'Each is "<Group> effect (all N)": every piece\'s code in layer order under /* ═════ <layer> ═════ [layerId#index] */, disabled so it never runs twice.',
191
+ 'In the editor, selecting the group shows it in Effects Studio with each piece\'s snippet in the right-hand column; Update writes edits back to the pieces. Every MCP write keeps it in sync.'];
192
+ for (const m of logicLayoutChecks(artboard))
193
+ lines.push(`! ${m}`);
194
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
195
+ }
196
+ catch (e) {
197
+ return reportError(`mirror_group_effects failed: ${e.message}`);
198
+ }
199
+ }
200
+ case 'optimize_effects': {
201
+ try {
202
+ /* lossless: tree-shakes each CustomEffect against its own constants (var GAME = { part: ... }) */
203
+ const file = resolveSafePath(splitScreenPath(String(args.path)).file);
204
+ const doc = JSON.parse(readFileSync(file, 'utf8'));
205
+ const before = JSON.stringify(doc).length;
206
+ const st = optimizeEffectsInDoc(doc);
207
+ const after = JSON.stringify(doc).length;
208
+ if (!args.dryRun && st.changed)
209
+ writeFileSync(file, JSON.stringify(doc));
210
+ const lines = [
211
+ `${args.dryRun ? 'Would optimise' : 'Optimised'} ${st.changed}/${st.effects} CustomEffects in ${basename(file)}: effect code ${Math.round(st.before / 1024)} KB -> ${Math.round(st.after / 1024)} KB, file ${(before / 1048576).toFixed(2)} MB -> ${(after / 1048576).toFixed(2)} MB.`,
212
+ 'Lossless: only code a layer can never run is removed; names and formatting stay readable. Check with preview_frames.',
213
+ 'Tip: compare constant fields directly (if (GAME.part === "world")), not through a local copy, so more dead code folds away.',
214
+ ];
215
+ if (st.notes.length)
216
+ lines.push('Not changed:', ...st.notes.map((n) => `- ${n}`));
217
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
218
+ }
219
+ catch (e) {
220
+ return reportError(`optimize_effects failed: ${e.message}`);
221
+ }
222
+ }
156
223
  case 'build_bexode': {
157
224
  try {
158
225
  const src = resolveSafePath(splitScreenPath(String(args.path)).file);
159
226
  const out = resolveSafePath(args.outputPath || String(args.path).split('#')[0].replace(/\.exode$/i, '.bexode'));
160
227
  mkdirSync(dirname(out), { recursive: true });
161
- const r = spawnSync(exodeCli(), ['build', src, '-o', out, '-O', 'json', ...(args.strict ? ['--strict'] : [])], { encoding: 'utf8' });
228
+ /* lossless effect optimisation: each CustomEffect keeps only the code its layer can reach.
229
+ The source file is untouched; the compiler reads an optimised temporary copy. */
230
+ let buildSrc = src, fxNote = '';
231
+ if (args.optimize !== false && /\.exode$/i.test(src)) {
232
+ const doc = JSON.parse(readFileSync(src, 'utf8'));
233
+ const st = optimizeEffectsInDoc(doc);
234
+ if (st.changed) {
235
+ buildSrc = join(tmpdir(), `exode-opt-${Date.now().toString(36)}-${basename(src)}`);
236
+ writeFileSync(buildSrc, JSON.stringify(doc));
237
+ fxNote = `Effect code optimised (lossless): ${st.changed}/${st.effects} effects, ${Math.round(st.before / 1024)} KB -> ${Math.round(st.after / 1024)} KB.`;
238
+ }
239
+ }
240
+ const r = spawnSync(exodeCli(), ['build', buildSrc, '-o', out, '-O', 'json', ...(args.strict ? ['--strict'] : [])], { encoding: 'utf8' });
162
241
  const text = (r.stdout || '').trim() || (r.stderr || '').trim();
163
242
  if (r.error)
164
243
  return reportError(`build_bexode failed: ${r.error.message}`);
@@ -171,6 +250,8 @@ export async function handleRenderTool(name, args) {
171
250
  summary = { output: f.bexode || out, originalBytes: f.original_size, compiledBytes: f.compiled_size, reduction: `${f.reduction_percentage}%`, warnings: (f.warnings || []).slice(0, 10) };
172
251
  }
173
252
  catch { /* keep raw text */ }
253
+ if (fxNote && typeof summary === 'object')
254
+ summary.effects = fxNote;
174
255
  return { content: [{ type: 'text', text: typeof summary === 'string' ? summary : JSON.stringify(summary, null, 2) }] };
175
256
  }
176
257
  catch (e) {
@@ -259,7 +340,22 @@ export async function handleRenderTool(name, args) {
259
340
  obj.style = obj.style || {};
260
341
  const list = Array.isArray(obj.style.effects) ? obj.style.effects : [];
261
342
  const kept = args.replace ? list.filter((e) => e?.type !== 'CustomEffect') : list;
262
- kept.push({ id, type: 'CustomEffect', name: args.name || 'Custom Effect', isEnabled: true, params: args.params || {}, code });
343
+ /* Apps and games: a live update() loop stays a live effect (the editor would otherwise turn it into
344
+ hundreds of layers), and lots of drawn text belongs in native Text objects. */
345
+ const appNotes = [];
346
+ let fxCode = code;
347
+ if (/function\s+update\s*\(/.test(fxCode) && !fxCode.includes('EXODE_KEEP_LIVE')) {
348
+ fxCode = '/* EXODE_KEEP_LIVE: runs a live update() loop; keep it as an effect, not layers. */\n' + fxCode;
349
+ appNotes.push('Tagged EXODE_KEEP_LIVE: this code runs update(), so the editor keeps it as a live effect instead of converting it to layers.');
350
+ }
351
+ const textCalls = (fxCode.match(/fillText\s*\(/g) || []).length;
352
+ const strokeCalls = (fxCode.match(/\.lineTo\s*\(/g) || []).length;
353
+ if (strokeCalls >= 20 && !/function\s+nativeBake\s*\(/.test(fxCode))
354
+ appNotes.push('This code draws a lot of line work. If it is a structured scene (a model, building, machine or map), make its parts native layers: add nativeBake() with the native kit and call bake_native_layers, keeping only glow as effect (get_motion_skill { topic: \'native-layers\' }).');
355
+ if (textCalls >= 6)
356
+ appNotes.push(`The code draws ${textCalls} pieces of text. HUD, menu and button text should be native Text objects bound to inputs, so it shows in Layers and Logic (get_motion_skill { topic: 'apps' }).`);
357
+ globalThis.__fxNotes = appNotes;
358
+ kept.push({ id, type: 'CustomEffect', name: args.name || 'Custom Effect', isEnabled: true, params: args.params || {}, code: fxCode });
263
359
  obj.style.effects = kept;
264
360
  }
265
361
  else {
@@ -272,6 +368,8 @@ export async function handleRenderTool(name, args) {
272
368
  const lines = [`Added ${isEffect ? 'CustomEffect' : 'code animation'} ${id} to ${obj.id}.`];
273
369
  if (check.warnings.length)
274
370
  lines.push('Warnings:', ...check.warnings.map((w) => `- ${w}`));
371
+ if (isEffect && globalThis.__fxNotes?.length)
372
+ lines.push('Notes:', ...globalThis.__fxNotes.map((n) => `- ${n}`));
275
373
  lines.push('Check it with preview_frames: effects swallow their own errors, and the preview lists them.');
276
374
  return { content: [{ type: 'text', text: lines.join('\n') }] };
277
375
  }
@@ -1 +1 @@
1
- {"version":3,"file":"renderHandlers.js","sourceRoot":"","sources":["renderHandlers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderHandlers.js","sourceRoot":"","sources":["renderHandlers.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,9 @@ import { readArtboard, reportError, writeArtboard, WORKSPACE_ROOT } from '../uti
10
10
  import { previewFrames, renderVideo, parsePointer, type PointerScript, type SceneOptions, type VideoFormat } from '../render/videoRenderer.js';
11
11
  import { formatBrief, rollMotionBrief, skillDir, SKILL_TOPICS, type BriefAxis } from '../render/motionBrief.js';
12
12
  import { splitScreenPath } from '../screens.js';
13
+ import { optimizeEffectsInDoc } from '../effectOptimizer.js';
14
+ import { bakeNativeLayers, nativeLayerChecks, NATIVE_KIT_JS, refreshGroupMirrors, logicGroups, logicLayoutChecks } from '../nativeLayers.js';
15
+ import { tmpdir } from 'os';
13
16
 
14
17
  const HERE = dirname(fileURLToPath(import.meta.url));
15
18
 
@@ -134,12 +137,82 @@ export async function handleRenderTool(name: string, args: any): Promise<any> {
134
137
  }
135
138
  }
136
139
 
140
+ case 'bake_native_layers': {
141
+ try {
142
+ if (args.kit) return { content: [{ type: 'text', text: `Paste this kit once into the effect code (all layers that share the script):\n\n${NATIVE_KIT_JS}` }] };
143
+ const artboard: any = readArtboard(String(args.path));
144
+ const reports = bakeNativeLayers(artboard, { effectIds: Array.isArray(args.effectIds) ? args.effectIds.map(String) : undefined });
145
+ if (!args.dryRun) writeArtboard(String(args.path), artboard);
146
+ const lines = [`${args.dryRun ? 'Would bake' : 'Baked'} native layers in ${basename(String(args.path).split('#')[0]!)}:`];
147
+ for (const r of reports) {
148
+ lines.push(`- ${r.effect}: ${r.groups} groups, ${r.layers} Path layers, ${r.segments} segments (tight frames, placed just below the effect).`);
149
+ for (const w of r.warnings) lines.push(` ! ${w}`);
150
+ }
151
+ for (const m of nativeLayerChecks(artboard)) lines.push(`! ${m}`);
152
+ lines.push('NATIVE_ORG (frame centres) was written into every effect that uses it, and the engineKey input added.',
153
+ 'Next: preview_frames (with a pointer script for drags/clicks) to confirm motion and interaction match the effect, then lock background layers.',
154
+ 'Re-run this tool whenever nativeBake() changes (new parts, renamed parts). It replaces the previous bake.');
155
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
156
+ } catch (e: any) {
157
+ return reportError(`bake_native_layers failed: ${e.message}`);
158
+ }
159
+ }
160
+
161
+ case 'mirror_group_effects': {
162
+ try {
163
+ const artboard: any = readArtboard(String(args.path));
164
+ const wanted: string[] = Array.isArray(args.groups) && args.groups.length ? args.groups.map(String) : logicGroups(artboard).map((g: any) => g.id);
165
+ const changed = refreshGroupMirrors(artboard, wanted);
166
+ if (!args.dryRun) writeArtboard(String(args.path), artboard);
167
+ const lines = [changed.length ? `${args.dryRun ? 'Would add or refresh' : 'Added or refreshed'} the group effect on: ${changed.join(', ')}.` : 'Group effects already match their pieces.',
168
+ 'Each is "<Group> effect (all N)": every piece\'s code in layer order under /* ═════ <layer> ═════ [layerId#index] */, disabled so it never runs twice.',
169
+ 'In the editor, selecting the group shows it in Effects Studio with each piece\'s snippet in the right-hand column; Update writes edits back to the pieces. Every MCP write keeps it in sync.'];
170
+ for (const m of logicLayoutChecks(artboard)) lines.push(`! ${m}`);
171
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
172
+ } catch (e: any) {
173
+ return reportError(`mirror_group_effects failed: ${e.message}`);
174
+ }
175
+ }
176
+
177
+ case 'optimize_effects': {
178
+ try {
179
+ /* lossless: tree-shakes each CustomEffect against its own constants (var GAME = { part: ... }) */
180
+ const file = resolveSafePath(splitScreenPath(String(args.path)).file);
181
+ const doc: any = JSON.parse(readFileSync(file, 'utf8'));
182
+ const before = JSON.stringify(doc).length;
183
+ const st = optimizeEffectsInDoc(doc);
184
+ const after = JSON.stringify(doc).length;
185
+ if (!args.dryRun && st.changed) writeFileSync(file, JSON.stringify(doc));
186
+ const lines = [
187
+ `${args.dryRun ? 'Would optimise' : 'Optimised'} ${st.changed}/${st.effects} CustomEffects in ${basename(file)}: effect code ${Math.round(st.before / 1024)} KB -> ${Math.round(st.after / 1024)} KB, file ${(before / 1048576).toFixed(2)} MB -> ${(after / 1048576).toFixed(2)} MB.`,
188
+ 'Lossless: only code a layer can never run is removed; names and formatting stay readable. Check with preview_frames.',
189
+ 'Tip: compare constant fields directly (if (GAME.part === "world")), not through a local copy, so more dead code folds away.',
190
+ ];
191
+ if (st.notes.length) lines.push('Not changed:', ...st.notes.map((n: string) => `- ${n}`));
192
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
193
+ } catch (e: any) {
194
+ return reportError(`optimize_effects failed: ${e.message}`);
195
+ }
196
+ }
197
+
137
198
  case 'build_bexode': {
138
199
  try {
139
200
  const src = resolveSafePath(splitScreenPath(String(args.path)).file);
140
201
  const out = resolveSafePath(args.outputPath || String(args.path).split('#')[0]!.replace(/\.exode$/i, '.bexode'));
141
202
  mkdirSync(dirname(out), { recursive: true });
142
- const r = spawnSync(exodeCli(), ['build', src, '-o', out, '-O', 'json', ...(args.strict ? ['--strict'] : [])], { encoding: 'utf8' });
203
+ /* lossless effect optimisation: each CustomEffect keeps only the code its layer can reach.
204
+ The source file is untouched; the compiler reads an optimised temporary copy. */
205
+ let buildSrc = src, fxNote = '';
206
+ if (args.optimize !== false && /\.exode$/i.test(src)) {
207
+ const doc: any = JSON.parse(readFileSync(src, 'utf8'));
208
+ const st = optimizeEffectsInDoc(doc);
209
+ if (st.changed) {
210
+ buildSrc = join(tmpdir(), `exode-opt-${Date.now().toString(36)}-${basename(src)}`);
211
+ writeFileSync(buildSrc, JSON.stringify(doc));
212
+ fxNote = `Effect code optimised (lossless): ${st.changed}/${st.effects} effects, ${Math.round(st.before / 1024)} KB -> ${Math.round(st.after / 1024)} KB.`;
213
+ }
214
+ }
215
+ const r = spawnSync(exodeCli(), ['build', buildSrc, '-o', out, '-O', 'json', ...(args.strict ? ['--strict'] : [])], { encoding: 'utf8' });
143
216
  const text = (r.stdout || '').trim() || (r.stderr || '').trim();
144
217
  if (r.error) return reportError(`build_bexode failed: ${r.error.message}`);
145
218
  if (r.status !== 0) return reportError(`build_bexode failed: ${text.slice(0, 1500)}`);
@@ -148,6 +221,7 @@ export async function handleRenderTool(name: string, args: any): Promise<any> {
148
221
  const j = JSON.parse(text); const f = j.data?.files?.[0] || {};
149
222
  summary = { output: f.bexode || out, originalBytes: f.original_size, compiledBytes: f.compiled_size, reduction: `${f.reduction_percentage}%`, warnings: (f.warnings || []).slice(0, 10) };
150
223
  } catch { /* keep raw text */ }
224
+ if (fxNote && typeof summary === 'object') summary.effects = fxNote;
151
225
  return { content: [{ type: 'text', text: typeof summary === 'string' ? summary : JSON.stringify(summary, null, 2) }] };
152
226
  } catch (e: any) {
153
227
  return reportError(`build_bexode failed: ${e.message}`);
@@ -226,7 +300,20 @@ export async function handleRenderTool(name: string, args: any): Promise<any> {
226
300
  obj.style = obj.style || {};
227
301
  const list: any[] = Array.isArray(obj.style.effects) ? obj.style.effects : [];
228
302
  const kept = args.replace ? list.filter((e) => e?.type !== 'CustomEffect') : list;
229
- kept.push({ id, type: 'CustomEffect', name: args.name || 'Custom Effect', isEnabled: true, params: args.params || {}, code });
303
+ /* Apps and games: a live update() loop stays a live effect (the editor would otherwise turn it into
304
+ hundreds of layers), and lots of drawn text belongs in native Text objects. */
305
+ const appNotes: string[] = [];
306
+ let fxCode = code;
307
+ if (/function\s+update\s*\(/.test(fxCode) && !fxCode.includes('EXODE_KEEP_LIVE')) {
308
+ fxCode = '/* EXODE_KEEP_LIVE: runs a live update() loop; keep it as an effect, not layers. */\n' + fxCode;
309
+ appNotes.push('Tagged EXODE_KEEP_LIVE: this code runs update(), so the editor keeps it as a live effect instead of converting it to layers.');
310
+ }
311
+ const textCalls = (fxCode.match(/fillText\s*\(/g) || []).length;
312
+ const strokeCalls = (fxCode.match(/\.lineTo\s*\(/g) || []).length;
313
+ if (strokeCalls >= 20 && !/function\s+nativeBake\s*\(/.test(fxCode)) appNotes.push('This code draws a lot of line work. If it is a structured scene (a model, building, machine or map), make its parts native layers: add nativeBake() with the native kit and call bake_native_layers, keeping only glow as effect (get_motion_skill { topic: \'native-layers\' }).');
314
+ if (textCalls >= 6) appNotes.push(`The code draws ${textCalls} pieces of text. HUD, menu and button text should be native Text objects bound to inputs, so it shows in Layers and Logic (get_motion_skill { topic: 'apps' }).`);
315
+ (globalThis as any).__fxNotes = appNotes;
316
+ kept.push({ id, type: 'CustomEffect', name: args.name || 'Custom Effect', isEnabled: true, params: args.params || {}, code: fxCode });
230
317
  obj.style.effects = kept;
231
318
  } else {
232
319
  const list: any[] = Array.isArray(obj.codeAnimations) ? obj.codeAnimations : [];
@@ -237,6 +324,7 @@ export async function handleRenderTool(name: string, args: any): Promise<any> {
237
324
  writeArtboard(args.path, artboard);
238
325
  const lines = [`Added ${isEffect ? 'CustomEffect' : 'code animation'} ${id} to ${obj.id}.`];
239
326
  if (check.warnings.length) lines.push('Warnings:', ...check.warnings.map((w) => `- ${w}`));
327
+ if (isEffect && (globalThis as any).__fxNotes?.length) lines.push('Notes:', ...(globalThis as any).__fxNotes.map((n: string) => `- ${n}`));
240
328
  lines.push('Check it with preview_frames: effects swallow their own errors, and the preview lists them.');
241
329
  return { content: [{ type: 'text', text: lines.join('\n') }] };
242
330
  } catch (e: any) {
@@ -1 +1 @@
1
- {"version":3,"file":"scaffoldHandlers.d.ts","sourceRoot":"","sources":["scaffoldHandlers.ts"],"names":[],"mappings":"AAeA,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,oBA6a/D"}
1
+ {"version":3,"file":"scaffoldHandlers.d.ts","sourceRoot":"","sources":["scaffoldHandlers.ts"],"names":[],"mappings":"AAgBA,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,oBA8a/D"}