@vedangiitb/qwintly-core 1.3.22 → 1.3.24

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 (39) hide show
  1. package/dist/ai/prompts/codegen.prompt.d.ts.map +1 -1
  2. package/dist/ai/prompts/codegen.prompt.js +3 -1
  3. package/dist/ai/prompts/codegen.prompt.js.map +1 -1
  4. package/dist/ai/prompts/examples/codegen.examples.d.ts.map +1 -1
  5. package/dist/ai/prompts/examples/codegen.examples.js +16 -0
  6. package/dist/ai/prompts/examples/codegen.examples.js.map +1 -1
  7. package/dist/ai/prompts/planner.prompt.d.ts.map +1 -1
  8. package/dist/ai/prompts/planner.prompt.js +1 -0
  9. package/dist/ai/prompts/planner.prompt.js.map +1 -1
  10. package/dist/ai/prompts/validator.prompt.d.ts.map +1 -1
  11. package/dist/ai/prompts/validator.prompt.js +1 -0
  12. package/dist/ai/prompts/validator.prompt.js.map +1 -1
  13. package/dist/ai/toolLoop/toolLoopRunner.d.ts.map +1 -1
  14. package/dist/ai/toolLoop/toolLoopRunner.js +23 -1
  15. package/dist/ai/toolLoop/toolLoopRunner.js.map +1 -1
  16. package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts.map +1 -1
  17. package/dist/ai/toolLoop/toolLoopRunnerUtils.js +3 -4
  18. package/dist/ai/toolLoop/toolLoopRunnerUtils.js.map +1 -1
  19. package/dist/ai/tools/implementations/factories.d.ts +11 -3
  20. package/dist/ai/tools/implementations/factories.d.ts.map +1 -1
  21. package/dist/ai/tools/implementations/updateGlobalStyles.impl.d.ts +11 -6
  22. package/dist/ai/tools/implementations/updateGlobalStyles.impl.d.ts.map +1 -1
  23. package/dist/ai/tools/implementations/updateGlobalStyles.impl.js +8 -15
  24. package/dist/ai/tools/implementations/updateGlobalStyles.impl.js.map +1 -1
  25. package/dist/ai/tools/schemas/updateGlobalStyles.schema.d.ts +2 -6
  26. package/dist/ai/tools/schemas/updateGlobalStyles.schema.d.ts.map +1 -1
  27. package/dist/ai/tools/schemas/updateGlobalStyles.schema.js +9 -7
  28. package/dist/ai/tools/schemas/updateGlobalStyles.schema.js.map +1 -1
  29. package/dist/ai/tools/validators/updateGlobalStyles.zod.d.ts +5 -0
  30. package/dist/ai/tools/validators/updateGlobalStyles.zod.d.ts.map +1 -0
  31. package/dist/ai/tools/validators/updateGlobalStyles.zod.js +17 -0
  32. package/dist/ai/tools/validators/updateGlobalStyles.zod.js.map +1 -0
  33. package/dist/tests/toolLoopRunner.updateGlobalStylesEmptyArgs.test.d.ts +2 -0
  34. package/dist/tests/toolLoopRunner.updateGlobalStylesEmptyArgs.test.d.ts.map +1 -0
  35. package/dist/tests/toolLoopRunner.updateGlobalStylesEmptyArgs.test.js +42 -0
  36. package/dist/tests/toolLoopRunner.updateGlobalStylesEmptyArgs.test.js.map +1 -0
  37. package/dist/tests/updateGlobalStyles.impl.test.js +6 -6
  38. package/dist/tests/updateGlobalStyles.impl.test.js.map +1 -1
  39. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.prompt.d.ts","sourceRoot":"","sources":["../../../src/ai/prompts/codegen.prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAQvE,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,GAAG,CAAC;IACV,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,QAAQ,uBAAuB,WAyE5D,CAAC"}
1
+ {"version":3,"file":"codegen.prompt.d.ts","sourceRoot":"","sources":["../../../src/ai/prompts/codegen.prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAQvE,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,GAAG,CAAC;IACV,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,QAAQ,uBAAuB,WA2E5D,CAAC"}
@@ -35,7 +35,9 @@ export const codegenPrompt = (params) => {
35
35
  - image src auto-generated from alt
36
36
  - lucide-react icons only
37
37
  - Prefer semantic Tailwind tokens (bg-background, text-foreground, border-border, ring-ring, etc.) over hardcoded colors (e.g. slate-*, bg-white). If you need different global colors/radius, call update_global_styles first, then use token-based classes.
38
- - Never call update_global_styles with an empty tokens object. Include at least one token key/value you want to change.
38
+ - update_global_styles args MUST be a flat JSON object with token keys as optional params. Include at least 1 key.
39
+ - Never call update_global_styles with {} (empty object). If you don't need to change tokens, do not call this tool.
40
+ - Example: {"radius":"0.75rem","background":"oklch(0.98 0.01 80)"}.
39
41
  `.trim());
40
42
  const projectConfiguration = mdSection("Project Config", [
41
43
  jsonBlock("framework", codegenIndex.projectConfigs.frameworkConfig),
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.prompt.js","sourceRoot":"","sources":["../../../src/ai/prompts/codegen.prompt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,SAAS,EACT,SAAS,EACT,gBAAgB,GACjB,MAAM,iCAAiC,CAAC;AASzC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAA+B,EAAE,EAAE;IAC/D,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAEtE,MAAM,MAAM,GAAG;;;;;;;;;MASX,gBAAgB,CAAC,YAAY,EAAE,SAAS,CAAC;GAC5C,CAAC,IAAI,EAAE,CAAC;IAET,MAAM,QAAQ,GAAG,SAAS,CACxB,mBAAmB,EACnB,SAAS,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC,CAChC,CAAC;IAEF,MAAM,SAAS,GAAG,SAAS,CACzB,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;MAsBE,CAAC,IAAI,EAAE,CACT,CAAC;IAEH,MAAM,oBAAoB,GAAG,SAAS,CACpC,gBAAgB,EAChB;QACE,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC;QAEnE,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,aAAa,CAAC;QAE/D,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC;KACpE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,OAAO,GAAG,SAAS,CACvB,kBAAkB,EAClB,SAAS,CAAC,SAAS,EAAE,gBAAgB,IAAI,EAAE,CAAC,CAC7C,CAAC;IAEF,MAAM,QAAQ,GAAG;QACf,MAAM;QACN,QAAQ;QACR,SAAS;QACT,oBAAoB;QACpB,OAAO;QACP,eAAe;KAChB,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC,CAAC","sourcesContent":["import { CodegenIndex, CollectedContext } from \"../../types/public.js\";\r\nimport { codegenExamples } from \"./examples/codegen.examples.js\";\r\nimport {\r\n jsonBlock,\r\n mdSection,\r\n projectStateNote,\r\n} from \"./helpers/promptParts.helper.js\";\r\n\r\nexport type CodegenNodePromptParams = {\r\n task: any;\r\n codegenIndex: CodegenIndex;\r\n collectedContext: CollectedContext;\r\n isNewProject: boolean;\r\n};\r\n\r\nexport const codegenPrompt = (params: CodegenNodePromptParams) => {\r\n const { task, codegenIndex, collectedContext, isNewProject } = params;\r\n\r\n const system = `\r\n You are a senior software engineer implementing tasks in an existing codebase.\r\n\r\n Rules:\r\n - Implement ONLY the requested task.\r\n - Prefer incremental edits over rewrites.\r\n - Be concise and deterministic.\r\n - Do not output code directly; use tools.\r\n\r\n ${projectStateNote(isNewProject, \"codegen\")}\r\n `.trim();\r\n\r\n const taskInfo = mdSection(\r\n \"Task to implement\",\r\n jsonBlock(\"task\", task ?? null),\r\n );\r\n\r\n const toolsInfo = mdSection(\n \"Tools\",\n `\n Available tools:\n\n - read_file: Read file\n - update_global_styles: Update app/styleConfig.json global design tokens\n - list_dir: List directory\n - create_new_route: Create route with page.tsx + pageConfig.json\n - insert_element: Insert element tree\n - delete_element: Delete element\n - update_classname: Update className\n - update_props: Update props\n - submit_codegen_done: Finish task\n\n Rules:\n - One insert_element per tree (include children inline) unless depth blocks it.\n - Create missing routes with create_new_route.\n - For any tool arg named route, always use URL paths with forward slashes (e.g. '/', '/pricing'); never use '\\\\' or filesystem paths like 'app/pricing'.\n - insert_element supports optional before_id to insert before an existing sibling; if omitted or not found, it appends to the end.\n - image src auto-generated from alt\n - lucide-react icons only\n - Prefer semantic Tailwind tokens (bg-background, text-foreground, border-border, ring-ring, etc.) over hardcoded colors (e.g. slate-*, bg-white). If you need different global colors/radius, call update_global_styles first, then use token-based classes.\n - Never call update_global_styles with an empty tokens object. Include at least one token key/value you want to change.\n `.trim(),\n );\n\r\n const projectConfiguration = mdSection(\r\n \"Project Config\",\r\n [\r\n jsonBlock(\"framework\", codegenIndex.projectConfigs.frameworkConfig),\r\n\r\n jsonBlock(\"runtime\", codegenIndex.projectConfigs.runtimeConfig),\r\n\r\n jsonBlock(\"rendering\", codegenIndex.projectConfigs.renderingConfig),\r\n ].join(\"\\n\"),\r\n );\r\n\r\n const context = mdSection(\r\n \"Relevant Context\",\r\n jsonBlock(\"context\", collectedContext ?? {}),\r\n );\r\n\r\n const sections = [\r\n system,\r\n taskInfo,\r\n toolsInfo,\r\n projectConfiguration,\r\n context,\r\n codegenExamples,\r\n ];\r\n\r\n return sections.join(\"\\n\\n---\\n\\n\");\r\n};\r\n"]}
1
+ {"version":3,"file":"codegen.prompt.js","sourceRoot":"","sources":["../../../src/ai/prompts/codegen.prompt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,SAAS,EACT,SAAS,EACT,gBAAgB,GACjB,MAAM,iCAAiC,CAAC;AASzC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAA+B,EAAE,EAAE;IAC/D,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAEtE,MAAM,MAAM,GAAG;;;;;;;;;MASX,gBAAgB,CAAC,YAAY,EAAE,SAAS,CAAC;GAC5C,CAAC,IAAI,EAAE,CAAC;IAET,MAAM,QAAQ,GAAG,SAAS,CACxB,mBAAmB,EACnB,SAAS,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC,CAChC,CAAC;IAEF,MAAM,SAAS,GAAG,SAAS,CACzB,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;;;MAwBE,CAAC,IAAI,EAAE,CACT,CAAC;IAEH,MAAM,oBAAoB,GAAG,SAAS,CACpC,gBAAgB,EAChB;QACE,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC;QAEnE,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,aAAa,CAAC;QAE/D,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC;KACpE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,OAAO,GAAG,SAAS,CACvB,kBAAkB,EAClB,SAAS,CAAC,SAAS,EAAE,gBAAgB,IAAI,EAAE,CAAC,CAC7C,CAAC;IAEF,MAAM,QAAQ,GAAG;QACf,MAAM;QACN,QAAQ;QACR,SAAS;QACT,oBAAoB;QACpB,OAAO;QACP,eAAe;KAChB,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC,CAAC","sourcesContent":["import { CodegenIndex, CollectedContext } from \"../../types/public.js\";\r\nimport { codegenExamples } from \"./examples/codegen.examples.js\";\r\nimport {\r\n jsonBlock,\r\n mdSection,\r\n projectStateNote,\r\n} from \"./helpers/promptParts.helper.js\";\r\n\r\nexport type CodegenNodePromptParams = {\r\n task: any;\r\n codegenIndex: CodegenIndex;\r\n collectedContext: CollectedContext;\r\n isNewProject: boolean;\r\n};\r\n\r\nexport const codegenPrompt = (params: CodegenNodePromptParams) => {\r\n const { task, codegenIndex, collectedContext, isNewProject } = params;\r\n\r\n const system = `\r\n You are a senior software engineer implementing tasks in an existing codebase.\r\n\r\n Rules:\r\n - Implement ONLY the requested task.\r\n - Prefer incremental edits over rewrites.\r\n - Be concise and deterministic.\r\n - Do not output code directly; use tools.\r\n\r\n ${projectStateNote(isNewProject, \"codegen\")}\r\n `.trim();\r\n\r\n const taskInfo = mdSection(\r\n \"Task to implement\",\r\n jsonBlock(\"task\", task ?? null),\r\n );\r\n\r\n const toolsInfo = mdSection(\n \"Tools\",\n `\n Available tools:\n\n - read_file: Read file\n - update_global_styles: Update app/styleConfig.json global design tokens\n - list_dir: List directory\n - create_new_route: Create route with page.tsx + pageConfig.json\n - insert_element: Insert element tree\n - delete_element: Delete element\n - update_classname: Update className\n - update_props: Update props\n - submit_codegen_done: Finish task\n\n Rules:\n - One insert_element per tree (include children inline) unless depth blocks it.\n - Create missing routes with create_new_route.\n - For any tool arg named route, always use URL paths with forward slashes (e.g. '/', '/pricing'); never use '\\\\' or filesystem paths like 'app/pricing'.\n - insert_element supports optional before_id to insert before an existing sibling; if omitted or not found, it appends to the end.\n - image src auto-generated from alt\n - lucide-react icons only\n - Prefer semantic Tailwind tokens (bg-background, text-foreground, border-border, ring-ring, etc.) over hardcoded colors (e.g. slate-*, bg-white). If you need different global colors/radius, call update_global_styles first, then use token-based classes.\n - update_global_styles args MUST be a flat JSON object with token keys as optional params. Include at least 1 key.\n - Never call update_global_styles with {} (empty object). If you don't need to change tokens, do not call this tool.\n - Example: {\"radius\":\"0.75rem\",\"background\":\"oklch(0.98 0.01 80)\"}.\n `.trim(),\n );\n\r\n const projectConfiguration = mdSection(\r\n \"Project Config\",\r\n [\r\n jsonBlock(\"framework\", codegenIndex.projectConfigs.frameworkConfig),\r\n\r\n jsonBlock(\"runtime\", codegenIndex.projectConfigs.runtimeConfig),\r\n\r\n jsonBlock(\"rendering\", codegenIndex.projectConfigs.renderingConfig),\r\n ].join(\"\\n\"),\r\n );\r\n\r\n const context = mdSection(\r\n \"Relevant Context\",\r\n jsonBlock(\"context\", collectedContext ?? {}),\r\n );\r\n\r\n const sections = [\r\n system,\r\n taskInfo,\r\n toolsInfo,\r\n projectConfiguration,\r\n context,\r\n codegenExamples,\r\n ];\r\n\r\n return sections.join(\"\\n\\n---\\n\\n\");\r\n};\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.examples.d.ts","sourceRoot":"","sources":["../../../../src/ai/prompts/examples/codegen.examples.ts"],"names":[],"mappings":"AAqFA,eAAO,MAAM,eAAe,QAAsB,CAAC"}
1
+ {"version":3,"file":"codegen.examples.d.ts","sourceRoot":"","sources":["../../../../src/ai/prompts/examples/codegen.examples.ts"],"names":[],"mappings":"AAsGA,eAAO,MAAM,eAAe,QAAsB,CAAC"}
@@ -40,6 +40,22 @@ Tool call:
40
40
  - Use \`children\` to nest elements; children can themselves have \`children\` (deep nesting is supported).
41
41
  - Optional \`before_id\` inserts before an existing sibling; omit it to append at the end.
42
42
  - Use the returned \`inserted_id\` for follow-up updates.`,
43
+ `### Example: \`update_global_styles\` (change global tokens)
44
+ Goal: Adjust global theme tokens so semantic Tailwind classes (\`bg-background\`, \`text-foreground\`, \`border-border\`, etc.) reflect the desired look.
45
+
46
+ Tool call:
47
+ \`\`\`json
48
+ {
49
+ "radius": "0.75rem",
50
+ "background": "oklch(0.985 0.008 80.2)",
51
+ "primary": "oklch(0.62 0.16 199.4)"
52
+ }
53
+ \`\`\`
54
+
55
+ Notes:
56
+ - Args are a flat JSON object with token keys as optional params.
57
+ - Include at least 1 key/value; never call \`update_global_styles\` with \`{}\`.
58
+ - Use safe, non-empty CSS strings (avoid \`<\`, \`>\`, or \`</style\`).`,
43
59
  `### Example: \`update_classname\` (replace className fully)
44
60
  Goal: Update styling on an existing element.
45
61
 
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.examples.js","sourceRoot":"","sources":["../../../../src/ai/prompts/examples/codegen.examples.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG;IACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DAwC0D;IAE1D;;;;;;;;;;;;;+DAa6D;IAE7D;;;;;;;;;;;;;;;;;;;;;;;;8FAwB4F;CAC7F,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC","sourcesContent":["const examples = [\n `## Examples of tool calls\n\n ### Example: \\`insert_element\\` (add a CTA section)\n Goal: Insert a new section under the page root on route \\`/\\`.\n\nTool call:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"parent_id\": \"root\",\n \"before_id\": \"el_existing_sibling_id\",\n \"element\": {\n \"type\": \"div\",\n \"className\": \"mt-10 flex items-center justify-between gap-6 rounded-2xl border border-border bg-background p-6 text-foreground\",\n \"children\": [\n {\n \"type\": \"div\",\n \"className\": \"flex flex-col gap-1\",\n \"children\": [\n { \"type\": \"text\", \"className\": \"text-lg font-semibold\", \"props\": { \"text\": \"Ready to get started?\" } },\n { \"type\": \"text\", \"className\": \"text-sm text-muted-foreground\", \"props\": { \"text\": \"Create your first project in under a minute.\" } }\n ]\n },\n {\n \"type\": \"button\",\n \"className\": \"inline-flex items-center justify-center rounded-xl bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:opacity-90\",\n \"props\": {\n \"text\": \"Get Started\",\n \"onClick\": { \"kind\": \"route\", \"href\": \"/signup\" }\n }\n }\n ]\n }\n}\n\\`\\`\\`\n\n Notes:\n - Always pass a complete \\`className\\` string (Tailwind only).\n - Use \\`children\\` to nest elements; children can themselves have \\`children\\` (deep nesting is supported).\n - Optional \\`before_id\\` inserts before an existing sibling; omit it to append at the end.\n - Use the returned \\`inserted_id\\` for follow-up updates.`,\n\n `### Example: \\`update_classname\\` (replace className fully)\nGoal: Update styling on an existing element.\n\nTool call:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_123abc\",\n \"className\": \"mt-8 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3\"\n}\n\\`\\`\\`\n\nNotes:\n- Provide the full \\`className\\`; do not send partial patches.`,\n\n `### Example: \\`update_props\\` (update element props)\nGoal: Update the text and click action for a button.\n\nTool call (function name in tool schema is \\`update_props\\`):\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_123abc\",\n \"text\": \"Start free trial\",\n \"onClick\": { \"kind\": \"route\", \"href\": \"/pricing\", \"replace\": false }\n}\n\\`\\`\\`\n\nOther common prop updates:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_img_001\",\n \"alt\": \"A person collaborating on a laptop in a bright office\"\n}\n\\`\\`\\`\n\nNotes:\n- Only include props you want to change; omitted fields remain unchanged.\n- For images, \\`alt\\` is also used to fetch a suitable Unsplash image (src is auto-resolved).`,\n];\n\nexport const codegenExamples = examples.join(\"\\n\");\n"]}
1
+ {"version":3,"file":"codegen.examples.js","sourceRoot":"","sources":["../../../../src/ai/prompts/examples/codegen.examples.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG;IACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DAwC0D;IAE1D;;;;;;;;;;;;;;;wEAesE;IAEtE;;;;;;;;;;;;;+DAa6D;IAE7D;;;;;;;;;;;;;;;;;;;;;;;;8FAwB4F;CAC7F,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC","sourcesContent":["const examples = [\n `## Examples of tool calls\n\n ### Example: \\`insert_element\\` (add a CTA section)\n Goal: Insert a new section under the page root on route \\`/\\`.\n\nTool call:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"parent_id\": \"root\",\n \"before_id\": \"el_existing_sibling_id\",\n \"element\": {\n \"type\": \"div\",\n \"className\": \"mt-10 flex items-center justify-between gap-6 rounded-2xl border border-border bg-background p-6 text-foreground\",\n \"children\": [\n {\n \"type\": \"div\",\n \"className\": \"flex flex-col gap-1\",\n \"children\": [\n { \"type\": \"text\", \"className\": \"text-lg font-semibold\", \"props\": { \"text\": \"Ready to get started?\" } },\n { \"type\": \"text\", \"className\": \"text-sm text-muted-foreground\", \"props\": { \"text\": \"Create your first project in under a minute.\" } }\n ]\n },\n {\n \"type\": \"button\",\n \"className\": \"inline-flex items-center justify-center rounded-xl bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:opacity-90\",\n \"props\": {\n \"text\": \"Get Started\",\n \"onClick\": { \"kind\": \"route\", \"href\": \"/signup\" }\n }\n }\n ]\n }\n}\n\\`\\`\\`\n\n Notes:\n - Always pass a complete \\`className\\` string (Tailwind only).\n - Use \\`children\\` to nest elements; children can themselves have \\`children\\` (deep nesting is supported).\n - Optional \\`before_id\\` inserts before an existing sibling; omit it to append at the end.\n - Use the returned \\`inserted_id\\` for follow-up updates.`,\n\n `### Example: \\`update_global_styles\\` (change global tokens)\nGoal: Adjust global theme tokens so semantic Tailwind classes (\\`bg-background\\`, \\`text-foreground\\`, \\`border-border\\`, etc.) reflect the desired look.\n\nTool call:\n\\`\\`\\`json\n{\n \"radius\": \"0.75rem\",\n \"background\": \"oklch(0.985 0.008 80.2)\",\n \"primary\": \"oklch(0.62 0.16 199.4)\"\n}\n\\`\\`\\`\n\nNotes:\n- Args are a flat JSON object with token keys as optional params.\n- Include at least 1 key/value; never call \\`update_global_styles\\` with \\`{}\\`.\n- Use safe, non-empty CSS strings (avoid \\`<\\`, \\`>\\`, or \\`</style\\`).`,\n\n `### Example: \\`update_classname\\` (replace className fully)\nGoal: Update styling on an existing element.\n\nTool call:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_123abc\",\n \"className\": \"mt-8 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3\"\n}\n\\`\\`\\`\n\nNotes:\n- Provide the full \\`className\\`; do not send partial patches.`,\n\n `### Example: \\`update_props\\` (update element props)\nGoal: Update the text and click action for a button.\n\nTool call (function name in tool schema is \\`update_props\\`):\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_123abc\",\n \"text\": \"Start free trial\",\n \"onClick\": { \"kind\": \"route\", \"href\": \"/pricing\", \"replace\": false }\n}\n\\`\\`\\`\n\nOther common prop updates:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_img_001\",\n \"alt\": \"A person collaborating on a laptop in a bright office\"\n}\n\\`\\`\\`\n\nNotes:\n- Only include props you want to change; omitted fields remain unchanged.\n- For images, \\`alt\\` is also used to fetch a suitable Unsplash image (src is auto-resolved).`,\n];\n\nexport const codegenExamples = examples.join(\"\\n\");\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"planner.prompt.d.ts","sourceRoot":"","sources":["../../../src/ai/prompts/planner.prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AASrD,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,QAAQ,oBAAoB,WAmEzD,CAAC"}
1
+ {"version":3,"file":"planner.prompt.d.ts","sourceRoot":"","sources":["../../../src/ai/prompts/planner.prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AASrD,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,QAAQ,oBAAoB,WAoEzD,CAAC"}
@@ -26,6 +26,7 @@ export const plannerPrompt = (params) => {
26
26
  Styling guidance:
27
27
  - Codegen can call update_global_styles to modify app/styleConfig.json (global design tokens).
28
28
  - Prefer semantic Tailwind token classes (bg-background, text-foreground, border-border, ring-ring, etc.) so global styles are utilized.
29
+ - If a task requires changing theme tokens, specify exact update_global_styles args as a flat object: {"<tokenKey>":"<cssString>"} (never {}).
29
30
  `);
30
31
  const rendering = renderPlannerTaskFormatSection();
31
32
  const projectConfiguration = mdSection("Project Config", [
@@ -1 +1 @@
1
- {"version":3,"file":"planner.prompt.js","sourceRoot":"","sources":["../../../src/ai/prompts/planner.prompt.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,8BAA8B,GAC/B,MAAM,iCAAiC,CAAC;AASzC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAA4B,EAAE,EAAE;IAC5D,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAE3E,MAAM,MAAM,GAAG;;;;;;;;;;;;MAYX,gBAAgB,CAAC,YAAY,EAAE,SAAS,CAAC;GAC5C,CAAC,IAAI,EAAE,CAAC;IACT,MAAM,aAAa,GAAG,SAAS,CAC7B,UAAU,EACV,SAAS,CAAC,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC,CACpC,CAAC;IAEF,MAAM,SAAS,GAAG,SAAS,CACzB,OAAO,EACP;;;;;;;;;KASC,CACF,CAAC;IAEF,MAAM,SAAS,GAAG,8BAA8B,EAAE,CAAC;IAEnD,MAAM,oBAAoB,GAAG,SAAS,CACpC,gBAAgB,EAChB;QACE,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC;QAEnE,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,aAAa,CAAC;QAE/D,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,aAAa,CAAC;QAE/D,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC;KACpE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,OAAO,GAAG,SAAS,CACvB,kBAAkB,EAClB,SAAS,CAAC,SAAS,EAAE,gBAAgB,IAAI,EAAE,CAAC,CAC7C,CAAC;IAEF,MAAM,QAAQ,GAAG;QACf,MAAM;QACN,aAAa;QACb,SAAS;QACT,SAAS;QACT,oBAAoB;QACpB,OAAO;QACP,eAAe;KAChB,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC,CAAC","sourcesContent":["import { CollectedContext } from \"../../types/context.types.js\";\r\nimport { PlannerIndex } from \"../../types/public.js\";\r\nimport { plannerExamples } from \"./examples/planner.examples.js\";\r\nimport {\r\n jsonBlock,\r\n mdSection,\r\n projectStateNote,\r\n renderPlannerTaskFormatSection,\r\n} from \"./helpers/promptParts.helper.js\";\r\n\r\nexport type PlanNodePromptParams = {\r\n planTasks: unknown[];\r\n collectedContext: CollectedContext;\r\n plannerIndex: PlannerIndex;\r\n isNewProject: boolean;\r\n};\r\n\r\nexport const plannerPrompt = (params: PlanNodePromptParams) => {\r\n const { planTasks, collectedContext, plannerIndex, isNewProject } = params;\r\n\r\n const system = `\r\n You are a senior software architect creating implementation tasks.\r\n\r\n Rules:\r\n - Create atomic, deterministic tasks.\r\n - Include exact file paths to create/modify.\r\n - Prefer incremental edits over rewrites.\r\n - Reuse existing code/patterns.\r\n - Be concise but complete.\r\n - Do not write code.\r\n - Tasks must be directly executable by codegen agents.\r\n\r\n ${projectStateNote(isNewProject, \"planner\")}\r\n `.trim();\r\n const planTasksInfo = mdSection(\r\n \"PM Tasks\",\r\n jsonBlock(\"Tasks\", planTasks ?? []),\r\n );\r\n\r\n const toolsInfo = mdSection(\n \"Tools\",\n `\n - read_file: read file\n - search: search codebase\n - list_dir: list dirs\n - submit_planner_tasks: Finalize planner output\n\n Styling guidance:\n - Codegen can call update_global_styles to modify app/styleConfig.json (global design tokens).\n - Prefer semantic Tailwind token classes (bg-background, text-foreground, border-border, ring-ring, etc.) so global styles are utilized.\n `,\n );\n\r\n const rendering = renderPlannerTaskFormatSection();\r\n\r\n const projectConfiguration = mdSection(\r\n \"Project Config\",\r\n [\r\n jsonBlock(\"framework\", plannerIndex.projectConfigs.frameworkConfig),\r\n\r\n jsonBlock(\"runtime\", plannerIndex.projectConfigs.runtimeConfig),\r\n\r\n jsonBlock(\"tooling\", plannerIndex.projectConfigs.toolingConfig),\r\n\r\n jsonBlock(\"rendering\", plannerIndex.projectConfigs.renderingConfig),\r\n ].join(\"\\n\"),\r\n );\r\n\r\n const context = mdSection(\r\n \"Relevant Context\",\r\n jsonBlock(\"context\", collectedContext ?? {}),\r\n );\r\n\r\n const sections = [\r\n system,\r\n planTasksInfo,\r\n toolsInfo,\r\n rendering,\r\n projectConfiguration,\r\n context,\r\n plannerExamples,\r\n ];\r\n\r\n return sections.join(\"\\n\\n---\\n\\n\");\r\n};\r\n"]}
1
+ {"version":3,"file":"planner.prompt.js","sourceRoot":"","sources":["../../../src/ai/prompts/planner.prompt.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,8BAA8B,GAC/B,MAAM,iCAAiC,CAAC;AASzC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAA4B,EAAE,EAAE;IAC5D,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAE3E,MAAM,MAAM,GAAG;;;;;;;;;;;;MAYX,gBAAgB,CAAC,YAAY,EAAE,SAAS,CAAC;GAC5C,CAAC,IAAI,EAAE,CAAC;IACT,MAAM,aAAa,GAAG,SAAS,CAC7B,UAAU,EACV,SAAS,CAAC,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC,CACpC,CAAC;IAEF,MAAM,SAAS,GAAG,SAAS,CACzB,OAAO,EACP;;;;;;;;;;KAUC,CACF,CAAC;IAEF,MAAM,SAAS,GAAG,8BAA8B,EAAE,CAAC;IAEnD,MAAM,oBAAoB,GAAG,SAAS,CACpC,gBAAgB,EAChB;QACE,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC;QAEnE,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,aAAa,CAAC;QAE/D,SAAS,CAAC,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,aAAa,CAAC;QAE/D,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,cAAc,CAAC,eAAe,CAAC;KACpE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,OAAO,GAAG,SAAS,CACvB,kBAAkB,EAClB,SAAS,CAAC,SAAS,EAAE,gBAAgB,IAAI,EAAE,CAAC,CAC7C,CAAC;IAEF,MAAM,QAAQ,GAAG;QACf,MAAM;QACN,aAAa;QACb,SAAS;QACT,SAAS;QACT,oBAAoB;QACpB,OAAO;QACP,eAAe;KAChB,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC,CAAC","sourcesContent":["import { CollectedContext } from \"../../types/context.types.js\";\r\nimport { PlannerIndex } from \"../../types/public.js\";\r\nimport { plannerExamples } from \"./examples/planner.examples.js\";\r\nimport {\r\n jsonBlock,\r\n mdSection,\r\n projectStateNote,\r\n renderPlannerTaskFormatSection,\r\n} from \"./helpers/promptParts.helper.js\";\r\n\r\nexport type PlanNodePromptParams = {\r\n planTasks: unknown[];\r\n collectedContext: CollectedContext;\r\n plannerIndex: PlannerIndex;\r\n isNewProject: boolean;\r\n};\r\n\r\nexport const plannerPrompt = (params: PlanNodePromptParams) => {\r\n const { planTasks, collectedContext, plannerIndex, isNewProject } = params;\r\n\r\n const system = `\r\n You are a senior software architect creating implementation tasks.\r\n\r\n Rules:\r\n - Create atomic, deterministic tasks.\r\n - Include exact file paths to create/modify.\r\n - Prefer incremental edits over rewrites.\r\n - Reuse existing code/patterns.\r\n - Be concise but complete.\r\n - Do not write code.\r\n - Tasks must be directly executable by codegen agents.\r\n\r\n ${projectStateNote(isNewProject, \"planner\")}\r\n `.trim();\r\n const planTasksInfo = mdSection(\r\n \"PM Tasks\",\r\n jsonBlock(\"Tasks\", planTasks ?? []),\r\n );\r\n\r\n const toolsInfo = mdSection(\n \"Tools\",\n `\n - read_file: read file\n - search: search codebase\n - list_dir: list dirs\n - submit_planner_tasks: Finalize planner output\n\n Styling guidance:\n - Codegen can call update_global_styles to modify app/styleConfig.json (global design tokens).\n - Prefer semantic Tailwind token classes (bg-background, text-foreground, border-border, ring-ring, etc.) so global styles are utilized.\n - If a task requires changing theme tokens, specify exact update_global_styles args as a flat object: {\"<tokenKey>\":\"<cssString>\"} (never {}).\n `,\n );\n\r\n const rendering = renderPlannerTaskFormatSection();\r\n\r\n const projectConfiguration = mdSection(\r\n \"Project Config\",\r\n [\r\n jsonBlock(\"framework\", plannerIndex.projectConfigs.frameworkConfig),\r\n\r\n jsonBlock(\"runtime\", plannerIndex.projectConfigs.runtimeConfig),\r\n\r\n jsonBlock(\"tooling\", plannerIndex.projectConfigs.toolingConfig),\r\n\r\n jsonBlock(\"rendering\", plannerIndex.projectConfigs.renderingConfig),\r\n ].join(\"\\n\"),\r\n );\r\n\r\n const context = mdSection(\r\n \"Relevant Context\",\r\n jsonBlock(\"context\", collectedContext ?? {}),\r\n );\r\n\r\n const sections = [\r\n system,\r\n planTasksInfo,\r\n toolsInfo,\r\n rendering,\r\n projectConfiguration,\r\n context,\r\n plannerExamples,\r\n ];\r\n\r\n return sections.join(\"\\n\\n---\\n\\n\");\r\n};\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"validator.prompt.d.ts","sourceRoot":"","sources":["../../../src/ai/prompts/validator.prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAOvD,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,cAAc,EAAE,cAAc,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,QAAQ,0BAA0B,WA8EjE,CAAC"}
1
+ {"version":3,"file":"validator.prompt.d.ts","sourceRoot":"","sources":["../../../src/ai/prompts/validator.prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAOvD,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,cAAc,EAAE,cAAc,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,QAAQ,0BAA0B,WA+EjE,CAAC"}
@@ -38,6 +38,7 @@ export const validatorPrompt = (params) => {
38
38
  Styling guidance:
39
39
  - Codegen can call update_global_styles to modify app/styleConfig.json (global design tokens).
40
40
  - Prefer semantic Tailwind token classes (bg-background, text-foreground, border-border, ring-ring, etc.) so global styles are utilized.
41
+ - If a fix requires changing theme tokens, specify exact update_global_styles args as a flat object: {"<tokenKey>":"<cssString>"} (never {}).
41
42
  `.trim());
42
43
  const rendering = renderPlannerTaskFormatSection();
43
44
  const projectConfiguration = mdSection("Project Config", [
@@ -1 +1 @@
1
- {"version":3,"file":"validator.prompt.js","sourceRoot":"","sources":["../../../src/ai/prompts/validator.prompt.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EACT,SAAS,EACT,8BAA8B,GAC/B,MAAM,iCAAiC,CAAC;AAYzC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAkC,EAAE,EAAE;IACpE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,CAAC;IAEnD,MAAM,MAAM,GAAG;;;;;;;;;;;;GAYd,CAAC,IAAI,EAAE,CAAC;IAET,MAAM,cAAc,GAClB,MAAM,CAAC,MAAM,KAAK,CAAC;QACjB,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,MAAM;aACH,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,QAAQ,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;aAChE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEpB,MAAM,eAAe,GACnB,OAAO,CAAC,MAAM,KAAK,CAAC;QAClB,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEnE,MAAM,UAAU,GAAG,SAAS,CAC1B,YAAY,EACZ;;QAEI,cAAc;;;QAGd,eAAe;KAClB,CAAC,IAAI,EAAE,CACT,CAAC;IAEF,MAAM,SAAS,GAAG,SAAS,CACzB,OAAO,EACP;;;;;;;;;KASC,CAAC,IAAI,EAAE,CACT,CAAC;IAEF,MAAM,SAAS,GAAG,8BAA8B,EAAE,CAAC;IAEnD,MAAM,oBAAoB,GAAG,SAAS,CACpC,gBAAgB,EAChB;QACE,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,cAAc,CAAC,eAAe,CAAC;QAErE,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,cAAc,CAAC,aAAa,CAAC;QAEjE,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,cAAc,CAAC,aAAa,CAAC;QAEjE,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,cAAc,CAAC,eAAe,CAAC;KACtE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,QAAQ,GAAG;QACf,MAAM;QACN,UAAU;QACV,SAAS;QACT,SAAS;QACT,oBAAoB;KACrB,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC,CAAC","sourcesContent":["import { ValidatorIndex } from \"../../types/public.js\";\r\nimport {\r\n jsonBlock,\r\n mdSection,\r\n renderPlannerTaskFormatSection,\r\n} from \"./helpers/promptParts.helper.js\";\r\n\r\nexport type ValidationNodePromptParams = {\r\n errors: Array<{\r\n type?: string | null;\r\n filePath?: string | null;\r\n message?: string | null;\r\n }>;\r\n history: Array<{ file?: string; fix?: string }>;\r\n validatorIndex: ValidatorIndex;\r\n};\r\n\r\nexport const validatorPrompt = (params: ValidationNodePromptParams) => {\r\n const { errors, history, validatorIndex } = params;\r\n\r\n const system = `\r\n You are a senior software engineer creating fix tasks for validation failures.\r\n\r\n Rules:\r\n - Fix ALL validation errors.\r\n - Create atomic, deterministic tasks.\r\n - Include exact file paths.\r\n - Prefer incremental edits over rewrites.\r\n - Reuse existing code/patterns.\r\n - Be concise but complete.\r\n - Do not write code.\r\n - Tasks must be directly executable by codegen agents.\r\n `.trim();\r\n\r\n const renderedErrors =\r\n errors.length === 0\r\n ? \"none\"\r\n : errors\r\n .map((e) => `type:${e.type} file:${e.filePath} msg:${e.message}`)\r\n .join(\"\\n\");\r\n\r\n const renderedHistory =\r\n history.length === 0\r\n ? \"none\"\r\n : history.map((h) => `file:${h.file} fix:${h.fix}`).join(\"\\n\");\r\n\r\n const errorsInfo = mdSection(\r\n \"Validation\",\r\n `\r\n Errors:\r\n ${renderedErrors}\r\n\r\n History:\r\n ${renderedHistory}\r\n `.trim(),\r\n );\r\n\r\n const toolsInfo = mdSection(\n \"Tools\",\n `\n - read_file: read file\n - search: search codebase\n - list_dir: list dirs\n - submit_planner_tasks: submit tasks\n\n Styling guidance:\n - Codegen can call update_global_styles to modify app/styleConfig.json (global design tokens).\n - Prefer semantic Tailwind token classes (bg-background, text-foreground, border-border, ring-ring, etc.) so global styles are utilized.\n `.trim(),\n );\n\r\n const rendering = renderPlannerTaskFormatSection();\r\n\r\n const projectConfiguration = mdSection(\r\n \"Project Config\",\r\n [\r\n jsonBlock(\"framework\", validatorIndex.projectConfigs.frameworkConfig),\r\n\r\n jsonBlock(\"runtime\", validatorIndex.projectConfigs.runtimeConfig),\r\n\r\n jsonBlock(\"tooling\", validatorIndex.projectConfigs.toolingConfig),\r\n\r\n jsonBlock(\"rendering\", validatorIndex.projectConfigs.renderingConfig),\r\n ].join(\"\\n\"),\r\n );\r\n\r\n const sections = [\r\n system,\r\n errorsInfo,\r\n toolsInfo,\r\n rendering,\r\n projectConfiguration,\r\n ];\r\n\r\n return sections.join(\"\\n\\n---\\n\\n\");\r\n};\r\n"]}
1
+ {"version":3,"file":"validator.prompt.js","sourceRoot":"","sources":["../../../src/ai/prompts/validator.prompt.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EACT,SAAS,EACT,8BAA8B,GAC/B,MAAM,iCAAiC,CAAC;AAYzC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAkC,EAAE,EAAE;IACpE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,CAAC;IAEnD,MAAM,MAAM,GAAG;;;;;;;;;;;;GAYd,CAAC,IAAI,EAAE,CAAC;IAET,MAAM,cAAc,GAClB,MAAM,CAAC,MAAM,KAAK,CAAC;QACjB,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,MAAM;aACH,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,QAAQ,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;aAChE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEpB,MAAM,eAAe,GACnB,OAAO,CAAC,MAAM,KAAK,CAAC;QAClB,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEnE,MAAM,UAAU,GAAG,SAAS,CAC1B,YAAY,EACZ;;QAEI,cAAc;;;QAGd,eAAe;KAClB,CAAC,IAAI,EAAE,CACT,CAAC;IAEF,MAAM,SAAS,GAAG,SAAS,CACzB,OAAO,EACP;;;;;;;;;;KAUC,CAAC,IAAI,EAAE,CACT,CAAC;IAEF,MAAM,SAAS,GAAG,8BAA8B,EAAE,CAAC;IAEnD,MAAM,oBAAoB,GAAG,SAAS,CACpC,gBAAgB,EAChB;QACE,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,cAAc,CAAC,eAAe,CAAC;QAErE,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,cAAc,CAAC,aAAa,CAAC;QAEjE,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,cAAc,CAAC,aAAa,CAAC;QAEjE,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,cAAc,CAAC,eAAe,CAAC;KACtE,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,QAAQ,GAAG;QACf,MAAM;QACN,UAAU;QACV,SAAS;QACT,SAAS;QACT,oBAAoB;KACrB,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC,CAAC","sourcesContent":["import { ValidatorIndex } from \"../../types/public.js\";\r\nimport {\r\n jsonBlock,\r\n mdSection,\r\n renderPlannerTaskFormatSection,\r\n} from \"./helpers/promptParts.helper.js\";\r\n\r\nexport type ValidationNodePromptParams = {\r\n errors: Array<{\r\n type?: string | null;\r\n filePath?: string | null;\r\n message?: string | null;\r\n }>;\r\n history: Array<{ file?: string; fix?: string }>;\r\n validatorIndex: ValidatorIndex;\r\n};\r\n\r\nexport const validatorPrompt = (params: ValidationNodePromptParams) => {\r\n const { errors, history, validatorIndex } = params;\r\n\r\n const system = `\r\n You are a senior software engineer creating fix tasks for validation failures.\r\n\r\n Rules:\r\n - Fix ALL validation errors.\r\n - Create atomic, deterministic tasks.\r\n - Include exact file paths.\r\n - Prefer incremental edits over rewrites.\r\n - Reuse existing code/patterns.\r\n - Be concise but complete.\r\n - Do not write code.\r\n - Tasks must be directly executable by codegen agents.\r\n `.trim();\r\n\r\n const renderedErrors =\r\n errors.length === 0\r\n ? \"none\"\r\n : errors\r\n .map((e) => `type:${e.type} file:${e.filePath} msg:${e.message}`)\r\n .join(\"\\n\");\r\n\r\n const renderedHistory =\r\n history.length === 0\r\n ? \"none\"\r\n : history.map((h) => `file:${h.file} fix:${h.fix}`).join(\"\\n\");\r\n\r\n const errorsInfo = mdSection(\r\n \"Validation\",\r\n `\r\n Errors:\r\n ${renderedErrors}\r\n\r\n History:\r\n ${renderedHistory}\r\n `.trim(),\r\n );\r\n\r\n const toolsInfo = mdSection(\n \"Tools\",\n `\n - read_file: read file\n - search: search codebase\n - list_dir: list dirs\n - submit_planner_tasks: submit tasks\n\n Styling guidance:\n - Codegen can call update_global_styles to modify app/styleConfig.json (global design tokens).\n - Prefer semantic Tailwind token classes (bg-background, text-foreground, border-border, ring-ring, etc.) so global styles are utilized.\n - If a fix requires changing theme tokens, specify exact update_global_styles args as a flat object: {\"<tokenKey>\":\"<cssString>\"} (never {}).\n `.trim(),\n );\n\r\n const rendering = renderPlannerTaskFormatSection();\r\n\r\n const projectConfiguration = mdSection(\r\n \"Project Config\",\r\n [\r\n jsonBlock(\"framework\", validatorIndex.projectConfigs.frameworkConfig),\r\n\r\n jsonBlock(\"runtime\", validatorIndex.projectConfigs.runtimeConfig),\r\n\r\n jsonBlock(\"tooling\", validatorIndex.projectConfigs.toolingConfig),\r\n\r\n jsonBlock(\"rendering\", validatorIndex.projectConfigs.renderingConfig),\r\n ].join(\"\\n\"),\r\n );\r\n\r\n const sections = [\r\n system,\r\n errorsInfo,\r\n toolsInfo,\r\n rendering,\r\n projectConfiguration,\r\n ];\r\n\r\n return sections.join(\"\\n\\n---\\n\\n\");\r\n};\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"toolLoopRunner.d.ts","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAAe,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAML,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAQ9B,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9E,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9E,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,CACrB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,yBAAyB,CAAC;CAC7C,KACE,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE,CAAC;AAEF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,cAAc,CAAC,CA0azB"}
1
+ {"version":3,"file":"toolLoopRunner.d.ts","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAAe,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE/D,OAAO,EAML,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAQ9B,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9E,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9E,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,CACrB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,yBAAyB,CAAC;CAC7C,KACE,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE,CAAC;AAEF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,cAAc,CAAC,CAmczB"}
@@ -1,9 +1,12 @@
1
1
  import { FunctionCallingConfigMode } from "@google/genai";
2
2
  import { persistToolCall } from "../../services/toolcallPersist.service.js";
3
3
  import { EVENT_TYPES } from "../../types/events.js";
4
+ import { STYLE_TOKEN_KEYS } from "../../types/styleConfig.js";
4
5
  import { compactForModel, DEFAULT_CONTEXT_POLICY, normalizeReadFileArgs, redactFunctionCallArgs, } from "./toolLoopContext.js";
5
6
  import { aiCallWithRetry, buildToolStatusMessage, recordToolEvent, serializeError, } from "./toolLoopRunnerUtils.js";
6
7
  export async function runToolLoop(options) {
8
+ const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
9
+ const styleTokenKeySet = new Set(STYLE_TOKEN_KEYS);
7
10
  const { initialContents, tools, handlers, maxSteps = 30, toolCallingMode = FunctionCallingConfigMode.ANY, terminalToolNames = [], keepFullTrace = true, contextPolicy, aiCall, logger, applyPatchAutoRetryMax = 2, aiCallAutoRetryMax = 3, // must have it to try 3 times as gemini errors a lot due to high demand sometimes
8
11
  aiCallAutoRetryBaseMs = 400, aiCallAutoRetryMaxMs = 10000, persistResponse, } = options;
9
12
  if (typeof aiCall !== "function") {
@@ -230,7 +233,26 @@ export async function runToolLoop(options) {
230
233
  }
231
234
  else {
232
235
  try {
233
- toolResultRaw = await handler(effectiveArgs);
236
+ if (name === "update_global_styles") {
237
+ const flatKeys = Object.keys(effectiveArgs ?? {}).filter((k) => styleTokenKeySet.has(k));
238
+ if (flatKeys.length === 0) {
239
+ toolResultRaw = {
240
+ success: false,
241
+ error: "must include at least one token key/value",
242
+ error_detail: {
243
+ name: "InvalidToolArgumentsError",
244
+ message: "update_global_styles requires at least one token key/value (e.g. { radius: \"0.75rem\" }).",
245
+ },
246
+ note: "Resend update_global_styles with at least one token key/value, or skip this tool call.",
247
+ };
248
+ }
249
+ else {
250
+ toolResultRaw = await handler(effectiveArgs);
251
+ }
252
+ }
253
+ else {
254
+ toolResultRaw = await handler(effectiveArgs);
255
+ }
234
256
  }
235
257
  catch (err) {
236
258
  logger(`AI tool: ${name} failed`, EVENT_TYPES.STEP_ERROR);
@@ -1 +1 @@
1
- {"version":3,"file":"toolLoopRunner.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunner.ts"],"names":[],"mappings":"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","sourcesContent":["import { FunctionCallingConfigMode, Tool } from \"@google/genai\";\nimport { persistToolCall } from \"../../services/toolcallPersist.service.js\";\nimport { EVENT_TYPES, EventType } from \"../../types/events.js\";\nimport {\n compactForModel,\n DEFAULT_CONTEXT_POLICY,\n normalizeReadFileArgs,\n redactFunctionCallArgs,\n ToolEvent,\n ToolLoopContextPolicy,\n} from \"./toolLoopContext.js\";\nimport {\n aiCallWithRetry,\n buildToolStatusMessage,\n recordToolEvent,\n serializeError,\n} from \"./toolLoopRunnerUtils.js\";\n\nexport type ToolHandler = (args: Record<string, unknown>) => Promise<unknown>;\n\nexport type ToolLoopResult = {\n contents: any[];\n modelContents: any[];\n finalText: string;\n steps: number;\n terminalCall?: {\n name: string;\n args: Record<string, unknown>;\n response: unknown;\n };\n};\n\nexport type Logger = (message: string, eventType: EventType) => Promise<void>;\n\nexport type AiCallResponse = {\n functionCalls?: any[];\n text?: string;\n};\n\nexport type AiCallFn = (\n request: unknown,\n options: {\n tools?: Tool[];\n model?: string;\n toolCallingMode?: FunctionCallingConfigMode;\n },\n) => Promise<AiCallResponse>;\n\nexport type RunToolLoopOptions = {\n initialContents: any[];\n tools: Tool[];\n handlers: Record<string, ToolHandler>;\n maxSteps?: number;\n toolCallingMode?: FunctionCallingConfigMode;\n terminalToolNames?: string[];\n keepFullTrace?: boolean;\n contextPolicy?: ToolLoopContextPolicy;\n aiCall: AiCallFn;\n logger: Logger;\n applyPatchAutoRetryMax?: number;\n aiCallAutoRetryMax?: number;\n aiCallAutoRetryBaseMs?: number;\n aiCallAutoRetryMaxMs?: number;\n persistResponse?: (modelInput: any, modelOutput: any) => Promise<void>;\n};\n\nexport async function runToolLoop(\n options: RunToolLoopOptions,\n): Promise<ToolLoopResult> {\n const {\n initialContents,\n tools,\n handlers,\n maxSteps = 30,\n toolCallingMode = FunctionCallingConfigMode.ANY,\n terminalToolNames = [],\n keepFullTrace = true,\n contextPolicy,\n aiCall,\n logger,\n applyPatchAutoRetryMax = 2,\n aiCallAutoRetryMax = 3, // must have it to try 3 times as gemini errors a lot due to high demand sometimes\n aiCallAutoRetryBaseMs = 400,\n aiCallAutoRetryMaxMs = 10_000,\n persistResponse,\n } = options;\n\n if (typeof aiCall !== \"function\") {\n throw new Error(\"Tool loop: aiCall is required.\");\n }\n\n const policy: Required<ToolLoopContextPolicy> = {\n ...DEFAULT_CONTEXT_POLICY,\n ...(contextPolicy ?? {}),\n };\n\n const toolEvents: ToolEvent[] = [];\n let applyPatchRetryCount = 0;\n\n const EXECUTION_GUIDE_MARKER = \"TOOL_LOOP_EXECUTION_GUIDE_V1\";\n const executionGuideInstruction = {\n role: \"user\",\n parts: [\n {\n text:\n `${EXECUTION_GUIDE_MARKER}\\n` +\n `Execution limit: At most ${maxSteps} assistant turn(s) in this tool loop. ` +\n `One turn = one assistant response in the tool loop.\\n` +\n `Complete the task in as few turns as possible and avoid unnecessary actions. Prioritize correctness.`,\n },\n ],\n };\n\n const fullTraceContents: any[] = keepFullTrace\n ? [...initialContents, executionGuideInstruction]\n : [];\n let modelContents: any[] = [...initialContents, executionGuideInstruction];\n const pinnedInitialCount = initialContents.length + 1;\n const pushBoth = (fullItem: any, modelItem: any) => {\n if (keepFullTrace) fullTraceContents.push(fullItem);\n modelContents.push(modelItem);\n };\n const pushModelOnly = (modelItem: any) => {\n modelContents.push(modelItem);\n };\n\n for (let step = 0; step < maxSteps; step++) {\n modelContents = compactForModel({\n initialCount: pinnedInitialCount,\n modelContents,\n toolEvents,\n policy,\n });\n\n if (policy.logApproxModelChars) {\n const approxChars = JSON.stringify(modelContents).length;\n console.log(\"Tool loop: approx model chars\", {\n approxChars,\n step: step + 1,\n });\n }\n\n let response: Awaited<ReturnType<AiCallFn>>;\n try {\n response = await aiCallWithRetry({\n aiCall,\n request: modelContents,\n options: { tools, toolCallingMode },\n retryMax: aiCallAutoRetryMax,\n retryBaseMs: aiCallAutoRetryBaseMs,\n retryMaxMs: aiCallAutoRetryMaxMs,\n step: step + 1,\n logger,\n });\n } catch (err) {\n logger(\n \"Tool loop: AI provider error; preserving context and continuing\",\n EVENT_TYPES.STEP_ERROR,\n );\n console.error(\"Tool loop: aiCall failed (provider/server side)\", err, {\n step: step + 1,\n error: serializeError(err),\n });\n\n const message =\n err instanceof Error ? err.message : JSON.stringify(err ?? null);\n const providerErrorInstruction = {\n role: \"user\",\n parts: [\n {\n text:\n `AI provider error (server-side). Do NOT clear or restart context; continue from the existing conversation state.\\n` +\n `Error: ${message}\\n` +\n `Next: retry the last request using the same context. If you were about to call tools, resend a valid tool call.`,\n },\n ],\n };\n if (keepFullTrace) fullTraceContents.push(providerErrorInstruction);\n continue;\n }\n\n if (persistResponse) {\n try {\n await persistResponse(modelContents, response);\n } catch (err) {\n console.error(\"Tool loop: failed to persist response\", err, {\n step: step + 1,\n });\n }\n }\n\n const functionCalls = response.functionCalls ?? [];\n if (functionCalls.length === 0) {\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: (response.text ?? \"\").trim(),\n steps: step + 1,\n };\n }\n\n const signatureById = (() => {\n try {\n const candidates = Array.isArray((response as any)?.candidates)\n ? ((response as any).candidates as any[])\n : [];\n const parts = candidates?.[0]?.content?.parts;\n const arr = Array.isArray(parts) ? (parts as any[]) : [];\n const map = new Map<string, string>();\n for (const p of arr) {\n const fc = p?.functionCall;\n const id = fc?.id;\n const sig = p?.thoughtSignature ?? p?.thought_signature;\n if (typeof id === \"string\" && typeof sig === \"string\" && sig) {\n map.set(id, sig);\n }\n }\n return map;\n } catch {\n return new Map<string, string>();\n }\n })();\n\n for (let callIndex = 0; callIndex < functionCalls.length; callIndex++) {\n const call = functionCalls[callIndex];\n const name = call.name?.toString() ?? \"\";\n const args = (call.args ?? {}) as Record<string, unknown>;\n const thoughtSignature: string | undefined = (() => {\n const direct =\n (call as any)?.thought_signature ?? (call as any)?.thoughtSignature;\n if (typeof direct === \"string\" && direct) return direct;\n const id = (call as any)?.id;\n if (typeof id === \"string\" && signatureById.has(id)) {\n return signatureById.get(id);\n }\n return undefined;\n })();\n\n if (!name) {\n logger(\n \"Tool loop: malformed function call from model; preserving context and continuing\",\n EVENT_TYPES.STEP_ERROR,\n );\n const malformedInstruction = {\n role: \"user\",\n parts: [\n {\n text:\n `Malformed function call received (missing tool name). Do NOT clear or restart context.\\n` +\n `Resend a single valid tool call with a non-empty name and JSON args.\\n` +\n `Bad call: ${JSON.stringify(call ?? null).slice(0, 1500)}`,\n },\n ],\n };\n if (keepFullTrace) fullTraceContents.push(malformedInstruction);\n modelContents.push(malformedInstruction);\n continue;\n }\n\n const handler = handlers[name];\n const handlerMissingResult = !handler\n ? {\n success: false,\n error: `No handler registered for \"${name}\".`,\n error_detail: {\n name: \"MissingToolHandlerError\",\n message: `No handler registered for \"${name}\".`,\n },\n }\n : null;\n\n let effectiveArgs: Record<string, unknown> = args;\n let readFileMeta: {\n start: number;\n end: number;\n wasCapped: boolean;\n } | null = null;\n if (name === \"read_file\") {\n const normalized = normalizeReadFileArgs(\n effectiveArgs,\n policy.readFileDefaultMaxLines,\n );\n effectiveArgs = normalized.effectiveArgs;\n readFileMeta = {\n start: normalized.start,\n end: normalized.end,\n wasCapped: normalized.wasCapped,\n };\n }\n\n logger(\n buildToolStatusMessage(name, effectiveArgs, readFileMeta),\n EVENT_TYPES.STEP_STARTED,\n );\n\n const modelArgs = redactFunctionCallArgs(name, effectiveArgs);\n\n const functionCallPart = {\n functionCall: {\n name,\n args: effectiveArgs,\n },\n ...(thoughtSignature\n ? { thoughtSignature: thoughtSignature, thought_signature: thoughtSignature }\n : {}),\n };\n\n const functionCallPartModel = {\n functionCall: {\n name,\n args: modelArgs,\n },\n ...(thoughtSignature\n ? { thoughtSignature: thoughtSignature, thought_signature: thoughtSignature }\n : {}),\n };\n\n const assistantFull = {\n role: \"model\",\n parts: [\n {\n ...functionCallPart,\n },\n ],\n };\n\n const assistantModel = {\n role: \"model\",\n parts: [\n {\n ...functionCallPartModel,\n },\n ],\n };\n\n if (keepFullTrace) {\n pushBoth(assistantFull, assistantModel);\n } else {\n pushModelOnly(assistantModel);\n }\n\n let toolResultRaw: unknown;\n if (handlerMissingResult) {\n toolResultRaw = handlerMissingResult;\n } else {\n try {\n toolResultRaw = await handler(effectiveArgs);\n } catch (err) {\n logger(`AI tool: ${name} failed`, EVENT_TYPES.STEP_ERROR);\n console.error(\"Tool loop: handler threw\", err, {\n tool: name,\n step: step + 1,\n });\n toolResultRaw = {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n error_detail: serializeError(err),\n note: \"Tool handler threw. Inspect error_detail and retry with corrected args or a different approach.\",\n };\n }\n }\n let toolResult: unknown = toolResultRaw;\n\n if (name === \"read_file\" && readFileMeta) {\n const path = String(effectiveArgs.path ?? \"\");\n\n const jsonPayload =\n (toolResultRaw as any)?.kind === \"json\"\n ? (toolResultRaw as any)?.json\n : undefined;\n if (jsonPayload !== undefined) {\n // Token-efficient: return JSON as structured data (no double-stringifying).\n toolResult = { path, json: jsonPayload };\n } else {\n const rawContent =\n typeof (toolResultRaw as any)?.content === \"string\"\n ? String((toolResultRaw as any).content)\n : typeof toolResultRaw === \"string\"\n ? toolResultRaw\n : JSON.stringify(toolResultRaw ?? null);\n\n toolResult = {\n path,\n start_line: readFileMeta.start,\n end_line: readFileMeta.end,\n truncated: readFileMeta.wasCapped,\n content: rawContent,\n note: readFileMeta.wasCapped\n ? `Capped to ${policy.readFileDefaultMaxLines} lines. Request more with start_line/end_line.`\n : undefined,\n };\n }\n }\n\n try {\n await persistToolCall(name, modelArgs, toolResult);\n } catch (err) {\n console.error(\"Tool loop: failed to persist tool call\", err, {\n tool: name,\n step: step + 1,\n });\n }\n\n const responseFull = {\n role: \"user\",\n parts: [\n {\n functionResponse: {\n name,\n response: toolResult,\n },\n },\n ],\n };\n\n if (keepFullTrace) {\n fullTraceContents.push(responseFull);\n }\n modelContents.push(responseFull);\n\n if (\n name === \"apply_patch\" &&\n (toolResult as any)?.success === false &&\n applyPatchAutoRetryMax > 0 &&\n applyPatchRetryCount < applyPatchAutoRetryMax\n ) {\n applyPatchRetryCount += 1;\n\n const error = String((toolResult as any)?.error ?? \"unknown error\");\n const debugFiles = Array.isArray((toolResult as any)?.debug?.files)\n ? ((toolResult as any).debug.files as Array<{\n path?: string;\n head?: string;\n }>)\n : [];\n\n const debugText =\n debugFiles.length > 0\n ? `\\n\\nFILE SNAPSHOTS (for regenerating the patch):\\n${debugFiles\n .slice(0, 3)\n .map(\n (f) =>\n `--- ${String(f.path ?? \"\")} ---\\n${String(\n f.head ?? \"\",\n )}\\n--- end ---`,\n )\n .join(\"\\n\\n\")}`\n : \"\";\n\n const retryInstruction = {\n role: \"user\",\n parts: [\n {\n text:\n `apply_patch failed (attempt ${applyPatchRetryCount}/${applyPatchAutoRetryMax}): ${error}\\n` +\n `Regenerate a patch that matches the current file contents. ` +\n `For large rewrites, prefer write_file(path, content) or Delete+Add instead of Update.` +\n debugText,\n },\n ],\n };\n\n if (keepFullTrace) fullTraceContents.push(retryInstruction);\n modelContents.push(retryInstruction);\n }\n\n recordToolEvent({\n toolEvents,\n name,\n effectiveArgs,\n modelArgs,\n readFileMeta,\n toolResult,\n toolResultRaw,\n });\n\n if (terminalToolNames.includes(name)) {\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: \"\",\n steps: step + 1,\n terminalCall: { name, args: effectiveArgs, response: toolResultRaw },\n };\n }\n }\n }\n\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: `Stopped: max steps reached (${maxSteps}).`,\n steps: maxSteps,\n };\n}\n"]}
1
+ {"version":3,"file":"toolLoopRunner.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunner.ts"],"names":[],"mappings":"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","sourcesContent":["import { FunctionCallingConfigMode, Tool } from \"@google/genai\";\nimport { persistToolCall } from \"../../services/toolcallPersist.service.js\";\nimport { EVENT_TYPES, EventType } from \"../../types/events.js\";\nimport { STYLE_TOKEN_KEYS } from \"../../types/styleConfig.js\";\nimport {\n compactForModel,\n DEFAULT_CONTEXT_POLICY,\n normalizeReadFileArgs,\n redactFunctionCallArgs,\n ToolEvent,\n ToolLoopContextPolicy,\n} from \"./toolLoopContext.js\";\nimport {\n aiCallWithRetry,\n buildToolStatusMessage,\n recordToolEvent,\n serializeError,\n} from \"./toolLoopRunnerUtils.js\";\n\nexport type ToolHandler = (args: Record<string, unknown>) => Promise<unknown>;\n\nexport type ToolLoopResult = {\n contents: any[];\n modelContents: any[];\n finalText: string;\n steps: number;\n terminalCall?: {\n name: string;\n args: Record<string, unknown>;\n response: unknown;\n };\n};\n\nexport type Logger = (message: string, eventType: EventType) => Promise<void>;\n\nexport type AiCallResponse = {\n functionCalls?: any[];\n text?: string;\n};\n\nexport type AiCallFn = (\n request: unknown,\n options: {\n tools?: Tool[];\n model?: string;\n toolCallingMode?: FunctionCallingConfigMode;\n },\n) => Promise<AiCallResponse>;\n\nexport type RunToolLoopOptions = {\n initialContents: any[];\n tools: Tool[];\n handlers: Record<string, ToolHandler>;\n maxSteps?: number;\n toolCallingMode?: FunctionCallingConfigMode;\n terminalToolNames?: string[];\n keepFullTrace?: boolean;\n contextPolicy?: ToolLoopContextPolicy;\n aiCall: AiCallFn;\n logger: Logger;\n applyPatchAutoRetryMax?: number;\n aiCallAutoRetryMax?: number;\n aiCallAutoRetryBaseMs?: number;\n aiCallAutoRetryMaxMs?: number;\n persistResponse?: (modelInput: any, modelOutput: any) => Promise<void>;\n};\n\nexport async function runToolLoop(\n options: RunToolLoopOptions,\n): Promise<ToolLoopResult> {\n const isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\n const styleTokenKeySet = new Set<string>(STYLE_TOKEN_KEYS as unknown as string[]);\n\n const {\n initialContents,\n tools,\n handlers,\n maxSteps = 30,\n toolCallingMode = FunctionCallingConfigMode.ANY,\n terminalToolNames = [],\n keepFullTrace = true,\n contextPolicy,\n aiCall,\n logger,\n applyPatchAutoRetryMax = 2,\n aiCallAutoRetryMax = 3, // must have it to try 3 times as gemini errors a lot due to high demand sometimes\n aiCallAutoRetryBaseMs = 400,\n aiCallAutoRetryMaxMs = 10_000,\n persistResponse,\n } = options;\n\n if (typeof aiCall !== \"function\") {\n throw new Error(\"Tool loop: aiCall is required.\");\n }\n\n const policy: Required<ToolLoopContextPolicy> = {\n ...DEFAULT_CONTEXT_POLICY,\n ...(contextPolicy ?? {}),\n };\n\n const toolEvents: ToolEvent[] = [];\n let applyPatchRetryCount = 0;\n\n const EXECUTION_GUIDE_MARKER = \"TOOL_LOOP_EXECUTION_GUIDE_V1\";\n const executionGuideInstruction = {\n role: \"user\",\n parts: [\n {\n text:\n `${EXECUTION_GUIDE_MARKER}\\n` +\n `Execution limit: At most ${maxSteps} assistant turn(s) in this tool loop. ` +\n `One turn = one assistant response in the tool loop.\\n` +\n `Complete the task in as few turns as possible and avoid unnecessary actions. Prioritize correctness.`,\n },\n ],\n };\n\n const fullTraceContents: any[] = keepFullTrace\n ? [...initialContents, executionGuideInstruction]\n : [];\n let modelContents: any[] = [...initialContents, executionGuideInstruction];\n const pinnedInitialCount = initialContents.length + 1;\n const pushBoth = (fullItem: any, modelItem: any) => {\n if (keepFullTrace) fullTraceContents.push(fullItem);\n modelContents.push(modelItem);\n };\n const pushModelOnly = (modelItem: any) => {\n modelContents.push(modelItem);\n };\n\n for (let step = 0; step < maxSteps; step++) {\n modelContents = compactForModel({\n initialCount: pinnedInitialCount,\n modelContents,\n toolEvents,\n policy,\n });\n\n if (policy.logApproxModelChars) {\n const approxChars = JSON.stringify(modelContents).length;\n console.log(\"Tool loop: approx model chars\", {\n approxChars,\n step: step + 1,\n });\n }\n\n let response: Awaited<ReturnType<AiCallFn>>;\n try {\n response = await aiCallWithRetry({\n aiCall,\n request: modelContents,\n options: { tools, toolCallingMode },\n retryMax: aiCallAutoRetryMax,\n retryBaseMs: aiCallAutoRetryBaseMs,\n retryMaxMs: aiCallAutoRetryMaxMs,\n step: step + 1,\n logger,\n });\n } catch (err) {\n logger(\n \"Tool loop: AI provider error; preserving context and continuing\",\n EVENT_TYPES.STEP_ERROR,\n );\n console.error(\"Tool loop: aiCall failed (provider/server side)\", err, {\n step: step + 1,\n error: serializeError(err),\n });\n\n const message =\n err instanceof Error ? err.message : JSON.stringify(err ?? null);\n const providerErrorInstruction = {\n role: \"user\",\n parts: [\n {\n text:\n `AI provider error (server-side). Do NOT clear or restart context; continue from the existing conversation state.\\n` +\n `Error: ${message}\\n` +\n `Next: retry the last request using the same context. If you were about to call tools, resend a valid tool call.`,\n },\n ],\n };\n if (keepFullTrace) fullTraceContents.push(providerErrorInstruction);\n continue;\n }\n\n if (persistResponse) {\n try {\n await persistResponse(modelContents, response);\n } catch (err) {\n console.error(\"Tool loop: failed to persist response\", err, {\n step: step + 1,\n });\n }\n }\n\n const functionCalls = response.functionCalls ?? [];\n if (functionCalls.length === 0) {\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: (response.text ?? \"\").trim(),\n steps: step + 1,\n };\n }\n\n const signatureById = (() => {\n try {\n const candidates = Array.isArray((response as any)?.candidates)\n ? ((response as any).candidates as any[])\n : [];\n const parts = candidates?.[0]?.content?.parts;\n const arr = Array.isArray(parts) ? (parts as any[]) : [];\n const map = new Map<string, string>();\n for (const p of arr) {\n const fc = p?.functionCall;\n const id = fc?.id;\n const sig = p?.thoughtSignature ?? p?.thought_signature;\n if (typeof id === \"string\" && typeof sig === \"string\" && sig) {\n map.set(id, sig);\n }\n }\n return map;\n } catch {\n return new Map<string, string>();\n }\n })();\n\n for (let callIndex = 0; callIndex < functionCalls.length; callIndex++) {\n const call = functionCalls[callIndex];\n const name = call.name?.toString() ?? \"\";\n const args = (call.args ?? {}) as Record<string, unknown>;\n const thoughtSignature: string | undefined = (() => {\n const direct =\n (call as any)?.thought_signature ?? (call as any)?.thoughtSignature;\n if (typeof direct === \"string\" && direct) return direct;\n const id = (call as any)?.id;\n if (typeof id === \"string\" && signatureById.has(id)) {\n return signatureById.get(id);\n }\n return undefined;\n })();\n\n if (!name) {\n logger(\n \"Tool loop: malformed function call from model; preserving context and continuing\",\n EVENT_TYPES.STEP_ERROR,\n );\n const malformedInstruction = {\n role: \"user\",\n parts: [\n {\n text:\n `Malformed function call received (missing tool name). Do NOT clear or restart context.\\n` +\n `Resend a single valid tool call with a non-empty name and JSON args.\\n` +\n `Bad call: ${JSON.stringify(call ?? null).slice(0, 1500)}`,\n },\n ],\n };\n if (keepFullTrace) fullTraceContents.push(malformedInstruction);\n modelContents.push(malformedInstruction);\n continue;\n }\n\n const handler = handlers[name];\n const handlerMissingResult = !handler\n ? {\n success: false,\n error: `No handler registered for \"${name}\".`,\n error_detail: {\n name: \"MissingToolHandlerError\",\n message: `No handler registered for \"${name}\".`,\n },\n }\n : null;\n\n let effectiveArgs: Record<string, unknown> = args;\n let readFileMeta: {\n start: number;\n end: number;\n wasCapped: boolean;\n } | null = null;\n if (name === \"read_file\") {\n const normalized = normalizeReadFileArgs(\n effectiveArgs,\n policy.readFileDefaultMaxLines,\n );\n effectiveArgs = normalized.effectiveArgs;\n readFileMeta = {\n start: normalized.start,\n end: normalized.end,\n wasCapped: normalized.wasCapped,\n };\n }\n\n logger(\n buildToolStatusMessage(name, effectiveArgs, readFileMeta),\n EVENT_TYPES.STEP_STARTED,\n );\n\n const modelArgs = redactFunctionCallArgs(name, effectiveArgs);\n\n const functionCallPart = {\n functionCall: {\n name,\n args: effectiveArgs,\n },\n ...(thoughtSignature\n ? { thoughtSignature: thoughtSignature, thought_signature: thoughtSignature }\n : {}),\n };\n\n const functionCallPartModel = {\n functionCall: {\n name,\n args: modelArgs,\n },\n ...(thoughtSignature\n ? { thoughtSignature: thoughtSignature, thought_signature: thoughtSignature }\n : {}),\n };\n\n const assistantFull = {\n role: \"model\",\n parts: [\n {\n ...functionCallPart,\n },\n ],\n };\n\n const assistantModel = {\n role: \"model\",\n parts: [\n {\n ...functionCallPartModel,\n },\n ],\n };\n\n if (keepFullTrace) {\n pushBoth(assistantFull, assistantModel);\n } else {\n pushModelOnly(assistantModel);\n }\n\n let toolResultRaw: unknown;\n if (handlerMissingResult) {\n toolResultRaw = handlerMissingResult;\n } else {\n try {\n if (name === \"update_global_styles\") {\n const flatKeys = Object.keys(effectiveArgs ?? {}).filter((k) =>\n styleTokenKeySet.has(k),\n );\n if (flatKeys.length === 0) {\n toolResultRaw = {\n success: false,\n error: \"must include at least one token key/value\",\n error_detail: {\n name: \"InvalidToolArgumentsError\",\n message:\n \"update_global_styles requires at least one token key/value (e.g. { radius: \\\"0.75rem\\\" }).\",\n },\n note: \"Resend update_global_styles with at least one token key/value, or skip this tool call.\",\n };\n } else {\n toolResultRaw = await handler(effectiveArgs);\n }\n } else {\n toolResultRaw = await handler(effectiveArgs);\n }\n } catch (err) {\n logger(`AI tool: ${name} failed`, EVENT_TYPES.STEP_ERROR);\n console.error(\"Tool loop: handler threw\", err, {\n tool: name,\n step: step + 1,\n });\n toolResultRaw = {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n error_detail: serializeError(err),\n note: \"Tool handler threw. Inspect error_detail and retry with corrected args or a different approach.\",\n };\n }\n }\n let toolResult: unknown = toolResultRaw;\n\n if (name === \"read_file\" && readFileMeta) {\n const path = String(effectiveArgs.path ?? \"\");\n\n const jsonPayload =\n (toolResultRaw as any)?.kind === \"json\"\n ? (toolResultRaw as any)?.json\n : undefined;\n if (jsonPayload !== undefined) {\n // Token-efficient: return JSON as structured data (no double-stringifying).\n toolResult = { path, json: jsonPayload };\n } else {\n const rawContent =\n typeof (toolResultRaw as any)?.content === \"string\"\n ? String((toolResultRaw as any).content)\n : typeof toolResultRaw === \"string\"\n ? toolResultRaw\n : JSON.stringify(toolResultRaw ?? null);\n\n toolResult = {\n path,\n start_line: readFileMeta.start,\n end_line: readFileMeta.end,\n truncated: readFileMeta.wasCapped,\n content: rawContent,\n note: readFileMeta.wasCapped\n ? `Capped to ${policy.readFileDefaultMaxLines} lines. Request more with start_line/end_line.`\n : undefined,\n };\n }\n }\n\n try {\n await persistToolCall(name, modelArgs, toolResult);\n } catch (err) {\n console.error(\"Tool loop: failed to persist tool call\", err, {\n tool: name,\n step: step + 1,\n });\n }\n\n const responseFull = {\n role: \"user\",\n parts: [\n {\n functionResponse: {\n name,\n response: toolResult,\n },\n },\n ],\n };\n\n if (keepFullTrace) {\n fullTraceContents.push(responseFull);\n }\n modelContents.push(responseFull);\n\n if (\n name === \"apply_patch\" &&\n (toolResult as any)?.success === false &&\n applyPatchAutoRetryMax > 0 &&\n applyPatchRetryCount < applyPatchAutoRetryMax\n ) {\n applyPatchRetryCount += 1;\n\n const error = String((toolResult as any)?.error ?? \"unknown error\");\n const debugFiles = Array.isArray((toolResult as any)?.debug?.files)\n ? ((toolResult as any).debug.files as Array<{\n path?: string;\n head?: string;\n }>)\n : [];\n\n const debugText =\n debugFiles.length > 0\n ? `\\n\\nFILE SNAPSHOTS (for regenerating the patch):\\n${debugFiles\n .slice(0, 3)\n .map(\n (f) =>\n `--- ${String(f.path ?? \"\")} ---\\n${String(\n f.head ?? \"\",\n )}\\n--- end ---`,\n )\n .join(\"\\n\\n\")}`\n : \"\";\n\n const retryInstruction = {\n role: \"user\",\n parts: [\n {\n text:\n `apply_patch failed (attempt ${applyPatchRetryCount}/${applyPatchAutoRetryMax}): ${error}\\n` +\n `Regenerate a patch that matches the current file contents. ` +\n `For large rewrites, prefer write_file(path, content) or Delete+Add instead of Update.` +\n debugText,\n },\n ],\n };\n\n if (keepFullTrace) fullTraceContents.push(retryInstruction);\n modelContents.push(retryInstruction);\n }\n\n recordToolEvent({\n toolEvents,\n name,\n effectiveArgs,\n modelArgs,\n readFileMeta,\n toolResult,\n toolResultRaw,\n });\n\n if (terminalToolNames.includes(name)) {\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: \"\",\n steps: step + 1,\n terminalCall: { name, args: effectiveArgs, response: toolResultRaw },\n };\n }\n }\n }\n\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: `Stopped: max steps reached (${maxSteps}).`,\n steps: maxSteps,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"toolLoopRunnerUtils.d.ts","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunnerUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAA0B,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,kBACsC,CAAC;AAEvE,eAAO,MAAM,cAAc,GAAI,KAAK,OAAO;;;;;;;;;;;;CAuB1C,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,KAAK,OAAO,YA2BlD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,QAAQ,MAAM,EACd,OAAO,MAAM,WAMd,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,QAAQ;IAC5C,MAAM,EAAE,QAAQ,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QAAC,eAAe,CAAC,EAAE,yBAAyB,CAAA;KAAE,CAAC;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,0DA2BA,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,MAAM,MAAM,EACZ,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,cAAc;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,WAqBxE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,QAAQ;IACtC,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACxE,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;CACxB,SAuPA,CAAC"}
1
+ {"version":3,"file":"toolLoopRunnerUtils.d.ts","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunnerUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAA0B,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGvD,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,kBACsC,CAAC;AAEvE,eAAO,MAAM,cAAc,GAAI,KAAK,OAAO;;;;;;;;;;;;CAuB1C,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,KAAK,OAAO,YA2BlD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,QAAQ,MAAM,EACd,OAAO,MAAM,WAMd,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,QAAQ;IAC5C,MAAM,EAAE,QAAQ,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QAAC,eAAe,CAAC,EAAE,yBAAyB,CAAA;KAAE,CAAC;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,0DA2BA,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,MAAM,MAAM,EACZ,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,cAAc;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,WAqBxE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,QAAQ;IACtC,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACxE,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;CACxB,SAsPA,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { EVENT_TYPES } from "../../types/events.js";
2
2
  import { getApplyPatchEventMeta } from "./toolLoopContext.js";
3
+ import { STYLE_TOKEN_KEYS } from "../../types/styleConfig.js";
3
4
  export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
4
5
  export const serializeError = (err) => {
5
6
  if (err instanceof Error) {
@@ -231,10 +232,8 @@ export const recordToolEvent = (params) => {
231
232
  }
232
233
  }
233
234
  if (name === "update_global_styles") {
234
- const tokens = effectiveArgs?.tokens;
235
- const tokenKeys = tokens && typeof tokens === "object" && !Array.isArray(tokens)
236
- ? Object.keys(tokens)
237
- : [];
235
+ const tokenKeySet = new Set(STYLE_TOKEN_KEYS);
236
+ const tokenKeys = Object.keys(effectiveArgs ?? {}).filter((k) => tokenKeySet.has(k));
238
237
  const successVal = toolResult?.success;
239
238
  if (typeof successVal === "boolean") {
240
239
  const changedVal = toolResult?.changed;
@@ -1 +1 @@
1
- {"version":3,"file":"toolLoopRunnerUtils.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunnerUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { FunctionCallingConfigMode, Tool } from \"@google/genai\";\nimport { EVENT_TYPES } from \"../../types/events.js\";\nimport { getApplyPatchEventMeta, ToolEvent } from \"./toolLoopContext.js\";\nimport { AiCallFn, Logger } from \"./toolLoopRunner.js\";\n\nexport const sleep = (ms: number) =>\n new Promise<void>((resolve) => setTimeout(resolve, Math.max(0, ms)));\n\nexport const serializeError = (err: unknown) => {\n if (err instanceof Error) {\n const cause = (err as any).cause as unknown;\n return {\n name: err.name,\n message: err.message,\n stack: err.stack,\n cause:\n cause instanceof Error\n ? {\n name: cause.name,\n message: cause.message,\n stack: cause.stack,\n }\n : cause,\n };\n }\n\n return {\n name: typeof err,\n message: typeof err === \"string\" ? err : \"Non-Error thrown\",\n value: err,\n };\n};\n\nexport const isTransientAiCallError = (err: unknown) => {\n let cur: any = err as any;\n for (let depth = 0; depth < 4 && cur; depth++) {\n const code =\n cur?.error?.code ?? cur?.code ?? cur?.statusCode ?? cur?.response?.status;\n\n const status =\n cur?.error?.status ?? cur?.status ?? cur?.response?.data?.error?.status;\n\n const message =\n cur?.error?.message ?? cur?.message ?? cur?.response?.data?.error?.message;\n\n const msg = typeof message === \"string\" ? message.toLowerCase() : \"\";\n const stat = typeof status === \"string\" ? status.toUpperCase() : \"\";\n\n if (code === 503) return true;\n if (code === 429) return true;\n if (stat === \"UNAVAILABLE\") return true;\n if (stat === \"RESOURCE_EXHAUSTED\") return true;\n if (msg.includes(\"high demand\")) return true;\n if (msg.includes(\"try again later\")) return true;\n if (msg.includes(\"temporar\")) return true;\n\n cur = cur?.cause;\n }\n\n return false;\n};\n\nexport const computeBackoffMs = (\n attempt: number,\n baseMs: number,\n maxMs: number,\n) => {\n const exp = baseMs * Math.pow(2, Math.max(0, attempt - 1));\n const capped = Math.min(maxMs, exp);\n const jitter = capped * (0.2 * Math.random());\n return Math.round(capped + jitter);\n};\n\nexport const aiCallWithRetry = async (params: {\n aiCall: AiCallFn;\n request: unknown;\n options: { tools?: Tool[]; toolCallingMode?: FunctionCallingConfigMode };\n retryMax: number;\n retryBaseMs: number;\n retryMaxMs: number;\n step: number;\n logger: Logger;\n}) => {\n const {\n aiCall,\n request,\n options,\n retryMax,\n retryBaseMs,\n retryMaxMs,\n logger,\n } = params;\n\n let retryCount = 0;\n while (true) {\n try {\n return await aiCall(request, options);\n } catch (err) {\n const transient = isTransientAiCallError(err);\n if (!transient || retryMax <= 0 || retryCount >= retryMax) {\n throw err;\n }\n\n retryCount += 1;\n const delayMs = computeBackoffMs(retryCount, retryBaseMs, retryMaxMs);\n logger(\"Tool loop: aiCall failed; retrying\", EVENT_TYPES.STEP_RETRY);\n await sleep(delayMs);\n }\n }\n};\n\nexport const buildToolStatusMessage = (\n name: string,\n effectiveArgs: Record<string, unknown>,\n readFileMeta: { start: number; end: number; wasCapped: boolean } | null,\n) => {\n if (name === \"read_file\" && readFileMeta) {\n return `AI tool: read_file (${readFileMeta.start}-${readFileMeta.end}${\n readFileMeta.wasCapped ? \", capped\" : \"\"\n })`;\n }\n\n if (name === \"apply_patch\") {\n const meta = getApplyPatchEventMeta(effectiveArgs);\n const files = Array.isArray(meta.files) ? meta.files.length : 0;\n return `AI tool: apply_patch (${files} file${files === 1 ? \"\" : \"s\"})`;\n }\n\n if (name === \"search\") return \"AI tool: search\";\n if (name === \"list_dir\") return \"AI tool: list_dir\";\n if (name === \"write_file\") return \"AI tool: write_file\";\n if (name === \"submit_planner_tasks\") return \"AI tool: submit_planner_tasks\";\n if (name === \"submit_codegen_done\") return \"AI tool: submit_codegen_done\";\n\n return `AI tool: ${name}`;\n};\n\nexport const recordToolEvent = (params: {\n toolEvents: ToolEvent[];\n name: string;\n effectiveArgs: Record<string, unknown>;\n modelArgs: Record<string, unknown>;\n readFileMeta: { start: number; end: number; wasCapped: boolean } | null;\n toolResult: unknown;\n toolResultRaw: unknown;\n}) => {\n const oneLine = (value: unknown, maxLen = 140) => {\n const raw =\n typeof value === \"string\"\n ? value\n : value === undefined\n ? \"\"\n : value === null\n ? \"null\"\n : JSON.stringify(value);\n const collapsed = raw.replace(/\\s+/g, \" \").trim();\n if (collapsed.length <= maxLen) return collapsed;\n return `${collapsed.slice(0, Math.max(0, maxLen - 1))}…`;\n };\n\n const getStringArg = (key: string) => oneLine(params.effectiveArgs[key] ?? \"\");\n\n const {\n toolEvents,\n name,\n effectiveArgs,\n modelArgs,\n readFileMeta,\n toolResult,\n toolResultRaw,\n } = params;\n\n try {\n if (name === \"read_file\") {\n const path = String(effectiveArgs.path ?? \"\");\n const start =\n readFileMeta?.start ?? Number(effectiveArgs.start_line ?? 1);\n const end = readFileMeta?.end ?? Number(effectiveArgs.end_line ?? start);\n toolEvents.push({\n name,\n summary: `read_file ${path}:${start}-${end}${readFileMeta?.wasCapped ? \" (capped)\" : \"\"}`,\n });\n return;\n }\n\n if (name === \"apply_patch\") {\n const meta =\n typeof (modelArgs as any).patch_string === \"object\"\n ? ((modelArgs as any).patch_string as any)\n : null;\n const fallback = getApplyPatchEventMeta(effectiveArgs);\n const ok =\n (toolResult as any)?.success === true\n ? \"success\"\n : (toolResult as any)?.success === false\n ? \"failure\"\n : \"done\";\n toolEvents.push({\n name,\n summary: `apply_patch files=${JSON.stringify(meta?.files ?? fallback.files)} sha256=${String(meta?.sha256 ?? fallback.sha256).slice(0, 12)} chars=${meta?.chars ?? fallback.chars} result=${ok}`,\n });\n return;\n }\n\n if (name === \"create_new_route\") {\n const parentRoute = getStringArg(\"parent_route\") || \"/\";\n const routeName = getStringArg(\"route_name\");\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const route = oneLine((toolResult as any)?.route ?? \"\");\n const createdFiles = Array.isArray((toolResult as any)?.created_files)\n ? ((toolResult as any).created_files as unknown[])\n : [];\n const filesText =\n successVal === true\n ? ` created_files=${createdFiles.length}`\n : \"\";\n const routeText = route ? ` route=${route}` : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `create_new_route ${successVal ? \"success\" : \"failure\"} parent_route=${parentRoute} route_name=${routeName}${routeText}${filesText}${errText}`,\n });\n return;\n }\n }\n\n if (name === \"insert_element\") {\n const route = getStringArg(\"route\");\n const parentId = getStringArg(\"parent_id\");\n const beforeId = getStringArg(\"before_id\");\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const insertedId = oneLine((toolResult as any)?.inserted_id ?? \"\");\n const changedVal = (toolResult as any)?.changed;\n const changedText =\n typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const beforeText = beforeId ? ` before_id=${beforeId}` : \"\";\n const insertedText = insertedId ? ` inserted_id=${insertedId}` : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `insert_element ${successVal ? \"success\" : \"failure\"} route=${route} parent_id=${parentId}${beforeText}${insertedText}${changedText}${errText}`,\n });\n return;\n }\n }\n\n if (name === \"update_classname\") {\n const route = getStringArg(\"route\");\n const elementId = getStringArg(\"element_id\");\n const className = oneLine(effectiveArgs.className ?? \"\", 160);\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const changedVal = (toolResult as any)?.changed;\n const changedText =\n typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const updatedId = oneLine((toolResult as any)?.updated_id ?? \"\");\n const updatedText = updatedId ? ` updated_id=${updatedId}` : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `update_classname ${successVal ? \"success\" : \"failure\"} route=${route} element_id=${elementId} className=\"${className}\"${updatedText}${changedText}${errText}`,\n });\n return;\n }\n }\n\n if (name === \"update_props\") {\n const route = getStringArg(\"route\");\n const elementId = getStringArg(\"element_id\");\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const changedVal = (toolResult as any)?.changed;\n const changedText =\n typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const updatedId = oneLine((toolResult as any)?.updated_id ?? \"\");\n const updatedText = updatedId ? ` updated_id=${updatedId}` : \"\";\n const patchKeys = Object.keys(effectiveArgs ?? {}).filter((k) => {\n if (k === \"route\" || k === \"element_id\") return false;\n const v = (effectiveArgs as any)[k];\n return v !== undefined && v !== null;\n });\n const keysText =\n patchKeys.length > 0\n ? ` keys=${oneLine(patchKeys.sort().join(\",\"), 140)}`\n : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `update_props ${successVal ? \"success\" : \"failure\"} route=${route} element_id=${elementId}${keysText}${updatedText}${changedText}${errText}`,\n });\n return;\n }\n }\n\n if (name === \"update_global_styles\") {\n const tokens = (effectiveArgs as any)?.tokens;\n const tokenKeys = tokens && typeof tokens === \"object\" && !Array.isArray(tokens)\n ? Object.keys(tokens as Record<string, unknown>)\n : [];\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const changedVal = (toolResult as any)?.changed;\n const changedText =\n typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const version = (toolResult as any)?.version;\n const versionText =\n typeof version === \"number\" && Number.isFinite(version)\n ? ` version=${version}`\n : \"\";\n const created = (toolResult as any)?.created;\n const createdText =\n typeof created === \"boolean\" ? ` created=${created}` : \"\";\n const keysText =\n tokenKeys.length > 0\n ? ` tokens=${oneLine(tokenKeys.sort().join(\",\"), 160)}`\n : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `update_global_styles ${successVal ? \"success\" : \"failure\"}${keysText}${versionText}${createdText}${changedText}${errText}`,\n });\n return;\n }\n }\n\n if (name === \"search\") {\n const q = String(effectiveArgs.search_query ?? \"\").trim();\n const results = Array.isArray((toolResultRaw as any)?.results)\n ? (toolResultRaw as any).results\n : [];\n toolEvents.push({\n name,\n summary: `search \"${q}\" -> ${results.length} results`,\n });\n return;\n }\n\n if (name === \"list_dir\") {\n const p = String(effectiveArgs.path ?? \"\");\n const d = Number(effectiveArgs.depth ?? 1);\n toolEvents.push({ name, summary: `list_dir ${p} depth=${d}` });\n return;\n }\n\n if (name === \"create_file\") {\n const p = String(effectiveArgs.path ?? \"\");\n toolEvents.push({ name, summary: `create_file ${p}` });\n return;\n }\n\n if (name === \"delete_file\") {\n const p = String(effectiveArgs.path ?? \"\");\n toolEvents.push({ name, summary: `delete_file ${p}` });\n return;\n }\n\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const changedVal = (toolResult as any)?.changed;\n const changedText = typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `${name} ${successVal ? \"success\" : \"failure\"}${changedText}${errText}`,\n });\n return;\n }\n\n toolEvents.push({ name, summary: `${name} called` });\n } catch {\n toolEvents.push({ name, summary: `${name} called` });\n }\n};\n"]}
1
+ {"version":3,"file":"toolLoopRunnerUtils.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunnerUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { FunctionCallingConfigMode, Tool } from \"@google/genai\";\nimport { EVENT_TYPES } from \"../../types/events.js\";\nimport { getApplyPatchEventMeta, ToolEvent } from \"./toolLoopContext.js\";\nimport { AiCallFn, Logger } from \"./toolLoopRunner.js\";\nimport { STYLE_TOKEN_KEYS } from \"../../types/styleConfig.js\";\n\nexport const sleep = (ms: number) =>\n new Promise<void>((resolve) => setTimeout(resolve, Math.max(0, ms)));\n\nexport const serializeError = (err: unknown) => {\n if (err instanceof Error) {\n const cause = (err as any).cause as unknown;\n return {\n name: err.name,\n message: err.message,\n stack: err.stack,\n cause:\n cause instanceof Error\n ? {\n name: cause.name,\n message: cause.message,\n stack: cause.stack,\n }\n : cause,\n };\n }\n\n return {\n name: typeof err,\n message: typeof err === \"string\" ? err : \"Non-Error thrown\",\n value: err,\n };\n};\n\nexport const isTransientAiCallError = (err: unknown) => {\n let cur: any = err as any;\n for (let depth = 0; depth < 4 && cur; depth++) {\n const code =\n cur?.error?.code ?? cur?.code ?? cur?.statusCode ?? cur?.response?.status;\n\n const status =\n cur?.error?.status ?? cur?.status ?? cur?.response?.data?.error?.status;\n\n const message =\n cur?.error?.message ?? cur?.message ?? cur?.response?.data?.error?.message;\n\n const msg = typeof message === \"string\" ? message.toLowerCase() : \"\";\n const stat = typeof status === \"string\" ? status.toUpperCase() : \"\";\n\n if (code === 503) return true;\n if (code === 429) return true;\n if (stat === \"UNAVAILABLE\") return true;\n if (stat === \"RESOURCE_EXHAUSTED\") return true;\n if (msg.includes(\"high demand\")) return true;\n if (msg.includes(\"try again later\")) return true;\n if (msg.includes(\"temporar\")) return true;\n\n cur = cur?.cause;\n }\n\n return false;\n};\n\nexport const computeBackoffMs = (\n attempt: number,\n baseMs: number,\n maxMs: number,\n) => {\n const exp = baseMs * Math.pow(2, Math.max(0, attempt - 1));\n const capped = Math.min(maxMs, exp);\n const jitter = capped * (0.2 * Math.random());\n return Math.round(capped + jitter);\n};\n\nexport const aiCallWithRetry = async (params: {\n aiCall: AiCallFn;\n request: unknown;\n options: { tools?: Tool[]; toolCallingMode?: FunctionCallingConfigMode };\n retryMax: number;\n retryBaseMs: number;\n retryMaxMs: number;\n step: number;\n logger: Logger;\n}) => {\n const {\n aiCall,\n request,\n options,\n retryMax,\n retryBaseMs,\n retryMaxMs,\n logger,\n } = params;\n\n let retryCount = 0;\n while (true) {\n try {\n return await aiCall(request, options);\n } catch (err) {\n const transient = isTransientAiCallError(err);\n if (!transient || retryMax <= 0 || retryCount >= retryMax) {\n throw err;\n }\n\n retryCount += 1;\n const delayMs = computeBackoffMs(retryCount, retryBaseMs, retryMaxMs);\n logger(\"Tool loop: aiCall failed; retrying\", EVENT_TYPES.STEP_RETRY);\n await sleep(delayMs);\n }\n }\n};\n\nexport const buildToolStatusMessage = (\n name: string,\n effectiveArgs: Record<string, unknown>,\n readFileMeta: { start: number; end: number; wasCapped: boolean } | null,\n) => {\n if (name === \"read_file\" && readFileMeta) {\n return `AI tool: read_file (${readFileMeta.start}-${readFileMeta.end}${\n readFileMeta.wasCapped ? \", capped\" : \"\"\n })`;\n }\n\n if (name === \"apply_patch\") {\n const meta = getApplyPatchEventMeta(effectiveArgs);\n const files = Array.isArray(meta.files) ? meta.files.length : 0;\n return `AI tool: apply_patch (${files} file${files === 1 ? \"\" : \"s\"})`;\n }\n\n if (name === \"search\") return \"AI tool: search\";\n if (name === \"list_dir\") return \"AI tool: list_dir\";\n if (name === \"write_file\") return \"AI tool: write_file\";\n if (name === \"submit_planner_tasks\") return \"AI tool: submit_planner_tasks\";\n if (name === \"submit_codegen_done\") return \"AI tool: submit_codegen_done\";\n\n return `AI tool: ${name}`;\n};\n\nexport const recordToolEvent = (params: {\n toolEvents: ToolEvent[];\n name: string;\n effectiveArgs: Record<string, unknown>;\n modelArgs: Record<string, unknown>;\n readFileMeta: { start: number; end: number; wasCapped: boolean } | null;\n toolResult: unknown;\n toolResultRaw: unknown;\n}) => {\n const oneLine = (value: unknown, maxLen = 140) => {\n const raw =\n typeof value === \"string\"\n ? value\n : value === undefined\n ? \"\"\n : value === null\n ? \"null\"\n : JSON.stringify(value);\n const collapsed = raw.replace(/\\s+/g, \" \").trim();\n if (collapsed.length <= maxLen) return collapsed;\n return `${collapsed.slice(0, Math.max(0, maxLen - 1))}…`;\n };\n\n const getStringArg = (key: string) => oneLine(params.effectiveArgs[key] ?? \"\");\n\n const {\n toolEvents,\n name,\n effectiveArgs,\n modelArgs,\n readFileMeta,\n toolResult,\n toolResultRaw,\n } = params;\n\n try {\n if (name === \"read_file\") {\n const path = String(effectiveArgs.path ?? \"\");\n const start =\n readFileMeta?.start ?? Number(effectiveArgs.start_line ?? 1);\n const end = readFileMeta?.end ?? Number(effectiveArgs.end_line ?? start);\n toolEvents.push({\n name,\n summary: `read_file ${path}:${start}-${end}${readFileMeta?.wasCapped ? \" (capped)\" : \"\"}`,\n });\n return;\n }\n\n if (name === \"apply_patch\") {\n const meta =\n typeof (modelArgs as any).patch_string === \"object\"\n ? ((modelArgs as any).patch_string as any)\n : null;\n const fallback = getApplyPatchEventMeta(effectiveArgs);\n const ok =\n (toolResult as any)?.success === true\n ? \"success\"\n : (toolResult as any)?.success === false\n ? \"failure\"\n : \"done\";\n toolEvents.push({\n name,\n summary: `apply_patch files=${JSON.stringify(meta?.files ?? fallback.files)} sha256=${String(meta?.sha256 ?? fallback.sha256).slice(0, 12)} chars=${meta?.chars ?? fallback.chars} result=${ok}`,\n });\n return;\n }\n\n if (name === \"create_new_route\") {\n const parentRoute = getStringArg(\"parent_route\") || \"/\";\n const routeName = getStringArg(\"route_name\");\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const route = oneLine((toolResult as any)?.route ?? \"\");\n const createdFiles = Array.isArray((toolResult as any)?.created_files)\n ? ((toolResult as any).created_files as unknown[])\n : [];\n const filesText =\n successVal === true\n ? ` created_files=${createdFiles.length}`\n : \"\";\n const routeText = route ? ` route=${route}` : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `create_new_route ${successVal ? \"success\" : \"failure\"} parent_route=${parentRoute} route_name=${routeName}${routeText}${filesText}${errText}`,\n });\n return;\n }\n }\n\n if (name === \"insert_element\") {\n const route = getStringArg(\"route\");\n const parentId = getStringArg(\"parent_id\");\n const beforeId = getStringArg(\"before_id\");\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const insertedId = oneLine((toolResult as any)?.inserted_id ?? \"\");\n const changedVal = (toolResult as any)?.changed;\n const changedText =\n typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const beforeText = beforeId ? ` before_id=${beforeId}` : \"\";\n const insertedText = insertedId ? ` inserted_id=${insertedId}` : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `insert_element ${successVal ? \"success\" : \"failure\"} route=${route} parent_id=${parentId}${beforeText}${insertedText}${changedText}${errText}`,\n });\n return;\n }\n }\n\n if (name === \"update_classname\") {\n const route = getStringArg(\"route\");\n const elementId = getStringArg(\"element_id\");\n const className = oneLine(effectiveArgs.className ?? \"\", 160);\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const changedVal = (toolResult as any)?.changed;\n const changedText =\n typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const updatedId = oneLine((toolResult as any)?.updated_id ?? \"\");\n const updatedText = updatedId ? ` updated_id=${updatedId}` : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `update_classname ${successVal ? \"success\" : \"failure\"} route=${route} element_id=${elementId} className=\"${className}\"${updatedText}${changedText}${errText}`,\n });\n return;\n }\n }\n\n if (name === \"update_props\") {\n const route = getStringArg(\"route\");\n const elementId = getStringArg(\"element_id\");\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const changedVal = (toolResult as any)?.changed;\n const changedText =\n typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const updatedId = oneLine((toolResult as any)?.updated_id ?? \"\");\n const updatedText = updatedId ? ` updated_id=${updatedId}` : \"\";\n const patchKeys = Object.keys(effectiveArgs ?? {}).filter((k) => {\n if (k === \"route\" || k === \"element_id\") return false;\n const v = (effectiveArgs as any)[k];\n return v !== undefined && v !== null;\n });\n const keysText =\n patchKeys.length > 0\n ? ` keys=${oneLine(patchKeys.sort().join(\",\"), 140)}`\n : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `update_props ${successVal ? \"success\" : \"failure\"} route=${route} element_id=${elementId}${keysText}${updatedText}${changedText}${errText}`,\n });\n return;\n }\n }\n\n if (name === \"update_global_styles\") {\n const tokenKeySet = new Set<string>(STYLE_TOKEN_KEYS as unknown as string[]);\n const tokenKeys =\n Object.keys(effectiveArgs ?? {}).filter((k) => tokenKeySet.has(k));\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const changedVal = (toolResult as any)?.changed;\n const changedText =\n typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const version = (toolResult as any)?.version;\n const versionText =\n typeof version === \"number\" && Number.isFinite(version)\n ? ` version=${version}`\n : \"\";\n const created = (toolResult as any)?.created;\n const createdText =\n typeof created === \"boolean\" ? ` created=${created}` : \"\";\n const keysText =\n tokenKeys.length > 0\n ? ` tokens=${oneLine(tokenKeys.sort().join(\",\"), 160)}`\n : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `update_global_styles ${successVal ? \"success\" : \"failure\"}${keysText}${versionText}${createdText}${changedText}${errText}`,\n });\n return;\n }\n }\n\n if (name === \"search\") {\n const q = String(effectiveArgs.search_query ?? \"\").trim();\n const results = Array.isArray((toolResultRaw as any)?.results)\n ? (toolResultRaw as any).results\n : [];\n toolEvents.push({\n name,\n summary: `search \"${q}\" -> ${results.length} results`,\n });\n return;\n }\n\n if (name === \"list_dir\") {\n const p = String(effectiveArgs.path ?? \"\");\n const d = Number(effectiveArgs.depth ?? 1);\n toolEvents.push({ name, summary: `list_dir ${p} depth=${d}` });\n return;\n }\n\n if (name === \"create_file\") {\n const p = String(effectiveArgs.path ?? \"\");\n toolEvents.push({ name, summary: `create_file ${p}` });\n return;\n }\n\n if (name === \"delete_file\") {\n const p = String(effectiveArgs.path ?? \"\");\n toolEvents.push({ name, summary: `delete_file ${p}` });\n return;\n }\n\n const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const changedVal = (toolResult as any)?.changed;\n const changedText = typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const errText =\n successVal === false\n ? ` error=${oneLine((toolResult as any)?.error ?? \"unknown\", 160)}`\n : \"\";\n toolEvents.push({\n name,\n summary: `${name} ${successVal ? \"success\" : \"failure\"}${changedText}${errText}`,\n });\n return;\n }\n\n toolEvents.push({ name, summary: `${name} called` });\n } catch {\n toolEvents.push({ name, summary: `${name} called` });\n }\n};\n"]}
@@ -95,11 +95,18 @@ export declare const createWorkspaceToolImpls: (deps: SearchDeps) => {
95
95
  changed?: undefined;
96
96
  warnings?: undefined;
97
97
  }>;
98
- updateGlobalStylesImpl: (args: {
99
- tokens: Partial<Record<import("../../../types/styleConfig.js").StyleTokenKey, string>>;
100
- }) => Promise<{
98
+ updateGlobalStylesImpl: (rawArgs: unknown) => Promise<{
101
99
  success: boolean;
102
100
  error: string;
101
+ error_detail: import("zod").ZodFlattenedError<Record<string, unknown>, string>;
102
+ changed?: undefined;
103
+ file?: undefined;
104
+ version?: undefined;
105
+ created?: undefined;
106
+ } | {
107
+ success: boolean;
108
+ error: string;
109
+ error_detail?: undefined;
103
110
  changed?: undefined;
104
111
  file?: undefined;
105
112
  version?: undefined;
@@ -111,6 +118,7 @@ export declare const createWorkspaceToolImpls: (deps: SearchDeps) => {
111
118
  version: number;
112
119
  created: boolean;
113
120
  error?: undefined;
121
+ error_detail?: undefined;
114
122
  }>;
115
123
  createNewRouteImpl: (parentRoute: string, routeName: string) => Promise<{
116
124
  success: false;
@@ -1 +1 @@
1
- {"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/factories.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAMrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EACV,UAAU,EACV,MAAM,EACN,aAAa,GACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,eAAO,MAAM,wBAAwB,GAAI,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BxD,CAAC"}
1
+ {"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/factories.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAMrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EACV,UAAU,EACV,MAAM,EACN,aAAa,GACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,eAAO,MAAM,wBAAwB,GAAI,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0BxD,CAAC"}
@@ -1,11 +1,16 @@
1
- import { type StyleTokenKey } from "../../../types/styleConfig.js";
2
1
  import { type WorkspaceDeps } from "./workspaceDeps.js";
3
- type UpdateGlobalStylesArgs = {
4
- tokens: Partial<Record<StyleTokenKey, string>>;
5
- };
6
- export declare const createUpdateGlobalStylesImpl: (deps: WorkspaceDeps) => (args: UpdateGlobalStylesArgs) => Promise<{
2
+ export declare const createUpdateGlobalStylesImpl: (deps: WorkspaceDeps) => (rawArgs: unknown) => Promise<{
7
3
  success: boolean;
8
4
  error: string;
5
+ error_detail: import("zod").ZodFlattenedError<Record<string, unknown>, string>;
6
+ changed?: undefined;
7
+ file?: undefined;
8
+ version?: undefined;
9
+ created?: undefined;
10
+ } | {
11
+ success: boolean;
12
+ error: string;
13
+ error_detail?: undefined;
9
14
  changed?: undefined;
10
15
  file?: undefined;
11
16
  version?: undefined;
@@ -17,6 +22,6 @@ export declare const createUpdateGlobalStylesImpl: (deps: WorkspaceDeps) => (arg
17
22
  version: number;
18
23
  created: boolean;
19
24
  error?: undefined;
25
+ error_detail?: undefined;
20
26
  }>;
21
- export {};
22
27
  //# sourceMappingURL=updateGlobalStyles.impl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"updateGlobalStyles.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/updateGlobalStyles.impl.ts"],"names":[],"mappings":"AAGA,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,KAAK,sBAAsB,GAAG;IAC5B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;CAChD,CAAC;AAgBF,eAAO,MAAM,4BAA4B,GAAI,MAAM,aAAa,MAGhD,MAAM,sBAAsB;;;;;;;;;;;;;;EA8E3C,CAAC"}
1
+ {"version":3,"file":"updateGlobalStyles.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/updateGlobalStyles.impl.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAcxD,eAAO,MAAM,4BAA4B,GAAI,MAAM,aAAa,MAGhD,SAAS,OAAO;;;;;;;;;;;;;;;;;;;;;;;;EAuE/B,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import path from "node:path";
2
2
  import { toWorkspacePath } from "../helpers/fileSystem.helpers.js";
3
3
  import { writeFileAtomic } from "../helpers/pageConfigJson.helpers.js";
4
- import { assertStyleConfig, defaultStyleConfigJson, STYLE_TOKEN_KEYS, } from "../../../types/styleConfig.js";
4
+ import { assertStyleConfig, defaultStyleConfigJson, } from "../../../types/styleConfig.js";
5
+ import { UpdateGlobalStylesArgsZod } from "../validators/updateGlobalStyles.zod.js";
5
6
  const STYLE_CONFIG_REL_PATH = path.posix.join("app", "styleConfig.json");
6
7
  const parseStyleConfigOrDefault = (raw) => {
7
8
  try {
@@ -12,26 +13,18 @@ const parseStyleConfigOrDefault = (raw) => {
12
13
  return assertStyleConfig(defaultStyleConfigJson);
13
14
  }
14
15
  };
15
- const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
16
16
  export const createUpdateGlobalStylesImpl = (deps) => {
17
17
  const { workspaceRoot, fs } = deps;
18
- return async (args) => {
19
- const tokensPatch = args?.tokens;
20
- if (!isPlainObject(tokensPatch)) {
21
- return { success: false, error: "invalid tokens" };
22
- }
23
- const allowedKeys = new Set(STYLE_TOKEN_KEYS);
24
- const patchKeys = Object.keys(tokensPatch);
25
- if (patchKeys.length === 0) {
26
- return { success: false, error: "tokens patch must not be empty" };
27
- }
28
- const unknownKeys = patchKeys.filter((k) => !allowedKeys.has(k));
29
- if (unknownKeys.length > 0) {
18
+ return async (rawArgs) => {
19
+ const parsed = UpdateGlobalStylesArgsZod.safeParse(rawArgs);
20
+ if (!parsed.success) {
30
21
  return {
31
22
  success: false,
32
- error: `unknown token keys: ${unknownKeys.sort().join(", ")}`,
23
+ error: "invalid args",
24
+ error_detail: parsed.error.flatten(),
33
25
  };
34
26
  }
27
+ const tokensPatch = parsed.data;
35
28
  const configPath = toWorkspacePath(workspaceRoot, STYLE_CONFIG_REL_PATH);
36
29
  let beforeConfig;
37
30
  let existed = true;
@@ -1 +1 @@
1
- {"version":3,"file":"updateGlobalStyles.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/updateGlobalStyles.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport { toWorkspacePath } from \"../helpers/fileSystem.helpers.js\";\nimport { writeFileAtomic } from \"../helpers/pageConfigJson.helpers.js\";\nimport {\n assertStyleConfig,\n defaultStyleConfigJson,\n STYLE_TOKEN_KEYS,\n type StyleConfig,\n type StyleTokenKey,\n} from \"../../../types/styleConfig.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\ntype UpdateGlobalStylesArgs = {\n tokens: Partial<Record<StyleTokenKey, string>>;\n};\n\nconst STYLE_CONFIG_REL_PATH = path.posix.join(\"app\", \"styleConfig.json\");\n\nconst parseStyleConfigOrDefault = (raw: string): StyleConfig => {\n try {\n const parsed = JSON.parse(String(raw ?? \"\"));\n return assertStyleConfig(parsed);\n } catch {\n return assertStyleConfig(defaultStyleConfigJson);\n }\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nexport const createUpdateGlobalStylesImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (args: UpdateGlobalStylesArgs) => {\n const tokensPatch = (args as any)?.tokens;\n if (!isPlainObject(tokensPatch)) {\n return { success: false, error: \"invalid tokens\" };\n }\n\n const allowedKeys = new Set<string>(STYLE_TOKEN_KEYS as unknown as string[]);\n const patchKeys = Object.keys(tokensPatch);\n if (patchKeys.length === 0) {\n return { success: false, error: \"tokens patch must not be empty\" };\n }\n const unknownKeys = patchKeys.filter((k) => !allowedKeys.has(k));\n if (unknownKeys.length > 0) {\n return {\n success: false,\n error: `unknown token keys: ${unknownKeys.sort().join(\", \")}`,\n };\n }\n\n const configPath = toWorkspacePath(workspaceRoot, STYLE_CONFIG_REL_PATH);\n\n let beforeConfig: StyleConfig;\n let existed = true;\n try {\n const raw = await fs.readFile(configPath);\n beforeConfig = parseStyleConfigOrDefault(raw);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code !== \"ENOENT\") {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n existed = false;\n beforeConfig = assertStyleConfig(defaultStyleConfigJson);\n }\n\n const merged: StyleConfig = {\n version: beforeConfig.version,\n tokens: {\n ...beforeConfig.tokens,\n ...(tokensPatch as Partial<Record<StyleTokenKey, string>>),\n } as any,\n };\n\n let validated: StyleConfig;\n try {\n validated = assertStyleConfig(merged);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n const nextVersion = Number.isFinite(validated.version)\n ? validated.version + 1\n : 1;\n const afterConfig: StyleConfig = { ...validated, version: nextVersion };\n\n const after = JSON.stringify(afterConfig, null, 2) + \"\\n\";\n try {\n await writeFileAtomic(configPath, after);\n return {\n success: true,\n changed: true,\n file: STYLE_CONFIG_REL_PATH,\n version: nextVersion,\n created: !existed,\n };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n };\n};\n"]}
1
+ {"version":3,"file":"updateGlobalStyles.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/updateGlobalStyles.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport { toWorkspacePath } from \"../helpers/fileSystem.helpers.js\";\nimport { writeFileAtomic } from \"../helpers/pageConfigJson.helpers.js\";\nimport {\n assertStyleConfig,\n defaultStyleConfigJson,\n type StyleConfig,\n type StyleTokenKey,\n} from \"../../../types/styleConfig.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\nimport { UpdateGlobalStylesArgsZod } from \"../validators/updateGlobalStyles.zod.js\";\n\nconst STYLE_CONFIG_REL_PATH = path.posix.join(\"app\", \"styleConfig.json\");\n\nconst parseStyleConfigOrDefault = (raw: string): StyleConfig => {\n try {\n const parsed = JSON.parse(String(raw ?? \"\"));\n return assertStyleConfig(parsed);\n } catch {\n return assertStyleConfig(defaultStyleConfigJson);\n }\n};\n\nexport const createUpdateGlobalStylesImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (rawArgs: unknown) => {\n const parsed = UpdateGlobalStylesArgsZod.safeParse(rawArgs);\n if (!parsed.success) {\n return {\n success: false,\n error: \"invalid args\",\n error_detail: parsed.error.flatten(),\n };\n }\n\n const tokensPatch = parsed.data as Partial<Record<StyleTokenKey, string>>;\n\n const configPath = toWorkspacePath(workspaceRoot, STYLE_CONFIG_REL_PATH);\n\n let beforeConfig: StyleConfig;\n let existed = true;\n try {\n const raw = await fs.readFile(configPath);\n beforeConfig = parseStyleConfigOrDefault(raw);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code !== \"ENOENT\") {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n existed = false;\n beforeConfig = assertStyleConfig(defaultStyleConfigJson);\n }\n\n const merged: StyleConfig = {\n version: beforeConfig.version,\n tokens: {\n ...beforeConfig.tokens,\n ...(tokensPatch as Partial<Record<StyleTokenKey, string>>),\n } as any,\n };\n\n let validated: StyleConfig;\n try {\n validated = assertStyleConfig(merged);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n const nextVersion = Number.isFinite(validated.version)\n ? validated.version + 1\n : 1;\n const afterConfig: StyleConfig = { ...validated, version: nextVersion };\n\n const after = JSON.stringify(afterConfig, null, 2) + \"\\n\";\n try {\n await writeFileAtomic(configPath, after);\n return {\n success: true,\n changed: true,\n file: STYLE_CONFIG_REL_PATH,\n version: nextVersion,\n created: !existed,\n };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n };\n};\n"]}
@@ -5,16 +5,12 @@ export declare const UpdateGlobalStylesSchema: {
5
5
  parameters: {
6
6
  type: Type;
7
7
  properties: {
8
- tokens: {
8
+ [k: string]: {
9
9
  type: Type;
10
10
  description: string;
11
- minProperties: string;
12
- additionalProperties: {
13
- type: Type;
14
- };
15
11
  };
16
12
  };
17
- required: string[];
13
+ description: string;
18
14
  };
19
15
  };
20
16
  //# sourceMappingURL=updateGlobalStyles.schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"updateGlobalStyles.schema.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/updateGlobalStyles.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;CAmBpC,CAAC"}
1
+ {"version":3,"file":"updateGlobalStyles.schema.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/updateGlobalStyles.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;CAsBpC,CAAC"}
@@ -6,14 +6,16 @@ export const UpdateGlobalStylesSchema = {
6
6
  parameters: {
7
7
  type: Type.OBJECT,
8
8
  properties: {
9
- tokens: {
10
- type: Type.OBJECT,
11
- description: `Partial tokens patch (must include at least 1 key). Allowed keys: ${STYLE_TOKEN_KEYS.join(", ")}. Values must be non-empty safe CSS strings (e.g. '0.75rem' or 'oklch(0.62 0.16 199.4)'). Unknown keys are rejected.`,
12
- minProperties: "1",
13
- additionalProperties: { type: Type.STRING },
14
- },
9
+ ...Object.fromEntries(STYLE_TOKEN_KEYS.map((k) => [
10
+ k,
11
+ {
12
+ type: Type.STRING,
13
+ description: "CSS value string for this token (e.g. '0.75rem' or 'oklch(0.62 0.16 199.4)'). Omit keys you don't want to change.",
14
+ },
15
+ ])),
15
16
  },
16
- required: ["tokens"],
17
+ description: `Args are a flat object where each key is an optional token name; include at least 1 key. ` +
18
+ `Allowed keys: ${STYLE_TOKEN_KEYS.join(", ")}.`,
17
19
  },
18
20
  };
19
21
  //# sourceMappingURL=updateGlobalStyles.schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"updateGlobalStyles.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/updateGlobalStyles.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACT,wKAAwK;IAC1K,UAAU,EAAE;QACV,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,UAAU,EAAE;YACV,MAAM,EAAE;gBACN,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EACT,qEAAqE,gBAAgB,CAAC,IAAI,CACxF,IAAI,CACL,sHAAsH;gBACzH,aAAa,EAAE,GAAG;gBAClB,oBAAoB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE;aAC5C;SACF;QACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;KACrB;CACF,CAAC","sourcesContent":["import { Type } from \"@google/genai\";\nimport { STYLE_TOKEN_KEYS } from \"../../../types/styleConfig.js\";\n\nexport const UpdateGlobalStylesSchema = {\n name: \"update_global_styles\",\n description:\n \"Updates global design tokens in app/styleConfig.json. Use this to change theme colors/radius used by semantic Tailwind classes like bg-background and text-foreground.\",\n parameters: {\n type: Type.OBJECT,\n properties: {\n tokens: {\n type: Type.OBJECT,\n description:\n `Partial tokens patch (must include at least 1 key). Allowed keys: ${STYLE_TOKEN_KEYS.join(\n \", \",\n )}. Values must be non-empty safe CSS strings (e.g. '0.75rem' or 'oklch(0.62 0.16 199.4)'). Unknown keys are rejected.`,\n minProperties: \"1\",\n additionalProperties: { type: Type.STRING },\n },\n },\n required: [\"tokens\"],\n },\n};\n"]}
1
+ {"version":3,"file":"updateGlobalStyles.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/updateGlobalStyles.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EACT,wKAAwK;IAC1K,UAAU,EAAE;QACV,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,UAAU,EAAE;YACV,GAAG,MAAM,CAAC,WAAW,CACnB,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAC1B,CAAC;gBACD;oBACE,IAAI,EAAE,IAAI,CAAC,MAAM;oBACjB,WAAW,EACT,mHAAmH;iBACtH;aACF,CAAC,CACH;SACF;QACD,WAAW,EACT,2FAA2F;YAC3F,iBAAiB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;KAClD;CACF,CAAC","sourcesContent":["import { Type } from \"@google/genai\";\nimport { STYLE_TOKEN_KEYS } from \"../../../types/styleConfig.js\";\n\nexport const UpdateGlobalStylesSchema = {\n name: \"update_global_styles\",\n description:\n \"Updates global design tokens in app/styleConfig.json. Use this to change theme colors/radius used by semantic Tailwind classes like bg-background and text-foreground.\",\n parameters: {\n type: Type.OBJECT,\n properties: {\n ...Object.fromEntries(\n STYLE_TOKEN_KEYS.map((k) => [\n k,\n {\n type: Type.STRING,\n description:\n \"CSS value string for this token (e.g. '0.75rem' or 'oklch(0.62 0.16 199.4)'). Omit keys you don't want to change.\",\n },\n ]),\n ),\n },\n description:\n `Args are a flat object where each key is an optional token name; include at least 1 key. ` +\n `Allowed keys: ${STYLE_TOKEN_KEYS.join(\", \")}.`,\n },\n};\n"]}
@@ -0,0 +1,5 @@
1
+ import { z } from "zod";
2
+ export declare const UpdateGlobalStylesArgsZod: z.ZodObject<{
3
+ [x: string]: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
4
+ }, z.core.$strict>;
5
+ //# sourceMappingURL=updateGlobalStyles.zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateGlobalStyles.zod.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/validators/updateGlobalStyles.zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,yBAAyB;;kBAgBlC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ import { STYLE_TOKEN_KEYS } from "../../../types/styleConfig.js";
3
+ const allowedKeys = STYLE_TOKEN_KEYS;
4
+ export const UpdateGlobalStylesArgsZod = z
5
+ .object(Object.fromEntries(allowedKeys.map((k) => [
6
+ k,
7
+ z
8
+ .string()
9
+ .transform((v) => v.trim())
10
+ .refine((v) => v.length > 0, "must be non-empty")
11
+ .optional(),
12
+ ])))
13
+ .strict()
14
+ .refine((obj) => Object.keys(obj).length > 0, {
15
+ message: "must include at least one token key/value",
16
+ });
17
+ //# sourceMappingURL=updateGlobalStyles.zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateGlobalStyles.zod.js","sourceRoot":"","sources":["../../../../src/ai/tools/validators/updateGlobalStyles.zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAsB,MAAM,+BAA+B,CAAC;AAErF,MAAM,WAAW,GAAG,gBAA8C,CAAC;AAEnE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC;KACvC,MAAM,CACL,MAAM,CAAC,WAAW,CAChB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACrB,CAAC;IACD,CAAC;SACE,MAAM,EAAE;SACR,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,mBAAmB,CAAC;SAChD,QAAQ,EAAE;CACd,CAAC,CACwC,CAC7C;KACA,MAAM,EAAE;KACR,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;IAC5C,OAAO,EAAE,2CAA2C;CACrD,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\nimport { STYLE_TOKEN_KEYS, type StyleTokenKey } from \"../../../types/styleConfig.js\";\n\nconst allowedKeys = STYLE_TOKEN_KEYS as unknown as StyleTokenKey[];\n\nexport const UpdateGlobalStylesArgsZod = z\n .object(\n Object.fromEntries(\n allowedKeys.map((k) => [\n k,\n z\n .string()\n .transform((v) => v.trim())\n .refine((v) => v.length > 0, \"must be non-empty\")\n .optional(),\n ]),\n ) as unknown as Record<string, z.ZodTypeAny>,\n )\n .strict()\n .refine((obj) => Object.keys(obj).length > 0, {\n message: \"must include at least one token key/value\",\n });\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=toolLoopRunner.updateGlobalStylesEmptyArgs.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolLoopRunner.updateGlobalStylesEmptyArgs.test.d.ts","sourceRoot":"","sources":["../../src/tests/toolLoopRunner.updateGlobalStylesEmptyArgs.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { FunctionCallingConfigMode } from "@google/genai";
4
+ import { runToolLoop } from "../ai/toolLoop/toolLoopRunner.js";
5
+ test("tool loop: update_global_styles empty tokens is rejected without calling handler", async () => {
6
+ let handlerCalls = 0;
7
+ let aiCalls = 0;
8
+ const aiCall = async () => {
9
+ aiCalls += 1;
10
+ if (aiCalls === 1) {
11
+ return {
12
+ functionCalls: [{ name: "update_global_styles", args: {} }],
13
+ };
14
+ }
15
+ return { functionCalls: [], text: "ok" };
16
+ };
17
+ const res = await runToolLoop({
18
+ initialContents: [],
19
+ tools: [],
20
+ handlers: {
21
+ update_global_styles: async () => {
22
+ handlerCalls += 1;
23
+ return { success: true };
24
+ },
25
+ },
26
+ aiCall,
27
+ logger: async () => { },
28
+ toolCallingMode: FunctionCallingConfigMode.ANY,
29
+ maxSteps: 5,
30
+ keepFullTrace: false,
31
+ });
32
+ assert.equal(handlerCalls, 0);
33
+ assert.equal(res.finalText, "ok");
34
+ const toolResponses = res.modelContents.filter((c) => c?.role === "user" &&
35
+ Array.isArray(c?.parts) &&
36
+ c.parts.some((p) => p?.functionResponse?.name === "update_global_styles"));
37
+ assert.equal(toolResponses.length, 1);
38
+ const fr = toolResponses[0].parts.find((p) => p?.functionResponse?.name === "update_global_styles")?.functionResponse?.response;
39
+ assert.equal(fr?.success, false);
40
+ assert.match(String(fr?.error ?? ""), /at least one token/i);
41
+ });
42
+ //# sourceMappingURL=toolLoopRunner.updateGlobalStylesEmptyArgs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolLoopRunner.updateGlobalStylesEmptyArgs.test.js","sourceRoot":"","sources":["../../src/tests/toolLoopRunner.updateGlobalStylesEmptyArgs.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAE/D,IAAI,CAAC,kFAAkF,EAAE,KAAK,IAAI,EAAE;IAClG,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;QACxB,OAAO,IAAI,CAAC,CAAC;QACb,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;YAClB,OAAO;gBACL,aAAa,EAAE,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;aAC5D,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC3C,CAAC,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC;QAC5B,eAAe,EAAE,EAAE;QACnB,KAAK,EAAE,EAAE;QACT,QAAQ,EAAE;YACR,oBAAoB,EAAE,KAAK,IAAI,EAAE;gBAC/B,YAAY,IAAI,CAAC,CAAC;gBAClB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YAC3B,CAAC;SACF;QACD,MAAM;QACN,MAAM,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACtB,eAAe,EAAE,yBAAyB,CAAC,GAAG;QAC9C,QAAQ,EAAE,CAAC;QACX,aAAa,EAAE,KAAK;KACrB,CAAC,CAAC;IAEH,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAC9B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAElC,MAAM,aAAa,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,CAC5C,CAAC,CAAM,EAAE,EAAE,CACT,CAAC,EAAE,IAAI,KAAK,MAAM;QAClB,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC;QACvB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,KAAK,sBAAsB,CAAC,CACjF,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAEtC,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CACpC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,KAAK,sBAAsB,CACjE,EAAE,gBAAgB,EAAE,QAAQ,CAAC;IAE9B,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACjC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,qBAAqB,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC","sourcesContent":["import assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport { FunctionCallingConfigMode } from \"@google/genai\";\nimport { runToolLoop } from \"../ai/toolLoop/toolLoopRunner.js\";\n\ntest(\"tool loop: update_global_styles empty tokens is rejected without calling handler\", async () => {\n let handlerCalls = 0;\n\n let aiCalls = 0;\n const aiCall = async () => {\n aiCalls += 1;\n if (aiCalls === 1) {\n return {\n functionCalls: [{ name: \"update_global_styles\", args: {} }],\n };\n }\n return { functionCalls: [], text: \"ok\" };\n };\n\n const res = await runToolLoop({\n initialContents: [],\n tools: [],\n handlers: {\n update_global_styles: async () => {\n handlerCalls += 1;\n return { success: true };\n },\n },\n aiCall,\n logger: async () => {},\n toolCallingMode: FunctionCallingConfigMode.ANY,\n maxSteps: 5,\n keepFullTrace: false,\n });\n\n assert.equal(handlerCalls, 0);\n assert.equal(res.finalText, \"ok\");\n\n const toolResponses = res.modelContents.filter(\n (c: any) =>\n c?.role === \"user\" &&\n Array.isArray(c?.parts) &&\n c.parts.some((p: any) => p?.functionResponse?.name === \"update_global_styles\"),\n );\n assert.equal(toolResponses.length, 1);\n\n const fr = toolResponses[0].parts.find(\n (p: any) => p?.functionResponse?.name === \"update_global_styles\",\n )?.functionResponse?.response;\n\n assert.equal(fr?.success, false);\n assert.match(String(fr?.error ?? \"\"), /at least one token/i);\n});\n"]}
@@ -63,7 +63,7 @@ test("update_global_styles: merges tokens and bumps version", async () => {
63
63
  },
64
64
  }, null, 2) + "\n", "utf-8");
65
65
  const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() });
66
- const res = await impl({ tokens: { background: "oklch(0.88 0.02 80.2)" } });
66
+ const res = await impl({ background: "oklch(0.88 0.02 80.2)" });
67
67
  assert.equal(res?.success, true);
68
68
  assert.equal(res?.version, 11);
69
69
  const stored = await readStyleConfig(workspaceRoot);
@@ -79,7 +79,7 @@ test("update_global_styles: missing file => creates defaults and applies patch",
79
79
  try {
80
80
  await fs.mkdir(path.join(workspaceRoot, "app"), { recursive: true });
81
81
  const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() });
82
- const res = await impl({ tokens: { radius: "0.5rem" } });
82
+ const res = await impl({ radius: "0.5rem" });
83
83
  assert.equal(res?.success, true);
84
84
  assert.equal(res?.created, true);
85
85
  const stored = await readStyleConfig(workspaceRoot);
@@ -96,7 +96,7 @@ test("update_global_styles: invalid JSON => recreates defaults then applies patc
96
96
  await fs.mkdir(path.join(workspaceRoot, "app"), { recursive: true });
97
97
  await fs.writeFile(path.join(workspaceRoot, "app", "styleConfig.json"), "{", "utf-8");
98
98
  const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() });
99
- const res = await impl({ tokens: { border: "oklch(0.5 0.02 82.5)" } });
99
+ const res = await impl({ border: "oklch(0.5 0.02 82.5)" });
100
100
  assert.equal(res?.success, true);
101
101
  const stored = await readStyleConfig(workspaceRoot);
102
102
  assert.equal(stored.tokens.border, "oklch(0.5 0.02 82.5)");
@@ -111,7 +111,7 @@ test("update_global_styles: unknown token key is rejected", async () => {
111
111
  try {
112
112
  await fs.mkdir(path.join(workspaceRoot, "app"), { recursive: true });
113
113
  const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() });
114
- const res = await impl({ tokens: { notAKey: "oklch(0.1 0 0)" } });
114
+ const res = await impl({ notAKey: "oklch(0.1 0 0)" });
115
115
  assert.equal(res?.success, false);
116
116
  }
117
117
  finally {
@@ -123,7 +123,7 @@ test("update_global_styles: unsafe/empty token value is rejected", async () => {
123
123
  try {
124
124
  await fs.mkdir(path.join(workspaceRoot, "app"), { recursive: true });
125
125
  const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() });
126
- const res = await impl({ tokens: { background: "" } });
126
+ const res = await impl({ background: "" });
127
127
  assert.equal(res?.success, false);
128
128
  }
129
129
  finally {
@@ -136,7 +136,7 @@ test("update_global_styles: empty tokens patch is rejected", async () => {
136
136
  await fs.mkdir(path.join(workspaceRoot, "app"), { recursive: true });
137
137
  await fs.writeFile(path.join(workspaceRoot, "app", "styleConfig.json"), JSON.stringify({ version: 1, tokens: { radius: "0.85rem" } }), "utf-8");
138
138
  const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() });
139
- const res = await impl({ tokens: {} });
139
+ const res = await impl({});
140
140
  assert.equal(res?.success, false);
141
141
  const stored = await readStyleConfig(workspaceRoot);
142
142
  assert.equal(stored.version, 1);
@@ -1 +1 @@
1
- {"version":3,"file":"updateGlobalStyles.impl.test.js","sourceRoot":"","sources":["../../src/tests/updateGlobalStyles.impl.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EACL,4BAA4B,GAC7B,MAAM,wDAAwD,CAAC;AAIhE,MAAM,UAAU,GAAG,CAAC,SAA2B,EAAU,EAAE;IACzD,OAAO;QACL,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;QACpE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,CACzC,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,IAAI,EAAE,EAAE,OAAO,CAAC;QACpD,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;YAC5B,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACpE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC;QACnD,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CACjC,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;QAClD,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC;KACrB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,KAAK,EAAE,aAAqB,EAAE,EAAE;IACtD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAC3B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,kBAAkB,CAAC,EACnD,OAAO,CACR,CAAC;IACF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAQ,CAAC;AAChC,CAAC,CAAC;AAEF,IAAI,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;IACvE,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IAChF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,kBAAkB,CAAC,EACnD,IAAI,CAAC,SAAS,CACZ;YACE,OAAO,EAAE,EAAE;YACX,MAAM,EAAE;gBACN,MAAM,EAAE,MAAM;gBACd,UAAU,EAAE,sBAAsB;gBAClC,UAAU,EAAE,uBAAuB;gBACnC,IAAI,EAAE,yBAAyB;gBAC/B,cAAc,EAAE,uBAAuB;gBACvC,OAAO,EAAE,yBAAyB;gBAClC,iBAAiB,EAAE,uBAAuB;gBAC1C,OAAO,EAAE,wBAAwB;gBACjC,iBAAiB,EAAE,yBAAyB;gBAC5C,SAAS,EAAE,uBAAuB;gBAClC,mBAAmB,EAAE,wBAAwB;gBAC7C,KAAK,EAAE,uBAAuB;gBAC9B,eAAe,EAAE,wBAAwB;gBACzC,MAAM,EAAE,sBAAsB;gBAC9B,gBAAgB,EAAE,wBAAwB;gBAC1C,WAAW,EAAE,uBAAuB;gBACpC,MAAM,EAAE,uBAAuB;gBAC/B,KAAK,EAAE,uBAAuB;gBAC9B,IAAI,EAAE,wBAAwB;gBAC9B,MAAM,EAAE,wBAAwB;gBAChC,MAAM,EAAE,wBAAwB;gBAChC,MAAM,EAAE,wBAAwB;gBAChC,MAAM,EAAE,uBAAuB;gBAC/B,MAAM,EAAE,uBAAuB;gBAC/B,OAAO,EAAE,wBAAwB;gBACjC,iBAAiB,EAAE,uBAAuB;gBAC1C,cAAc,EAAE,wBAAwB;gBACxC,wBAAwB,EAAE,yBAAyB;gBACnD,aAAa,EAAE,uBAAuB;gBACtC,uBAAuB,EAAE,wBAAwB;gBACjD,aAAa,EAAE,uBAAuB;gBACtC,WAAW,EAAE,wBAAwB;aACtC;SACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI,EACR,OAAO,CACR,CAAC;QAEF,MAAM,IAAI,GAAG,4BAA4B,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,EAAS,CAAC,CAAC;QACtF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,uBAAuB,EAAE,EAAE,CAAC,CAAC;QAC5E,MAAM,CAAC,KAAK,CAAE,GAAW,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAE,GAAW,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;QAExC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;IAClE,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;IAC1F,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IAChF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,4BAA4B,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,EAAS,CAAC,CAAC;QACtF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,KAAK,CAAE,GAAW,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAE,GAAW,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAE1C,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAClC,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6EAA6E,EAAE,KAAK,IAAI,EAAE;IAC7F,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IAChF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,kBAAkB,CAAC,EACnD,GAAG,EACH,OAAO,CACR,CAAC;QACF,MAAM,IAAI,GAAG,4BAA4B,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,EAAS,CAAC,CAAC;QACtF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE,EAAE,CAAC,CAAC;QACvE,MAAM,CAAC,KAAK,CAAE,GAAW,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAE1C,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;QAC3D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAClC,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;IACrE,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IAChF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,4BAA4B,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,EAAS,CAAC,CAAC;QACtF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAS,EAAE,CAAC,CAAC;QACzE,MAAM,CAAC,KAAK,CAAE,GAAW,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;IAC5E,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IAChF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,4BAA4B,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,EAAS,CAAC,CAAC;QACtF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAE,GAAW,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;IACtE,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IAChF,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,kBAAkB,CAAC,EACnD,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,EAC7D,OAAO,CACR,CAAC;QAEF,MAAM,IAAI,GAAG,4BAA4B,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,UAAU,EAAE,EAAS,CAAC,CAAC;QACtF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,EAAS,EAAE,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAE,GAAW,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAClC,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC,CAAC,CAAC","sourcesContent":["import assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport fs from \"node:fs/promises\";\nimport {\n createUpdateGlobalStylesImpl,\n} from \"../ai/tools/implementations/updateGlobalStyles.impl.js\";\n\ntype CoreFs = Parameters<typeof createUpdateGlobalStylesImpl>[0][\"fs\"];\n\nconst makeRealFs = (overrides?: Partial<CoreFs>): CoreFs => {\n return {\n readFile: async (absolutePath) => fs.readFile(absolutePath, \"utf-8\"),\n writeFile: async (absolutePath, content) =>\n fs.writeFile(absolutePath, content ?? \"\", \"utf-8\"),\n mkdirp: async (absoluteDir) => {\n await fs.mkdir(absoluteDir, { recursive: true });\n },\n rmFile: async (absolutePath) => fs.rm(absolutePath, { force: true }),\n stat: async (absolutePath) => fs.stat(absolutePath),\n safeReadDir: async (absoluteDir) =>\n fs.readdir(absoluteDir, { withFileTypes: true }),\n ...(overrides ?? {}),\n };\n};\n\nconst readStyleConfig = async (workspaceRoot: string) => {\n const raw = await fs.readFile(\n path.join(workspaceRoot, \"app\", \"styleConfig.json\"),\n \"utf-8\",\n );\n return JSON.parse(raw) as any;\n};\n\ntest(\"update_global_styles: merges tokens and bumps version\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n await fs.writeFile(\n path.join(workspaceRoot, \"app\", \"styleConfig.json\"),\n JSON.stringify(\n {\n version: 10,\n tokens: {\n radius: \"1rem\",\n background: \"oklch(0.9 0.02 80.2)\",\n foreground: \"oklch(0.2 0.03 255.4)\",\n card: \"oklch(0.995 0.004 80.2)\",\n cardForeground: \"oklch(0.2 0.03 255.4)\",\n popover: \"oklch(0.995 0.004 80.2)\",\n popoverForeground: \"oklch(0.2 0.03 255.4)\",\n primary: \"oklch(0.62 0.16 199.4)\",\n primaryForeground: \"oklch(0.985 0.008 80.2)\",\n secondary: \"oklch(0.94 0.02 83.1)\",\n secondaryForeground: \"oklch(0.22 0.04 258.2)\",\n muted: \"oklch(0.95 0.01 85.6)\",\n mutedForeground: \"oklch(0.46 0.04 257.6)\",\n accent: \"oklch(0.9 0.06 78.4)\",\n accentForeground: \"oklch(0.22 0.04 258.2)\",\n destructive: \"oklch(0.57 0.21 25.6)\",\n border: \"oklch(0.89 0.02 82.5)\",\n input: \"oklch(0.92 0.02 82.5)\",\n ring: \"oklch(0.62 0.16 199.4)\",\n chart1: \"oklch(0.62 0.16 199.4)\",\n chart2: \"oklch(0.66 0.14 143.6)\",\n chart3: \"oklch(0.52 0.12 297.6)\",\n chart4: \"oklch(0.74 0.16 79.3)\",\n chart5: \"oklch(0.62 0.18 24.8)\",\n sidebar: \"oklch(0.975 0.01 82.5)\",\n sidebarForeground: \"oklch(0.2 0.03 255.4)\",\n sidebarPrimary: \"oklch(0.62 0.16 199.4)\",\n sidebarPrimaryForeground: \"oklch(0.985 0.008 80.2)\",\n sidebarAccent: \"oklch(0.94 0.02 83.1)\",\n sidebarAccentForeground: \"oklch(0.22 0.04 258.2)\",\n sidebarBorder: \"oklch(0.89 0.02 82.5)\",\n sidebarRing: \"oklch(0.62 0.16 199.4)\",\n },\n },\n null,\n 2,\n ) + \"\\n\",\n \"utf-8\",\n );\n\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ tokens: { background: \"oklch(0.88 0.02 80.2)\" } });\n assert.equal((res as any)?.success, true);\n assert.equal((res as any)?.version, 11);\n\n const stored = await readStyleConfig(workspaceRoot);\n assert.equal(stored.version, 11);\n assert.equal(stored.tokens.background, \"oklch(0.88 0.02 80.2)\");\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"update_global_styles: missing file => creates defaults and applies patch\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ tokens: { radius: \"0.5rem\" } });\n assert.equal((res as any)?.success, true);\n assert.equal((res as any)?.created, true);\n\n const stored = await readStyleConfig(workspaceRoot);\n assert.equal(stored.tokens.radius, \"0.5rem\");\n assert.equal(stored.version, 2);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"update_global_styles: invalid JSON => recreates defaults then applies patch\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n await fs.writeFile(\n path.join(workspaceRoot, \"app\", \"styleConfig.json\"),\n \"{\",\n \"utf-8\",\n );\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ tokens: { border: \"oklch(0.5 0.02 82.5)\" } });\n assert.equal((res as any)?.success, true);\n\n const stored = await readStyleConfig(workspaceRoot);\n assert.equal(stored.tokens.border, \"oklch(0.5 0.02 82.5)\");\n assert.equal(stored.version, 2);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"update_global_styles: unknown token key is rejected\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ tokens: { notAKey: \"oklch(0.1 0 0)\" } as any });\n assert.equal((res as any)?.success, false);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"update_global_styles: unsafe/empty token value is rejected\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ tokens: { background: \"\" } });\n assert.equal((res as any)?.success, false);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"update_global_styles: empty tokens patch is rejected\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n await fs.writeFile(\n path.join(workspaceRoot, \"app\", \"styleConfig.json\"),\n JSON.stringify({ version: 1, tokens: { radius: \"0.85rem\" } }),\n \"utf-8\",\n );\n\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ tokens: {} as any });\n assert.equal((res as any)?.success, false);\n\n const stored = await readStyleConfig(workspaceRoot);\n assert.equal(stored.version, 1);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n"]}
1
+ {"version":3,"file":"updateGlobalStyles.impl.test.js","sourceRoot":"","sources":["../../src/tests/updateGlobalStyles.impl.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport path from \"node:path\";\nimport os from \"node:os\";\nimport fs from \"node:fs/promises\";\nimport {\n createUpdateGlobalStylesImpl,\n} from \"../ai/tools/implementations/updateGlobalStyles.impl.js\";\n\ntype CoreFs = Parameters<typeof createUpdateGlobalStylesImpl>[0][\"fs\"];\n\nconst makeRealFs = (overrides?: Partial<CoreFs>): CoreFs => {\n return {\n readFile: async (absolutePath) => fs.readFile(absolutePath, \"utf-8\"),\n writeFile: async (absolutePath, content) =>\n fs.writeFile(absolutePath, content ?? \"\", \"utf-8\"),\n mkdirp: async (absoluteDir) => {\n await fs.mkdir(absoluteDir, { recursive: true });\n },\n rmFile: async (absolutePath) => fs.rm(absolutePath, { force: true }),\n stat: async (absolutePath) => fs.stat(absolutePath),\n safeReadDir: async (absoluteDir) =>\n fs.readdir(absoluteDir, { withFileTypes: true }),\n ...(overrides ?? {}),\n };\n};\n\nconst readStyleConfig = async (workspaceRoot: string) => {\n const raw = await fs.readFile(\n path.join(workspaceRoot, \"app\", \"styleConfig.json\"),\n \"utf-8\",\n );\n return JSON.parse(raw) as any;\n};\n\ntest(\"update_global_styles: merges tokens and bumps version\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n await fs.writeFile(\n path.join(workspaceRoot, \"app\", \"styleConfig.json\"),\n JSON.stringify(\n {\n version: 10,\n tokens: {\n radius: \"1rem\",\n background: \"oklch(0.9 0.02 80.2)\",\n foreground: \"oklch(0.2 0.03 255.4)\",\n card: \"oklch(0.995 0.004 80.2)\",\n cardForeground: \"oklch(0.2 0.03 255.4)\",\n popover: \"oklch(0.995 0.004 80.2)\",\n popoverForeground: \"oklch(0.2 0.03 255.4)\",\n primary: \"oklch(0.62 0.16 199.4)\",\n primaryForeground: \"oklch(0.985 0.008 80.2)\",\n secondary: \"oklch(0.94 0.02 83.1)\",\n secondaryForeground: \"oklch(0.22 0.04 258.2)\",\n muted: \"oklch(0.95 0.01 85.6)\",\n mutedForeground: \"oklch(0.46 0.04 257.6)\",\n accent: \"oklch(0.9 0.06 78.4)\",\n accentForeground: \"oklch(0.22 0.04 258.2)\",\n destructive: \"oklch(0.57 0.21 25.6)\",\n border: \"oklch(0.89 0.02 82.5)\",\n input: \"oklch(0.92 0.02 82.5)\",\n ring: \"oklch(0.62 0.16 199.4)\",\n chart1: \"oklch(0.62 0.16 199.4)\",\n chart2: \"oklch(0.66 0.14 143.6)\",\n chart3: \"oklch(0.52 0.12 297.6)\",\n chart4: \"oklch(0.74 0.16 79.3)\",\n chart5: \"oklch(0.62 0.18 24.8)\",\n sidebar: \"oklch(0.975 0.01 82.5)\",\n sidebarForeground: \"oklch(0.2 0.03 255.4)\",\n sidebarPrimary: \"oklch(0.62 0.16 199.4)\",\n sidebarPrimaryForeground: \"oklch(0.985 0.008 80.2)\",\n sidebarAccent: \"oklch(0.94 0.02 83.1)\",\n sidebarAccentForeground: \"oklch(0.22 0.04 258.2)\",\n sidebarBorder: \"oklch(0.89 0.02 82.5)\",\n sidebarRing: \"oklch(0.62 0.16 199.4)\",\n },\n },\n null,\n 2,\n ) + \"\\n\",\n \"utf-8\",\n );\n\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ background: \"oklch(0.88 0.02 80.2)\" });\n assert.equal((res as any)?.success, true);\n assert.equal((res as any)?.version, 11);\n\n const stored = await readStyleConfig(workspaceRoot);\n assert.equal(stored.version, 11);\n assert.equal(stored.tokens.background, \"oklch(0.88 0.02 80.2)\");\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"update_global_styles: missing file => creates defaults and applies patch\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ radius: \"0.5rem\" });\n assert.equal((res as any)?.success, true);\n assert.equal((res as any)?.created, true);\n\n const stored = await readStyleConfig(workspaceRoot);\n assert.equal(stored.tokens.radius, \"0.5rem\");\n assert.equal(stored.version, 2);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"update_global_styles: invalid JSON => recreates defaults then applies patch\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n await fs.writeFile(\n path.join(workspaceRoot, \"app\", \"styleConfig.json\"),\n \"{\",\n \"utf-8\",\n );\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ border: \"oklch(0.5 0.02 82.5)\" });\n assert.equal((res as any)?.success, true);\n\n const stored = await readStyleConfig(workspaceRoot);\n assert.equal(stored.tokens.border, \"oklch(0.5 0.02 82.5)\");\n assert.equal(stored.version, 2);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"update_global_styles: unknown token key is rejected\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ notAKey: \"oklch(0.1 0 0)\" } as any);\n assert.equal((res as any)?.success, false);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"update_global_styles: unsafe/empty token value is rejected\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({ background: \"\" });\n assert.equal((res as any)?.success, false);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"update_global_styles: empty tokens patch is rejected\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n await fs.writeFile(\n path.join(workspaceRoot, \"app\", \"styleConfig.json\"),\n JSON.stringify({ version: 1, tokens: { radius: \"0.85rem\" } }),\n \"utf-8\",\n );\n\n const impl = createUpdateGlobalStylesImpl({ workspaceRoot, fs: makeRealFs() } as any);\n const res = await impl({} as any);\n assert.equal((res as any)?.success, false);\n\n const stored = await readStyleConfig(workspaceRoot);\n assert.equal(stored.version, 1);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vedangiitb/qwintly-core",
3
- "version": "1.3.22",
3
+ "version": "1.3.24",
4
4
  "description": "Qwintly Core",
5
5
  "homepage": "https://github.com/vedangiitb/qwintly-core#readme",
6
6
  "bugs": {