{ "version": "3.16", "name": "AddPage", "description": "Add a new page (section + app route) to an existing project. Reads current ProjectMeta, adds the new page definition, generates section/component files, and updates app routing.", "sectionMerge": true, "registry": { "params": [ "pageDescription(STRING)", "currentMeta(OBJECT)" ], "services": [], "apis": [], "components": [], "vars": [ "$updatedMeta(OBJECT)", "$updatedMetaStr(STRING)", "$newSection(OBJECT)", "$newComponents(OBJECT)", "$newService(OBJECT)", "$targetApp(STRING)", "$targetAppFilePath(STRING)", "$existingVdb(STRING)", "$existingVth(STRING)" ], "files": { "inputs": [ ".vl-code/ProjectMeta.json", "Database/*", "Theme/*" ], "artifacts": [ ".vl-code/ProjectMeta.json", "Sections/*", "ExtComponents/*", "Services/*", "Apps/*" ] }, "docs": { "1": "VL Syntax Rules", "102": "Agent-GenServiceDomain-Prompt", "103": "Agent-GenComponent-Prompt", "104": "Agent-GenSection-Prompt", "105": "Agent-GenApp-Prompt" } }, "steps": [ { "id": "LLM_010_PlanPage", "meta": { "title": "1. Plan new page structure" }, "in": { "docs": [ "1" ], "max_tokens": 12288, "messages": [ { "role": "user", "content": "Current ProjectMeta:" }, { "role": "user", "content": "=currentMeta" }, { "role": "user", "content": "New page request:" }, { "role": "user", "content": "=pageDescription" }, { "role": "user", "content": "Plan the new page. Determine: 1) What new section to create (name, bindings, events), 2) What new components needed (if any), 3) What new service methods needed (if any), 4) Which existing app to add the route to.\n\nReturn a FLAT JSON object (no nesting) with EXACTLY these top-level keys:\n- \"section\": OBJECT with {id, filePath, description, consumesServices, usesComponents, bindings, events}\n- \"components\": ARRAY of component objects (empty array [] if none needed)\n- \"service\": OBJECT or null (null if no new service methods needed)\n- \"targetApp\": STRING (app id to add route to)\n- \"targetAppFilePath\": STRING (exact .vx file path to update)\n- \"route\": STRING (route path)\n- \"updatedMeta\": OBJECT (the FULL updated ProjectMeta with the new section/route added)\n\nIMPORTANT: Use exactly these key names at the top level. Do NOT wrap in a 'plan' or 'result' object. The key for the updated meta MUST be 'updatedMeta', not 'updatedProjectMeta'." } ], "output_config": { "format": { "type": "json_object" } } }, "out": { "$updatedMeta": "=_result.updatedMeta", "$updatedMetaStr": "=_result.updatedMeta", "$newSection": "=_result.section", "$newComponents": "=_result.components", "$newService": "=_result.service", "$targetApp": "=_result.targetApp", "$targetAppFilePath": "=_result.targetAppFilePath", "/.vl-code/ProjectMeta.json": "=_result.updatedMeta" }, "next": "LLM_020_GenSection" }, { "id": "LLM_020_GenSection", "meta": { "title": "2. Generate new section file" }, "in": { "docs": [ "1", "104" ], "max_tokens": 16000, "stream": true, "messages": [ { "role": "user", "content": "ProjectMeta:" }, { "role": "user", "content": "=$updatedMetaStr" }, { "role": "user", "content": "Generate the .sc section file for this new section:" }, { "role": "user", "content": "=$newSection\n\nIMPORTANT: The file MUST start with '// VL_VERSION:3.7' as the first non-empty line." }, { "role": "user", "content": "Compile-safety rules: 1) style: values must be static string literals only; never use ternary, concat, variables, or any expression inside style:. If appearance depends on data, split the node with If blocks or use StateStyle conditions instead of style:($cond ? \"a\" : \"b\"). 2) NEVER bind events directly on nodes; bind the event on the interactive child inside the loop instead. 3) NEVER emit deprecated trigger:\"hover\" blocks. 4) Use only VL-valid props and output only valid .sc source." } ] }, "out": { "/{$newSection.filePath}": "=_result" }, "next": "Branch_NeedComponents" }, { "id": "Branch_NeedComponents", "meta": { "title": "3. Check if new components needed" }, "cases": [ { "condition": "=$newComponents.length > 0", "next": "Loop_GenComponents" } ], "default": "Branch_NeedService" }, { "id": "Loop_GenComponents", "meta": { "title": "3a. Generate new components" }, "source": "=$newComponents", "mode": "parallel", "children": [ "LLM_030_GenComponent" ], "next": "Branch_NeedService" }, { "id": "LLM_030_GenComponent", "meta": { "title": "Generate Component: =_item.name" }, "in": { "docs": [ "1", "103" ], "max_tokens": 8192, "stream": true, "messages": [ { "role": "user", "content": "ProjectMeta:" }, { "role": "user", "content": "=$updatedMetaStr" }, { "role": "user", "content": "Generate the .cp component file for:" }, { "role": "user", "content": "=_item\n\nIMPORTANT: The file MUST start with '// VL_VERSION:3.7' as the first non-empty line." } ] }, "out": { "/{_item.filePath}": "=_result" }, "onError": "skip" }, { "id": "Branch_NeedService", "meta": { "title": "4. Check if new service methods needed" }, "cases": [ { "condition": "=$newService !== null", "next": "LLM_040_GenService" } ], "default": "LLM_050_UpdateApp" }, { "id": "LLM_040_GenService", "meta": { "title": "4a. Generate/update service domain" }, "in": { "docs": [ "1", "102" ], "max_tokens": 12288, "stream": true, "messages": [ { "role": "user", "content": "ProjectMeta:" }, { "role": "user", "content": "=$updatedMetaStr" }, { "role": "user", "content": "Add or update the service domain with new methods for the page:" }, { "role": "user", "content": "=$newService\n\nIMPORTANT: The file MUST start with '// VL_VERSION:3.7' as the first non-empty line.\n\nBackend query-safety rules: build filter arrays incrementally. If an optional STRING/INT filter is empty, null, 0, or -1 (used as 'all'), DO NOT include that condition in select/count queries. Never generate conditions like [\"field\",\"*eq\",\"\"] or [\"field\",\"*contains\",\"\"] for optional filters. Prefer `_conditions([]) = []` plus IF checks and `_conditions.push(...)`." } ] }, "out": { "/{$newService.filePath}": "=_result" }, "next": "LLM_050_UpdateApp" }, { "id": "LLM_050_UpdateApp", "meta": { "title": "5. Update app routing" }, "in": { "docs": [ "1", "105" ], "max_tokens": 8192, "stream": true, "readFiles": [ "=$targetAppFilePath || ('Apps/' + $targetApp + '.vx')" ], "messages": [ { "role": "user", "content": "ProjectMeta:" }, { "role": "user", "content": "=$updatedMetaStr" }, { "role": "user", "content": "Target app:" }, { "role": "user", "content": "=$targetApp" }, { "role": "user", "content": "Target app file path:" }, { "role": "user", "content": "=$targetAppFilePath || ('Apps/' + $targetApp + '.vx')" }, { "role": "user", "content": "Update the app .vx file to include the new page route. Use sectionMerge semantics: preserve all existing routes, layout, and app-level state, and add only the new route and any required section references.\n\nIMPORTANT: Output the COMPLETE updated app file. The file MUST start with '// VL_VERSION:3.7' as the first non-empty line." } ] }, "out": { "/{$targetAppFilePath || ('Apps/' + $targetApp + '.vx')}": "=_result" }, "next": "Stop_Done" }, { "id": "Stop_Done", "meta": { "title": "Done — New page added" } } ] }