@vedangiitb/qwintly-core 1.6.3 → 1.6.5

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 (35) hide show
  1. package/dist/ai/prompts/codegen.prompt.js +1 -1
  2. package/dist/ai/prompts/codegen.prompt.js.map +1 -1
  3. package/dist/ai/prompts/examples/codegen.examples.d.ts.map +1 -1
  4. package/dist/ai/prompts/examples/codegen.examples.js +15 -0
  5. package/dist/ai/prompts/examples/codegen.examples.js.map +1 -1
  6. package/dist/ai/toolLoop/helpers/toolHandlers.helper.d.ts.map +1 -1
  7. package/dist/ai/toolLoop/helpers/toolHandlers.helper.js +11 -7
  8. package/dist/ai/toolLoop/helpers/toolHandlers.helper.js.map +1 -1
  9. package/dist/ai/toolLoop/toolLoopRunner.d.ts +1 -0
  10. package/dist/ai/toolLoop/toolLoopRunner.d.ts.map +1 -1
  11. package/dist/ai/toolLoop/toolLoopRunner.js +6 -3
  12. package/dist/ai/toolLoop/toolLoopRunner.js.map +1 -1
  13. package/dist/ai/toolLoop/toolStatusMessage.d.ts.map +1 -1
  14. package/dist/ai/toolLoop/toolStatusMessage.js +5 -1
  15. package/dist/ai/toolLoop/toolStatusMessage.js.map +1 -1
  16. package/dist/ai/tools/helpers/pageConfigJson.helpers.d.ts.map +1 -1
  17. package/dist/ai/tools/helpers/pageConfigJson.helpers.js +3 -1
  18. package/dist/ai/tools/helpers/pageConfigJson.helpers.js.map +1 -1
  19. package/dist/ai/tools/implementations/insertElement.impl.js +2 -2
  20. package/dist/ai/tools/implementations/insertElement.impl.js.map +1 -1
  21. package/dist/indexer/projectInfoIndex.d.ts.map +1 -1
  22. package/dist/indexer/projectInfoIndex.js +2 -102
  23. package/dist/indexer/projectInfoIndex.js.map +1 -1
  24. package/dist/tests/projectInfoIndex.test.js +1 -9
  25. package/dist/tests/projectInfoIndex.test.js.map +1 -1
  26. package/dist/tests/toolLoopRunner.routes.test.js +122 -0
  27. package/dist/tests/toolLoopRunner.routes.test.js.map +1 -1
  28. package/dist/types/projectInfo.types.d.ts +0 -5
  29. package/dist/types/projectInfo.types.d.ts.map +1 -1
  30. package/dist/types/projectInfo.types.js.map +1 -1
  31. package/package.json +1 -1
  32. package/dist/ai/ai.d.ts +0 -2
  33. package/dist/ai/ai.d.ts.map +0 -1
  34. package/dist/ai/ai.js +0 -2
  35. package/dist/ai/ai.js.map +0 -1
@@ -33,7 +33,7 @@ export const codegenPrompt = (params) => {
33
33
  - Create missing routes with create_new_route.
34
34
  - For any tool arg named route, always use URL paths with forward slashes (e.g. '/', '/pricing'); never use '\\' or filesystem paths like 'app/pricing'.
35
35
  - insert_element supports optional before_id to insert before an existing sibling; if omitted or not found, it appends to the end. Use this to do things like inserting navbar before the main content area, etc.
36
- - Include images whenever mentoned to be included. Just use alt tag for images. image src auto-generated from alt
36
+ - Include images whenever mentioned to be included. For images, set the type to 'image' and specify the description in the 'alt' prop under 'props' (e.g. "props": { "alt": "Description of the image" }). The image src will be auto-generated from this alt text. Do not concatenate props into the parentId.
37
37
  - lucide-react icons only
38
38
  - Prefer semantic Tailwind tokens (bg-background, text-foreground, border-border, ring-ring, etc.) over hardcoded colors (e.g. slate-*, bg-white) for global styles. If you need different global colors/radius, call update_global_styles first, then use token-based classes.
39
39
  - update_global_styles args MUST be a flat JSON object with token keys as optional params. Include at least 1 key.
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;MA2BE,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(\r\n \"Tools\",\r\n `\r\n Available tools:\r\n\r\n - read_file: Read file\r\n - update_global_styles: Update app/styleConfig.json global design tokens\r\n - list_dir: List directory\r\n - create_new_route: Create route with page.tsx + pageConfig.json\r\n - insert_element: Insert element tree (using flat array of elements)\r\n - delete_element: Delete element\r\n - update_classname: Update className\r\n - update_props: Update props\r\n - get_available_routes: Get available routes\r\n - submit_codegen_done: Finish task\r\n\r\n Rules:\r\n - Use \\`insert_element\\` to insert an entire UI tree at once. Pass a flat array of elements under \\`elements\\`. The root element of your new subtree must have \\`parentId\\` set to \\`\\\"parent\\\"\\`. All other elements in the array must set \\`parentId\\` matching the temporary \\`id\\` of their parent in that same array.\r\n - Create missing routes with create_new_route.\r\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'.\r\n - insert_element supports optional before_id to insert before an existing sibling; if omitted or not found, it appends to the end. Use this to do things like inserting navbar before the main content area, etc.\r\n - Include images whenever mentoned to be included. Just use alt tag for images. image src auto-generated from alt\r\n - lucide-react icons only\r\n - Prefer semantic Tailwind tokens (bg-background, text-foreground, border-border, ring-ring, etc.) over hardcoded colors (e.g. slate-*, bg-white) for global styles. If you need different global colors/radius, call update_global_styles first, then use token-based classes.\r\n - update_global_styles args MUST be a flat JSON object with token keys as optional params. Include at least 1 key.\r\n - While updating global styles make sure that the styles updating (ex. background, foreground) are used in the right places (using bg-background, text-foreground, etc.). If not include them by updating the classname using update_classname tool\r\n - Never call update_global_styles with {} (empty object). If you don't need to change styles, do not call this tool.\r\n - Example: {\"radius\":\"0.75rem\",\"background\":\"oklch(0.98 0.01 80)\"}.\r\n\r\n `.trim(),\r\n );\r\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;;;;;;;;;;;;;;;;;;;;;;;;;;;MA2BE,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(\r\n \"Tools\",\r\n `\r\n Available tools:\r\n\r\n - read_file: Read file\r\n - update_global_styles: Update app/styleConfig.json global design tokens\r\n - list_dir: List directory\r\n - create_new_route: Create route with page.tsx + pageConfig.json\r\n - insert_element: Insert element tree (using flat array of elements)\r\n - delete_element: Delete element\r\n - update_classname: Update className\r\n - update_props: Update props\r\n - get_available_routes: Get available routes\r\n - submit_codegen_done: Finish task\r\n\r\n Rules:\r\n - Use \\`insert_element\\` to insert an entire UI tree at once. Pass a flat array of elements under \\`elements\\`. The root element of your new subtree must have \\`parentId\\` set to \\`\\\"parent\\\"\\`. All other elements in the array must set \\`parentId\\` matching the temporary \\`id\\` of their parent in that same array.\r\n - Create missing routes with create_new_route.\r\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'.\r\n - insert_element supports optional before_id to insert before an existing sibling; if omitted or not found, it appends to the end. Use this to do things like inserting navbar before the main content area, etc.\r\n - Include images whenever mentioned to be included. For images, set the type to 'image' and specify the description in the 'alt' prop under 'props' (e.g. \"props\": { \"alt\": \"Description of the image\" }). The image src will be auto-generated from this alt text. Do not concatenate props into the parentId.\r\n - lucide-react icons only\r\n - Prefer semantic Tailwind tokens (bg-background, text-foreground, border-border, ring-ring, etc.) over hardcoded colors (e.g. slate-*, bg-white) for global styles. If you need different global colors/radius, call update_global_styles first, then use token-based classes.\r\n - update_global_styles args MUST be a flat JSON object with token keys as optional params. Include at least 1 key.\r\n - While updating global styles make sure that the styles updating (ex. background, foreground) are used in the right places (using bg-background, text-foreground, etc.). If not include them by updating the classname using update_classname tool\r\n - Never call update_global_styles with {} (empty object). If you don't need to change styles, do not call this tool.\r\n - Example: {\"radius\":\"0.75rem\",\"background\":\"oklch(0.98 0.01 80)\"}.\r\n\r\n `.trim(),\r\n );\r\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":"AAwHA,eAAO,MAAM,eAAe,QAAsB,CAAC"}
1
+ {"version":3,"file":"codegen.examples.d.ts","sourceRoot":"","sources":["../../../../src/ai/prompts/examples/codegen.examples.ts"],"names":[],"mappings":"AAuIA,eAAO,MAAM,eAAe,QAAsB,CAAC"}
@@ -46,6 +46,21 @@ Tool call:
46
46
  "text": "Get Started",
47
47
  "onClick": { "kind": "route", "href": "/signup" }
48
48
  }
49
+ },
50
+ {
51
+ "id": "cta_image_wrap",
52
+ "parentId": "cta_section",
53
+ "type": "div",
54
+ "className": "w-24 h-24 rounded-full overflow-hidden"
55
+ },
56
+ {
57
+ "id": "cta_image",
58
+ "parentId": "cta_image_wrap",
59
+ "type": "image",
60
+ "className": "w-full h-full object-cover",
61
+ "props": {
62
+ "alt": "A team collaborating in a bright workspace"
63
+ }
49
64
  }
50
65
  ]
51
66
  }
@@ -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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DA0D0D;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 \"elements\": [\n {\n \"id\": \"cta_section\",\n \"parentId\": \"parent\",\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 },\n {\n \"id\": \"text_container\",\n \"parentId\": \"cta_section\",\n \"type\": \"div\",\n \"className\": \"flex flex-col gap-1\"\n },\n {\n \"id\": \"cta_heading\",\n \"parentId\": \"text_container\",\n \"type\": \"text\",\n \"className\": \"text-lg font-semibold\",\n \"props\": { \"text\": \"Ready to get started?\" }\n },\n {\n \"id\": \"cta_subheading\",\n \"parentId\": \"text_container\",\n \"type\": \"text\",\n \"className\": \"text-sm text-muted-foreground\",\n \"props\": { \"text\": \"Create your first project in under a minute.\" }\n },\n {\n \"id\": \"cta_btn\",\n \"parentId\": \"cta_section\",\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 Notes:\n - Always pass a complete \\`className\\` string (Tailwind only).\n - Use \\`elements\\` flat list to represent UI structures of arbitrary depth.\n - Link child elements to their parent in the array by setting \\`parentId\\` to the parent element's temporary \\`id\\`.\n - The root element in the \\`elements\\` array must have \\`parentId\\` set to \\`\"parent\"\\`.\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
+ {"version":3,"file":"codegen.examples.js","sourceRoot":"","sources":["../../../../src/ai/prompts/examples/codegen.examples.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG;IACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DAyE0D;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 \"elements\": [\n {\n \"id\": \"cta_section\",\n \"parentId\": \"parent\",\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 },\n {\n \"id\": \"text_container\",\n \"parentId\": \"cta_section\",\n \"type\": \"div\",\n \"className\": \"flex flex-col gap-1\"\n },\n {\n \"id\": \"cta_heading\",\n \"parentId\": \"text_container\",\n \"type\": \"text\",\n \"className\": \"text-lg font-semibold\",\n \"props\": { \"text\": \"Ready to get started?\" }\n },\n {\n \"id\": \"cta_subheading\",\n \"parentId\": \"text_container\",\n \"type\": \"text\",\n \"className\": \"text-sm text-muted-foreground\",\n \"props\": { \"text\": \"Create your first project in under a minute.\" }\n },\n {\n \"id\": \"cta_btn\",\n \"parentId\": \"cta_section\",\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 \"id\": \"cta_image_wrap\",\n \"parentId\": \"cta_section\",\n \"type\": \"div\",\n \"className\": \"w-24 h-24 rounded-full overflow-hidden\"\n },\n {\n \"id\": \"cta_image\",\n \"parentId\": \"cta_image_wrap\",\n \"type\": \"image\",\n \"className\": \"w-full h-full object-cover\",\n \"props\": {\n \"alt\": \"A team collaborating in a bright workspace\"\n }\n }\n ]\n}\n\\`\\`\\`\n\n Notes:\n - Always pass a complete \\`className\\` string (Tailwind only).\n - Use \\`elements\\` flat list to represent UI structures of arbitrary depth.\n - Link child elements to their parent in the array by setting \\`parentId\\` to the parent element's temporary \\`id\\`.\n - The root element in the \\`elements\\` array must have \\`parentId\\` set to \\`\"parent\"\\`.\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":"toolHandlers.helper.d.ts","sourceRoot":"","sources":["../../../../src/ai/toolLoop/helpers/toolHandlers.helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AAIpF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,KAAK,EAAE,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;IACnD,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,CA4F9C"}
1
+ {"version":3,"file":"toolHandlers.helper.d.ts","sourceRoot":"","sources":["../../../../src/ai/toolLoop/helpers/toolHandlers.helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AAIpF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,KAAK,EAAE,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;IACnD,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,CAgG9C"}
@@ -52,20 +52,24 @@ export function createToolHandlers(params) {
52
52
  return result;
53
53
  },
54
54
  update_props: async (args) => {
55
- const route = String(args.route ?? "");
56
- const element_id = String(args.element_id ?? "");
57
- const props = args.props;
55
+ const { route, element_id, props, ...rest } = args;
56
+ const routeStr = String(route ?? "");
57
+ const elementIdStr = String(element_id ?? "");
58
+ const mergedProps = {
59
+ ...(typeof props === "object" && props !== null ? props : {}),
60
+ ...rest,
61
+ };
58
62
  const result = await params.impls.updatePropsImpl({
59
- route,
60
- element_id,
61
- ...props,
63
+ route: routeStr,
64
+ element_id: elementIdStr,
65
+ ...mergedProps,
62
66
  });
63
67
  return result;
64
68
  },
65
69
  update_classname: async (args) => {
66
70
  const route = String(args.route ?? "");
67
71
  const element_id = String(args.element_id ?? "");
68
- const class_name = String(args.class_name ?? "");
72
+ const class_name = String(args.className ?? args.class_name ?? "");
69
73
  const result = await params.impls.updateClassNameImpl(route, element_id, class_name);
70
74
  return result;
71
75
  },
@@ -1 +1 @@
1
- {"version":3,"file":"toolHandlers.helper.js","sourceRoot":"","sources":["../../../../src/ai/toolLoop/helpers/toolHandlers.helper.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAvailableRoutes } from \"../../tools/helpers/pageConfigJson.helpers.js\";\nimport { createWorkspaceToolImpls } from \"../../tools/implementations/factories.js\";\nimport { nodeFs } from \"./fsHelpers.js\";\nimport { parsePlannerTasksUnknown } from \"./plannerTaskParser.js\";\n\nexport function createToolHandlers(params: {\n impls: ReturnType<typeof createWorkspaceToolImpls>;\n workspaceRoot: string;\n}): Record<string, (args: any) => Promise<any>> {\n return {\n read_file: async (args) => {\n const path = String(args.path ?? \"\");\n const startLine =\n args.start_line === undefined ? undefined : Number(args.start_line);\n const endLine =\n args.end_line === undefined ? undefined : Number(args.end_line);\n const content = await params.impls.readFileImpl(path, startLine, endLine);\n return { path, content };\n },\n write_file: (args) =>\n params.impls.writeFileImpl(String(args.path ?? \"\"), String(args.content ?? \"\")),\n list_dir: async (args) => {\n const content = await params.impls.listDirImpl(\n String(args.path ?? \"\"),\n Number(args.depth ?? 1),\n );\n return { content };\n },\n search: async (args) => {\n const results = await params.impls.searchImpl(String(args.search_query ?? \"\"));\n return { results };\n },\n apply_patch: (args) =>\n params.impls.applyPatchImpl(String(args.patch_string ?? \"\")),\n update_global_styles: async (args) => {\n const result = await params.impls.updateGlobalStylesImpl(args);\n return result;\n },\n create_new_route: async (args) => {\n const parentRoute = String(args.parent_route ?? \"\");\n const routeName = String(args.route_name ?? \"\");\n const result = await params.impls.createNewRouteImpl(parentRoute, routeName);\n return result;\n },\n delete_element: async (args) => {\n const route = String(args.route ?? \"\");\n const element_id = String(args.element_id ?? \"\");\n const result = await params.impls.deleteElementImpl(route, element_id);\n return result;\n },\n insert_element: async (args) => {\n const result = await params.impls.insertElementImpl(args);\n if (!result.success) {\n const available = await getAvailableRoutes({\n workspaceRoot: params.workspaceRoot,\n fs: nodeFs,\n });\n return {\n success: false,\n error: `insert_element failed: ${result.error}. Available routes are: ${JSON.stringify(available)}. If you intend to create a new route, create it using the 'create_new_route' tool.`,\n available_routes: available,\n };\n }\n return result;\n },\n update_props: async (args) => {\n const route = String(args.route ?? \"\");\n const element_id = String(args.element_id ?? \"\");\n const props: any = args.props;\n const result = await params.impls.updatePropsImpl({\n route,\n element_id,\n ...props,\n });\n return result;\n },\n update_classname: async (args) => {\n const route = String(args.route ?? \"\");\n const element_id = String(args.element_id ?? \"\");\n const class_name = String(args.class_name ?? \"\");\n const result = await params.impls.updateClassNameImpl(\n route,\n element_id,\n class_name,\n );\n return result;\n },\n get_available_routes: async (args) => {\n const routes = await getAvailableRoutes({ workspaceRoot: params.workspaceRoot, fs: nodeFs });\n return { success: true, routes };\n },\n submit_codegen_done: async (args) => ({\n success: true,\n summary: String(args.summary ?? \"\").trim(),\n }),\n submit_planner_tasks: async (args) => {\n const tasks = parsePlannerTasksUnknown(args.planner_tasks);\n return { success: true, count: tasks.length };\n },\n };\n}\n"]}
1
+ {"version":3,"file":"toolHandlers.helper.js","sourceRoot":"","sources":["../../../../src/ai/toolLoop/helpers/toolHandlers.helper.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAvailableRoutes } from \"../../tools/helpers/pageConfigJson.helpers.js\";\nimport { createWorkspaceToolImpls } from \"../../tools/implementations/factories.js\";\nimport { nodeFs } from \"./fsHelpers.js\";\nimport { parsePlannerTasksUnknown } from \"./plannerTaskParser.js\";\n\nexport function createToolHandlers(params: {\n impls: ReturnType<typeof createWorkspaceToolImpls>;\n workspaceRoot: string;\n}): Record<string, (args: any) => Promise<any>> {\n return {\n read_file: async (args) => {\n const path = String(args.path ?? \"\");\n const startLine =\n args.start_line === undefined ? undefined : Number(args.start_line);\n const endLine =\n args.end_line === undefined ? undefined : Number(args.end_line);\n const content = await params.impls.readFileImpl(path, startLine, endLine);\n return { path, content };\n },\n write_file: (args) =>\n params.impls.writeFileImpl(String(args.path ?? \"\"), String(args.content ?? \"\")),\n list_dir: async (args) => {\n const content = await params.impls.listDirImpl(\n String(args.path ?? \"\"),\n Number(args.depth ?? 1),\n );\n return { content };\n },\n search: async (args) => {\n const results = await params.impls.searchImpl(String(args.search_query ?? \"\"));\n return { results };\n },\n apply_patch: (args) =>\n params.impls.applyPatchImpl(String(args.patch_string ?? \"\")),\n update_global_styles: async (args) => {\n const result = await params.impls.updateGlobalStylesImpl(args);\n return result;\n },\n create_new_route: async (args) => {\n const parentRoute = String(args.parent_route ?? \"\");\n const routeName = String(args.route_name ?? \"\");\n const result = await params.impls.createNewRouteImpl(parentRoute, routeName);\n return result;\n },\n delete_element: async (args) => {\n const route = String(args.route ?? \"\");\n const element_id = String(args.element_id ?? \"\");\n const result = await params.impls.deleteElementImpl(route, element_id);\n return result;\n },\n insert_element: async (args) => {\n const result = await params.impls.insertElementImpl(args);\n if (!result.success) {\n const available = await getAvailableRoutes({\n workspaceRoot: params.workspaceRoot,\n fs: nodeFs,\n });\n return {\n success: false,\n error: `insert_element failed: ${result.error}. Available routes are: ${JSON.stringify(available)}. If you intend to create a new route, create it using the 'create_new_route' tool.`,\n available_routes: available,\n };\n }\n return result;\n },\n update_props: async (args) => {\n const { route, element_id, props, ...rest } = args;\n const routeStr = String(route ?? \"\");\n const elementIdStr = String(element_id ?? \"\");\n const mergedProps = {\n ...(typeof props === \"object\" && props !== null ? props : {}),\n ...rest,\n };\n const result = await params.impls.updatePropsImpl({\n route: routeStr,\n element_id: elementIdStr,\n ...mergedProps,\n });\n return result;\n },\n update_classname: async (args) => {\n const route = String(args.route ?? \"\");\n const element_id = String(args.element_id ?? \"\");\n const class_name = String(args.className ?? args.class_name ?? \"\");\n const result = await params.impls.updateClassNameImpl(\n route,\n element_id,\n class_name,\n );\n return result;\n },\n get_available_routes: async (args) => {\n const routes = await getAvailableRoutes({ workspaceRoot: params.workspaceRoot, fs: nodeFs });\n return { success: true, routes };\n },\n submit_codegen_done: async (args) => ({\n success: true,\n summary: String(args.summary ?? \"\").trim(),\n }),\n submit_planner_tasks: async (args) => {\n const tasks = parsePlannerTasksUnknown(args.planner_tasks);\n return { success: true, count: tasks.length };\n },\n };\n}\n"]}
@@ -12,6 +12,7 @@ export type ToolLoopResult = {
12
12
  args: Record<string, unknown>;
13
13
  response: unknown;
14
14
  };
15
+ success: boolean;
15
16
  };
16
17
  export type Logger = (message: string, eventType: EventType, displayedSummary?: boolean) => Promise<void>;
17
18
  export type AiCallResponse = {
@@ -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;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpF,OAAO,EAAe,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAmB/D,OAAO,EAKL,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAG9B,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,CACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,EACpB,gBAAgB,CAAC,EAAE,OAAO,KACvB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,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,gBAAgB,GAAG;IAC7B,UAAU,EAAE,IAAI,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,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;IACvE,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,cAAc,CAAC,CAsXzB"}
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;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpF,OAAO,EAAe,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAmB/D,OAAO,EAKL,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAG9B,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;IACF,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,EACpB,gBAAgB,CAAC,EAAE,OAAO,KACvB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,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,gBAAgB,GAAG;IAC7B,UAAU,EAAE,IAAI,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,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;IACvE,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,cAAc,CAAC,CAkXzB"}
@@ -31,7 +31,7 @@ export async function runToolLoop(options) {
31
31
  workspaceRoot,
32
32
  });
33
33
  if (typeof aiCall !== "function") {
34
- throw new Error("Tool loop: aiCall is required.");
34
+ throw new TypeError("Tool loop: aiCall is required.");
35
35
  }
36
36
  const policy = {
37
37
  ...DEFAULT_CONTEXT_POLICY,
@@ -138,11 +138,12 @@ export async function runToolLoop(options) {
138
138
  modelContents,
139
139
  finalText: (response.text ?? "").trim(),
140
140
  steps: step + 1,
141
+ success: false,
141
142
  };
142
143
  }
143
144
  const signatureById = extractThoughtSignatures(response);
144
- for (let callIndex = 0; callIndex < functionCalls.length; callIndex++) {
145
- const call = functionCalls[callIndex];
145
+ for (const element of functionCalls) {
146
+ const call = element;
146
147
  const name = call.name?.toString() ?? "";
147
148
  const args = (call.args ?? {});
148
149
  const thoughtSignature = (() => {
@@ -295,6 +296,7 @@ export async function runToolLoop(options) {
295
296
  finalText: "",
296
297
  steps: step + 1,
297
298
  terminalCall: { name, args: effectiveArgs, response: toolResultRaw },
299
+ success: true,
298
300
  };
299
301
  }
300
302
  }
@@ -305,6 +307,7 @@ export async function runToolLoop(options) {
305
307
  modelContents,
306
308
  finalText: `Stopped: max steps reached (${maxSteps}).`,
307
309
  steps: maxSteps,
310
+ success: false,
308
311
  };
309
312
  }
310
313
  //# sourceMappingURL=toolLoopRunner.js.map
@@ -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 type { GenTokensRepository } from \"../../repository/genTokens.repository.js\";\nimport { persistToolCall } from \"../../services/toolcallPersist.service.js\";\nimport { EVENT_TYPES, EventType } from \"../../types/events.js\";\nimport { STYLE_TOKEN_KEYS } from \"../../types/styleConfig.js\";\nimport { createWorkspaceToolImpls } from \"../tools/implementations/factories.js\";\nimport { aiCallWithRetry } from \"./helpers/aiCall.helper.js\";\nimport { serializeError } from \"./helpers/errors.helper.js\";\nimport { nodeFs } from \"./helpers/fsHelpers.js\";\nimport { handleApplyPatchFailure } from \"./helpers/patchRetry.helper.js\";\nimport {\n extractUsageTokenCounts,\n persistTokensOnce,\n} from \"./helpers/persistTokens.helpers.js\";\nimport { extractThoughtSignatures } from \"./helpers/signatures.helper.js\";\nimport { normalizeToolArgs } from \"./helpers/toolArgs.helper.js\";\nimport {\n executeToolHandler,\n postProcessToolResult,\n} from \"./helpers/toolExecution.helper.js\";\nimport { createToolHandlers } from \"./helpers/toolHandlers.helper.js\";\nimport { recordToolEvent } from \"./toolEventSummary.js\";\nimport {\n compactForModel,\n DEFAULT_CONTEXT_POLICY,\n redactFunctionCallArgs,\n ToolEvent,\n ToolLoopContextPolicy,\n} from \"./toolLoopContext.js\";\nimport { buildToolStatusMessage } from \"./toolStatusMessage.js\";\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 = (\n message: string,\n eventType: EventType,\n displayedSummary?: boolean,\n) => 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 TokenPersistence = {\n repository: Pick<GenTokensRepository, \"persistGenTokens\">;\n sessionId: string;\n model: string;\n};\n\nexport type RunToolLoopOptions = {\n initialContents: any[];\n tools: Tool[];\n workspaceRoot: string;\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 tokenPersistence?: TokenPersistence;\n};\n\nexport async function runToolLoop(\n options: RunToolLoopOptions,\n): Promise<ToolLoopResult> {\n const styleTokenKeySet = new Set<string>(\n STYLE_TOKEN_KEYS as unknown as string[],\n );\n\n const {\n initialContents,\n tools,\n workspaceRoot,\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 tokenPersistence,\n } = options;\n\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let sawAnyTokenUsage = false;\n\n const impls = createWorkspaceToolImpls({\n workspaceRoot,\n fs: nodeFs,\n });\n\n const toolHandlers = createToolHandlers({\n impls,\n workspaceRoot,\n });\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 {\n const usage = extractUsageTokenCounts(response);\n if (usage) {\n sawAnyTokenUsage = true;\n totalInputTokens += usage.inputTokens;\n totalOutputTokens += usage.outputTokens;\n }\n }\n\n const functionCalls = response.functionCalls ?? [];\n if (functionCalls.length === 0) {\n await persistTokensOnce(\n tokenPersistence,\n sawAnyTokenUsage,\n totalInputTokens,\n totalOutputTokens,\n );\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: (response.text ?? \"\").trim(),\n steps: step + 1,\n };\n }\n\n const signatureById = extractThoughtSignatures(response);\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 = toolHandlers[name];\n\n const { effectiveArgs, readFileMeta } = normalizeToolArgs(\n name,\n args,\n {\n readFileDefaultMaxLines: policy.readFileDefaultMaxLines,\n styleTokenKeySet,\n }\n );\n\n logger(\n buildToolStatusMessage(name, effectiveArgs, readFileMeta),\n EVENT_TYPES.STEP_STARTED,\n true,\n );\n\n const modelArgs = redactFunctionCallArgs(name, effectiveArgs);\n\n const functionCallPart = {\n functionCall: {\n name,\n args: effectiveArgs,\n },\n ...(thoughtSignature\n ? {\n thoughtSignature: thoughtSignature,\n thought_signature: thoughtSignature,\n }\n : {}),\n };\n\n const functionCallPartModel = {\n functionCall: {\n name,\n args: modelArgs,\n },\n ...(thoughtSignature\n ? {\n thoughtSignature: thoughtSignature,\n thought_signature: thoughtSignature,\n }\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 const toolResultRaw = await executeToolHandler({\n name,\n handler,\n effectiveArgs,\n styleTokenKeySet,\n step: step + 1,\n logger,\n });\n\n const toolResult = postProcessToolResult({\n name,\n toolResultRaw,\n effectiveArgs,\n readFileMeta,\n readFileDefaultMaxLines: policy.readFileDefaultMaxLines,\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 const failureResult = handleApplyPatchFailure({\n toolResult,\n applyPatchAutoRetryMax,\n applyPatchRetryCount,\n keepFullTrace,\n fullTraceContents,\n modelContents,\n });\n applyPatchRetryCount = failureResult.applyPatchRetryCount;\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 await persistTokensOnce(\n tokenPersistence,\n sawAnyTokenUsage,\n totalInputTokens,\n totalOutputTokens,\n );\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 await persistTokensOnce(\n tokenPersistence,\n sawAnyTokenUsage,\n totalInputTokens,\n totalOutputTokens,\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 type { GenTokensRepository } from \"../../repository/genTokens.repository.js\";\nimport { persistToolCall } from \"../../services/toolcallPersist.service.js\";\nimport { EVENT_TYPES, EventType } from \"../../types/events.js\";\nimport { STYLE_TOKEN_KEYS } from \"../../types/styleConfig.js\";\nimport { createWorkspaceToolImpls } from \"../tools/implementations/factories.js\";\nimport { aiCallWithRetry } from \"./helpers/aiCall.helper.js\";\nimport { serializeError } from \"./helpers/errors.helper.js\";\nimport { nodeFs } from \"./helpers/fsHelpers.js\";\nimport { handleApplyPatchFailure } from \"./helpers/patchRetry.helper.js\";\nimport {\n extractUsageTokenCounts,\n persistTokensOnce,\n} from \"./helpers/persistTokens.helpers.js\";\nimport { extractThoughtSignatures } from \"./helpers/signatures.helper.js\";\nimport { normalizeToolArgs } from \"./helpers/toolArgs.helper.js\";\nimport {\n executeToolHandler,\n postProcessToolResult,\n} from \"./helpers/toolExecution.helper.js\";\nimport { createToolHandlers } from \"./helpers/toolHandlers.helper.js\";\nimport { recordToolEvent } from \"./toolEventSummary.js\";\nimport {\n compactForModel,\n DEFAULT_CONTEXT_POLICY,\n redactFunctionCallArgs,\n ToolEvent,\n ToolLoopContextPolicy,\n} from \"./toolLoopContext.js\";\nimport { buildToolStatusMessage } from \"./toolStatusMessage.js\";\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 success: boolean;\n};\n\nexport type Logger = (\n message: string,\n eventType: EventType,\n displayedSummary?: boolean,\n) => 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 TokenPersistence = {\n repository: Pick<GenTokensRepository, \"persistGenTokens\">;\n sessionId: string;\n model: string;\n};\n\nexport type RunToolLoopOptions = {\n initialContents: any[];\n tools: Tool[];\n workspaceRoot: string;\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 tokenPersistence?: TokenPersistence;\n};\n\nexport async function runToolLoop(\n options: RunToolLoopOptions,\n): Promise<ToolLoopResult> {\n const styleTokenKeySet = new Set<string>(STYLE_TOKEN_KEYS);\n\n const {\n initialContents,\n tools,\n workspaceRoot,\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 tokenPersistence,\n } = options;\n\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let sawAnyTokenUsage = false;\n\n const impls = createWorkspaceToolImpls({\n workspaceRoot,\n fs: nodeFs,\n });\n\n const toolHandlers = createToolHandlers({\n impls,\n workspaceRoot,\n });\n\n if (typeof aiCall !== \"function\") {\n throw new TypeError(\"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 {\n const usage = extractUsageTokenCounts(response);\n if (usage) {\n sawAnyTokenUsage = true;\n totalInputTokens += usage.inputTokens;\n totalOutputTokens += usage.outputTokens;\n }\n }\n\n const functionCalls = response.functionCalls ?? [];\n if (functionCalls.length === 0) {\n await persistTokensOnce(\n tokenPersistence,\n sawAnyTokenUsage,\n totalInputTokens,\n totalOutputTokens,\n );\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: (response.text ?? \"\").trim(),\n steps: step + 1,\n success: false,\n };\n }\n\n const signatureById = extractThoughtSignatures(response);\n\n for (const element of functionCalls) {\n const call = element;\n const name = call.name?.toString() ?? \"\";\n const args = (call.args ?? {}) as Record<string, unknown>;\n const thoughtSignature: string | undefined = (() => {\n const direct = call?.thought_signature ?? call?.thoughtSignature;\n if (typeof direct === \"string\" && direct) return direct;\n const id = call?.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 = toolHandlers[name];\n\n const { effectiveArgs, readFileMeta } = normalizeToolArgs(name, args, {\n readFileDefaultMaxLines: policy.readFileDefaultMaxLines,\n styleTokenKeySet,\n });\n\n logger(\n buildToolStatusMessage(name, effectiveArgs, readFileMeta),\n EVENT_TYPES.STEP_STARTED,\n true,\n );\n\n const modelArgs = redactFunctionCallArgs(name, effectiveArgs);\n\n const functionCallPart = {\n functionCall: {\n name,\n args: effectiveArgs,\n },\n ...(thoughtSignature\n ? {\n thoughtSignature: thoughtSignature,\n thought_signature: thoughtSignature,\n }\n : {}),\n };\n\n const functionCallPartModel = {\n functionCall: {\n name,\n args: modelArgs,\n },\n ...(thoughtSignature\n ? {\n thoughtSignature: thoughtSignature,\n thought_signature: thoughtSignature,\n }\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 const toolResultRaw = await executeToolHandler({\n name,\n handler,\n effectiveArgs,\n styleTokenKeySet,\n step: step + 1,\n logger,\n });\n\n const toolResult = postProcessToolResult({\n name,\n toolResultRaw,\n effectiveArgs,\n readFileMeta,\n readFileDefaultMaxLines: policy.readFileDefaultMaxLines,\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 const failureResult = handleApplyPatchFailure({\n toolResult,\n applyPatchAutoRetryMax,\n applyPatchRetryCount,\n keepFullTrace,\n fullTraceContents,\n modelContents,\n });\n applyPatchRetryCount = failureResult.applyPatchRetryCount;\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 await persistTokensOnce(\n tokenPersistence,\n sawAnyTokenUsage,\n totalInputTokens,\n totalOutputTokens,\n );\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: \"\",\n steps: step + 1,\n terminalCall: { name, args: effectiveArgs, response: toolResultRaw },\n success: true,\n };\n }\n }\n }\n\n await persistTokensOnce(\n tokenPersistence,\n sawAnyTokenUsage,\n totalInputTokens,\n totalOutputTokens,\n );\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: `Stopped: max steps reached (${maxSteps}).`,\n steps: maxSteps,\n success: false,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"toolStatusMessage.d.ts","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolStatusMessage.ts"],"names":[],"mappings":"AAsJA,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,KACtE,MAOF,CAAC"}
1
+ {"version":3,"file":"toolStatusMessage.d.ts","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolStatusMessage.ts"],"names":[],"mappings":"AA2JA,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,KACtE,MAOF,CAAC"}
@@ -90,7 +90,11 @@ const buildUpdateClassnameStatus = ({ name, effectiveArgs }) => {
90
90
  return null;
91
91
  const route = typeof effectiveArgs.route === "string" ? effectiveArgs.route : "";
92
92
  const id = typeof effectiveArgs.element_id === "string" ? effectiveArgs.element_id : "";
93
- const className = typeof effectiveArgs.class_name === "string" ? effectiveArgs.class_name : "";
93
+ const className = typeof effectiveArgs.className === "string"
94
+ ? effectiveArgs.className
95
+ : typeof effectiveArgs.class_name === "string"
96
+ ? effectiveArgs.class_name
97
+ : "";
94
98
  const classNameStr = className ? ` to "${className}"` : "";
95
99
  return `AI tool: Updating class name for element "${id}" on route "${route}"${classNameStr}`;
96
100
  };
@@ -1 +1 @@
1
- {"version":3,"file":"toolStatusMessage.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolStatusMessage.ts"],"names":[],"mappings":"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","sourcesContent":["import { getApplyPatchEventMeta } from \"./helpers/applyPatch.helper.js\";\n\ntype StatusMessageInput = {\n name: string;\n effectiveArgs: Record<string, unknown>;\n readFileMeta: { start: number; end: number; wasCapped: boolean } | null;\n};\n\ntype StatusMessageBuilder = (input: StatusMessageInput) => string | null;\n\nconst buildReadFileStatus: StatusMessageBuilder = ({\n name,\n effectiveArgs,\n readFileMeta,\n}) => {\n if (name !== \"read_file\") return null;\n\n const path = typeof effectiveArgs.path === \"string\" ? effectiveArgs.path : \"\";\n if (readFileMeta) {\n return `AI tool: Reading file \"${path}\" (lines ${readFileMeta.start}-${readFileMeta.end}${\n readFileMeta.wasCapped ? \", capped\" : \"\"\n })`;\n }\n\n const start =\n effectiveArgs.start_line === undefined ? 1 : Number(effectiveArgs.start_line);\n const end =\n effectiveArgs.end_line === undefined\n ? undefined\n : Number(effectiveArgs.end_line);\n const lines = end === undefined ? `starting at line ${start}` : `lines ${start}-${end}`;\n return `AI tool: Reading file \"${path}\" (${lines})`;\n};\n\nconst buildWriteFileStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"write_file\") return null;\n const path = typeof effectiveArgs.path === \"string\" ? effectiveArgs.path : \"\";\n return `AI tool: Writing file \"${path}\"`;\n};\n\nconst buildApplyPatchStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"apply_patch\") return null;\n\n const meta = getApplyPatchEventMeta(effectiveArgs);\n const files = Array.isArray(meta.files) ? meta.files : [];\n if (files.length === 0) return \"AI tool: Applying patch\";\n if (files.length <= 3) return `AI tool: Applying changes to \"${files.join(\", \")}\"`;\n return `AI tool: Applying changes to ${files.length} files: \"${files\n .slice(0, 3)\n .join(\", \")}\" (+${files.length - 3} more)`;\n};\n\nconst buildSearchStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"search\") return null;\n const query = typeof effectiveArgs.search_query === \"string\" ? effectiveArgs.search_query : \"\";\n return query\n ? `AI tool: Searching workspace for \"${query}\"`\n : \"AI tool: Searching workspace\";\n};\n\nconst buildListDirStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"list_dir\") return null;\n const path = typeof effectiveArgs.path === \"string\" ? effectiveArgs.path : \"\";\n const depth = effectiveArgs.depth === undefined ? 1 : Number(effectiveArgs.depth);\n return `AI tool: Listing contents of directory \"${path}\" (depth: ${depth})`;\n};\n\nconst buildUpdateGlobalStylesStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"update_global_styles\") return null;\n const keys = Object.keys(effectiveArgs);\n return keys.length > 0\n ? `AI tool: Updating global styles (${keys.join(\", \")})`\n : \"AI tool: Updating global styles\";\n};\n\nconst buildCreateNewRouteStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"create_new_route\") return null;\n const route = typeof effectiveArgs.route_name === \"string\" ? effectiveArgs.route_name : \"\";\n const parent =\n typeof effectiveArgs.parent_route === \"string\" ? effectiveArgs.parent_route : \"/\";\n return `AI tool: Creating new route \"${route}\" (parent: \"${parent}\")`;\n};\n\nconst buildDeleteElementStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"delete_element\") return null;\n const route = typeof effectiveArgs.route === \"string\" ? effectiveArgs.route : \"\";\n const id = typeof effectiveArgs.element_id === \"string\" ? effectiveArgs.element_id : \"\";\n return `AI tool: Deleting element \"${id}\" from route \"${route}\"`;\n};\n\nconst buildInsertElementStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"insert_element\") return null;\n const route = typeof effectiveArgs.route === \"string\" ? effectiveArgs.route : \"\";\n const parent = typeof effectiveArgs.parent_id === \"string\" ? effectiveArgs.parent_id : \"\";\n const before = typeof effectiveArgs.before_id === \"string\" ? effectiveArgs.before_id : \"\";\n const beforeStr = before ? `, before \"${before}\"` : \"\";\n return `AI tool: Inserting element into route \"${route}\" (under parent \"${parent}\"${beforeStr})`;\n};\n\nconst buildUpdatePropsStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"update_props\") return null;\n const route = typeof effectiveArgs.route === \"string\" ? effectiveArgs.route : \"\";\n const id = typeof effectiveArgs.element_id === \"string\" ? effectiveArgs.element_id : \"\";\n return `AI tool: Updating properties for element \"${id}\" on route \"${route}\"`;\n};\n\nconst buildUpdateClassnameStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"update_classname\") return null;\n const route = typeof effectiveArgs.route === \"string\" ? effectiveArgs.route : \"\";\n const id = typeof effectiveArgs.element_id === \"string\" ? effectiveArgs.element_id : \"\";\n const className = typeof effectiveArgs.class_name === \"string\" ? effectiveArgs.class_name : \"\";\n const classNameStr = className ? ` to \"${className}\"` : \"\";\n return `AI tool: Updating class name for element \"${id}\" on route \"${route}\"${classNameStr}`;\n};\n\nconst buildGetAvailableRoutesStatus: StatusMessageBuilder = ({ name }) => {\n if (name !== \"get_available_routes\") return null;\n return \"AI tool: Retrieving available routes\";\n};\n\nconst buildSubmitPlannerTasksStatus: StatusMessageBuilder = ({ name }) => {\n if (name !== \"submit_planner_tasks\") return null;\n return \"AI tool: Submitting planner tasks\";\n};\n\nconst buildSubmitCodegenDoneStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"submit_codegen_done\") return null;\n const summary = typeof effectiveArgs.summary === \"string\" ? effectiveArgs.summary : \"\";\n return summary\n ? `AI tool: Submitting completed work: \"${summary}\"`\n : \"AI tool: Submitting completed work\";\n};\n\nconst BUILDERS: StatusMessageBuilder[] = [\n buildReadFileStatus,\n buildWriteFileStatus,\n buildApplyPatchStatus,\n buildSearchStatus,\n buildListDirStatus,\n buildUpdateGlobalStylesStatus,\n buildCreateNewRouteStatus,\n buildDeleteElementStatus,\n buildInsertElementStatus,\n buildUpdatePropsStatus,\n buildUpdateClassnameStatus,\n buildGetAvailableRoutesStatus,\n buildSubmitPlannerTasksStatus,\n buildSubmitCodegenDoneStatus,\n];\n\nexport const buildToolStatusMessage = (\n name: string,\n effectiveArgs: Record<string, unknown>,\n readFileMeta: { start: number; end: number; wasCapped: boolean } | null,\n): string => {\n const input: StatusMessageInput = { name, effectiveArgs, readFileMeta };\n for (const b of BUILDERS) {\n const msg = b(input);\n if (msg) return msg;\n }\n return `AI tool: ${name}`;\n};\n\n"]}
1
+ {"version":3,"file":"toolStatusMessage.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolStatusMessage.ts"],"names":[],"mappings":"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","sourcesContent":["import { getApplyPatchEventMeta } from \"./helpers/applyPatch.helper.js\";\n\ntype StatusMessageInput = {\n name: string;\n effectiveArgs: Record<string, unknown>;\n readFileMeta: { start: number; end: number; wasCapped: boolean } | null;\n};\n\ntype StatusMessageBuilder = (input: StatusMessageInput) => string | null;\n\nconst buildReadFileStatus: StatusMessageBuilder = ({\n name,\n effectiveArgs,\n readFileMeta,\n}) => {\n if (name !== \"read_file\") return null;\n\n const path = typeof effectiveArgs.path === \"string\" ? effectiveArgs.path : \"\";\n if (readFileMeta) {\n return `AI tool: Reading file \"${path}\" (lines ${readFileMeta.start}-${readFileMeta.end}${\n readFileMeta.wasCapped ? \", capped\" : \"\"\n })`;\n }\n\n const start =\n effectiveArgs.start_line === undefined ? 1 : Number(effectiveArgs.start_line);\n const end =\n effectiveArgs.end_line === undefined\n ? undefined\n : Number(effectiveArgs.end_line);\n const lines = end === undefined ? `starting at line ${start}` : `lines ${start}-${end}`;\n return `AI tool: Reading file \"${path}\" (${lines})`;\n};\n\nconst buildWriteFileStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"write_file\") return null;\n const path = typeof effectiveArgs.path === \"string\" ? effectiveArgs.path : \"\";\n return `AI tool: Writing file \"${path}\"`;\n};\n\nconst buildApplyPatchStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"apply_patch\") return null;\n\n const meta = getApplyPatchEventMeta(effectiveArgs);\n const files = Array.isArray(meta.files) ? meta.files : [];\n if (files.length === 0) return \"AI tool: Applying patch\";\n if (files.length <= 3) return `AI tool: Applying changes to \"${files.join(\", \")}\"`;\n return `AI tool: Applying changes to ${files.length} files: \"${files\n .slice(0, 3)\n .join(\", \")}\" (+${files.length - 3} more)`;\n};\n\nconst buildSearchStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"search\") return null;\n const query = typeof effectiveArgs.search_query === \"string\" ? effectiveArgs.search_query : \"\";\n return query\n ? `AI tool: Searching workspace for \"${query}\"`\n : \"AI tool: Searching workspace\";\n};\n\nconst buildListDirStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"list_dir\") return null;\n const path = typeof effectiveArgs.path === \"string\" ? effectiveArgs.path : \"\";\n const depth = effectiveArgs.depth === undefined ? 1 : Number(effectiveArgs.depth);\n return `AI tool: Listing contents of directory \"${path}\" (depth: ${depth})`;\n};\n\nconst buildUpdateGlobalStylesStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"update_global_styles\") return null;\n const keys = Object.keys(effectiveArgs);\n return keys.length > 0\n ? `AI tool: Updating global styles (${keys.join(\", \")})`\n : \"AI tool: Updating global styles\";\n};\n\nconst buildCreateNewRouteStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"create_new_route\") return null;\n const route = typeof effectiveArgs.route_name === \"string\" ? effectiveArgs.route_name : \"\";\n const parent =\n typeof effectiveArgs.parent_route === \"string\" ? effectiveArgs.parent_route : \"/\";\n return `AI tool: Creating new route \"${route}\" (parent: \"${parent}\")`;\n};\n\nconst buildDeleteElementStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"delete_element\") return null;\n const route = typeof effectiveArgs.route === \"string\" ? effectiveArgs.route : \"\";\n const id = typeof effectiveArgs.element_id === \"string\" ? effectiveArgs.element_id : \"\";\n return `AI tool: Deleting element \"${id}\" from route \"${route}\"`;\n};\n\nconst buildInsertElementStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"insert_element\") return null;\n const route = typeof effectiveArgs.route === \"string\" ? effectiveArgs.route : \"\";\n const parent = typeof effectiveArgs.parent_id === \"string\" ? effectiveArgs.parent_id : \"\";\n const before = typeof effectiveArgs.before_id === \"string\" ? effectiveArgs.before_id : \"\";\n const beforeStr = before ? `, before \"${before}\"` : \"\";\n return `AI tool: Inserting element into route \"${route}\" (under parent \"${parent}\"${beforeStr})`;\n};\n\nconst buildUpdatePropsStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"update_props\") return null;\n const route = typeof effectiveArgs.route === \"string\" ? effectiveArgs.route : \"\";\n const id = typeof effectiveArgs.element_id === \"string\" ? effectiveArgs.element_id : \"\";\n return `AI tool: Updating properties for element \"${id}\" on route \"${route}\"`;\n};\n\nconst buildUpdateClassnameStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"update_classname\") return null;\n const route = typeof effectiveArgs.route === \"string\" ? effectiveArgs.route : \"\";\n const id = typeof effectiveArgs.element_id === \"string\" ? effectiveArgs.element_id : \"\";\n const className =\n typeof effectiveArgs.className === \"string\"\n ? effectiveArgs.className\n : typeof effectiveArgs.class_name === \"string\"\n ? effectiveArgs.class_name\n : \"\";\n const classNameStr = className ? ` to \"${className}\"` : \"\";\n return `AI tool: Updating class name for element \"${id}\" on route \"${route}\"${classNameStr}`;\n};\n\nconst buildGetAvailableRoutesStatus: StatusMessageBuilder = ({ name }) => {\n if (name !== \"get_available_routes\") return null;\n return \"AI tool: Retrieving available routes\";\n};\n\nconst buildSubmitPlannerTasksStatus: StatusMessageBuilder = ({ name }) => {\n if (name !== \"submit_planner_tasks\") return null;\n return \"AI tool: Submitting planner tasks\";\n};\n\nconst buildSubmitCodegenDoneStatus: StatusMessageBuilder = ({ name, effectiveArgs }) => {\n if (name !== \"submit_codegen_done\") return null;\n const summary = typeof effectiveArgs.summary === \"string\" ? effectiveArgs.summary : \"\";\n return summary\n ? `AI tool: Submitting completed work: \"${summary}\"`\n : \"AI tool: Submitting completed work\";\n};\n\nconst BUILDERS: StatusMessageBuilder[] = [\n buildReadFileStatus,\n buildWriteFileStatus,\n buildApplyPatchStatus,\n buildSearchStatus,\n buildListDirStatus,\n buildUpdateGlobalStylesStatus,\n buildCreateNewRouteStatus,\n buildDeleteElementStatus,\n buildInsertElementStatus,\n buildUpdatePropsStatus,\n buildUpdateClassnameStatus,\n buildGetAvailableRoutesStatus,\n buildSubmitPlannerTasksStatus,\n buildSubmitCodegenDoneStatus,\n];\n\nexport const buildToolStatusMessage = (\n name: string,\n effectiveArgs: Record<string, unknown>,\n readFileMeta: { start: number; end: number; wasCapped: boolean } | null,\n): string => {\n const input: StatusMessageInput = { name, effectiveArgs, readFileMeta };\n for (const b of BUILDERS) {\n const msg = b(input);\n if (msg) return msg;\n }\n return `AI tool: ${name}`;\n};\n\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"pageConfigJson.helpers.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/pageConfigJson.helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAGjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAElE,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO,MAAM,KAAG,MAAM,EAQ5D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,YAM5C,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,eAAe,MAAM,EAAE,OAAO,MAAM,WAOzE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,KAAG,cAkBrD,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,QAAQ,cAAc,WACO,CAAC;AAEtE,eAAO,MAAM,iBAAiB,GAAI,UAAU,cAAc,EAAE,gBAa3D,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAU,cAAc,EAAE,EAC1B,aAAa,GAAG,CAAC,MAAM,CAAC,SA0BzB,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,UAAU,cAAc,EAAE,EAC1B,WAAW,MAAM,KAChB,cAAc,GAAG,IAkBnB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,UAAU,cAAc,EAAE,EAC1B,IAAI,MAAM,KACT,OAkBF,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,UAAU,MAAM,EAAE,SAAS,MAAM,kBAkDtE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,MAAM;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,EAAE,EAAE;QACF,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC;YAClD,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,OAAO,CAAC;YAC3B,MAAM,EAAE,MAAM,OAAO,CAAC;SACvB,CAAC,CAAC,CAAC;KACL,CAAC;CACH,KAAG,OAAO,CAAC,MAAM,EAAE,CAoCnB,CAAC;AAWF,eAAO,MAAM,UAAU,GAAI,eAAe,MAAM,EAAE,gBAAgB,MAAM,KAAG,OA6B1E,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,eAAe,MAAM,EACrB,OAAO,MAAM,EACb,IAAI,MAAM,KACT,OAAO,CAAC,MAAM,CAsBhB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,eAAe,MAAM,EACrB,OAAO,MAAM,EACb,IAAI,MAAM;;;;;;;;;;;;EA4CX,CAAC"}
1
+ {"version":3,"file":"pageConfigJson.helpers.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/pageConfigJson.helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAIlE,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO,MAAM,KAAG,MAAM,EAQ5D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,YAM5C,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,eAAe,MAAM,EAAE,OAAO,MAAM,WAOzE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,KAAG,cAkBrD,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,QAAQ,cAAc,WACO,CAAC;AAEtE,eAAO,MAAM,iBAAiB,GAAI,UAAU,cAAc,EAAE,gBAa3D,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAU,cAAc,EAAE,EAC1B,aAAa,GAAG,CAAC,MAAM,CAAC,SA0BzB,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,UAAU,cAAc,EAAE,EAC1B,WAAW,MAAM,KAChB,cAAc,GAAG,IAkBnB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,UAAU,cAAc,EAAE,EAC1B,IAAI,MAAM,KACT,OAkBF,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,UAAU,MAAM,EAAE,SAAS,MAAM,kBAkDtE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,MAAM;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,EAAE,EAAE;QACF,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAC3C,KAAK,CAAC;YACJ,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,OAAO,CAAC;YAC3B,MAAM,EAAE,MAAM,OAAO,CAAC;SACvB,CAAC,CACH,CAAC;KACH,CAAC;CACH,KAAG,OAAO,CAAC,MAAM,EAAE,CAwCnB,CAAC;AAWF,eAAO,MAAM,UAAU,GACrB,eAAe,MAAM,EACrB,gBAAgB,MAAM,KACrB,OA6BF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,eAAe,MAAM,EACrB,OAAO,MAAM,EACb,IAAI,MAAM,KACT,OAAO,CAAC,MAAM,CAsBhB,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,eAAe,MAAM,EACrB,OAAO,MAAM,EACb,IAAI,MAAM;;;;;;;;;;;;EA6CX,CAAC"}
@@ -206,7 +206,9 @@ export const getAvailableRoutes = async (deps) => {
206
206
  routes.push(routeStr === "/" ? "/" : routeStr.replace(/\/$/, ""));
207
207
  }
208
208
  for (const entry of entries) {
209
- if (entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith(".")) {
209
+ if (entry.isDirectory() &&
210
+ entry.name !== "node_modules" &&
211
+ !entry.name.startsWith(".")) {
210
212
  await scan(path.join(dirPath, entry.name));
211
213
  }
212
214
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pageConfigJson.helpers.js","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/pageConfigJson.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { BuilderElement } from \"../../../types/elements.js\";\nimport { createElementId } from \"./elementid.helpers.js\";\nimport { toWorkspacePath } from \"./fileSystem.helpers.js\";\nimport type { CoreFs } from \"../implementations/workspaceDeps.js\";\n\nexport type PageConfigJson = {\n elements: BuilderElement[];\n};\n\nexport const normalizeRouteSegments = (route: string): string[] => {\n const raw = String(route ?? \"\").trim();\n if (!raw || raw === \"/\") return [];\n return raw\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .map((s) => s.trim())\n .filter(Boolean);\n};\n\nexport const isSafeSegment = (segment: string) => {\n const s = String(segment ?? \"\").trim();\n if (!s) return false;\n if (s === \".\" || s === \"..\") return false;\n if (s.includes(\"/\") || s.includes(\"\\\\\")) return false;\n return true;\n};\n\nexport const getPageConfigJsonPath = (workspaceRoot: string, route: string) => {\n const segments = normalizeRouteSegments(route);\n if (segments.some((s) => !isSafeSegment(s))) {\n throw new Error(\"invalid route\");\n }\n const rel = path.posix.join(\"app\", ...segments, \"pageConfig.json\");\n return toWorkspacePath(workspaceRoot, rel);\n};\n\nexport const parsePageConfigJson = (content: string): PageConfigJson => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(String(content ?? \"\"));\n } catch {\n throw new Error(\"pageConfig.json is not valid JSON\");\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"pageConfig.json must be an object\");\n }\n\n const elements = (parsed as any).elements;\n if (!Array.isArray(elements)) {\n throw new Error('pageConfig.json must contain \"elements\" array');\n }\n\n return { elements: elements as BuilderElement[] };\n};\n\nexport const stringifyPageConfigJson = (config: PageConfigJson) =>\n JSON.stringify({ elements: config.elements ?? [] }, null, 2) + \"\\n\";\n\nexport const extractAllIdsDeep = (elements: BuilderElement[]) => {\n const ids = new Set<string>();\n const walk = (arr: BuilderElement[]) => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n const id = (el as any).id;\n if (typeof id === \"string\" && id.trim()) ids.add(id.trim());\n const children = (el as any).children;\n if (Array.isArray(children)) walk(children as BuilderElement[]);\n }\n };\n walk(Array.isArray(elements) ? elements : []);\n return ids;\n};\n\nexport const ensureElementIds = (\n elements: BuilderElement[],\n existingIds: Set<string>,\n) => {\n const seen = new Set<string>();\n const walk = (arr: BuilderElement[]) => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n\n const anyEl = el as any;\n const currentId = typeof anyEl.id === \"string\" ? anyEl.id.trim() : \"\";\n if (!currentId || seen.has(currentId)) {\n const newId = createElementId(existingIds);\n anyEl.id = newId;\n existingIds.add(newId);\n seen.add(newId);\n } else {\n anyEl.id = currentId;\n existingIds.add(currentId);\n seen.add(currentId);\n }\n\n if (Array.isArray(anyEl.children)) {\n walk(anyEl.children as BuilderElement[]);\n }\n }\n };\n walk(elements);\n};\n\nexport const findElementById = (\n elements: BuilderElement[],\n elementId: string,\n): BuilderElement | null => {\n const id = String(elementId ?? \"\").trim();\n if (!id) return null;\n\n const walk = (arr: BuilderElement[]): BuilderElement | null => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n if ((el as any).id === id) return el;\n const children = (el as any).children;\n if (Array.isArray(children)) {\n const found = walk(children as BuilderElement[]);\n if (found) return found;\n }\n }\n return null;\n };\n\n return walk(elements);\n};\n\nexport const deleteElementById = (\n elements: BuilderElement[],\n id: string,\n): boolean => {\n const target = String(id ?? \"\").trim();\n if (!target) return false;\n\n let deleted = false;\n const walk = (arr: BuilderElement[]) => {\n for (let idx = arr.length - 1; idx >= 0; idx--) {\n const el = arr[idx] as any;\n if (el?.id === target) {\n arr.splice(idx, 1);\n deleted = true;\n continue;\n }\n if (Array.isArray(el?.children)) walk(el.children as BuilderElement[]);\n }\n };\n walk(elements);\n return deleted;\n};\n\nexport const writeFileAtomic = async (filePath: string, content: string) => {\n const dir = path.dirname(filePath);\n const base = path.basename(filePath);\n const tmp = path.join(\n dir,\n `.qwintly_tmp_${base}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n const bak = path.join(\n dir,\n `.qwintly_bak_${base}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n\n try {\n await fs.mkdir(dir, { recursive: true });\n await fs.writeFile(tmp, content ?? \"\", \"utf-8\");\n\n // Windows rename doesn't overwrite; do a 2-step swap.\n try {\n await fs.rename(filePath, bak);\n await fs.rename(tmp, filePath);\n await fs.rm(bak, { force: true });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") {\n // No previous file; just put the temp file in place.\n await fs.rename(tmp, filePath);\n } else {\n throw err;\n }\n }\n } catch (err) {\n // rollback best-effort\n try {\n await fs.rm(tmp, { force: true });\n } catch {\n // ignore\n }\n try {\n await fs.stat(bak);\n try {\n await fs.rm(filePath, { force: true });\n } catch {\n // ignore\n }\n await fs.rename(bak, filePath);\n } catch {\n // ignore\n }\n throw err;\n }\n};\n\nexport const getAvailableRoutes = async (deps: {\n workspaceRoot: string;\n fs: {\n safeReadDir: (absoluteDir: string) => Promise<Array<{\n name: string;\n isDirectory: () => boolean;\n isFile: () => boolean;\n }>>;\n };\n}): Promise<string[]> => {\n const { workspaceRoot, fs } = deps;\n const appDir = toWorkspacePath(workspaceRoot, \"app\");\n const routes: string[] = [];\n\n const scan = async (dirPath: string) => {\n let entries;\n try {\n entries = await fs.safeReadDir(dirPath);\n } catch {\n return;\n }\n\n let hasPageConfig = false;\n for (const entry of entries) {\n if (entry.isFile() && entry.name === \"pageConfig.json\") {\n hasPageConfig = true;\n break;\n }\n }\n\n if (hasPageConfig) {\n const rel = path.relative(appDir, dirPath);\n const routeStr = \"/\" + rel.replace(/\\\\/g, \"/\");\n routes.push(routeStr === \"/\" ? \"/\" : routeStr.replace(/\\/$/, \"\"));\n }\n\n for (const entry of entries) {\n if (entry.isDirectory() && entry.name !== \"node_modules\" && !entry.name.startsWith(\".\")) {\n await scan(path.join(dirPath, entry.name));\n }\n }\n };\n\n await scan(appDir);\n return routes.sort((a, b) => a.localeCompare(b));\n};\n\nconst isCatchAll = (segment: string): boolean =>\n segment.startsWith(\"[\") && segment.endsWith(\"]\") && segment.includes(\"...\");\n\nconst isDynamic = (segment: string): boolean =>\n segment.startsWith(\"[\") && segment.endsWith(\"]\");\n\nconst isOptionalCatchAll = (segment: string): boolean =>\n segment.startsWith(\"[[\") && segment.endsWith(\"]]\") && segment.includes(\"...\");\n\nexport const matchRoute = (physicalRoute: string, requestedRoute: string): boolean => {\n const physSegs = normalizeRouteSegments(physicalRoute);\n const reqSegs = normalizeRouteSegments(requestedRoute);\n\n let pIdx = 0;\n let rIdx = 0;\n\n while (pIdx < physSegs.length && rIdx < reqSegs.length) {\n const phys = physSegs[pIdx];\n const req = reqSegs[rIdx];\n\n if (isCatchAll(phys)) {\n return true;\n }\n\n if (isDynamic(phys) || phys.toLowerCase() === req.toLowerCase()) {\n pIdx++;\n rIdx++;\n continue;\n }\n\n return false;\n }\n\n if (rIdx === reqSegs.length && pIdx < physSegs.length) {\n return physSegs.slice(pIdx).every(isOptionalCatchAll);\n }\n\n return pIdx === physSegs.length && rIdx === reqSegs.length;\n};\n\nexport const resolvePageConfigJsonPath = async (\n workspaceRoot: string,\n route: string,\n fs: CoreFs,\n): Promise<string> => {\n // 1. Try exact match first\n const exactPath = getPageConfigJsonPath(workspaceRoot, route);\n try {\n await fs.stat(exactPath);\n return exactPath;\n } catch {\n // Exact file does not exist, let's resolve dynamically\n }\n\n // 2. Fetch all available routes in the workspace\n const available = await getAvailableRoutes({ workspaceRoot, fs });\n\n // 3. Find first matching route\n for (const physRoute of available) {\n if (matchRoute(physRoute, route)) {\n return getPageConfigJsonPath(workspaceRoot, physRoute);\n }\n }\n\n // 4. Fallback: if no match, just return the exact path\n return exactPath;\n};\n\nexport const loadAndPreparePageConfig = async (\n workspaceRoot: string,\n route: string,\n fs: CoreFs,\n) => {\n let configPath: string;\n try {\n configPath = await resolvePageConfigJsonPath(workspaceRoot, route, fs);\n } catch (err) {\n return {\n success: false as const,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let before = \"\";\n try {\n before = await fs.readFile(configPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") return { success: false as const, error: \"not found\" };\n return {\n success: false as const,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let parsed: ReturnType<typeof parsePageConfigJson>;\n try {\n parsed = parsePageConfigJson(before);\n } catch (err) {\n return {\n success: false as const,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n const elements = parsed.elements ?? [];\n const existingIds = extractAllIdsDeep(elements);\n ensureElementIds(elements, existingIds);\n\n return {\n success: true as const,\n configPath,\n elements,\n existingIds,\n };\n};\n\n\n"]}
1
+ {"version":3,"file":"pageConfigJson.helpers.js","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/pageConfigJson.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { BuilderElement } from \"../../../types/elements.js\";\nimport type { CoreFs } from \"../implementations/workspaceDeps.js\";\nimport { createElementId } from \"./elementid.helpers.js\";\nimport { toWorkspacePath } from \"./fileSystem.helpers.js\";\n\nexport type PageConfigJson = {\n elements: BuilderElement[];\n};\n\nexport const normalizeRouteSegments = (route: string): string[] => {\n const raw = String(route ?? \"\").trim();\n if (!raw || raw === \"/\") return [];\n return raw\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .map((s) => s.trim())\n .filter(Boolean);\n};\n\nexport const isSafeSegment = (segment: string) => {\n const s = String(segment ?? \"\").trim();\n if (!s) return false;\n if (s === \".\" || s === \"..\") return false;\n if (s.includes(\"/\") || s.includes(\"\\\\\")) return false;\n return true;\n};\n\nexport const getPageConfigJsonPath = (workspaceRoot: string, route: string) => {\n const segments = normalizeRouteSegments(route);\n if (segments.some((s) => !isSafeSegment(s))) {\n throw new Error(\"invalid route\");\n }\n const rel = path.posix.join(\"app\", ...segments, \"pageConfig.json\");\n return toWorkspacePath(workspaceRoot, rel);\n};\n\nexport const parsePageConfigJson = (content: string): PageConfigJson => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(String(content ?? \"\"));\n } catch {\n throw new Error(\"pageConfig.json is not valid JSON\");\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"pageConfig.json must be an object\");\n }\n\n const elements = (parsed as any).elements;\n if (!Array.isArray(elements)) {\n throw new Error('pageConfig.json must contain \"elements\" array');\n }\n\n return { elements: elements as BuilderElement[] };\n};\n\nexport const stringifyPageConfigJson = (config: PageConfigJson) =>\n JSON.stringify({ elements: config.elements ?? [] }, null, 2) + \"\\n\";\n\nexport const extractAllIdsDeep = (elements: BuilderElement[]) => {\n const ids = new Set<string>();\n const walk = (arr: BuilderElement[]) => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n const id = (el as any).id;\n if (typeof id === \"string\" && id.trim()) ids.add(id.trim());\n const children = (el as any).children;\n if (Array.isArray(children)) walk(children as BuilderElement[]);\n }\n };\n walk(Array.isArray(elements) ? elements : []);\n return ids;\n};\n\nexport const ensureElementIds = (\n elements: BuilderElement[],\n existingIds: Set<string>,\n) => {\n const seen = new Set<string>();\n const walk = (arr: BuilderElement[]) => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n\n const anyEl = el as any;\n const currentId = typeof anyEl.id === \"string\" ? anyEl.id.trim() : \"\";\n if (!currentId || seen.has(currentId)) {\n const newId = createElementId(existingIds);\n anyEl.id = newId;\n existingIds.add(newId);\n seen.add(newId);\n } else {\n anyEl.id = currentId;\n existingIds.add(currentId);\n seen.add(currentId);\n }\n\n if (Array.isArray(anyEl.children)) {\n walk(anyEl.children as BuilderElement[]);\n }\n }\n };\n walk(elements);\n};\n\nexport const findElementById = (\n elements: BuilderElement[],\n elementId: string,\n): BuilderElement | null => {\n const id = String(elementId ?? \"\").trim();\n if (!id) return null;\n\n const walk = (arr: BuilderElement[]): BuilderElement | null => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n if ((el as any).id === id) return el;\n const children = (el as any).children;\n if (Array.isArray(children)) {\n const found = walk(children as BuilderElement[]);\n if (found) return found;\n }\n }\n return null;\n };\n\n return walk(elements);\n};\n\nexport const deleteElementById = (\n elements: BuilderElement[],\n id: string,\n): boolean => {\n const target = String(id ?? \"\").trim();\n if (!target) return false;\n\n let deleted = false;\n const walk = (arr: BuilderElement[]) => {\n for (let idx = arr.length - 1; idx >= 0; idx--) {\n const el = arr[idx] as any;\n if (el?.id === target) {\n arr.splice(idx, 1);\n deleted = true;\n continue;\n }\n if (Array.isArray(el?.children)) walk(el.children as BuilderElement[]);\n }\n };\n walk(elements);\n return deleted;\n};\n\nexport const writeFileAtomic = async (filePath: string, content: string) => {\n const dir = path.dirname(filePath);\n const base = path.basename(filePath);\n const tmp = path.join(\n dir,\n `.qwintly_tmp_${base}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n const bak = path.join(\n dir,\n `.qwintly_bak_${base}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n\n try {\n await fs.mkdir(dir, { recursive: true });\n await fs.writeFile(tmp, content ?? \"\", \"utf-8\");\n\n // Windows rename doesn't overwrite; do a 2-step swap.\n try {\n await fs.rename(filePath, bak);\n await fs.rename(tmp, filePath);\n await fs.rm(bak, { force: true });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") {\n // No previous file; just put the temp file in place.\n await fs.rename(tmp, filePath);\n } else {\n throw err;\n }\n }\n } catch (err) {\n // rollback best-effort\n try {\n await fs.rm(tmp, { force: true });\n } catch {\n // ignore\n }\n try {\n await fs.stat(bak);\n try {\n await fs.rm(filePath, { force: true });\n } catch {\n // ignore\n }\n await fs.rename(bak, filePath);\n } catch {\n // ignore\n }\n throw err;\n }\n};\n\nexport const getAvailableRoutes = async (deps: {\n workspaceRoot: string;\n fs: {\n safeReadDir: (absoluteDir: string) => Promise<\n Array<{\n name: string;\n isDirectory: () => boolean;\n isFile: () => boolean;\n }>\n >;\n };\n}): Promise<string[]> => {\n const { workspaceRoot, fs } = deps;\n const appDir = toWorkspacePath(workspaceRoot, \"app\");\n const routes: string[] = [];\n\n const scan = async (dirPath: string) => {\n let entries;\n try {\n entries = await fs.safeReadDir(dirPath);\n } catch {\n return;\n }\n\n let hasPageConfig = false;\n for (const entry of entries) {\n if (entry.isFile() && entry.name === \"pageConfig.json\") {\n hasPageConfig = true;\n break;\n }\n }\n\n if (hasPageConfig) {\n const rel = path.relative(appDir, dirPath);\n const routeStr = \"/\" + rel.replace(/\\\\/g, \"/\");\n routes.push(routeStr === \"/\" ? \"/\" : routeStr.replace(/\\/$/, \"\"));\n }\n\n for (const entry of entries) {\n if (\n entry.isDirectory() &&\n entry.name !== \"node_modules\" &&\n !entry.name.startsWith(\".\")\n ) {\n await scan(path.join(dirPath, entry.name));\n }\n }\n };\n\n await scan(appDir);\n return routes.sort((a, b) => a.localeCompare(b));\n};\n\nconst isCatchAll = (segment: string): boolean =>\n segment.startsWith(\"[\") && segment.endsWith(\"]\") && segment.includes(\"...\");\n\nconst isDynamic = (segment: string): boolean =>\n segment.startsWith(\"[\") && segment.endsWith(\"]\");\n\nconst isOptionalCatchAll = (segment: string): boolean =>\n segment.startsWith(\"[[\") && segment.endsWith(\"]]\") && segment.includes(\"...\");\n\nexport const matchRoute = (\n physicalRoute: string,\n requestedRoute: string,\n): boolean => {\n const physSegs = normalizeRouteSegments(physicalRoute);\n const reqSegs = normalizeRouteSegments(requestedRoute);\n\n let pIdx = 0;\n let rIdx = 0;\n\n while (pIdx < physSegs.length && rIdx < reqSegs.length) {\n const phys = physSegs[pIdx];\n const req = reqSegs[rIdx];\n\n if (isCatchAll(phys)) {\n return true;\n }\n\n if (isDynamic(phys) || phys.toLowerCase() === req.toLowerCase()) {\n pIdx++;\n rIdx++;\n continue;\n }\n\n return false;\n }\n\n if (rIdx === reqSegs.length && pIdx < physSegs.length) {\n return physSegs.slice(pIdx).every(isOptionalCatchAll);\n }\n\n return pIdx === physSegs.length && rIdx === reqSegs.length;\n};\n\nexport const resolvePageConfigJsonPath = async (\n workspaceRoot: string,\n route: string,\n fs: CoreFs,\n): Promise<string> => {\n // 1. Try exact match first\n const exactPath = getPageConfigJsonPath(workspaceRoot, route);\n try {\n await fs.stat(exactPath);\n return exactPath;\n } catch {\n // Exact file does not exist, let's resolve dynamically\n }\n\n // 2. Fetch all available routes in the workspace\n const available = await getAvailableRoutes({ workspaceRoot, fs });\n\n // 3. Find first matching route\n for (const physRoute of available) {\n if (matchRoute(physRoute, route)) {\n return getPageConfigJsonPath(workspaceRoot, physRoute);\n }\n }\n\n // 4. Fallback: if no match, just return the exact path\n return exactPath;\n};\n\nexport const loadAndPreparePageConfig = async (\n workspaceRoot: string,\n route: string,\n fs: CoreFs,\n) => {\n let configPath: string;\n try {\n configPath = await resolvePageConfigJsonPath(workspaceRoot, route, fs);\n } catch (err) {\n return {\n success: false as const,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let before = \"\";\n try {\n before = await fs.readFile(configPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\")\n return { success: false as const, error: \"not found\" };\n return {\n success: false as const,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let parsed: ReturnType<typeof parsePageConfigJson>;\n try {\n parsed = parsePageConfigJson(before);\n } catch (err) {\n return {\n success: false as const,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n const elements = parsed.elements ?? [];\n const existingIds = extractAllIdsDeep(elements);\n ensureElementIds(elements, existingIds);\n\n return {\n success: true as const,\n configPath,\n elements,\n existingIds,\n };\n};\n"]}
@@ -22,7 +22,7 @@ function reconstructTree(flatElements) {
22
22
  }
23
23
  const parentNode = buildMap.get(flat.parentId);
24
24
  if (!parentNode) {
25
- throw new Error(`Parent element with id '${flat.parentId}' not found in the list`);
25
+ throw new Error(`Parent element with id '${flat.parentId}' not found in the list. Please read the file using read_file tool to see the valid parent ids available. DO NOT do insert with same args without calling read_file tool.`);
26
26
  }
27
27
  const currentNode = buildMap.get(flat.id);
28
28
  if (currentNode) {
@@ -38,7 +38,7 @@ export const createInsertElementImpl = (deps) => {
38
38
  const { workspaceRoot, fs } = deps;
39
39
  return async (routeOrArgs, parentId, inputElements, beforeId) => {
40
40
  const rawArgs = typeof routeOrArgs === "object" && routeOrArgs !== null
41
- ? routeOrArgs
41
+ ? (routeOrArgs)
42
42
  : {
43
43
  route: routeOrArgs,
44
44
  parent_id: parentId,
@@ -1 +1 @@
1
- {"version":3,"file":"insertElement.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/insertElement.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveUnsplashImagesDeep } from \"../../../image/unsplash.service.js\";\nimport type { BuilderElement } from \"../../../types/elements.js\";\nimport {\n ensureElementIds,\n findElementById,\n loadAndPreparePageConfig,\n stringifyPageConfigJson,\n writeFileAtomic,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { InsertElementArgsZod } from \"../validators/builderElement.zod.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nfunction reconstructTree(flatElements: any[]): BuilderElement[] {\n const rootFlats = flatElements.filter((el) => el.parentId === \"parent\");\n if (rootFlats.length === 0) {\n throw new Error(\"No root element found with parentId 'parent'\");\n }\n\n const buildMap = new Map<string, any>();\n for (const flat of flatElements) {\n buildMap.set(flat.id, {\n type: flat.type,\n className: flat.className,\n visible: flat.visible,\n props: flat.props ? structuredClone(flat.props) : undefined,\n children: [],\n });\n }\n\n for (const flat of flatElements) {\n if (flat.parentId === \"parent\") {\n continue;\n }\n const parentNode = buildMap.get(flat.parentId);\n if (!parentNode) {\n throw new Error(\n `Parent element with id '${flat.parentId}' not found in the list`,\n );\n }\n const currentNode = buildMap.get(flat.id);\n if (currentNode) {\n if (!parentNode.children) {\n parentNode.children = [];\n }\n parentNode.children.push(currentNode);\n }\n }\n\n return rootFlats.map((rootFlat) => buildMap.get(rootFlat.id));\n}\n\nexport const createInsertElementImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (\n routeOrArgs: string | Record<string, unknown>,\n parentId?: string,\n inputElements?: any[],\n beforeId?: string,\n ) => {\n const rawArgs =\n typeof routeOrArgs === \"object\" && routeOrArgs !== null\n ? (routeOrArgs as Record<string, unknown>)\n : {\n route: routeOrArgs,\n parent_id: parentId,\n before_id: beforeId,\n elements: inputElements,\n };\n\n const parsedArgs = InsertElementArgsZod.safeParse(rawArgs);\n if (!parsedArgs.success) {\n return {\n success: false,\n error: \"invalid args\",\n error_detail: parsedArgs.error.flatten(),\n };\n }\n\n const parent_id = String(parsedArgs.data.parent_id ?? \"\").trim();\n if (!parent_id) return { success: false, error: \"invalid parent_id\" };\n\n const before_id = String(parsedArgs.data.before_id ?? \"\").trim();\n\n const prep = await loadAndPreparePageConfig(workspaceRoot, parsedArgs.data.route, fs);\n if (!prep.success) return prep;\n\n const { configPath, elements, existingIds } = prep;\n\n // Clone + inject ids for the inserted element subtree.\n let toInsert: BuilderElement[];\n try {\n toInsert = reconstructTree(parsedArgs.data.elements);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n for (const el of toInsert) {\n await resolveUnsplashImagesDeep(el);\n }\n ensureElementIds(toInsert, existingIds);\n\n const parent = findElementById(elements, parent_id);\n if (!parent) return { success: false, error: \"parent not found\" };\n\n const anyParent = parent as any;\n if (!anyParent.children || !Array.isArray(anyParent.children))\n anyParent.children = [];\n\n const children = anyParent.children as BuilderElement[];\n const idx = before_id ? children.findIndex((c: any) => String(c?.id ?? \"\") === before_id) : -1;\n if (idx >= 0) {\n children.splice(idx, 0, ...toInsert);\n } else {\n children.push(...toInsert);\n }\n\n const after = stringifyPageConfigJson({ elements });\n try {\n await writeFileAtomic(configPath, after);\n return {\n success: true,\n changed: true,\n inserted_id: (toInsert[0] as any).id,\n inserted_ids: toInsert.map((el: any) => el.id),\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":"insertElement.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/insertElement.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveUnsplashImagesDeep } from \"../../../image/unsplash.service.js\";\nimport type { BuilderElement } from \"../../../types/elements.js\";\nimport {\n ensureElementIds,\n findElementById,\n loadAndPreparePageConfig,\n stringifyPageConfigJson,\n writeFileAtomic,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { InsertElementArgsZod } from \"../validators/builderElement.zod.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nfunction reconstructTree(flatElements: any[]): BuilderElement[] {\n const rootFlats = flatElements.filter((el) => el.parentId === \"parent\");\n if (rootFlats.length === 0) {\n throw new Error(\"No root element found with parentId 'parent'\");\n }\n\n const buildMap = new Map<string, any>();\n for (const flat of flatElements) {\n buildMap.set(flat.id, {\n type: flat.type,\n className: flat.className,\n visible: flat.visible,\n props: flat.props ? structuredClone(flat.props) : undefined,\n children: [],\n });\n }\n\n for (const flat of flatElements) {\n if (flat.parentId === \"parent\") {\n continue;\n }\n const parentNode = buildMap.get(flat.parentId);\n if (!parentNode) {\n throw new Error(\n `Parent element with id '${flat.parentId}' not found in the list. Please read the file using read_file tool to see the valid parent ids available. DO NOT do insert with same args without calling read_file tool.`,\n );\n }\n const currentNode = buildMap.get(flat.id);\n if (currentNode) {\n if (!parentNode.children) {\n parentNode.children = [];\n }\n parentNode.children.push(currentNode);\n }\n }\n\n return rootFlats.map((rootFlat) => buildMap.get(rootFlat.id));\n}\n\nexport const createInsertElementImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (\n routeOrArgs: string | Record<string, unknown>,\n parentId?: string,\n inputElements?: any[],\n beforeId?: string,\n ) => {\n const rawArgs =\n typeof routeOrArgs === \"object\" && routeOrArgs !== null\n ? (routeOrArgs)\n : {\n route: routeOrArgs,\n parent_id: parentId,\n before_id: beforeId,\n elements: inputElements,\n };\n\n const parsedArgs = InsertElementArgsZod.safeParse(rawArgs);\n if (!parsedArgs.success) {\n return {\n success: false,\n error: \"invalid args\",\n error_detail: parsedArgs.error.flatten(),\n };\n }\n\n const parent_id = String(parsedArgs.data.parent_id ?? \"\").trim();\n if (!parent_id) return { success: false, error: \"invalid parent_id\" };\n\n const before_id = String(parsedArgs.data.before_id ?? \"\").trim();\n\n const prep = await loadAndPreparePageConfig(workspaceRoot, parsedArgs.data.route, fs);\n if (!prep.success) return prep;\n\n const { configPath, elements, existingIds } = prep;\n\n // Clone + inject ids for the inserted element subtree.\n let toInsert: BuilderElement[];\n try {\n toInsert = reconstructTree(parsedArgs.data.elements);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n for (const el of toInsert) {\n await resolveUnsplashImagesDeep(el);\n }\n ensureElementIds(toInsert, existingIds);\n\n const parent = findElementById(elements, parent_id);\n if (!parent) return { success: false, error: \"parent not found\" };\n\n const anyParent = parent as any;\n if (!anyParent.children || !Array.isArray(anyParent.children))\n anyParent.children = [];\n\n const children = anyParent.children as BuilderElement[];\n const idx = before_id ? children.findIndex((c: any) => String(c?.id ?? \"\") === before_id) : -1;\n if (idx >= 0) {\n children.splice(idx, 0, ...toInsert);\n } else {\n children.push(...toInsert);\n }\n\n const after = stringifyPageConfigJson({ elements });\n try {\n await writeFileAtomic(configPath, after);\n return {\n success: true,\n changed: true,\n inserted_id: (toInsert[0] as any).id,\n inserted_ids: toInsert.map((el: any) => el.id),\n };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n };\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"projectInfoIndex.d.ts","sourceRoot":"","sources":["../../src/indexer/projectInfoIndex.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAiG5D,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC,CAkDtB"}
1
+ {"version":3,"file":"projectInfoIndex.d.ts","sourceRoot":"","sources":["../../src/indexer/projectInfoIndex.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAU5D,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC,CA+BtB"}
@@ -1,92 +1,10 @@
1
- import { getAvailableRoutes, getPageConfigJsonPath, } from "../ai/tools/helpers/pageConfigJson.helpers.js";
2
- import { readFile, safeReadDir } from "../utils/workspace.js";
3
- const sectionNameFromId = (id) => {
4
- if (!id)
5
- return "";
6
- if (id.endsWith("-section"))
7
- return id.slice(0, -"-section".length);
8
- if (id.endsWith("-container"))
9
- return id.slice(0, -"-container".length);
10
- return id;
11
- };
1
+ import { getAvailableRoutes, } from "../ai/tools/helpers/pageConfigJson.helpers.js";
2
+ import { safeReadDir } from "../utils/workspace.js";
12
3
  const computePageNameFromRoute = (pageRoute) => {
13
4
  if (pageRoute === "/")
14
5
  return "root";
15
6
  return pageRoute.slice(1).split("/").join("-");
16
7
  };
17
- const findRootElement = (els) => {
18
- let rootElement = null;
19
- const findRoot = (items) => {
20
- for (const el of items) {
21
- if (el && typeof el === "object") {
22
- if (el.type === "div" && el.id === "root") {
23
- rootElement = el;
24
- return;
25
- }
26
- if (Array.isArray(el.children)) {
27
- findRoot(el.children);
28
- if (rootElement)
29
- return;
30
- }
31
- }
32
- }
33
- };
34
- findRoot(els);
35
- return rootElement;
36
- };
37
- const extractRootSections = (rootElement) => {
38
- if (!rootElement || !Array.isArray(rootElement.children))
39
- return [];
40
- const rootSections = [];
41
- for (const child of rootElement.children) {
42
- if (child &&
43
- typeof child === "object" &&
44
- child.type === "div" &&
45
- child.id &&
46
- child.id !== "root") {
47
- const name = sectionNameFromId(child.id);
48
- if (name) {
49
- rootSections.push(name);
50
- }
51
- }
52
- }
53
- return rootSections;
54
- };
55
- const collectFallbackSections = (elements) => {
56
- const seen = new Set();
57
- const results = [];
58
- const collectFallback = (els) => {
59
- for (const el of els) {
60
- if (el && typeof el === "object") {
61
- if (el.type === "div" &&
62
- el.id &&
63
- el.id !== "root" &&
64
- (el.id.endsWith("-section") || el.id.endsWith("-container"))) {
65
- const sectionName = sectionNameFromId(el.id);
66
- if (sectionName && !seen.has(sectionName)) {
67
- seen.add(sectionName);
68
- results.push(sectionName);
69
- }
70
- }
71
- if (Array.isArray(el.children)) {
72
- collectFallback(el.children);
73
- }
74
- }
75
- }
76
- };
77
- collectFallback(elements);
78
- return results;
79
- };
80
- const extractSectionNamesFromParsedConfig = (config) => {
81
- if (!config || !Array.isArray(config.elements))
82
- return [];
83
- const rootElement = findRootElement(config.elements);
84
- const rootSections = extractRootSections(rootElement);
85
- if (rootSections.length > 0) {
86
- return rootSections;
87
- }
88
- return collectFallbackSections(config.elements);
89
- };
90
8
  export async function computeProjectInfo(rootDir) {
91
9
  const routes = await getAvailableRoutes({
92
10
  workspaceRoot: rootDir,
@@ -96,29 +14,11 @@ export async function computeProjectInfo(rootDir) {
96
14
  for (const pageRoute of routes) {
97
15
  const pageName = computePageNameFromRoute(pageRoute);
98
16
  const description = `${pageName} page for this project`;
99
- let sectionNames = [];
100
- try {
101
- const configPath = getPageConfigJsonPath(rootDir, pageRoute);
102
- const content = await readFile(configPath);
103
- if (content) {
104
- const config = JSON.parse(content);
105
- sectionNames = extractSectionNamesFromParsedConfig(config);
106
- }
107
- }
108
- catch {
109
- // Ignore reading/parsing errors, treat as no sections
110
- }
111
17
  const page = {
112
18
  pageRoute,
113
19
  pageName,
114
20
  description,
115
21
  };
116
- if (sectionNames.length > 0) {
117
- page.sections = sectionNames.map((sectionName) => ({
118
- sectionName,
119
- description: `${sectionName} section for this page`,
120
- }));
121
- }
122
22
  uiPages.push(page);
123
23
  }
124
24
  uiPages.sort((a, b) => a.pageRoute.localeCompare(b.pageRoute, undefined, {
@@ -1 +1 @@
1
- {"version":3,"file":"projectInfoIndex.js","sourceRoot":"","sources":["../../src/indexer/projectInfoIndex.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getAvailableRoutes,\n getPageConfigJsonPath,\n} from \"../ai/tools/helpers/pageConfigJson.helpers.js\";\nimport { ProjectInfo } from \"../types/projectInfo.types.js\";\nimport { readFile, safeReadDir } from \"../utils/workspace.js\";\n\ntype UiPage = ProjectInfo[\"uiPages\"][number];\n\nconst sectionNameFromId = (id: string): string => {\n if (!id) return \"\";\n if (id.endsWith(\"-section\")) return id.slice(0, -\"-section\".length);\n if (id.endsWith(\"-container\")) return id.slice(0, -\"-container\".length);\n return id;\n};\n\nconst computePageNameFromRoute = (pageRoute: string): string => {\n if (pageRoute === \"/\") return \"root\";\n return pageRoute.slice(1).split(\"/\").join(\"-\");\n};\n\nconst findRootElement = (els: any[]): any => {\n let rootElement: any = null;\n const findRoot = (items: any[]) => {\n for (const el of items) {\n if (el && typeof el === \"object\") {\n if (el.type === \"div\" && el.id === \"root\") {\n rootElement = el;\n return;\n }\n if (Array.isArray(el.children)) {\n findRoot(el.children);\n if (rootElement) return;\n }\n }\n }\n };\n findRoot(els);\n return rootElement;\n};\n\nconst extractRootSections = (rootElement: any): string[] => {\n if (!rootElement || !Array.isArray(rootElement.children)) return [];\n const rootSections: string[] = [];\n for (const child of rootElement.children) {\n if (\n child &&\n typeof child === \"object\" &&\n child.type === \"div\" &&\n child.id &&\n child.id !== \"root\"\n ) {\n const name = sectionNameFromId(child.id);\n if (name) {\n rootSections.push(name);\n }\n }\n }\n return rootSections;\n};\n\nconst collectFallbackSections = (elements: any[]): string[] => {\n const seen = new Set<string>();\n const results: string[] = [];\n const collectFallback = (els: any[]) => {\n for (const el of els) {\n if (el && typeof el === \"object\") {\n if (\n el.type === \"div\" &&\n el.id &&\n el.id !== \"root\" &&\n (el.id.endsWith(\"-section\") || el.id.endsWith(\"-container\"))\n ) {\n const sectionName = sectionNameFromId(el.id);\n if (sectionName && !seen.has(sectionName)) {\n seen.add(sectionName);\n results.push(sectionName);\n }\n }\n if (Array.isArray(el.children)) {\n collectFallback(el.children);\n }\n }\n }\n };\n collectFallback(elements);\n return results;\n};\n\nconst extractSectionNamesFromParsedConfig = (config: any): string[] => {\n if (!config || !Array.isArray(config.elements)) return [];\n\n const rootElement = findRootElement(config.elements);\n const rootSections = extractRootSections(rootElement);\n if (rootSections.length > 0) {\n return rootSections;\n }\n\n return collectFallbackSections(config.elements);\n};\n\nexport async function computeProjectInfo(\n rootDir: string,\n): Promise<ProjectInfo> {\n const routes = await getAvailableRoutes({\n workspaceRoot: rootDir,\n fs: { safeReadDir },\n });\n\n const uiPages: UiPage[] = [];\n\n for (const pageRoute of routes) {\n const pageName = computePageNameFromRoute(pageRoute);\n const description = `${pageName} page for this project`;\n\n let sectionNames: string[] = [];\n try {\n const configPath = getPageConfigJsonPath(rootDir, pageRoute);\n const content = await readFile(configPath);\n if (content) {\n const config = JSON.parse(content);\n sectionNames = extractSectionNamesFromParsedConfig(config);\n }\n } catch {\n // Ignore reading/parsing errors, treat as no sections\n }\n\n const page: UiPage = {\n pageRoute,\n pageName,\n description,\n };\n\n if (sectionNames.length > 0) {\n page.sections = sectionNames.map((sectionName) => ({\n sectionName,\n description: `${sectionName} section for this page`,\n }));\n }\n\n uiPages.push(page);\n }\n\n uiPages.sort((a, b) =>\n a.pageRoute.localeCompare(b.pageRoute, undefined, {\n sensitivity: \"base\",\n }),\n );\n\n return {\n uiPages,\n lastUpdatedPlanVersion: 1,\n };\n}"]}
1
+ {"version":3,"file":"projectInfoIndex.js","sourceRoot":"","sources":["../../src/indexer/projectInfoIndex.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GACnB,MAAM,+CAA+C,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIpD,MAAM,wBAAwB,GAAG,CAAC,SAAiB,EAAU,EAAE;IAC7D,IAAI,SAAS,KAAK,GAAG;QAAE,OAAO,MAAM,CAAC;IACrC,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAe;IAEf,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;QACtC,aAAa,EAAE,OAAO;QACtB,EAAE,EAAE,EAAE,WAAW,EAAE;KACpB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,WAAW,GAAG,GAAG,QAAQ,wBAAwB,CAAC;QAExD,MAAM,IAAI,GAAW;YACnB,SAAS;YACT,QAAQ;YACR,WAAW;SACZ,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACpB,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE;QAChD,WAAW,EAAE,MAAM;KACpB,CAAC,CACH,CAAC;IAEF,OAAO;QACL,OAAO;QACP,sBAAsB,EAAE,CAAC;KAC1B,CAAC;AACJ,CAAC","sourcesContent":["import {\n getAvailableRoutes,\n} from \"../ai/tools/helpers/pageConfigJson.helpers.js\";\nimport { ProjectInfo } from \"../types/projectInfo.types.js\";\nimport { safeReadDir } from \"../utils/workspace.js\";\n\ntype UiPage = ProjectInfo[\"uiPages\"][number];\n\nconst computePageNameFromRoute = (pageRoute: string): string => {\n if (pageRoute === \"/\") return \"root\";\n return pageRoute.slice(1).split(\"/\").join(\"-\");\n};\n\nexport async function computeProjectInfo(\n rootDir: string,\n): Promise<ProjectInfo> {\n const routes = await getAvailableRoutes({\n workspaceRoot: rootDir,\n fs: { safeReadDir },\n });\n\n const uiPages: UiPage[] = [];\n\n for (const pageRoute of routes) {\n const pageName = computePageNameFromRoute(pageRoute);\n const description = `${pageName} page for this project`;\n\n const page: UiPage = {\n pageRoute,\n pageName,\n description,\n };\n\n uiPages.push(page);\n }\n\n uiPages.sort((a, b) =>\n a.pageRoute.localeCompare(b.pageRoute, undefined, {\n sensitivity: \"base\",\n }),\n );\n\n return {\n uiPages,\n lastUpdatedPlanVersion: 1,\n };\n}"]}
@@ -4,7 +4,7 @@ import path from "node:path";
4
4
  import os from "node:os";
5
5
  import fs from "node:fs/promises";
6
6
  import { computeProjectInfo } from "../indexer/projectInfoIndex.js";
7
- test("computeProjectInfo: scans routes and sections from pageConfig.json files", async () => {
7
+ test("computeProjectInfo: scans routes from directories and constructs pages", async () => {
8
8
  const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), "qwintly-core-project-info-"));
9
9
  try {
10
10
  // 1. Create a root pageConfig.json with a div root and two sections
@@ -49,24 +49,16 @@ test("computeProjectInfo: scans routes and sections from pageConfig.json files",
49
49
  assert.ok(rootPage);
50
50
  assert.equal(rootPage.pageName, "root");
51
51
  assert.equal(rootPage.description, "root page for this project");
52
- assert.deepEqual(rootPage.sections, [
53
- { sectionName: "hero", description: "hero section for this page" },
54
- { sectionName: "footer", description: "footer section for this page" }
55
- ]);
56
52
  // /dashboard route
57
53
  const dashboardPage = projectInfo.uiPages.find(p => p.pageRoute === "/dashboard");
58
54
  assert.ok(dashboardPage);
59
55
  assert.equal(dashboardPage.pageName, "dashboard");
60
56
  assert.equal(dashboardPage.description, "dashboard page for this project");
61
- assert.equal(dashboardPage.sections, undefined);
62
57
  // /dashboard/settings route
63
58
  const settingsPage = projectInfo.uiPages.find(p => p.pageRoute === "/dashboard/settings");
64
59
  assert.ok(settingsPage);
65
60
  assert.equal(settingsPage.pageName, "dashboard-settings");
66
61
  assert.equal(settingsPage.description, "dashboard-settings page for this project");
67
- assert.deepEqual(settingsPage.sections, [
68
- { sectionName: "settings", description: "settings section for this page" }
69
- ]);
70
62
  }
71
63
  finally {
72
64
  await fs.rm(workspaceRoot, { recursive: true, force: true });
@@ -1 +1 @@
1
- {"version":3,"file":"projectInfoIndex.test.js","sourceRoot":"","sources":["../../src/tests/projectInfoIndex.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 { computeProjectInfo } from \"../indexer/projectInfoIndex.js\";\n\ntest(\"computeProjectInfo: scans routes and sections from pageConfig.json files\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-project-info-\"));\n try {\n // 1. Create a root pageConfig.json with a div root and two sections\n const rootDir = path.join(workspaceRoot, \"app\");\n await fs.mkdir(rootDir, { recursive: true });\n await fs.writeFile(\n path.join(rootDir, \"pageConfig.json\"),\n JSON.stringify({\n elements: [\n {\n id: \"root\",\n type: \"div\",\n children: [\n { id: \"hero-section\", type: \"div\", children: [] },\n { id: \"footer-container\", type: \"div\", children: [] },\n { id: \"some-text\", type: \"text\", props: { text: \"hello\" } }\n ]\n }\n ]\n })\n );\n\n // 2. Create a nested pageConfig.json under /dashboard/settings with a fallback section\n const settingsDir = path.join(workspaceRoot, \"app\", \"dashboard\", \"settings\");\n await fs.mkdir(settingsDir, { recursive: true });\n await fs.writeFile(\n path.join(settingsDir, \"pageConfig.json\"),\n JSON.stringify({\n elements: [\n {\n id: \"settings-container\",\n type: \"div\",\n children: []\n }\n ]\n })\n );\n\n // 3. Create a nested pageConfig.json under /dashboard with no sections\n const dashboardDir = path.join(workspaceRoot, \"app\", \"dashboard\");\n await fs.mkdir(dashboardDir, { recursive: true });\n await fs.writeFile(\n path.join(dashboardDir, \"pageConfig.json\"),\n JSON.stringify({\n elements: []\n })\n );\n\n const projectInfo = await computeProjectInfo(workspaceRoot);\n\n assert.equal(projectInfo.uiPages.length, 3);\n assert.equal(projectInfo.lastUpdatedPlanVersion, 1);\n\n // / route\n const rootPage = projectInfo.uiPages.find(p => p.pageRoute === \"/\");\n assert.ok(rootPage);\n assert.equal(rootPage.pageName, \"root\");\n assert.equal(rootPage.description, \"root page for this project\");\n assert.deepEqual(rootPage.sections, [\n { sectionName: \"hero\", description: \"hero section for this page\" },\n { sectionName: \"footer\", description: \"footer section for this page\" }\n ]);\n\n // /dashboard route\n const dashboardPage = projectInfo.uiPages.find(p => p.pageRoute === \"/dashboard\");\n assert.ok(dashboardPage);\n assert.equal(dashboardPage.pageName, \"dashboard\");\n assert.equal(dashboardPage.description, \"dashboard page for this project\");\n assert.equal(dashboardPage.sections, undefined);\n\n // /dashboard/settings route\n const settingsPage = projectInfo.uiPages.find(p => p.pageRoute === \"/dashboard/settings\");\n assert.ok(settingsPage);\n assert.equal(settingsPage.pageName, \"dashboard-settings\");\n assert.equal(settingsPage.description, \"dashboard-settings page for this project\");\n assert.deepEqual(settingsPage.sections, [\n { sectionName: \"settings\", description: \"settings section for this page\" }\n ]);\n\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n"]}
1
+ {"version":3,"file":"projectInfoIndex.test.js","sourceRoot":"","sources":["../../src/tests/projectInfoIndex.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 { computeProjectInfo } from \"../indexer/projectInfoIndex.js\";\n\ntest(\"computeProjectInfo: scans routes from directories and constructs pages\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-project-info-\"));\n try {\n // 1. Create a root pageConfig.json with a div root and two sections\n const rootDir = path.join(workspaceRoot, \"app\");\n await fs.mkdir(rootDir, { recursive: true });\n await fs.writeFile(\n path.join(rootDir, \"pageConfig.json\"),\n JSON.stringify({\n elements: [\n {\n id: \"root\",\n type: \"div\",\n children: [\n { id: \"hero-section\", type: \"div\", children: [] },\n { id: \"footer-container\", type: \"div\", children: [] },\n { id: \"some-text\", type: \"text\", props: { text: \"hello\" } }\n ]\n }\n ]\n })\n );\n\n // 2. Create a nested pageConfig.json under /dashboard/settings with a fallback section\n const settingsDir = path.join(workspaceRoot, \"app\", \"dashboard\", \"settings\");\n await fs.mkdir(settingsDir, { recursive: true });\n await fs.writeFile(\n path.join(settingsDir, \"pageConfig.json\"),\n JSON.stringify({\n elements: [\n {\n id: \"settings-container\",\n type: \"div\",\n children: []\n }\n ]\n })\n );\n\n // 3. Create a nested pageConfig.json under /dashboard with no sections\n const dashboardDir = path.join(workspaceRoot, \"app\", \"dashboard\");\n await fs.mkdir(dashboardDir, { recursive: true });\n await fs.writeFile(\n path.join(dashboardDir, \"pageConfig.json\"),\n JSON.stringify({\n elements: []\n })\n );\n\n const projectInfo = await computeProjectInfo(workspaceRoot);\n\n assert.equal(projectInfo.uiPages.length, 3);\n assert.equal(projectInfo.lastUpdatedPlanVersion, 1);\n\n // / route\n const rootPage = projectInfo.uiPages.find(p => p.pageRoute === \"/\");\n assert.ok(rootPage);\n assert.equal(rootPage.pageName, \"root\");\n assert.equal(rootPage.description, \"root page for this project\");\n\n // /dashboard route\n const dashboardPage = projectInfo.uiPages.find(p => p.pageRoute === \"/dashboard\");\n assert.ok(dashboardPage);\n assert.equal(dashboardPage.pageName, \"dashboard\");\n assert.equal(dashboardPage.description, \"dashboard page for this project\");\n\n // /dashboard/settings route\n const settingsPage = projectInfo.uiPages.find(p => p.pageRoute === \"/dashboard/settings\");\n assert.ok(settingsPage);\n assert.equal(settingsPage.pageName, \"dashboard-settings\");\n assert.equal(settingsPage.description, \"dashboard-settings page for this project\");\n\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n"]}
@@ -98,4 +98,126 @@ test("tool loop: get_available_routes retrieves routes", async () => {
98
98
  await fs.rm(workspaceRoot, { recursive: true, force: true });
99
99
  }
100
100
  });
101
+ test("tool loop: update_classname updates element's className using className parameter", async () => {
102
+ const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), "qwintly-core-runner-"));
103
+ try {
104
+ await fs.mkdir(path.join(workspaceRoot, "app"), { recursive: true });
105
+ const configPath = path.join(workspaceRoot, "app", "pageConfig.json");
106
+ await fs.writeFile(configPath, JSON.stringify({
107
+ elements: [
108
+ {
109
+ id: "el_mGCUHuZuL0",
110
+ type: "button",
111
+ props: { text: "Order Now" },
112
+ children: [],
113
+ className: "",
114
+ },
115
+ ],
116
+ }));
117
+ let aiCalls = 0;
118
+ const aiCall = async () => {
119
+ aiCalls += 1;
120
+ if (aiCalls === 1) {
121
+ return {
122
+ functionCalls: [
123
+ {
124
+ name: "update_classname",
125
+ args: {
126
+ route: "/",
127
+ element_id: "el_mGCUHuZuL0",
128
+ className: "bg-red-600 font-bold",
129
+ },
130
+ },
131
+ ],
132
+ };
133
+ }
134
+ return { functionCalls: [], text: "ok" };
135
+ };
136
+ const res = await runToolLoop({
137
+ initialContents: [],
138
+ tools: [],
139
+ workspaceRoot,
140
+ aiCall,
141
+ logger: async () => { },
142
+ toolCallingMode: FunctionCallingConfigMode.ANY,
143
+ maxSteps: 5,
144
+ keepFullTrace: false,
145
+ });
146
+ assert.equal(res.finalText, "ok");
147
+ const toolResponses = res.modelContents.filter((c) => c?.role === "user" &&
148
+ Array.isArray(c?.parts) &&
149
+ c.parts.some((p) => p?.functionResponse?.name === "update_classname"));
150
+ assert.equal(toolResponses.length, 1);
151
+ const response = toolResponses[0].parts.find((p) => p?.functionResponse?.name === "update_classname")?.functionResponse?.response;
152
+ assert.equal(response?.success, true);
153
+ assert.equal(response?.updated_id, "el_mGCUHuZuL0");
154
+ const afterConfig = JSON.parse(await fs.readFile(configPath, "utf-8"));
155
+ assert.equal(afterConfig.elements[0].className, "bg-red-600 font-bold");
156
+ }
157
+ finally {
158
+ await fs.rm(workspaceRoot, { recursive: true, force: true });
159
+ }
160
+ });
161
+ test("tool loop: update_props updates element's props using root-level parameters", async () => {
162
+ const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), "qwintly-core-runner-"));
163
+ try {
164
+ await fs.mkdir(path.join(workspaceRoot, "app"), { recursive: true });
165
+ const configPath = path.join(workspaceRoot, "app", "pageConfig.json");
166
+ await fs.writeFile(configPath, JSON.stringify({
167
+ elements: [
168
+ {
169
+ id: "el_k01Ij3HJvZ",
170
+ type: "text",
171
+ props: {
172
+ text: "A vibrant blast of sweet, sun-ripened strawberries.",
173
+ },
174
+ children: [],
175
+ className: "text-sm text-muted-foreground",
176
+ },
177
+ ],
178
+ }));
179
+ let aiCalls = 0;
180
+ const aiCall = async () => {
181
+ aiCalls += 1;
182
+ if (aiCalls === 1) {
183
+ return {
184
+ functionCalls: [
185
+ {
186
+ name: "update_props",
187
+ args: {
188
+ route: "/",
189
+ element_id: "el_k01Ij3HJvZ",
190
+ text: "Life is too short for boring flavors! This is pure strawberry joy.",
191
+ },
192
+ },
193
+ ],
194
+ };
195
+ }
196
+ return { functionCalls: [], text: "ok" };
197
+ };
198
+ const res = await runToolLoop({
199
+ initialContents: [],
200
+ tools: [],
201
+ workspaceRoot,
202
+ aiCall,
203
+ logger: async () => { },
204
+ toolCallingMode: FunctionCallingConfigMode.ANY,
205
+ maxSteps: 5,
206
+ keepFullTrace: false,
207
+ });
208
+ assert.equal(res.finalText, "ok");
209
+ const toolResponses = res.modelContents.filter((c) => c?.role === "user" &&
210
+ Array.isArray(c?.parts) &&
211
+ c.parts.some((p) => p?.functionResponse?.name === "update_props"));
212
+ assert.equal(toolResponses.length, 1);
213
+ const response = toolResponses[0].parts.find((p) => p?.functionResponse?.name === "update_props")?.functionResponse?.response;
214
+ assert.equal(response?.success, true);
215
+ assert.equal(response?.updated_id, "el_k01Ij3HJvZ");
216
+ const afterConfig = JSON.parse(await fs.readFile(configPath, "utf-8"));
217
+ assert.equal(afterConfig.elements[0].props.text, "Life is too short for boring flavors! This is pure strawberry joy.");
218
+ }
219
+ finally {
220
+ await fs.rm(workspaceRoot, { recursive: true, force: true });
221
+ }
222
+ });
101
223
  //# sourceMappingURL=toolLoopRunner.routes.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toolLoopRunner.routes.test.js","sourceRoot":"","sources":["../../src/tests/toolLoopRunner.routes.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 { FunctionCallingConfigMode } from \"@google/genai\";\nimport { runToolLoop } from \"../ai/toolLoop/toolLoopRunner.js\";\n\ntest(\"tool loop: insert_element failure includes available routes and hint\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-runner-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n // Let's create an existing route\n await fs.mkdir(path.join(workspaceRoot, \"app\", \"dashboard\"), { recursive: true });\n await fs.writeFile(path.join(workspaceRoot, \"app\", \"dashboard\", \"pageConfig.json\"), \"{}\");\n\n let aiCalls = 0;\n const aiCall = async () => {\n aiCalls += 1;\n if (aiCalls === 1) {\n return {\n functionCalls: [\n {\n name: \"insert_element\",\n args: {\n route: \"/invalid-route\",\n parent_id: \"root\",\n elements: [\n { id: \"text_el\", parentId: \"parent\", type: \"text\", props: { text: \"hi\" } }\n ],\n },\n },\n ],\n };\n }\n return { functionCalls: [], text: \"ok\" };\n };\n\n const res = await runToolLoop({\n initialContents: [],\n tools: [],\n workspaceRoot,\n aiCall,\n logger: async () => {},\n toolCallingMode: FunctionCallingConfigMode.ANY,\n maxSteps: 5,\n keepFullTrace: false,\n });\n\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 === \"insert_element\"),\n );\n assert.equal(toolResponses.length, 1);\n\n const response = toolResponses[0].parts.find(\n (p: any) => p?.functionResponse?.name === \"insert_element\",\n )?.functionResponse?.response;\n\n assert.equal(response?.success, false);\n assert.match(String(response?.error ?? \"\"), /insert_element failed/i);\n assert.match(String(response?.error ?? \"\"), /create_new_route/i);\n assert.deepEqual(response?.available_routes, [\"/dashboard\"]);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"tool loop: get_available_routes retrieves routes\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-runner-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n await fs.writeFile(path.join(workspaceRoot, \"app\", \"pageConfig.json\"), \"{}\");\n await fs.mkdir(path.join(workspaceRoot, \"app\", \"dashboard\"), { recursive: true });\n await fs.writeFile(path.join(workspaceRoot, \"app\", \"dashboard\", \"pageConfig.json\"), \"{}\");\n\n let aiCalls = 0;\n const aiCall = async () => {\n aiCalls += 1;\n if (aiCalls === 1) {\n return {\n functionCalls: [{ name: \"get_available_routes\", args: {} }],\n };\n }\n return { functionCalls: [], text: \"ok\" };\n };\n\n const res = await runToolLoop({\n initialContents: [],\n tools: [],\n workspaceRoot,\n aiCall,\n logger: async () => {},\n toolCallingMode: FunctionCallingConfigMode.ANY,\n maxSteps: 5,\n keepFullTrace: false,\n });\n\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 === \"get_available_routes\"),\n );\n assert.equal(toolResponses.length, 1);\n\n const response = toolResponses[0].parts.find(\n (p: any) => p?.functionResponse?.name === \"get_available_routes\",\n )?.functionResponse?.response;\n\n assert.equal(response?.success, true);\n assert.deepEqual(response?.routes, [\"/\", \"/dashboard\"]);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n"]}
1
+ {"version":3,"file":"toolLoopRunner.routes.test.js","sourceRoot":"","sources":["../../src/tests/toolLoopRunner.routes.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 { FunctionCallingConfigMode } from \"@google/genai\";\nimport { runToolLoop } from \"../ai/toolLoop/toolLoopRunner.js\";\n\ntest(\"tool loop: insert_element failure includes available routes and hint\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-runner-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n // Let's create an existing route\n await fs.mkdir(path.join(workspaceRoot, \"app\", \"dashboard\"), { recursive: true });\n await fs.writeFile(path.join(workspaceRoot, \"app\", \"dashboard\", \"pageConfig.json\"), \"{}\");\n\n let aiCalls = 0;\n const aiCall = async () => {\n aiCalls += 1;\n if (aiCalls === 1) {\n return {\n functionCalls: [\n {\n name: \"insert_element\",\n args: {\n route: \"/invalid-route\",\n parent_id: \"root\",\n elements: [\n { id: \"text_el\", parentId: \"parent\", type: \"text\", props: { text: \"hi\" } }\n ],\n },\n },\n ],\n };\n }\n return { functionCalls: [], text: \"ok\" };\n };\n\n const res = await runToolLoop({\n initialContents: [],\n tools: [],\n workspaceRoot,\n aiCall,\n logger: async () => {},\n toolCallingMode: FunctionCallingConfigMode.ANY,\n maxSteps: 5,\n keepFullTrace: false,\n });\n\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 === \"insert_element\"),\n );\n assert.equal(toolResponses.length, 1);\n\n const response = toolResponses[0].parts.find(\n (p: any) => p?.functionResponse?.name === \"insert_element\",\n )?.functionResponse?.response;\n\n assert.equal(response?.success, false);\n assert.match(String(response?.error ?? \"\"), /insert_element failed/i);\n assert.match(String(response?.error ?? \"\"), /create_new_route/i);\n assert.deepEqual(response?.available_routes, [\"/dashboard\"]);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"tool loop: get_available_routes retrieves routes\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-runner-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n await fs.writeFile(path.join(workspaceRoot, \"app\", \"pageConfig.json\"), \"{}\");\n await fs.mkdir(path.join(workspaceRoot, \"app\", \"dashboard\"), { recursive: true });\n await fs.writeFile(path.join(workspaceRoot, \"app\", \"dashboard\", \"pageConfig.json\"), \"{}\");\n\n let aiCalls = 0;\n const aiCall = async () => {\n aiCalls += 1;\n if (aiCalls === 1) {\n return {\n functionCalls: [{ name: \"get_available_routes\", args: {} }],\n };\n }\n return { functionCalls: [], text: \"ok\" };\n };\n\n const res = await runToolLoop({\n initialContents: [],\n tools: [],\n workspaceRoot,\n aiCall,\n logger: async () => {},\n toolCallingMode: FunctionCallingConfigMode.ANY,\n maxSteps: 5,\n keepFullTrace: false,\n });\n\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 === \"get_available_routes\"),\n );\n assert.equal(toolResponses.length, 1);\n\n const response = toolResponses[0].parts.find(\n (p: any) => p?.functionResponse?.name === \"get_available_routes\",\n )?.functionResponse?.response;\n\n assert.equal(response?.success, true);\n assert.deepEqual(response?.routes, [\"/\", \"/dashboard\"]);\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"tool loop: update_classname updates element's className using className parameter\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-runner-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n const configPath = path.join(workspaceRoot, \"app\", \"pageConfig.json\");\n await fs.writeFile(\n configPath,\n JSON.stringify({\n elements: [\n {\n id: \"el_mGCUHuZuL0\",\n type: \"button\",\n props: { text: \"Order Now\" },\n children: [],\n className: \"\",\n },\n ],\n })\n );\n\n let aiCalls = 0;\n const aiCall = async () => {\n aiCalls += 1;\n if (aiCalls === 1) {\n return {\n functionCalls: [\n {\n name: \"update_classname\",\n args: {\n route: \"/\",\n element_id: \"el_mGCUHuZuL0\",\n className: \"bg-red-600 font-bold\",\n },\n },\n ],\n };\n }\n return { functionCalls: [], text: \"ok\" };\n };\n\n const res = await runToolLoop({\n initialContents: [],\n tools: [],\n workspaceRoot,\n aiCall,\n logger: async () => {},\n toolCallingMode: FunctionCallingConfigMode.ANY,\n maxSteps: 5,\n keepFullTrace: false,\n });\n\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_classname\"),\n );\n assert.equal(toolResponses.length, 1);\n\n const response = toolResponses[0].parts.find(\n (p: any) => p?.functionResponse?.name === \"update_classname\",\n )?.functionResponse?.response;\n\n assert.equal(response?.success, true);\n assert.equal(response?.updated_id, \"el_mGCUHuZuL0\");\n\n const afterConfig = JSON.parse(await fs.readFile(configPath, \"utf-8\"));\n assert.equal(afterConfig.elements[0].className, \"bg-red-600 font-bold\");\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n\ntest(\"tool loop: update_props updates element's props using root-level parameters\", async () => {\n const workspaceRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"qwintly-core-runner-\"));\n try {\n await fs.mkdir(path.join(workspaceRoot, \"app\"), { recursive: true });\n const configPath = path.join(workspaceRoot, \"app\", \"pageConfig.json\");\n await fs.writeFile(\n configPath,\n JSON.stringify({\n elements: [\n {\n id: \"el_k01Ij3HJvZ\",\n type: \"text\",\n props: {\n text: \"A vibrant blast of sweet, sun-ripened strawberries.\",\n },\n children: [],\n className: \"text-sm text-muted-foreground\",\n },\n ],\n })\n );\n\n let aiCalls = 0;\n const aiCall = async () => {\n aiCalls += 1;\n if (aiCalls === 1) {\n return {\n functionCalls: [\n {\n name: \"update_props\",\n args: {\n route: \"/\",\n element_id: \"el_k01Ij3HJvZ\",\n text: \"Life is too short for boring flavors! This is pure strawberry joy.\",\n },\n },\n ],\n };\n }\n return { functionCalls: [], text: \"ok\" };\n };\n\n const res = await runToolLoop({\n initialContents: [],\n tools: [],\n workspaceRoot,\n aiCall,\n logger: async () => {},\n toolCallingMode: FunctionCallingConfigMode.ANY,\n maxSteps: 5,\n keepFullTrace: false,\n });\n\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_props\"),\n );\n assert.equal(toolResponses.length, 1);\n\n const response = toolResponses[0].parts.find(\n (p: any) => p?.functionResponse?.name === \"update_props\",\n )?.functionResponse?.response;\n\n assert.equal(response?.success, true);\n assert.equal(response?.updated_id, \"el_k01Ij3HJvZ\");\n\n const afterConfig = JSON.parse(await fs.readFile(configPath, \"utf-8\"));\n assert.equal(afterConfig.elements[0].props.text, \"Life is too short for boring flavors! This is pure strawberry joy.\");\n } finally {\n await fs.rm(workspaceRoot, { recursive: true, force: true });\n }\n});\n"]}
@@ -1,12 +1,7 @@
1
- interface PageSection {
2
- sectionName: string;
3
- description: string;
4
- }
5
1
  interface Page {
6
2
  pageRoute: string;
7
3
  pageName: string;
8
4
  description: string;
9
- sections?: PageSection[];
10
5
  }
11
6
  export interface ProjectInfo {
12
7
  uiPages: Page[];
@@ -1 +1 @@
1
- {"version":3,"file":"projectInfo.types.d.ts","sourceRoot":"","sources":["../../src/types/projectInfo.types.ts"],"names":[],"mappings":"AAAA,UAAU,WAAW;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,IAAI;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,IAAI,EAAE,CAAC;IAChB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC"}
1
+ {"version":3,"file":"projectInfo.types.d.ts","sourceRoot":"","sources":["../../src/types/projectInfo.types.ts"],"names":[],"mappings":"AAAA,UAAU,IAAI;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,IAAI,EAAE,CAAC;IAChB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"projectInfo.types.js","sourceRoot":"","sources":["../../src/types/projectInfo.types.ts"],"names":[],"mappings":"","sourcesContent":["interface PageSection {\n sectionName: string;\n description: string;\n}\n\ninterface Page {\n pageRoute: string;\n pageName: string;\n description: string;\n sections?: PageSection[];\n}\n\nexport interface ProjectInfo {\n uiPages: Page[];\n lastUpdatedPlanVersion?: number;\n}\n"]}
1
+ {"version":3,"file":"projectInfo.types.js","sourceRoot":"","sources":["../../src/types/projectInfo.types.ts"],"names":[],"mappings":"","sourcesContent":["interface Page {\n pageRoute: string;\n pageName: string;\n description: string;\n}\n\nexport interface ProjectInfo {\n uiPages: Page[];\n lastUpdatedPlanVersion?: number;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vedangiitb/qwintly-core",
3
- "version": "1.6.3",
3
+ "version": "1.6.5",
4
4
  "description": "Qwintly Core",
5
5
  "homepage": "https://github.com/vedangiitb/qwintly-core#readme",
6
6
  "bugs": {
package/dist/ai/ai.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=ai.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/ai/ai.ts"],"names":[],"mappings":""}
package/dist/ai/ai.js DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=ai.js.map
package/dist/ai/ai.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/ai/ai.ts"],"names":[],"mappings":"","sourcesContent":[""]}