@vedangiitb/qwintly-core 1.2.1 → 1.3.1
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.
- package/dist/ai/prompts/codegen.prompt.d.ts +9 -0
- package/dist/ai/prompts/codegen.prompt.d.ts.map +1 -0
- package/dist/ai/prompts/codegen.prompt.js +53 -0
- package/dist/ai/prompts/codegen.prompt.js.map +1 -0
- package/dist/ai/prompts/examples/codegen.examples.d.ts +2 -0
- package/dist/ai/prompts/examples/codegen.examples.d.ts.map +1 -0
- package/dist/ai/prompts/examples/codegen.examples.js +81 -0
- package/dist/ai/prompts/examples/codegen.examples.js.map +1 -0
- package/dist/ai/prompts/examples/planner.examples.d.ts +2 -0
- package/dist/ai/prompts/examples/planner.examples.d.ts.map +1 -0
- package/dist/ai/prompts/examples/planner.examples.js +33 -0
- package/dist/ai/prompts/examples/planner.examples.js.map +1 -0
- package/dist/ai/prompts/helpers/promptParts.helper.d.ts +8 -0
- package/dist/ai/prompts/helpers/promptParts.helper.d.ts.map +1 -0
- package/dist/ai/prompts/helpers/promptParts.helper.js +37 -0
- package/dist/ai/prompts/helpers/promptParts.helper.js.map +1 -0
- package/dist/ai/prompts/planner.prompt.d.ts +10 -0
- package/dist/ai/prompts/planner.prompt.d.ts.map +1 -0
- package/dist/ai/prompts/planner.prompt.js +49 -0
- package/dist/ai/prompts/planner.prompt.js.map +1 -0
- package/dist/ai/prompts/prompts.d.ts +4 -0
- package/dist/ai/prompts/prompts.d.ts.map +1 -0
- package/dist/ai/prompts/prompts.js +4 -0
- package/dist/ai/prompts/prompts.js.map +1 -0
- package/dist/ai/prompts/validator.prompt.d.ts +15 -0
- package/dist/ai/prompts/validator.prompt.d.ts.map +1 -0
- package/dist/ai/prompts/validator.prompt.js +55 -0
- package/dist/ai/prompts/validator.prompt.js.map +1 -0
- package/dist/ai/tools/helpers/elementid.helpers.d.ts +4 -0
- package/dist/ai/tools/helpers/elementid.helpers.d.ts.map +1 -0
- package/dist/ai/tools/helpers/elementid.helpers.js +19 -0
- package/dist/ai/tools/helpers/elementid.helpers.js.map +1 -0
- package/dist/ai/tools/helpers/getImage.helper.d.ts +2 -0
- package/dist/ai/tools/helpers/getImage.helper.d.ts.map +1 -0
- package/dist/ai/tools/helpers/getImage.helper.js +2 -0
- package/dist/ai/tools/helpers/getImage.helper.js.map +1 -0
- package/dist/ai/tools/helpers/pageConfigJson.helpers.d.ts +15 -0
- package/dist/ai/tools/helpers/pageConfigJson.helpers.d.ts.map +1 -0
- package/dist/ai/tools/helpers/pageConfigJson.helpers.js +172 -0
- package/dist/ai/tools/helpers/pageConfigJson.helpers.js.map +1 -0
- package/dist/ai/tools/implementations/createNewRoute.impl.d.ts +5 -0
- package/dist/ai/tools/implementations/createNewRoute.impl.d.ts.map +1 -0
- package/dist/ai/tools/implementations/createNewRoute.impl.js +101 -0
- package/dist/ai/tools/implementations/createNewRoute.impl.js.map +1 -0
- package/dist/ai/tools/implementations/deleteElement.impl.d.ts +18 -0
- package/dist/ai/tools/implementations/deleteElement.impl.d.ts.map +1 -0
- package/dist/ai/tools/implementations/deleteElement.impl.js +60 -0
- package/dist/ai/tools/implementations/deleteElement.impl.js.map +1 -0
- package/dist/ai/tools/implementations/factories.d.ts +72 -0
- package/dist/ai/tools/implementations/factories.d.ts.map +1 -1
- package/dist/ai/tools/implementations/factories.js +20 -0
- package/dist/ai/tools/implementations/factories.js.map +1 -1
- package/dist/ai/tools/implementations/insertElement.impl.d.ts +14 -0
- package/dist/ai/tools/implementations/insertElement.impl.d.ts.map +1 -0
- package/dist/ai/tools/implementations/insertElement.impl.js +73 -0
- package/dist/ai/tools/implementations/insertElement.impl.js.map +1 -0
- package/dist/ai/tools/implementations/updateClassName.impl.d.ts +13 -0
- package/dist/ai/tools/implementations/updateClassName.impl.d.ts.map +1 -0
- package/dist/ai/tools/implementations/updateClassName.impl.js +61 -0
- package/dist/ai/tools/implementations/updateClassName.impl.js.map +1 -0
- package/dist/ai/tools/implementations/updateProps.impl.d.ts +33 -0
- package/dist/ai/tools/implementations/updateProps.impl.d.ts.map +1 -0
- package/dist/ai/tools/implementations/updateProps.impl.js +90 -0
- package/dist/ai/tools/implementations/updateProps.impl.js.map +1 -0
- package/dist/ai/tools/schemas/createNewRoute.schema.d.ts +20 -0
- package/dist/ai/tools/schemas/createNewRoute.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/createNewRoute.schema.js +20 -0
- package/dist/ai/tools/schemas/createNewRoute.schema.js.map +1 -0
- package/dist/ai/tools/schemas/deleteElement.schema.d.ts +20 -0
- package/dist/ai/tools/schemas/deleteElement.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/deleteElement.schema.js +20 -0
- package/dist/ai/tools/schemas/deleteElement.schema.js.map +1 -0
- package/dist/ai/tools/schemas/insertElement.schema.d.ts +23 -0
- package/dist/ai/tools/schemas/insertElement.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/insertElement.schema.js +133 -0
- package/dist/ai/tools/schemas/insertElement.schema.js.map +1 -0
- package/dist/ai/tools/schemas/updateClassName.schema.d.ts +23 -0
- package/dist/ai/tools/schemas/updateClassName.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/updateClassName.schema.js +21 -0
- package/dist/ai/tools/schemas/updateClassName.schema.js.map +1 -0
- package/dist/ai/tools/schemas/updateProps.schema.d.ts +91 -0
- package/dist/ai/tools/schemas/updateProps.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/updateProps.schema.js +87 -0
- package/dist/ai/tools/schemas/updateProps.schema.js.map +1 -0
- package/dist/ai/tools/toolsets/codegenTools.d.ts.map +1 -1
- package/dist/ai/tools/toolsets/codegenTools.js +12 -4
- package/dist/ai/tools/toolsets/codegenTools.js.map +1 -1
- package/dist/core.d.ts +4 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +7 -0
- package/dist/core.js.map +1 -1
- package/dist/image/unsplash.service.d.ts +22 -0
- package/dist/image/unsplash.service.d.ts.map +1 -0
- package/dist/image/unsplash.service.js +120 -0
- package/dist/image/unsplash.service.js.map +1 -0
- package/dist/indexer/codegenIndex.d.ts.map +1 -1
- package/dist/indexer/codegenIndex.js +2 -5
- package/dist/indexer/codegenIndex.js.map +1 -1
- package/dist/indexer/data/configs.constants.d.ts +32 -56
- package/dist/indexer/data/configs.constants.d.ts.map +1 -1
- package/dist/indexer/data/configs.constants.js +61 -88
- package/dist/indexer/data/configs.constants.js.map +1 -1
- package/dist/indexer/plannerIndex.d.ts.map +1 -1
- package/dist/indexer/plannerIndex.js +2 -7
- package/dist/indexer/plannerIndex.js.map +1 -1
- package/dist/indexer/validatorIndex.d.ts.map +1 -1
- package/dist/indexer/validatorIndex.js +1 -0
- package/dist/indexer/validatorIndex.js.map +1 -1
- package/dist/tests/createNewRoute.impl.test.d.ts +2 -0
- package/dist/tests/createNewRoute.impl.test.d.ts.map +1 -0
- package/dist/tests/createNewRoute.impl.test.js +72 -0
- package/dist/tests/createNewRoute.impl.test.js.map +1 -0
- package/dist/tests/deleteElement.impl.test.d.ts +2 -0
- package/dist/tests/deleteElement.impl.test.d.ts.map +1 -0
- package/dist/tests/deleteElement.impl.test.js +88 -0
- package/dist/tests/deleteElement.impl.test.js.map +1 -0
- package/dist/tests/insertUpdate.impl.test.d.ts +2 -0
- package/dist/tests/insertUpdate.impl.test.d.ts.map +1 -0
- package/dist/tests/insertUpdate.impl.test.js +68 -0
- package/dist/tests/insertUpdate.impl.test.js.map +1 -0
- package/dist/types/elements.d.ts +43 -0
- package/dist/types/elements.d.ts.map +1 -0
- package/dist/types/elements.js +13 -0
- package/dist/types/elements.js.map +1 -0
- package/dist/types/image.d.ts +19 -0
- package/dist/types/image.d.ts.map +1 -0
- package/dist/types/image.js +3 -0
- package/dist/types/image.js.map +1 -0
- package/dist/types/index/configs.types.d.ts +2 -3
- package/dist/types/index/configs.types.d.ts.map +1 -1
- package/dist/types/index/configs.types.js.map +1 -1
- package/dist/types/index/index.types.d.ts +4 -6
- package/dist/types/index/index.types.d.ts.map +1 -1
- package/dist/types/index/index.types.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createElementId } from "./elementid.helpers.js";
|
|
4
|
+
import { toWorkspacePath } from "./fileSystem.helpers.js";
|
|
5
|
+
export const normalizeRouteSegments = (route) => {
|
|
6
|
+
const raw = String(route ?? "").trim();
|
|
7
|
+
if (!raw || raw === "/")
|
|
8
|
+
return [];
|
|
9
|
+
return raw
|
|
10
|
+
.replace(/\\/g, "/")
|
|
11
|
+
.split("/")
|
|
12
|
+
.map((s) => s.trim())
|
|
13
|
+
.filter(Boolean);
|
|
14
|
+
};
|
|
15
|
+
export const isSafeSegment = (segment) => {
|
|
16
|
+
const s = String(segment ?? "").trim();
|
|
17
|
+
if (!s)
|
|
18
|
+
return false;
|
|
19
|
+
if (s === "." || s === "..")
|
|
20
|
+
return false;
|
|
21
|
+
if (s.includes("/") || s.includes("\\"))
|
|
22
|
+
return false;
|
|
23
|
+
return true;
|
|
24
|
+
};
|
|
25
|
+
export const getPageConfigJsonPath = (workspaceRoot, route) => {
|
|
26
|
+
const segments = normalizeRouteSegments(route);
|
|
27
|
+
if (segments.some((s) => !isSafeSegment(s))) {
|
|
28
|
+
throw new Error("invalid route");
|
|
29
|
+
}
|
|
30
|
+
const rel = path.posix.join("app", ...segments, "pageConfig.json");
|
|
31
|
+
return toWorkspacePath(workspaceRoot, rel);
|
|
32
|
+
};
|
|
33
|
+
export const parsePageConfigJson = (content) => {
|
|
34
|
+
let parsed;
|
|
35
|
+
try {
|
|
36
|
+
parsed = JSON.parse(String(content ?? ""));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
throw new Error("pageConfig.json is not valid JSON");
|
|
40
|
+
}
|
|
41
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
42
|
+
throw new Error("pageConfig.json must be an object");
|
|
43
|
+
}
|
|
44
|
+
const elements = parsed.elements;
|
|
45
|
+
if (!Array.isArray(elements)) {
|
|
46
|
+
throw new Error('pageConfig.json must contain "elements" array');
|
|
47
|
+
}
|
|
48
|
+
return { elements: elements };
|
|
49
|
+
};
|
|
50
|
+
export const stringifyPageConfigJson = (config) => JSON.stringify({ elements: config.elements ?? [] }, null, 2) + "\n";
|
|
51
|
+
export const extractAllIdsDeep = (elements) => {
|
|
52
|
+
const ids = new Set();
|
|
53
|
+
const walk = (arr) => {
|
|
54
|
+
for (const el of arr) {
|
|
55
|
+
if (!el || typeof el !== "object")
|
|
56
|
+
continue;
|
|
57
|
+
const id = el.id;
|
|
58
|
+
if (typeof id === "string" && id.trim())
|
|
59
|
+
ids.add(id.trim());
|
|
60
|
+
const children = el.children;
|
|
61
|
+
if (Array.isArray(children))
|
|
62
|
+
walk(children);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
walk(Array.isArray(elements) ? elements : []);
|
|
66
|
+
return ids;
|
|
67
|
+
};
|
|
68
|
+
export const ensureElementIds = (elements, existingIds) => {
|
|
69
|
+
const seen = new Set();
|
|
70
|
+
const walk = (arr) => {
|
|
71
|
+
for (const el of arr) {
|
|
72
|
+
if (!el || typeof el !== "object")
|
|
73
|
+
continue;
|
|
74
|
+
const anyEl = el;
|
|
75
|
+
const currentId = typeof anyEl.id === "string" ? anyEl.id.trim() : "";
|
|
76
|
+
if (!currentId || seen.has(currentId)) {
|
|
77
|
+
const newId = createElementId(existingIds);
|
|
78
|
+
anyEl.id = newId;
|
|
79
|
+
existingIds.add(newId);
|
|
80
|
+
seen.add(newId);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
anyEl.id = currentId;
|
|
84
|
+
existingIds.add(currentId);
|
|
85
|
+
seen.add(currentId);
|
|
86
|
+
}
|
|
87
|
+
if (Array.isArray(anyEl.children)) {
|
|
88
|
+
walk(anyEl.children);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
walk(elements);
|
|
93
|
+
};
|
|
94
|
+
export const findElementById = (elements, elementId) => {
|
|
95
|
+
const id = String(elementId ?? "").trim();
|
|
96
|
+
if (!id)
|
|
97
|
+
return null;
|
|
98
|
+
const walk = (arr) => {
|
|
99
|
+
for (const el of arr) {
|
|
100
|
+
if (!el || typeof el !== "object")
|
|
101
|
+
continue;
|
|
102
|
+
if (el.id === id)
|
|
103
|
+
return el;
|
|
104
|
+
const children = el.children;
|
|
105
|
+
if (Array.isArray(children)) {
|
|
106
|
+
const found = walk(children);
|
|
107
|
+
if (found)
|
|
108
|
+
return found;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
};
|
|
113
|
+
return walk(elements);
|
|
114
|
+
};
|
|
115
|
+
export const deleteElementById = (elements, id) => {
|
|
116
|
+
const target = String(id ?? "").trim();
|
|
117
|
+
if (!target)
|
|
118
|
+
return false;
|
|
119
|
+
let deleted = false;
|
|
120
|
+
const walk = (arr) => {
|
|
121
|
+
for (let idx = arr.length - 1; idx >= 0; idx--) {
|
|
122
|
+
const el = arr[idx];
|
|
123
|
+
if (el?.id === target) {
|
|
124
|
+
arr.splice(idx, 1);
|
|
125
|
+
deleted = true;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (Array.isArray(el?.children))
|
|
129
|
+
walk(el.children);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
walk(elements);
|
|
133
|
+
return deleted;
|
|
134
|
+
};
|
|
135
|
+
export const writeFileAtomic = async (filePath, content) => {
|
|
136
|
+
const dir = path.dirname(filePath);
|
|
137
|
+
const base = path.basename(filePath);
|
|
138
|
+
const tmp = path.join(dir, `.qwintly_tmp_${base}_${Date.now()}_${Math.random().toString(16).slice(2)}`);
|
|
139
|
+
const bak = path.join(dir, `.qwintly_bak_${base}_${Date.now()}_${Math.random().toString(16).slice(2)}`);
|
|
140
|
+
try {
|
|
141
|
+
await fs.mkdir(dir, { recursive: true });
|
|
142
|
+
await fs.writeFile(tmp, content ?? "", "utf-8");
|
|
143
|
+
// Windows rename doesn't overwrite; do a 2-step swap.
|
|
144
|
+
await fs.rename(filePath, bak);
|
|
145
|
+
await fs.rename(tmp, filePath);
|
|
146
|
+
await fs.rm(bak, { force: true });
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
// rollback best-effort
|
|
150
|
+
try {
|
|
151
|
+
await fs.rm(tmp, { force: true });
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// ignore
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
await fs.stat(bak);
|
|
158
|
+
try {
|
|
159
|
+
await fs.rm(filePath, { force: true });
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// ignore
|
|
163
|
+
}
|
|
164
|
+
await fs.rename(bak, filePath);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// ignore
|
|
168
|
+
}
|
|
169
|
+
throw err;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
//# sourceMappingURL=pageConfigJson.helpers.js.map
|
|
@@ -0,0 +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\";\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 await fs.rename(filePath, bak);\n await fs.rename(tmp, filePath);\n await fs.rm(bak, { force: true });\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"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type WorkspaceDeps } from "./workspaceDeps.js";
|
|
2
|
+
export declare const createCreateNewRouteImpl: (deps: WorkspaceDeps) => (parentRoute: string, routeName: string) => Promise<string>;
|
|
3
|
+
export declare const DEFAULT_PAGE_CONFIG_JSON: string;
|
|
4
|
+
export declare const PAGE_TSX_TEMPLATE_STRING: string;
|
|
5
|
+
//# sourceMappingURL=createNewRoute.impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createNewRoute.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/createNewRoute.impl.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAwCxD,eAAO,MAAM,wBAAwB,GAAI,MAAM,aAAa,MAG5C,aAAa,MAAM,EAAE,WAAW,MAAM,oBAmErD,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAAsB,CAAC;AAC5D,eAAO,MAAM,wBAAwB,QAAoB,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { extractAllIds } from "../helpers/elementid.helpers.js";
|
|
4
|
+
import { toWorkspacePath } from "../helpers/fileSystem.helpers.js";
|
|
5
|
+
import { isSafeSegment, normalizeRouteSegments, } from "../helpers/pageConfigJson.helpers.js";
|
|
6
|
+
const PAGE_TSX_TEMPLATE = [
|
|
7
|
+
'import { RenderElement } from "@/lib/renderer/RenderElement";',
|
|
8
|
+
'import pageConfig from "./pageConfig.json";',
|
|
9
|
+
'import type { BuilderElement } from "@/types/elements";',
|
|
10
|
+
"",
|
|
11
|
+
"export default function Page() {",
|
|
12
|
+
" const config = pageConfig as { elements: BuilderElement[] };",
|
|
13
|
+
" return config.elements.map((el) => <RenderElement key={el.id} el={el} />);",
|
|
14
|
+
"}",
|
|
15
|
+
"",
|
|
16
|
+
].join("\n");
|
|
17
|
+
const DEFAULT_PAGE_CONFIG = (() => {
|
|
18
|
+
const elements = [
|
|
19
|
+
{
|
|
20
|
+
id: "root",
|
|
21
|
+
type: "div",
|
|
22
|
+
className: "min-h-screen p-6",
|
|
23
|
+
children: [
|
|
24
|
+
{
|
|
25
|
+
id: "title",
|
|
26
|
+
type: "text",
|
|
27
|
+
className: "text-sm font-semibold tracking-wide text-slate-200",
|
|
28
|
+
props: { text: "Qwintly Starter" },
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
// Validate uniqueness (and keep deterministic IDs).
|
|
34
|
+
const ids = extractAllIds(elements);
|
|
35
|
+
if (ids.size !== 2 || !ids.has("root") || !ids.has("title")) {
|
|
36
|
+
throw new Error("DEFAULT_PAGE_CONFIG ids must be stable and unique");
|
|
37
|
+
}
|
|
38
|
+
return JSON.stringify({ elements }, null, 2) + "\n";
|
|
39
|
+
})();
|
|
40
|
+
export const createCreateNewRouteImpl = (deps) => {
|
|
41
|
+
const { workspaceRoot, fs: coreFs } = deps;
|
|
42
|
+
return async (parentRoute, routeName) => {
|
|
43
|
+
const parentSegments = normalizeRouteSegments(parentRoute);
|
|
44
|
+
const routeSegment = String(routeName ?? "").trim();
|
|
45
|
+
if (!isSafeSegment(routeSegment)) {
|
|
46
|
+
return "failed to create";
|
|
47
|
+
}
|
|
48
|
+
if (parentSegments.some((s) => !isSafeSegment(s))) {
|
|
49
|
+
return "failed to create";
|
|
50
|
+
}
|
|
51
|
+
const appDir = toWorkspacePath(workspaceRoot, "app");
|
|
52
|
+
const parentDir = path.join(appDir, ...parentSegments);
|
|
53
|
+
const finalDir = path.join(parentDir, routeSegment);
|
|
54
|
+
// Parent must exist (don't implicitly create arbitrary routes).
|
|
55
|
+
try {
|
|
56
|
+
const st = await coreFs.stat(parentDir);
|
|
57
|
+
if (!st.isDirectory())
|
|
58
|
+
return "failed to create";
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const code = err?.code;
|
|
62
|
+
if (code === "ENOENT")
|
|
63
|
+
return "failed to create";
|
|
64
|
+
return "failed to create";
|
|
65
|
+
}
|
|
66
|
+
// Route must not already exist.
|
|
67
|
+
try {
|
|
68
|
+
await coreFs.stat(finalDir);
|
|
69
|
+
return "failed to create";
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
const code = err?.code;
|
|
73
|
+
if (code && code !== "ENOENT")
|
|
74
|
+
return "failed to create";
|
|
75
|
+
}
|
|
76
|
+
const tmpDir = path.join(parentDir, `.qwintly_route_tmp_${routeSegment}_${Date.now()}_${Math.random().toString(16).slice(2)}`);
|
|
77
|
+
try {
|
|
78
|
+
await coreFs.mkdirp(tmpDir);
|
|
79
|
+
await coreFs.writeFile(path.join(tmpDir, "page.tsx"), PAGE_TSX_TEMPLATE);
|
|
80
|
+
await coreFs.writeFile(path.join(tmpDir, "pageConfig.json"), DEFAULT_PAGE_CONFIG);
|
|
81
|
+
// Commit: move temp dir into place (best-effort atomic within same parent).
|
|
82
|
+
await fs.rename(tmpDir, finalDir);
|
|
83
|
+
const routePath = "/" + [...parentSegments, routeSegment].filter(Boolean).join("/");
|
|
84
|
+
return (`created page.tsx successfully and content of pageConfig.json at route "${routePath}":\n` +
|
|
85
|
+
DEFAULT_PAGE_CONFIG);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Rollback any partially-created temp output.
|
|
89
|
+
try {
|
|
90
|
+
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// best-effort cleanup only
|
|
94
|
+
}
|
|
95
|
+
return "failed to create";
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
export const DEFAULT_PAGE_CONFIG_JSON = DEFAULT_PAGE_CONFIG;
|
|
100
|
+
export const PAGE_TSX_TEMPLATE_STRING = PAGE_TSX_TEMPLATE;
|
|
101
|
+
//# sourceMappingURL=createNewRoute.impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createNewRoute.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/createNewRoute.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { extractAllIds } from \"../helpers/elementid.helpers.js\";\nimport { toWorkspacePath } from \"../helpers/fileSystem.helpers.js\";\nimport {\n isSafeSegment,\n normalizeRouteSegments,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nconst PAGE_TSX_TEMPLATE = [\n 'import { RenderElement } from \"@/lib/renderer/RenderElement\";',\n 'import pageConfig from \"./pageConfig.json\";',\n 'import type { BuilderElement } from \"@/types/elements\";',\n \"\",\n \"export 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].join(\"\\n\");\n\nconst DEFAULT_PAGE_CONFIG = (() => {\n const elements: any[] = [\n {\n id: \"root\",\n type: \"div\",\n className: \"min-h-screen p-6\",\n children: [\n {\n id: \"title\",\n type: \"text\",\n className: \"text-sm font-semibold tracking-wide text-slate-200\",\n props: { text: \"Qwintly Starter\" },\n },\n ],\n },\n ];\n\n // Validate uniqueness (and keep deterministic IDs).\n const ids = extractAllIds(elements as any);\n if (ids.size !== 2 || !ids.has(\"root\") || !ids.has(\"title\")) {\n throw new Error(\"DEFAULT_PAGE_CONFIG ids must be stable and unique\");\n }\n\n return JSON.stringify({ elements }, null, 2) + \"\\n\";\n})();\n\nexport const createCreateNewRouteImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs: coreFs } = deps;\n\n return async (parentRoute: string, routeName: string) => {\n const parentSegments = normalizeRouteSegments(parentRoute);\n const routeSegment = String(routeName ?? \"\").trim();\n\n if (!isSafeSegment(routeSegment)) {\n return \"failed to create\";\n }\n if (parentSegments.some((s) => !isSafeSegment(s))) {\n return \"failed to create\";\n }\n\n const appDir = toWorkspacePath(workspaceRoot, \"app\");\n const parentDir = path.join(appDir, ...parentSegments);\n const finalDir = path.join(parentDir, routeSegment);\n\n // Parent must exist (don't implicitly create arbitrary routes).\n try {\n const st = await coreFs.stat(parentDir);\n if (!st.isDirectory()) return \"failed to create\";\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") return \"failed to create\";\n return \"failed to create\";\n }\n\n // Route must not already exist.\n try {\n await coreFs.stat(finalDir);\n return \"failed to create\";\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code && code !== \"ENOENT\") return \"failed to create\";\n }\n\n const tmpDir = path.join(\n parentDir,\n `.qwintly_route_tmp_${routeSegment}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n\n try {\n await coreFs.mkdirp(tmpDir);\n await coreFs.writeFile(path.join(tmpDir, \"page.tsx\"), PAGE_TSX_TEMPLATE);\n await coreFs.writeFile(\n path.join(tmpDir, \"pageConfig.json\"),\n DEFAULT_PAGE_CONFIG,\n );\n\n // Commit: move temp dir into place (best-effort atomic within same parent).\n await fs.rename(tmpDir, finalDir);\n\n const routePath =\n \"/\" + [...parentSegments, routeSegment].filter(Boolean).join(\"/\");\n\n return (\n `created page.tsx successfully and content of pageConfig.json at route \"${routePath}\":\\n` +\n DEFAULT_PAGE_CONFIG\n );\n } catch {\n // Rollback any partially-created temp output.\n try {\n await fs.rm(tmpDir, { recursive: true, force: true });\n } catch {\n // best-effort cleanup only\n }\n return \"failed to create\";\n }\n };\n};\n\nexport const DEFAULT_PAGE_CONFIG_JSON = DEFAULT_PAGE_CONFIG;\nexport const PAGE_TSX_TEMPLATE_STRING = PAGE_TSX_TEMPLATE;\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type WorkspaceDeps } from "./workspaceDeps.js";
|
|
2
|
+
export declare const createDeleteElementImpl: (deps: WorkspaceDeps) => (route: string, elementId: string) => Promise<{
|
|
3
|
+
success: boolean;
|
|
4
|
+
error: string;
|
|
5
|
+
changed?: undefined;
|
|
6
|
+
deleted_id?: undefined;
|
|
7
|
+
} | {
|
|
8
|
+
success: boolean;
|
|
9
|
+
changed: boolean;
|
|
10
|
+
error?: undefined;
|
|
11
|
+
deleted_id?: undefined;
|
|
12
|
+
} | {
|
|
13
|
+
success: boolean;
|
|
14
|
+
changed: boolean;
|
|
15
|
+
deleted_id: string;
|
|
16
|
+
error?: undefined;
|
|
17
|
+
}>;
|
|
18
|
+
//# sourceMappingURL=deleteElement.impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deleteElement.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/deleteElement.impl.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,eAAO,MAAM,uBAAuB,GAAI,MAAM,aAAa,MAG3C,OAAO,MAAM,EAAE,WAAW,MAAM;;;;;;;;;;;;;;;EAuD/C,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { deleteElementById, ensureElementIds, extractAllIdsDeep, getPageConfigJsonPath, parsePageConfigJson, stringifyPageConfigJson, writeFileAtomic, } from "../helpers/pageConfigJson.helpers.js";
|
|
2
|
+
export const createDeleteElementImpl = (deps) => {
|
|
3
|
+
const { workspaceRoot, fs } = deps;
|
|
4
|
+
return async (route, elementId) => {
|
|
5
|
+
const id = String(elementId ?? "").trim();
|
|
6
|
+
if (!id)
|
|
7
|
+
return { success: false, error: "invalid element_id" };
|
|
8
|
+
let configPath;
|
|
9
|
+
try {
|
|
10
|
+
configPath = getPageConfigJsonPath(workspaceRoot, route);
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
return {
|
|
14
|
+
success: false,
|
|
15
|
+
error: err instanceof Error ? err.message : String(err),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
let before = "";
|
|
19
|
+
try {
|
|
20
|
+
before = await fs.readFile(configPath);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
const code = err?.code;
|
|
24
|
+
if (code === "ENOENT")
|
|
25
|
+
return { success: false, error: "not found" };
|
|
26
|
+
return {
|
|
27
|
+
success: false,
|
|
28
|
+
error: err instanceof Error ? err.message : String(err),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
let parsed;
|
|
32
|
+
try {
|
|
33
|
+
parsed = parsePageConfigJson(before);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
error: err instanceof Error ? err.message : String(err),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const elements = parsed.elements ?? [];
|
|
42
|
+
const existingIds = extractAllIdsDeep(elements);
|
|
43
|
+
ensureElementIds(elements, existingIds);
|
|
44
|
+
const deleted = deleteElementById(elements, id);
|
|
45
|
+
if (!deleted)
|
|
46
|
+
return { success: true, changed: false };
|
|
47
|
+
const after = stringifyPageConfigJson({ elements });
|
|
48
|
+
try {
|
|
49
|
+
await writeFileAtomic(configPath, after);
|
|
50
|
+
return { success: true, changed: true, deleted_id: id };
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
return {
|
|
54
|
+
success: false,
|
|
55
|
+
error: err instanceof Error ? err.message : String(err),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=deleteElement.impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deleteElement.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/deleteElement.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n deleteElementById,\n ensureElementIds,\n extractAllIdsDeep,\n getPageConfigJsonPath,\n parsePageConfigJson,\n stringifyPageConfigJson,\n writeFileAtomic,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nexport const createDeleteElementImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (route: string, elementId: string) => {\n const id = String(elementId ?? \"\").trim();\n if (!id) return { success: false, error: \"invalid element_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 const deleted = deleteElementById(elements, id);\n if (!deleted) return { success: true, changed: false };\n\n const after = stringifyPageConfigJson({ elements });\n\n try {\n await writeFileAtomic(configPath, after);\n return { success: true, changed: true, deleted_id: id };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n };\n};\n"]}
|
|
@@ -2,9 +2,14 @@ import { type SearchDeps } from "./search.impl.js";
|
|
|
2
2
|
export { DEFAULT_NOT_FOUND_RESPONSE } from "./workspaceDeps.js";
|
|
3
3
|
export type { CoreDirent, CoreFs, WorkspaceDeps, } from "./workspaceDeps.js";
|
|
4
4
|
export { createApplyPatchImpl } from "./applyPatch.impl.js";
|
|
5
|
+
export { createCreateNewRouteImpl } from "./createNewRoute.impl.js";
|
|
6
|
+
export { createDeleteElementImpl } from "./deleteElement.impl.js";
|
|
7
|
+
export { createInsertElementImpl } from "./insertElement.impl.js";
|
|
5
8
|
export { createListDirImpl } from "./listDir.impl.js";
|
|
6
9
|
export { createReadFileImpl } from "./readFile.impl.js";
|
|
7
10
|
export { createSearchImpl, type SearchDeps, type SearchResult, } from "./search.impl.js";
|
|
11
|
+
export { createUpdateClassNameImpl } from "./updateClassName.impl.js";
|
|
12
|
+
export { createUpdatePropsImpl } from "./updateProps.impl.js";
|
|
8
13
|
export { createWriteFileImpl } from "./writeFile.impl.js";
|
|
9
14
|
export declare const createWorkspaceToolImpls: (deps: SearchDeps) => {
|
|
10
15
|
readFileImpl: (filePath: string, startLine?: number, endLine?: number) => Promise<string>;
|
|
@@ -86,5 +91,72 @@ export declare const createWorkspaceToolImpls: (deps: SearchDeps) => {
|
|
|
86
91
|
changed?: undefined;
|
|
87
92
|
warnings?: undefined;
|
|
88
93
|
}>;
|
|
94
|
+
createNewRouteImpl: (parentRoute: string, routeName: string) => Promise<string>;
|
|
95
|
+
deleteElementImpl: (route: string, elementId: string) => Promise<{
|
|
96
|
+
success: boolean;
|
|
97
|
+
error: string;
|
|
98
|
+
changed?: undefined;
|
|
99
|
+
deleted_id?: undefined;
|
|
100
|
+
} | {
|
|
101
|
+
success: boolean;
|
|
102
|
+
changed: boolean;
|
|
103
|
+
error?: undefined;
|
|
104
|
+
deleted_id?: undefined;
|
|
105
|
+
} | {
|
|
106
|
+
success: boolean;
|
|
107
|
+
changed: boolean;
|
|
108
|
+
deleted_id: string;
|
|
109
|
+
error?: undefined;
|
|
110
|
+
}>;
|
|
111
|
+
insertElementImpl: (route: string, parentId: string, element: import("../../../types/elements.js").BuilderElement) => Promise<{
|
|
112
|
+
success: boolean;
|
|
113
|
+
error: string;
|
|
114
|
+
changed?: undefined;
|
|
115
|
+
inserted_id?: undefined;
|
|
116
|
+
} | {
|
|
117
|
+
success: boolean;
|
|
118
|
+
changed: boolean;
|
|
119
|
+
inserted_id: any;
|
|
120
|
+
error?: undefined;
|
|
121
|
+
}>;
|
|
122
|
+
updatePropsImpl: (args: {
|
|
123
|
+
route: string;
|
|
124
|
+
element_id: string;
|
|
125
|
+
} & Partial<{
|
|
126
|
+
onClick: import("../../../types/elements.js").OnClickAction;
|
|
127
|
+
text: string;
|
|
128
|
+
href: string;
|
|
129
|
+
placeholder: string;
|
|
130
|
+
alt: string;
|
|
131
|
+
target: string;
|
|
132
|
+
rel: string;
|
|
133
|
+
value: string;
|
|
134
|
+
type: string;
|
|
135
|
+
name: string;
|
|
136
|
+
size: number;
|
|
137
|
+
color: string;
|
|
138
|
+
strokeWidth: number;
|
|
139
|
+
}>) => Promise<{
|
|
140
|
+
success: boolean;
|
|
141
|
+
error: string;
|
|
142
|
+
changed?: undefined;
|
|
143
|
+
updated_id?: undefined;
|
|
144
|
+
} | {
|
|
145
|
+
success: boolean;
|
|
146
|
+
changed: boolean;
|
|
147
|
+
updated_id: string;
|
|
148
|
+
error?: undefined;
|
|
149
|
+
}>;
|
|
150
|
+
updateClassNameImpl: (route: string, elementId: string, className: string) => Promise<{
|
|
151
|
+
success: boolean;
|
|
152
|
+
error: string;
|
|
153
|
+
changed?: undefined;
|
|
154
|
+
updated_id?: undefined;
|
|
155
|
+
} | {
|
|
156
|
+
success: boolean;
|
|
157
|
+
changed: boolean;
|
|
158
|
+
updated_id: string;
|
|
159
|
+
error?: undefined;
|
|
160
|
+
}>;
|
|
89
161
|
};
|
|
90
162
|
//# sourceMappingURL=factories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/factories.ts"],"names":[],"mappings":"
|
|
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,13 +1,23 @@
|
|
|
1
1
|
import { createApplyPatchImpl } from "./applyPatch.impl.js";
|
|
2
|
+
import { createCreateNewRouteImpl } from "./createNewRoute.impl.js";
|
|
3
|
+
import { createDeleteElementImpl } from "./deleteElement.impl.js";
|
|
4
|
+
import { createInsertElementImpl } from "./insertElement.impl.js";
|
|
2
5
|
import { createListDirImpl } from "./listDir.impl.js";
|
|
3
6
|
import { createReadFileImpl } from "./readFile.impl.js";
|
|
4
7
|
import { createSearchImpl } from "./search.impl.js";
|
|
8
|
+
import { createUpdateClassNameImpl } from "./updateClassName.impl.js";
|
|
9
|
+
import { createUpdatePropsImpl } from "./updateProps.impl.js";
|
|
5
10
|
import { createWriteFileImpl } from "./writeFile.impl.js";
|
|
6
11
|
export { DEFAULT_NOT_FOUND_RESPONSE } from "./workspaceDeps.js";
|
|
7
12
|
export { createApplyPatchImpl } from "./applyPatch.impl.js";
|
|
13
|
+
export { createCreateNewRouteImpl } from "./createNewRoute.impl.js";
|
|
14
|
+
export { createDeleteElementImpl } from "./deleteElement.impl.js";
|
|
15
|
+
export { createInsertElementImpl } from "./insertElement.impl.js";
|
|
8
16
|
export { createListDirImpl } from "./listDir.impl.js";
|
|
9
17
|
export { createReadFileImpl } from "./readFile.impl.js";
|
|
10
18
|
export { createSearchImpl, } from "./search.impl.js";
|
|
19
|
+
export { createUpdateClassNameImpl } from "./updateClassName.impl.js";
|
|
20
|
+
export { createUpdatePropsImpl } from "./updateProps.impl.js";
|
|
11
21
|
export { createWriteFileImpl } from "./writeFile.impl.js";
|
|
12
22
|
export const createWorkspaceToolImpls = (deps) => {
|
|
13
23
|
const readFileImpl = createReadFileImpl(deps);
|
|
@@ -15,12 +25,22 @@ export const createWorkspaceToolImpls = (deps) => {
|
|
|
15
25
|
const listDirImpl = createListDirImpl(deps);
|
|
16
26
|
const searchImpl = createSearchImpl(deps);
|
|
17
27
|
const applyPatchImpl = createApplyPatchImpl(deps);
|
|
28
|
+
const createNewRouteImpl = createCreateNewRouteImpl(deps);
|
|
29
|
+
const deleteElementImpl = createDeleteElementImpl(deps);
|
|
30
|
+
const insertElementImpl = createInsertElementImpl(deps);
|
|
31
|
+
const updatePropsImpl = createUpdatePropsImpl(deps);
|
|
32
|
+
const updateClassNameImpl = createUpdateClassNameImpl(deps);
|
|
18
33
|
return {
|
|
19
34
|
readFileImpl,
|
|
20
35
|
writeFileImpl,
|
|
21
36
|
listDirImpl,
|
|
22
37
|
searchImpl,
|
|
23
38
|
applyPatchImpl,
|
|
39
|
+
createNewRouteImpl,
|
|
40
|
+
deleteElementImpl,
|
|
41
|
+
insertElementImpl,
|
|
42
|
+
updatePropsImpl,
|
|
43
|
+
updateClassNameImpl,
|
|
24
44
|
};
|
|
25
45
|
};
|
|
26
46
|
//# sourceMappingURL=factories.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factories.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/factories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAmB,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAOhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,gBAAgB,GAGjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,IAAgB,EAAE,EAAE;IAC3D,MAAM,YAAY,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"factories.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/factories.ts"],"names":[],"mappings":"AAAA,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,EAAE,gBAAgB,EAAmB,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAOhE,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,GAGjB,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,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,IAAgB,EAAE,EAAE;IAC3D,MAAM,YAAY,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IAC1D,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACxD,MAAM,eAAe,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,mBAAmB,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAE5D,OAAO;QACL,YAAY;QACZ,aAAa;QACb,WAAW;QACX,UAAU;QACV,cAAc;QACd,kBAAkB;QAClB,iBAAiB;QACjB,iBAAiB;QACjB,eAAe;QACf,mBAAmB;KACpB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { createApplyPatchImpl } from \"./applyPatch.impl.js\";\nimport { createCreateNewRouteImpl } from \"./createNewRoute.impl.js\";\nimport { createDeleteElementImpl } from \"./deleteElement.impl.js\";\nimport { createInsertElementImpl } from \"./insertElement.impl.js\";\nimport { createListDirImpl } from \"./listDir.impl.js\";\nimport { createReadFileImpl } from \"./readFile.impl.js\";\nimport { createSearchImpl, type SearchDeps } from \"./search.impl.js\";\nimport { createUpdateClassNameImpl } from \"./updateClassName.impl.js\";\nimport { createUpdatePropsImpl } from \"./updateProps.impl.js\";\nimport { createWriteFileImpl } from \"./writeFile.impl.js\";\n\nexport { DEFAULT_NOT_FOUND_RESPONSE } from \"./workspaceDeps.js\";\nexport type {\n CoreDirent,\n CoreFs,\n WorkspaceDeps,\n} from \"./workspaceDeps.js\";\n\nexport { createApplyPatchImpl } from \"./applyPatch.impl.js\";\nexport { createCreateNewRouteImpl } from \"./createNewRoute.impl.js\";\nexport { createDeleteElementImpl } from \"./deleteElement.impl.js\";\nexport { createInsertElementImpl } from \"./insertElement.impl.js\";\nexport { createListDirImpl } from \"./listDir.impl.js\";\nexport { createReadFileImpl } from \"./readFile.impl.js\";\nexport {\n createSearchImpl,\n type SearchDeps,\n type SearchResult,\n} from \"./search.impl.js\";\nexport { createUpdateClassNameImpl } from \"./updateClassName.impl.js\";\nexport { createUpdatePropsImpl } from \"./updateProps.impl.js\";\nexport { createWriteFileImpl } from \"./writeFile.impl.js\";\n\nexport const createWorkspaceToolImpls = (deps: SearchDeps) => {\n const readFileImpl = createReadFileImpl(deps);\n const writeFileImpl = createWriteFileImpl(deps);\n const listDirImpl = createListDirImpl(deps);\n const searchImpl = createSearchImpl(deps);\n const applyPatchImpl = createApplyPatchImpl(deps);\n const createNewRouteImpl = createCreateNewRouteImpl(deps);\n const deleteElementImpl = createDeleteElementImpl(deps);\n const insertElementImpl = createInsertElementImpl(deps);\n const updatePropsImpl = createUpdatePropsImpl(deps);\n const updateClassNameImpl = createUpdateClassNameImpl(deps);\n\n return {\n readFileImpl,\n writeFileImpl,\n listDirImpl,\n searchImpl,\n applyPatchImpl,\n createNewRouteImpl,\n deleteElementImpl,\n insertElementImpl,\n updatePropsImpl,\n updateClassNameImpl,\n };\n};\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BuilderElement } from "../../../types/elements.js";
|
|
2
|
+
import { type WorkspaceDeps } from "./workspaceDeps.js";
|
|
3
|
+
export declare const createInsertElementImpl: (deps: WorkspaceDeps) => (route: string, parentId: string, element: BuilderElement) => Promise<{
|
|
4
|
+
success: boolean;
|
|
5
|
+
error: string;
|
|
6
|
+
changed?: undefined;
|
|
7
|
+
inserted_id?: undefined;
|
|
8
|
+
} | {
|
|
9
|
+
success: boolean;
|
|
10
|
+
changed: boolean;
|
|
11
|
+
inserted_id: any;
|
|
12
|
+
error?: undefined;
|
|
13
|
+
}>;
|
|
14
|
+
//# sourceMappingURL=insertElement.impl.d.ts.map
|
|
@@ -0,0 +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"}
|