@vedangiitb/qwintly-core 1.3.5 → 1.3.7

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.
@@ -111,6 +111,17 @@ export declare const createWorkspaceToolImpls: (deps: SearchDeps) => {
111
111
  insertElementImpl: (route: string, parentId: string, element: import("../../../types/elements.js").BuilderElement) => Promise<{
112
112
  success: boolean;
113
113
  error: string;
114
+ error_detail: import("zod").ZodFlattenedError<{
115
+ route: string;
116
+ parent_id: string;
117
+ element: any;
118
+ }, string>;
119
+ changed?: undefined;
120
+ inserted_id?: undefined;
121
+ } | {
122
+ success: boolean;
123
+ error: string;
124
+ error_detail?: undefined;
114
125
  changed?: undefined;
115
126
  inserted_id?: undefined;
116
127
  } | {
@@ -118,6 +129,7 @@ export declare const createWorkspaceToolImpls: (deps: SearchDeps) => {
118
129
  changed: boolean;
119
130
  inserted_id: any;
120
131
  error?: undefined;
132
+ error_detail?: undefined;
121
133
  }>;
122
134
  updatePropsImpl: (args: {
123
135
  route: string;
@@ -1 +1 @@
1
- {"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/factories.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EACV,UAAU,EACV,MAAM,EACN,aAAa,GACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,eAAO,MAAM,wBAAwB,GAAI,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwBxD,CAAC"}
1
+ {"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/factories.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EACV,UAAU,EACV,MAAM,EACN,aAAa,GACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,eAAO,MAAM,wBAAwB,GAAI,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwBxD,CAAC"}
@@ -3,6 +3,17 @@ import { type WorkspaceDeps } from "./workspaceDeps.js";
3
3
  export declare const createInsertElementImpl: (deps: WorkspaceDeps) => (route: string, parentId: string, element: BuilderElement) => Promise<{
4
4
  success: boolean;
5
5
  error: string;
6
+ error_detail: import("zod").ZodFlattenedError<{
7
+ route: string;
8
+ parent_id: string;
9
+ element: any;
10
+ }, string>;
11
+ changed?: undefined;
12
+ inserted_id?: undefined;
13
+ } | {
14
+ success: boolean;
15
+ error: string;
16
+ error_detail?: undefined;
6
17
  changed?: undefined;
7
18
  inserted_id?: undefined;
8
19
  } | {
@@ -10,5 +21,6 @@ export declare const createInsertElementImpl: (deps: WorkspaceDeps) => (route: s
10
21
  changed: boolean;
11
22
  inserted_id: any;
12
23
  error?: undefined;
24
+ error_detail?: undefined;
13
25
  }>;
14
26
  //# sourceMappingURL=insertElement.impl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"insertElement.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/insertElement.impl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAUjE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,eAAO,MAAM,uBAAuB,GAAI,MAAM,aAAa,MAG3C,OAAO,MAAM,EAAE,UAAU,MAAM,EAAE,SAAS,cAAc;;;;;;;;;;EAqEvE,CAAC"}
1
+ {"version":3,"file":"insertElement.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/insertElement.impl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAWjE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,eAAO,MAAM,uBAAuB,GAAI,MAAM,aAAa,MAG3C,OAAO,MAAM,EAAE,UAAU,MAAM,EAAE,SAAS,cAAc;;;;;;;;;;;;;;;;;;;;;;EAkFvE,CAAC"}
@@ -1,8 +1,21 @@
1
1
  import { resolveUnsplashImagesDeep } from "../../../image/unsplash.service.js";
2
+ import { InsertElementArgsZod } from "../validators/builderElement.zod.js";
2
3
  import { ensureElementIds, extractAllIdsDeep, findElementById, getPageConfigJsonPath, parsePageConfigJson, stringifyPageConfigJson, writeFileAtomic, } from "../helpers/pageConfigJson.helpers.js";
3
4
  export const createInsertElementImpl = (deps) => {
4
5
  const { workspaceRoot, fs } = deps;
5
6
  return async (route, parentId, element) => {
7
+ const parsedArgs = InsertElementArgsZod.safeParse({
8
+ route,
9
+ parent_id: parentId,
10
+ element,
11
+ });
12
+ if (!parsedArgs.success) {
13
+ return {
14
+ success: false,
15
+ error: "invalid args",
16
+ error_detail: parsedArgs.error.flatten(),
17
+ };
18
+ }
6
19
  const parent_id = String(parentId ?? "").trim();
7
20
  if (!parent_id)
8
21
  return { success: false, error: "invalid parent_id" };
@@ -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 extractAllIdsDeep,\n findElementById,\n getPageConfigJsonPath,\n parsePageConfigJson,\n stringifyPageConfigJson,\n writeFileAtomic,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nexport const createInsertElementImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (route: string, parentId: string, element: BuilderElement) => {\n const parent_id = String(parentId ?? \"\").trim();\n if (!parent_id) return { success: false, error: \"invalid parent_id\" };\n\n let configPath: string;\n try {\n configPath = getPageConfigJsonPath(workspaceRoot, route);\n } catch (err) {\n return {\n success: false,\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, error: \"not found\" };\n return {\n success: false,\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,\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 // Clone + inject ids for the inserted element subtree.\n const toInsert = JSON.parse(\n JSON.stringify(element ?? null),\n ) as BuilderElement;\n await resolveUnsplashImagesDeep(toInsert);\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 (!Array.isArray(anyParent.children)) anyParent.children = [];\n (anyParent.children as BuilderElement[]).push(toInsert);\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 as any).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 { InsertElementArgsZod } from \"../validators/builderElement.zod.js\";\nimport {\n ensureElementIds,\n extractAllIdsDeep,\n findElementById,\n getPageConfigJsonPath,\n parsePageConfigJson,\n stringifyPageConfigJson,\n writeFileAtomic,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nexport const createInsertElementImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (route: string, parentId: string, element: BuilderElement) => {\n const parsedArgs = InsertElementArgsZod.safeParse({\n route,\n parent_id: parentId,\n element,\n });\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(parentId ?? \"\").trim();\n if (!parent_id) return { success: false, error: \"invalid parent_id\" };\n\n let configPath: string;\n try {\n configPath = getPageConfigJsonPath(workspaceRoot, route);\n } catch (err) {\n return {\n success: false,\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, error: \"not found\" };\n return {\n success: false,\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,\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 // Clone + inject ids for the inserted element subtree.\n const toInsert = JSON.parse(\n JSON.stringify(element ?? null),\n ) as BuilderElement;\n await resolveUnsplashImagesDeep(toInsert);\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 (!Array.isArray(anyParent.children)) anyParent.children = [];\n (anyParent.children as BuilderElement[]).push(toInsert);\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 as any).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":"insertElement.schema.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/insertElement.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,eAAO,MAAM,aAAa,8FAUhB,CAAC;AAqFX,eAAO,MAAM,oBAAoB,EAAE,GA8BlC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;CAuB/B,CAAC"}
1
+ {"version":3,"file":"insertElement.schema.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/insertElement.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,eAAO,MAAM,aAAa,8FAUhB,CAAC;AA2HX,eAAO,MAAM,oBAAoB,EAAE,GAAkC,CAAC;AAEtE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;CAuB/B,CAAC"}
@@ -82,36 +82,41 @@ const BuilderElementPropsSchema = {
82
82
  },
83
83
  },
84
84
  };
85
- // Recursive via JSON Schema $ref (no cyclic JS object needed).
86
- // This lets the model emit arbitrarily deep nested `children` safely.
87
- export const BuilderElementSchema = {
88
- type: Type.OBJECT,
89
- properties: {
90
- type: {
91
- type: Type.STRING,
92
- enum: ELEMENT_TYPES,
93
- description: "Element type to render. 'text' renders a <p>, 'image' renders an <img>, 'link' renders an <a>, 'icon' renders a Lucide icon, 'fragment' renders children only.",
94
- },
95
- className: {
96
- type: Type.STRING,
97
- description: "Tailwind CSS className applied to the rendered element (Tailwind only).",
98
- },
99
- visible: {
100
- type: Type.BOOLEAN,
101
- description: "Whether the element should be shown.",
102
- },
103
- props: BuilderElementPropsSchema,
104
- children: {
105
- type: Type.ARRAY,
106
- description: "Nested children (each child is another element). Use children[].children[] for deeper nesting.",
107
- items: {
108
- // JSON Schema self-reference: the item is another BuilderElement
109
- $ref: "#",
85
+ // NOTE: Gemini tool `parameters` schemas reject `$ref`, so true recursion isn't available here.
86
+ // We unroll nesting to a reasonable max depth; for deeper trees, insert in multiple steps.
87
+ const buildBuilderElementSchema = (depth) => {
88
+ return {
89
+ type: Type.OBJECT,
90
+ properties: {
91
+ type: {
92
+ type: Type.STRING,
93
+ enum: ELEMENT_TYPES,
94
+ description: "Element type to render. 'text' renders a <p>, 'image' renders an <img>, 'link' renders an <a>, 'icon' renders a Lucide icon, 'fragment' renders children only.",
95
+ },
96
+ className: {
97
+ type: Type.STRING,
98
+ description: "Tailwind CSS className applied to the rendered element (Tailwind only).",
99
+ },
100
+ visible: {
101
+ type: Type.BOOLEAN,
102
+ description: "Whether the element should be shown.",
103
+ },
104
+ props: BuilderElementPropsSchema,
105
+ children: {
106
+ type: Type.ARRAY,
107
+ description: "Nested children. Each child is another element and can itself have children (children[].children[]...).",
108
+ items: depth > 0
109
+ ? buildBuilderElementSchema(depth - 1)
110
+ : {
111
+ type: Type.OBJECT,
112
+ description: "Max depth reached in tool schema. If you need deeper nesting, insert the parent first, then insert children using the returned inserted_id as parent_id.",
113
+ },
110
114
  },
111
115
  },
112
- },
113
- required: ["type"],
116
+ required: ["type"],
117
+ };
114
118
  };
119
+ export const BuilderElementSchema = buildBuilderElementSchema(6);
115
120
  export const InsertElementSchema = {
116
121
  name: "insert_element",
117
122
  description: "Inserts element code. Use element.children to create nested UI. Each child is another BuilderElement and can itself have children.",
@@ -1 +1 @@
1
- {"version":3,"file":"insertElement.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/insertElement.schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type } from \"@google/genai\";\n\nexport const ELEMENT_TYPES = [\n \"fragment\",\n \"div\",\n \"text\",\n \"image\",\n \"button\",\n \"input\",\n \"textarea\",\n \"link\",\n \"icon\",\n] as const;\n\nconst OnClickActionSchema = {\n type: Type.OBJECT,\n properties: {\n kind: {\n type: Type.STRING,\n enum: [\"route\", \"back\", \"reload\", \"external\"],\n description:\n \"What happens when the element is clicked. 'route' navigates within the app, 'external' opens a URL, 'back' goes back, 'reload' refreshes.\",\n },\n href: {\n type: Type.STRING,\n description:\n \"URL to navigate to (used for kind='route' and kind='external').\",\n },\n replace: {\n type: Type.BOOLEAN,\n description: \"For kind='route': replace history instead of pushing.\",\n },\n newTab: {\n type: Type.BOOLEAN,\n description: \"For kind='external': open link in a new tab.\",\n },\n },\n required: [\"kind\"],\n};\n\nconst BuilderElementPropsSchema = {\n type: Type.OBJECT,\n properties: {\n onClick: OnClickActionSchema,\n text: {\n type: Type.STRING,\n description:\n \"Text content used by 'text' (<p>), 'button' (label), and as a fallback for 'link' when it has no children.\",\n },\n href: {\n type: Type.STRING,\n description: \"For 'link': the href attribute (defaults to '#').\",\n },\n placeholder: {\n type: Type.STRING,\n description: \"For 'input' and 'textarea': placeholder shown when empty.\",\n },\n alt: {\n type: Type.STRING,\n description:\n \"For 'image': alt text for accessibility AND the query used to fetch a suitable Unsplash image (src is auto-resolved from alt).\",\n },\n target: {\n type: Type.STRING,\n description: \"For 'link': target attribute (e.g. '_blank').\",\n },\n rel: {\n type: Type.STRING,\n description: \"For 'link': rel attribute (e.g. 'noreferrer').\",\n },\n value: {\n type: Type.STRING,\n description:\n \"For 'input' and 'textarea': default value (maps to defaultValue).\",\n },\n type: {\n type: Type.STRING,\n description:\n \"For 'input': input type (e.g. 'text', 'email', 'password'). Defaults to 'text'.\",\n },\n\n // icon\n name: {\n type: Type.STRING,\n description: \"For 'icon': Lucide icon name (e.g. 'ArrowRight', 'Menu').\",\n },\n size: { type: Type.NUMBER, description: \"For 'icon': size in px.\" },\n color: { type: Type.STRING, description: \"For 'icon': stroke color.\" },\n strokeWidth: {\n type: Type.NUMBER,\n description: \"For 'icon': stroke width.\",\n },\n },\n};\n\n// Recursive via JSON Schema $ref (no cyclic JS object needed).\n// This lets the model emit arbitrarily deep nested `children` safely.\nexport const BuilderElementSchema: any = {\n type: Type.OBJECT,\n properties: {\n type: {\n type: Type.STRING,\n enum: ELEMENT_TYPES,\n description:\n \"Element type to render. 'text' renders a <p>, 'image' renders an <img>, 'link' renders an <a>, 'icon' renders a Lucide icon, 'fragment' renders children only.\",\n },\n className: {\n type: Type.STRING,\n description:\n \"Tailwind CSS className applied to the rendered element (Tailwind only).\",\n },\n visible: {\n type: Type.BOOLEAN,\n description: \"Whether the element should be shown.\",\n },\n props: BuilderElementPropsSchema,\n children: {\n type: Type.ARRAY,\n description:\n \"Nested children (each child is another element). Use children[].children[] for deeper nesting.\",\n items: {\n // JSON Schema self-reference: the item is another BuilderElement\n $ref: \"#\",\n },\n },\n },\n required: [\"type\"],\n};\n\nexport const InsertElementSchema = {\n name: \"insert_element\",\n description:\n \"Inserts element code. Use element.children to create nested UI. Each child is another BuilderElement and can itself have children.\",\n parameters: {\n type: Type.OBJECT,\n properties: {\n route: {\n type: Type.STRING,\n description:\n \"The route to insert the element at. Example. '/' or '/about' etc.\",\n },\n parent_id: {\n type: Type.STRING,\n description: \"The parent id to insert the element at.\",\n },\n element: {\n ...BuilderElementSchema,\n description: \"The element to insert.\",\n },\n },\n required: [\"route\", \"parent_id\", \"element\"],\n },\n};\n"]}
1
+ {"version":3,"file":"insertElement.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/insertElement.schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type } from \"@google/genai\";\r\n\r\nexport const ELEMENT_TYPES = [\r\n \"fragment\",\r\n \"div\",\r\n \"text\",\r\n \"image\",\r\n \"button\",\r\n \"input\",\r\n \"textarea\",\r\n \"link\",\r\n \"icon\",\r\n] as const;\r\n\r\nconst OnClickActionSchema = {\r\n type: Type.OBJECT,\r\n properties: {\r\n kind: {\r\n type: Type.STRING,\r\n enum: [\"route\", \"back\", \"reload\", \"external\"],\r\n description:\r\n \"What happens when the element is clicked. 'route' navigates within the app, 'external' opens a URL, 'back' goes back, 'reload' refreshes.\",\r\n },\r\n href: {\r\n type: Type.STRING,\r\n description:\r\n \"URL to navigate to (used for kind='route' and kind='external').\",\r\n },\r\n replace: {\r\n type: Type.BOOLEAN,\r\n description: \"For kind='route': replace history instead of pushing.\",\r\n },\r\n newTab: {\r\n type: Type.BOOLEAN,\r\n description: \"For kind='external': open link in a new tab.\",\r\n },\r\n },\r\n required: [\"kind\"],\r\n};\r\n\r\nconst BuilderElementPropsSchema = {\r\n type: Type.OBJECT,\r\n properties: {\r\n onClick: OnClickActionSchema,\r\n text: {\r\n type: Type.STRING,\r\n description:\r\n \"Text content used by 'text' (<p>), 'button' (label), and as a fallback for 'link' when it has no children.\",\r\n },\r\n href: {\r\n type: Type.STRING,\r\n description: \"For 'link': the href attribute (defaults to '#').\",\r\n },\r\n placeholder: {\r\n type: Type.STRING,\r\n description: \"For 'input' and 'textarea': placeholder shown when empty.\",\r\n },\r\n alt: {\r\n type: Type.STRING,\r\n description:\r\n \"For 'image': alt text for accessibility AND the query used to fetch a suitable Unsplash image (src is auto-resolved from alt).\",\r\n },\r\n target: {\r\n type: Type.STRING,\r\n description: \"For 'link': target attribute (e.g. '_blank').\",\r\n },\r\n rel: {\r\n type: Type.STRING,\r\n description: \"For 'link': rel attribute (e.g. 'noreferrer').\",\r\n },\r\n value: {\r\n type: Type.STRING,\r\n description:\r\n \"For 'input' and 'textarea': default value (maps to defaultValue).\",\r\n },\r\n type: {\r\n type: Type.STRING,\r\n description:\r\n \"For 'input': input type (e.g. 'text', 'email', 'password'). Defaults to 'text'.\",\r\n },\r\n\r\n // icon\r\n name: {\r\n type: Type.STRING,\r\n description: \"For 'icon': Lucide icon name (e.g. 'ArrowRight', 'Menu').\",\r\n },\r\n size: { type: Type.NUMBER, description: \"For 'icon': size in px.\" },\r\n color: { type: Type.STRING, description: \"For 'icon': stroke color.\" },\r\n strokeWidth: {\r\n type: Type.NUMBER,\r\n description: \"For 'icon': stroke width.\",\r\n },\r\n },\r\n};\r\n\r\n// NOTE: Gemini tool `parameters` schemas reject `$ref`, so true recursion isn't available here.\r\n// We unroll nesting to a reasonable max depth; for deeper trees, insert in multiple steps.\r\nconst buildBuilderElementSchema = (depth: number): any => {\r\n return {\r\n type: Type.OBJECT,\r\n properties: {\r\n type: {\r\n type: Type.STRING,\r\n enum: ELEMENT_TYPES,\r\n description:\r\n \"Element type to render. 'text' renders a <p>, 'image' renders an <img>, 'link' renders an <a>, 'icon' renders a Lucide icon, 'fragment' renders children only.\",\r\n },\r\n className: {\r\n type: Type.STRING,\r\n description:\r\n \"Tailwind CSS className applied to the rendered element (Tailwind only).\",\r\n },\r\n visible: {\r\n type: Type.BOOLEAN,\r\n description: \"Whether the element should be shown.\",\r\n },\r\n props: BuilderElementPropsSchema,\r\n children: {\r\n type: Type.ARRAY,\r\n description:\r\n \"Nested children. Each child is another element and can itself have children (children[].children[]...).\",\r\n items:\r\n depth > 0\r\n ? buildBuilderElementSchema(depth - 1)\r\n : {\r\n type: Type.OBJECT,\r\n description:\r\n \"Max depth reached in tool schema. If you need deeper nesting, insert the parent first, then insert children using the returned inserted_id as parent_id.\",\r\n },\r\n },\r\n },\r\n required: [\"type\"],\r\n };\r\n};\r\n\r\nexport const BuilderElementSchema: any = buildBuilderElementSchema(6);\r\n\r\nexport const InsertElementSchema = {\r\n name: \"insert_element\",\r\n description:\r\n \"Inserts element code. Use element.children to create nested UI. Each child is another BuilderElement and can itself have children.\",\r\n parameters: {\r\n type: Type.OBJECT,\r\n properties: {\r\n route: {\r\n type: Type.STRING,\r\n description:\r\n \"The route to insert the element at. Example. '/' or '/about' etc.\",\r\n },\r\n parent_id: {\r\n type: Type.STRING,\r\n description: \"The parent id to insert the element at.\",\r\n },\r\n element: {\r\n ...BuilderElementSchema,\r\n description: \"The element to insert.\",\r\n },\r\n },\r\n required: [\"route\", \"parent_id\", \"element\"],\r\n },\r\n};\r\n"]}
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+ export declare const ELEMENT_TYPES: readonly ["fragment", "div", "text", "image", "button", "input", "textarea", "link", "icon"];
3
+ export declare const OnClickActionZod: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
+ kind: z.ZodLiteral<"route">;
5
+ href: z.ZodString;
6
+ replace: z.ZodOptional<z.ZodBoolean>;
7
+ }, z.core.$strip>, z.ZodObject<{
8
+ kind: z.ZodLiteral<"back">;
9
+ }, z.core.$strip>, z.ZodObject<{
10
+ kind: z.ZodLiteral<"reload">;
11
+ }, z.core.$strip>, z.ZodObject<{
12
+ kind: z.ZodLiteral<"external">;
13
+ href: z.ZodString;
14
+ newTab: z.ZodOptional<z.ZodBoolean>;
15
+ }, z.core.$strip>], "kind">;
16
+ export declare const BuilderElementZod: z.ZodType<any>;
17
+ export declare const InsertElementArgsZod: z.ZodObject<{
18
+ route: z.ZodString;
19
+ parent_id: z.ZodString;
20
+ element: z.ZodType<any, unknown, z.core.$ZodTypeInternals<any, unknown>>;
21
+ }, z.core.$strip>;
22
+ //# sourceMappingURL=builderElement.zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builderElement.zod.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/validators/builderElement.zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,aAAa,8FAUhB,CAAC;AAEX,eAAO,MAAM,gBAAgB;;;;;;;;;;;;2BAa3B,CAAC;AAEH,eAAO,MAAM,iBAAiB,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAuB3C,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;iBAI/B,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { z } from "zod";
2
+ export const ELEMENT_TYPES = [
3
+ "fragment",
4
+ "div",
5
+ "text",
6
+ "image",
7
+ "button",
8
+ "input",
9
+ "textarea",
10
+ "link",
11
+ "icon",
12
+ ];
13
+ export const OnClickActionZod = z.discriminatedUnion("kind", [
14
+ z.object({
15
+ kind: z.literal("route"),
16
+ href: z.string().min(1),
17
+ replace: z.boolean().optional(),
18
+ }),
19
+ z.object({ kind: z.literal("back") }),
20
+ z.object({ kind: z.literal("reload") }),
21
+ z.object({
22
+ kind: z.literal("external"),
23
+ href: z.string().min(1),
24
+ newTab: z.boolean().optional(),
25
+ }),
26
+ ]);
27
+ export const BuilderElementZod = z.object({
28
+ type: z.enum(ELEMENT_TYPES),
29
+ className: z.string().optional(),
30
+ visible: z.boolean().optional(),
31
+ props: z
32
+ .object({
33
+ onClick: OnClickActionZod.optional(),
34
+ text: z.string().optional(),
35
+ href: z.string().optional(),
36
+ placeholder: z.string().optional(),
37
+ alt: z.string().optional(),
38
+ target: z.string().optional(),
39
+ rel: z.string().optional(),
40
+ value: z.string().optional(),
41
+ type: z.string().optional(),
42
+ name: z.string().optional(),
43
+ size: z.number().optional(),
44
+ color: z.string().optional(),
45
+ strokeWidth: z.number().optional(),
46
+ })
47
+ .passthrough()
48
+ .optional(),
49
+ children: z.array(z.lazy(() => BuilderElementZod)).optional(),
50
+ });
51
+ export const InsertElementArgsZod = z.object({
52
+ route: z.string().min(1),
53
+ parent_id: z.string().min(1),
54
+ element: BuilderElementZod,
55
+ });
56
+ //# sourceMappingURL=builderElement.zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builderElement.zod.js","sourceRoot":"","sources":["../../../../src/ai/tools/validators/builderElement.zod.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nexport const ELEMENT_TYPES = [\n \"fragment\",\n \"div\",\n \"text\",\n \"image\",\n \"button\",\n \"input\",\n \"textarea\",\n \"link\",\n \"icon\",\n] as const;\n\nexport const OnClickActionZod = z.discriminatedUnion(\"kind\", [\n z.object({\n kind: z.literal(\"route\"),\n href: z.string().min(1),\n replace: z.boolean().optional(),\n }),\n z.object({ kind: z.literal(\"back\") }),\n z.object({ kind: z.literal(\"reload\") }),\n z.object({\n kind: z.literal(\"external\"),\n href: z.string().min(1),\n newTab: z.boolean().optional(),\n }),\n]);\n\nexport const BuilderElementZod: z.ZodType<any> = z.object({\n type: z.enum(ELEMENT_TYPES),\n className: z.string().optional(),\n visible: z.boolean().optional(),\n props: z\n .object({\n onClick: OnClickActionZod.optional(),\n text: z.string().optional(),\n href: z.string().optional(),\n placeholder: z.string().optional(),\n alt: z.string().optional(),\n target: z.string().optional(),\n rel: z.string().optional(),\n value: z.string().optional(),\n type: z.string().optional(),\n name: z.string().optional(),\n size: z.number().optional(),\n color: z.string().optional(),\n strokeWidth: z.number().optional(),\n })\n .passthrough()\n .optional(),\n children: z.array(z.lazy(() => BuilderElementZod)).optional(),\n});\n\nexport const InsertElementArgsZod = z.object({\n route: z.string().min(1),\n parent_id: z.string().min(1),\n element: BuilderElementZod,\n});\n\n"]}
@@ -22,7 +22,12 @@ export declare const projectConfigs: {
22
22
  readonly renderingConfig: {
23
23
  readonly approach: "config-driven UI rendering";
24
24
  readonly routeConventions: {
25
- readonly model: "Every route is driven by a colocated JSON config file.";
25
+ readonly model: "Routes mean URL paths (e.g. /about, /pricing) in a Next.js App Router app. Each URL route is implemented by a route folder under /app (e.g. app/about) and is driven by a colocated JSON config file.";
26
+ readonly definition: "In this repo, \"route\" always refers to the user-facing browser URL pathname, not an arbitrary file path.";
27
+ readonly examples: {
28
+ readonly urlRoutes: readonly ["/", "/about", "/pricing"];
29
+ readonly appRouterFolders: readonly ["app/page.tsx", "app/about/page.tsx", "app/pricing/page.tsx"];
30
+ };
26
31
  readonly filesPerRoute: readonly ["page.tsx", "pageConfig.json"];
27
32
  readonly sourceOfTruth: "pageConfig.json (edit this; page.tsx is a fixed renderer)";
28
33
  readonly configShape: {
@@ -32,6 +37,7 @@ export declare const projectConfigs: {
32
37
  };
33
38
  readonly note: "The page renders config.elements (array of BuilderElement).";
34
39
  };
40
+ readonly locationNote: "These files live inside the route folder (App Router convention). Example: for /about -> app/about/page.tsx and app/about/pageConfig.json.";
35
41
  };
36
42
  readonly pageRenderer: {
37
43
  readonly fileName: "page.tsx";
@@ -46,8 +52,8 @@ export declare const projectConfigs: {
46
52
  };
47
53
  };
48
54
  readonly generatorGuidance: {
49
- readonly do: readonly ["UI changes can happen only by editing the route's pageConfig.json elements tree.", "Use Tailwind in className; prefer composition via nested children."];
50
- readonly dont: readonly ["Do not change page.tsx structure for routes (it is a fixed renderer).", "Do not generate React components for layout; encode structure in JSON elements."];
55
+ readonly do: readonly ["Treat a route as a URL path (e.g. /about). Its code lives in the corresponding Next.js App Router folder (e.g. app/about).", "UI changes can happen only by editing that route folder's pageConfig.json elements tree.", "@/lib/renderer/RenderElement , @/types/elements already exist. No need to create them.", "When creating a new URL route (e.g. /pricing), create the App Router folder (e.g. app/pricing) with page.tsx (fixed renderer) + pageConfig.json (initial elements). After that, codegen should only modify pageConfig.json.", "Use Tailwind in className; prefer composition via nested children."];
56
+ readonly dont: readonly ["Do not confuse URL routes with file paths; do not invent 'routes' that are just filenames.", "Do not change page.tsx structure for URL routes (it is a fixed renderer).", "Do not generate React components for layout; encode structure in JSON elements."];
51
57
  };
52
58
  };
53
59
  };
@@ -1 +1 @@
1
- {"version":3,"file":"configs.constants.d.ts","sourceRoot":"","sources":["../../../src/indexer/data/configs.constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkFc,CAAC;AAE1C,eAAO,MAAM,QAAQ;;;;;;CAyBc,CAAC"}
1
+ {"version":3,"file":"configs.constants.d.ts","sourceRoot":"","sources":["../../../src/indexer/data/configs.constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+Fc,CAAC;AAE1C,eAAO,MAAM,QAAQ;;;;;;CAyBc,CAAC"}
@@ -22,7 +22,12 @@ export const projectConfigs = {
22
22
  renderingConfig: {
23
23
  approach: "config-driven UI rendering",
24
24
  routeConventions: {
25
- model: "Every route is driven by a colocated JSON config file.",
25
+ model: "Routes mean URL paths (e.g. /about, /pricing) in a Next.js App Router app. Each URL route is implemented by a route folder under /app (e.g. app/about) and is driven by a colocated JSON config file.",
26
+ definition: 'In this repo, "route" always refers to the user-facing browser URL pathname, not an arbitrary file path.',
27
+ examples: {
28
+ urlRoutes: ["/", "/about", "/pricing"],
29
+ appRouterFolders: ["app/page.tsx", "app/about/page.tsx", "app/pricing/page.tsx"],
30
+ },
26
31
  filesPerRoute: ["page.tsx", "pageConfig.json"],
27
32
  sourceOfTruth: "pageConfig.json (edit this; page.tsx is a fixed renderer)",
28
33
  configShape: {
@@ -30,6 +35,7 @@ export const projectConfigs = {
30
35
  root: { elements: "BuilderElement[]" },
31
36
  note: "The page renders config.elements (array of BuilderElement).",
32
37
  },
38
+ locationNote: "These files live inside the route folder (App Router convention). Example: for /about -> app/about/page.tsx and app/about/pageConfig.json.",
33
39
  },
34
40
  pageRenderer: {
35
41
  fileName: "page.tsx",
@@ -70,11 +76,15 @@ export default function Page() {
70
76
  },
71
77
  generatorGuidance: {
72
78
  do: [
73
- "UI changes can happen only by editing the route's pageConfig.json elements tree.",
79
+ "Treat a route as a URL path (e.g. /about). Its code lives in the corresponding Next.js App Router folder (e.g. app/about).",
80
+ "UI changes can happen only by editing that route folder's pageConfig.json elements tree.",
81
+ "@/lib/renderer/RenderElement , @/types/elements already exist. No need to create them.",
82
+ "When creating a new URL route (e.g. /pricing), create the App Router folder (e.g. app/pricing) with page.tsx (fixed renderer) + pageConfig.json (initial elements). After that, codegen should only modify pageConfig.json.",
74
83
  "Use Tailwind in className; prefer composition via nested children.",
75
84
  ],
76
85
  dont: [
77
- "Do not change page.tsx structure for routes (it is a fixed renderer).",
86
+ "Do not confuse URL routes with file paths; do not invent 'routes' that are just filenames.",
87
+ "Do not change page.tsx structure for URL routes (it is a fixed renderer).",
78
88
  "Do not generate React components for layout; encode structure in JSON elements.",
79
89
  ],
80
90
  },
@@ -1 +1 @@
1
- {"version":3,"file":"configs.constants.js","sourceRoot":"","sources":["../../../src/indexer/data/configs.constants.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,eAAe,EAAE;QACf,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,YAAY;QACtB,KAAK,EAAE,oBAAoB;QAC3B,OAAO,EAAE,cAAc;KACxB;IACD,aAAa,EAAE;QACb,MAAM,EAAE,eAAe;QACvB,aAAa,EAAE,UAAU;QACzB,SAAS,EAAE,UAAU;QACrB,YAAY,EAAE,+BAA+B;KAC9C;IACD,aAAa,EAAE;QACb,cAAc,EAAE,KAAK;QACrB,OAAO,EAAE,QAAQ;QACjB,UAAU,EAAE,UAAU;QACtB,SAAS,EAAE,cAAc;QACzB,OAAO,EAAE,MAAM;KAChB;IACD,eAAe,EAAE;QACf,QAAQ,EAAE,4BAA4B;QACtC,gBAAgB,EAAE;YAChB,KAAK,EAAE,wDAAwD;YAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,iBAAiB,CAAC;YAC9C,aAAa,EACX,2DAA2D;YAC7D,WAAW,EAAE;gBACX,IAAI,EAAE,iBAAiB;gBACvB,IAAI,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE;gBACtC,IAAI,EAAE,6DAA6D;aACpE;SACF;QACD,YAAY,EAAE;YACZ,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE;gBACR,2CAA2C;gBAC3C,gDAAgD;gBAChD,2EAA2E;aAC5E;YACD,eAAe,EAAE;;;;;;;EAOrB;SACG;QACD,QAAQ,EAAE;YACR,QAAQ,EAAE,gBAAgB;YAC1B,cAAc,EAAE;gBACd,UAAU;gBACV,KAAK;gBACL,MAAM;gBACN,OAAO;gBACP,QAAQ;gBACR,OAAO;gBACP,UAAU;gBACV,MAAM;gBACN,MAAM;aACP;YACD,SAAS,EAAE;gBACT,KAAK,EAAE;oBACL,gEAAgE;oBAChE,uDAAuD;oBACvD,+CAA+C;iBAChD;aACF;SACF;QACD,iBAAiB,EAAE;YACjB,EAAE,EAAE;gBACF,kFAAkF;gBAClF,oEAAoE;aACrE;YACD,IAAI,EAAE;gBACJ,uEAAuE;gBACvE,iFAAiF;aAClF;SACF;KACF;CACsC,CAAC;AAE1C,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,iBAAiB,EAAE;QACjB,KAAK;QACL,MAAM;QACN,KAAK;QACL,MAAM;QACN,OAAO;QACP,KAAK;QACL,MAAM;QACN,MAAM;QACN,OAAO;QACP,OAAO;KACR;IACD,kBAAkB,EAAE;QAClB,cAAc;QACd,OAAO;QACP,MAAM;QACN,OAAO;QACP,KAAK;QACL,UAAU;QACV,MAAM;KACP;IACD,YAAY,EAAE,MAAO;IACrB,SAAS,EAAE,GAAG;IACd,YAAY,EAAE,GAAG;CACgB,CAAC","sourcesContent":["import { ProjectConfigsConfig } from \"../../types/index/configs.types.js\";\nimport { IndexingConfig } from \"../../types/index/indexing.types.js\";\n\nexport const projectConfigs = {\n frameworkConfig: {\n name: \"Next.js\",\n router: \"App Router\",\n language: \"TypeScript\",\n icons: \"lucide-react icons\",\n styling: \"Tailwind CSS\",\n },\n runtimeConfig: {\n target: \"frontend-only\",\n serverActions: \"disabled\",\n apiRoutes: \"disabled\",\n dataFetching: \"client-side (fetch or mocked)\",\n },\n toolingConfig: {\n packageManager: \"npm\",\n linting: \"eslint\",\n formatting: \"prettier\",\n typecheck: \"tsc --noEmit\",\n testing: \"none\",\n },\n renderingConfig: {\n approach: \"config-driven UI rendering\",\n routeConventions: {\n model: \"Every route is driven by a colocated JSON config file.\",\n filesPerRoute: [\"page.tsx\", \"pageConfig.json\"],\n sourceOfTruth:\n \"pageConfig.json (edit this; page.tsx is a fixed renderer)\",\n configShape: {\n file: \"pageConfig.json\",\n root: { elements: \"BuilderElement[]\" },\n note: \"The page renders config.elements (array of BuilderElement).\",\n },\n },\n pageRenderer: {\n fileName: \"page.tsx\",\n behavior: [\n \"Imports pageConfig from ./pageConfig.json\",\n \"Casts config to { elements: BuilderElement[] }\",\n \"Renders: config.elements.map(el => <RenderElement key={el.id} el={el} />)\",\n ],\n canonicalSource: `import { RenderElement } from \"@/lib/renderer/RenderElement\";\nimport pageConfig from \"./pageConfig.json\";\nimport type { BuilderElement } from \"@/types/elements\";\n\nexport default function Page() {\n const config = pageConfig as { elements: BuilderElement[] };\n return config.elements.map((el) => <RenderElement key={el.id} el={el} />);\n}`,\n },\n elements: {\n typeName: \"BuilderElement\",\n supportedTypes: [\n \"fragment\",\n \"div\",\n \"text\",\n \"image\",\n \"button\",\n \"input\",\n \"textarea\",\n \"link\",\n \"icon\",\n ],\n rendering: {\n notes: [\n \"Unknown element types are warned and rendered as an error box.\",\n \"Elements support Tailwind-only styling via className.\",\n \"Elements may have children: BuilderElement[].\",\n ],\n },\n },\n generatorGuidance: {\n do: [\n \"UI changes can happen only by editing the route's pageConfig.json elements tree.\",\n \"Use Tailwind in className; prefer composition via nested children.\",\n ],\n dont: [\n \"Do not change page.tsx structure for routes (it is a fixed renderer).\",\n \"Do not generate React components for layout; encode structure in JSON elements.\",\n ],\n },\n },\n} as const satisfies ProjectConfigsConfig;\n\nexport const indexing = {\n includeExtensions: [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".json\",\n \".md\",\n \".mdx\",\n \".css\",\n \".scss\",\n \".sass\",\n ],\n excludeDirectories: [\n \"node_modules\",\n \".next\",\n \"dist\",\n \"build\",\n \"out\",\n \"coverage\",\n \".git\",\n ],\n maxFileBytes: 200_000,\n chunkSize: 900,\n chunkOverlap: 150,\n} as const satisfies IndexingConfig;\n"]}
1
+ {"version":3,"file":"configs.constants.js","sourceRoot":"","sources":["../../../src/indexer/data/configs.constants.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,eAAe,EAAE;QACf,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,YAAY;QACtB,KAAK,EAAE,oBAAoB;QAC3B,OAAO,EAAE,cAAc;KACxB;IACD,aAAa,EAAE;QACb,MAAM,EAAE,eAAe;QACvB,aAAa,EAAE,UAAU;QACzB,SAAS,EAAE,UAAU;QACrB,YAAY,EAAE,+BAA+B;KAC9C;IACD,aAAa,EAAE;QACb,cAAc,EAAE,KAAK;QACrB,OAAO,EAAE,QAAQ;QACjB,UAAU,EAAE,UAAU;QACtB,SAAS,EAAE,cAAc;QACzB,OAAO,EAAE,MAAM;KAChB;IACD,eAAe,EAAE;QACf,QAAQ,EAAE,4BAA4B;QACtC,gBAAgB,EAAE;YAChB,KAAK,EACH,uMAAuM;YACzM,UAAU,EACR,0GAA0G;YAC5G,QAAQ,EAAE;gBACR,SAAS,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,CAAC;gBACtC,gBAAgB,EAAE,CAAC,cAAc,EAAE,oBAAoB,EAAE,sBAAsB,CAAC;aACjF;YACD,aAAa,EAAE,CAAC,UAAU,EAAE,iBAAiB,CAAC;YAC9C,aAAa,EACX,2DAA2D;YAC7D,WAAW,EAAE;gBACX,IAAI,EAAE,iBAAiB;gBACvB,IAAI,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE;gBACtC,IAAI,EAAE,6DAA6D;aACpE;YACD,YAAY,EACV,4IAA4I;SAC/I;QACD,YAAY,EAAE;YACZ,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE;gBACR,2CAA2C;gBAC3C,gDAAgD;gBAChD,2EAA2E;aAC5E;YACD,eAAe,EAAE;;;;;;;EAOrB;SACG;QACD,QAAQ,EAAE;YACR,QAAQ,EAAE,gBAAgB;YAC1B,cAAc,EAAE;gBACd,UAAU;gBACV,KAAK;gBACL,MAAM;gBACN,OAAO;gBACP,QAAQ;gBACR,OAAO;gBACP,UAAU;gBACV,MAAM;gBACN,MAAM;aACP;YACD,SAAS,EAAE;gBACT,KAAK,EAAE;oBACL,gEAAgE;oBAChE,uDAAuD;oBACvD,+CAA+C;iBAChD;aACF;SACF;QACD,iBAAiB,EAAE;YACjB,EAAE,EAAE;gBACF,4HAA4H;gBAC5H,0FAA0F;gBAC1F,wFAAwF;gBACxF,6NAA6N;gBAC7N,oEAAoE;aACrE;YACD,IAAI,EAAE;gBACJ,4FAA4F;gBAC5F,2EAA2E;gBAC3E,iFAAiF;aAClF;SACF;KACF;CACsC,CAAC;AAE1C,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,iBAAiB,EAAE;QACjB,KAAK;QACL,MAAM;QACN,KAAK;QACL,MAAM;QACN,OAAO;QACP,KAAK;QACL,MAAM;QACN,MAAM;QACN,OAAO;QACP,OAAO;KACR;IACD,kBAAkB,EAAE;QAClB,cAAc;QACd,OAAO;QACP,MAAM;QACN,OAAO;QACP,KAAK;QACL,UAAU;QACV,MAAM;KACP;IACD,YAAY,EAAE,MAAO;IACrB,SAAS,EAAE,GAAG;IACd,YAAY,EAAE,GAAG;CACgB,CAAC","sourcesContent":["import { ProjectConfigsConfig } from \"../../types/index/configs.types.js\";\nimport { IndexingConfig } from \"../../types/index/indexing.types.js\";\n\nexport const projectConfigs = {\n frameworkConfig: {\n name: \"Next.js\",\n router: \"App Router\",\n language: \"TypeScript\",\n icons: \"lucide-react icons\",\n styling: \"Tailwind CSS\",\n },\n runtimeConfig: {\n target: \"frontend-only\",\n serverActions: \"disabled\",\n apiRoutes: \"disabled\",\n dataFetching: \"client-side (fetch or mocked)\",\n },\n toolingConfig: {\n packageManager: \"npm\",\n linting: \"eslint\",\n formatting: \"prettier\",\n typecheck: \"tsc --noEmit\",\n testing: \"none\",\n },\n renderingConfig: {\n approach: \"config-driven UI rendering\",\n routeConventions: {\n model:\n \"Routes mean URL paths (e.g. /about, /pricing) in a Next.js App Router app. Each URL route is implemented by a route folder under /app (e.g. app/about) and is driven by a colocated JSON config file.\",\n definition:\n 'In this repo, \"route\" always refers to the user-facing browser URL pathname, not an arbitrary file path.',\n examples: {\n urlRoutes: [\"/\", \"/about\", \"/pricing\"],\n appRouterFolders: [\"app/page.tsx\", \"app/about/page.tsx\", \"app/pricing/page.tsx\"],\n },\n filesPerRoute: [\"page.tsx\", \"pageConfig.json\"],\n sourceOfTruth:\n \"pageConfig.json (edit this; page.tsx is a fixed renderer)\",\n configShape: {\n file: \"pageConfig.json\",\n root: { elements: \"BuilderElement[]\" },\n note: \"The page renders config.elements (array of BuilderElement).\",\n },\n locationNote:\n \"These files live inside the route folder (App Router convention). Example: for /about -> app/about/page.tsx and app/about/pageConfig.json.\",\n },\n pageRenderer: {\n fileName: \"page.tsx\",\n behavior: [\n \"Imports pageConfig from ./pageConfig.json\",\n \"Casts config to { elements: BuilderElement[] }\",\n \"Renders: config.elements.map(el => <RenderElement key={el.id} el={el} />)\",\n ],\n canonicalSource: `import { RenderElement } from \"@/lib/renderer/RenderElement\";\nimport pageConfig from \"./pageConfig.json\";\nimport type { BuilderElement } from \"@/types/elements\";\n\nexport default function Page() {\n const config = pageConfig as { elements: BuilderElement[] };\n return config.elements.map((el) => <RenderElement key={el.id} el={el} />);\n}`,\n },\n elements: {\n typeName: \"BuilderElement\",\n supportedTypes: [\n \"fragment\",\n \"div\",\n \"text\",\n \"image\",\n \"button\",\n \"input\",\n \"textarea\",\n \"link\",\n \"icon\",\n ],\n rendering: {\n notes: [\n \"Unknown element types are warned and rendered as an error box.\",\n \"Elements support Tailwind-only styling via className.\",\n \"Elements may have children: BuilderElement[].\",\n ],\n },\n },\n generatorGuidance: {\n do: [\n \"Treat a route as a URL path (e.g. /about). Its code lives in the corresponding Next.js App Router folder (e.g. app/about).\",\n \"UI changes can happen only by editing that route folder's pageConfig.json elements tree.\",\n \"@/lib/renderer/RenderElement , @/types/elements already exist. No need to create them.\",\n \"When creating a new URL route (e.g. /pricing), create the App Router folder (e.g. app/pricing) with page.tsx (fixed renderer) + pageConfig.json (initial elements). After that, codegen should only modify pageConfig.json.\",\n \"Use Tailwind in className; prefer composition via nested children.\",\n ],\n dont: [\n \"Do not confuse URL routes with file paths; do not invent 'routes' that are just filenames.\",\n \"Do not change page.tsx structure for URL routes (it is a fixed renderer).\",\n \"Do not generate React components for layout; encode structure in JSON elements.\",\n ],\n },\n },\n} as const satisfies ProjectConfigsConfig;\n\nexport const indexing = {\n includeExtensions: [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".json\",\n \".md\",\n \".mdx\",\n \".css\",\n \".scss\",\n \".sass\",\n ],\n excludeDirectories: [\n \"node_modules\",\n \".next\",\n \"dist\",\n \"build\",\n \"out\",\n \"coverage\",\n \".git\",\n ],\n maxFileBytes: 200_000,\n chunkSize: 900,\n chunkOverlap: 150,\n} as const satisfies IndexingConfig;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vedangiitb/qwintly-core",
3
- "version": "1.3.5",
3
+ "version": "1.3.7",
4
4
  "description": "Qwintly Core",
5
5
  "homepage": "https://github.com/vedangiitb/qwintly-core#readme",
6
6
  "bugs": {