@vedangiitb/qwintly-core 1.0.2
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/README.md +8 -0
- package/dist/ai/ai.d.ts +2 -0
- package/dist/ai/ai.d.ts.map +1 -0
- package/dist/ai/ai.js +2 -0
- package/dist/ai/ai.js.map +1 -0
- package/dist/ai/generate/gemini.client.d.ts +15 -0
- package/dist/ai/generate/gemini.client.d.ts.map +1 -0
- package/dist/ai/generate/gemini.client.js +39 -0
- package/dist/ai/generate/gemini.client.js.map +1 -0
- package/dist/ai/generate/generateClient.d.ts +3 -0
- package/dist/ai/generate/generateClient.d.ts.map +1 -0
- package/dist/ai/generate/generateClient.js +8 -0
- package/dist/ai/generate/generateClient.js.map +1 -0
- package/dist/ai/toolLoop/toolLoopContext.d.ts +33 -0
- package/dist/ai/toolLoop/toolLoopContext.d.ts.map +1 -0
- package/dist/ai/toolLoop/toolLoopContext.js +112 -0
- package/dist/ai/toolLoop/toolLoopContext.js.map +1 -0
- package/dist/ai/toolLoop/toolLoopRunner.d.ts +43 -0
- package/dist/ai/toolLoop/toolLoopRunner.d.ts.map +1 -0
- package/dist/ai/toolLoop/toolLoopRunner.js +227 -0
- package/dist/ai/toolLoop/toolLoopRunner.js.map +1 -0
- package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts +51 -0
- package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts.map +1 -0
- package/dist/ai/toolLoop/toolLoopRunnerUtils.js +164 -0
- package/dist/ai/toolLoop/toolLoopRunnerUtils.js.map +1 -0
- package/dist/ai/tools/helpers/applyPatch.helpers.d.ts +36 -0
- package/dist/ai/tools/helpers/applyPatch.helpers.d.ts.map +1 -0
- package/dist/ai/tools/helpers/applyPatch.helpers.js +307 -0
- package/dist/ai/tools/helpers/applyPatch.helpers.js.map +1 -0
- package/dist/ai/tools/helpers/applyPatch.helpers.test.d.ts +2 -0
- package/dist/ai/tools/helpers/applyPatch.helpers.test.d.ts.map +1 -0
- package/dist/ai/tools/helpers/applyPatch.helpers.test.js +50 -0
- package/dist/ai/tools/helpers/applyPatch.helpers.test.js.map +1 -0
- package/dist/ai/tools/helpers/fileSystem.helpers.d.ts +2 -0
- package/dist/ai/tools/helpers/fileSystem.helpers.d.ts.map +1 -0
- package/dist/ai/tools/helpers/fileSystem.helpers.js +45 -0
- package/dist/ai/tools/helpers/fileSystem.helpers.js.map +1 -0
- package/dist/ai/tools/helpers/fileSystem.helpers.test.d.ts +2 -0
- package/dist/ai/tools/helpers/fileSystem.helpers.test.d.ts.map +1 -0
- package/dist/ai/tools/helpers/fileSystem.helpers.test.js +15 -0
- package/dist/ai/tools/helpers/fileSystem.helpers.test.js.map +1 -0
- package/dist/ai/tools/helpers/format.helpers.d.ts +2 -0
- package/dist/ai/tools/helpers/format.helpers.d.ts.map +1 -0
- package/dist/ai/tools/helpers/format.helpers.js +14 -0
- package/dist/ai/tools/helpers/format.helpers.js.map +1 -0
- package/dist/ai/tools/helpers/nextRouteFilePolicy.d.ts +8 -0
- package/dist/ai/tools/helpers/nextRouteFilePolicy.d.ts.map +1 -0
- package/dist/ai/tools/helpers/nextRouteFilePolicy.js +26 -0
- package/dist/ai/tools/helpers/nextRouteFilePolicy.js.map +1 -0
- package/dist/ai/tools/implementations/applyPatch.impl.d.ts +53 -0
- package/dist/ai/tools/implementations/applyPatch.impl.d.ts.map +1 -0
- package/dist/ai/tools/implementations/applyPatch.impl.js +242 -0
- package/dist/ai/tools/implementations/applyPatch.impl.js.map +1 -0
- package/dist/ai/tools/implementations/applyPatch.impl.test.d.ts +2 -0
- package/dist/ai/tools/implementations/applyPatch.impl.test.d.ts.map +1 -0
- package/dist/ai/tools/implementations/applyPatch.impl.test.js +72 -0
- package/dist/ai/tools/implementations/applyPatch.impl.test.js.map +1 -0
- package/dist/ai/tools/implementations/factories.d.ts +90 -0
- package/dist/ai/tools/implementations/factories.d.ts.map +1 -0
- package/dist/ai/tools/implementations/factories.js +26 -0
- package/dist/ai/tools/implementations/factories.js.map +1 -0
- package/dist/ai/tools/implementations/listDir.impl.d.ts +3 -0
- package/dist/ai/tools/implementations/listDir.impl.d.ts.map +1 -0
- package/dist/ai/tools/implementations/listDir.impl.js +47 -0
- package/dist/ai/tools/implementations/listDir.impl.js.map +1 -0
- package/dist/ai/tools/implementations/readFile.impl.d.ts +3 -0
- package/dist/ai/tools/implementations/readFile.impl.d.ts.map +1 -0
- package/dist/ai/tools/implementations/readFile.impl.js +23 -0
- package/dist/ai/tools/implementations/readFile.impl.js.map +1 -0
- package/dist/ai/tools/implementations/search.impl.d.ts +18 -0
- package/dist/ai/tools/implementations/search.impl.d.ts.map +1 -0
- package/dist/ai/tools/implementations/search.impl.js +74 -0
- package/dist/ai/tools/implementations/search.impl.js.map +1 -0
- package/dist/ai/tools/implementations/workspaceDeps.d.ts +22 -0
- package/dist/ai/tools/implementations/workspaceDeps.d.ts.map +1 -0
- package/dist/ai/tools/implementations/workspaceDeps.js +2 -0
- package/dist/ai/tools/implementations/workspaceDeps.js.map +1 -0
- package/dist/ai/tools/implementations/writeFile.impl.d.ts +27 -0
- package/dist/ai/tools/implementations/writeFile.impl.d.ts.map +1 -0
- package/dist/ai/tools/implementations/writeFile.impl.js +62 -0
- package/dist/ai/tools/implementations/writeFile.impl.js.map +1 -0
- package/dist/ai/tools/schemas/applyPatch.schema.d.ts +16 -0
- package/dist/ai/tools/schemas/applyPatch.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/applyPatch.schema.js +17 -0
- package/dist/ai/tools/schemas/applyPatch.schema.js.map +1 -0
- package/dist/ai/tools/schemas/listDir.schema.d.ts +22 -0
- package/dist/ai/tools/schemas/listDir.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/listDir.schema.js +22 -0
- package/dist/ai/tools/schemas/listDir.schema.js.map +1 -0
- package/dist/ai/tools/schemas/readFile.schema.d.ts +26 -0
- package/dist/ai/tools/schemas/readFile.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/readFile.schema.js +26 -0
- package/dist/ai/tools/schemas/readFile.schema.js.map +1 -0
- package/dist/ai/tools/schemas/search.schema.d.ts +16 -0
- package/dist/ai/tools/schemas/search.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/search.schema.js +16 -0
- package/dist/ai/tools/schemas/search.schema.js.map +1 -0
- package/dist/ai/tools/schemas/submitCodegenDone.schema.d.ts +16 -0
- package/dist/ai/tools/schemas/submitCodegenDone.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/submitCodegenDone.schema.js +16 -0
- package/dist/ai/tools/schemas/submitCodegenDone.schema.js.map +1 -0
- package/dist/ai/tools/schemas/submitPlannerTasks.schema.d.ts +33 -0
- package/dist/ai/tools/schemas/submitPlannerTasks.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/submitPlannerTasks.schema.js +31 -0
- package/dist/ai/tools/schemas/submitPlannerTasks.schema.js.map +1 -0
- package/dist/ai/tools/schemas/writeFile.schema.d.ts +20 -0
- package/dist/ai/tools/schemas/writeFile.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/writeFile.schema.js +23 -0
- package/dist/ai/tools/schemas/writeFile.schema.js.map +1 -0
- package/dist/ai/tools/toolsets/codegenTools.d.ts +3 -0
- package/dist/ai/tools/toolsets/codegenTools.d.ts.map +1 -0
- package/dist/ai/tools/toolsets/codegenTools.js +17 -0
- package/dist/ai/tools/toolsets/codegenTools.js.map +1 -0
- package/dist/ai/tools/toolsets/plannerTools.d.ts +3 -0
- package/dist/ai/tools/toolsets/plannerTools.d.ts.map +1 -0
- package/dist/ai/tools/toolsets/plannerTools.js +17 -0
- package/dist/ai/tools/toolsets/plannerTools.js.map +1 -0
- package/dist/core.d.ts +44 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +80 -0
- package/dist/core.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/codegenIndex.d.ts +3 -0
- package/dist/indexer/codegenIndex.d.ts.map +1 -0
- package/dist/indexer/codegenIndex.js +17 -0
- package/dist/indexer/codegenIndex.js.map +1 -0
- package/dist/indexer/data/configs.constants.d.ts +85 -0
- package/dist/indexer/data/configs.constants.d.ts.map +1 -0
- package/dist/indexer/data/configs.constants.js +136 -0
- package/dist/indexer/data/configs.constants.js.map +1 -0
- package/dist/indexer/helpers/buildFolderTree.d.ts +2 -0
- package/dist/indexer/helpers/buildFolderTree.d.ts.map +1 -0
- package/dist/indexer/helpers/buildFolderTree.js +40 -0
- package/dist/indexer/helpers/buildFolderTree.js.map +1 -0
- package/dist/indexer/plannerIndex.d.ts +3 -0
- package/dist/indexer/plannerIndex.d.ts.map +1 -0
- package/dist/indexer/plannerIndex.js +20 -0
- package/dist/indexer/plannerIndex.js.map +1 -0
- package/dist/indexer/projectInfoIndex.d.ts +3 -0
- package/dist/indexer/projectInfoIndex.d.ts.map +1 -0
- package/dist/indexer/projectInfoIndex.js +257 -0
- package/dist/indexer/projectInfoIndex.js.map +1 -0
- package/dist/indexer/validatorIndex.d.ts +3 -0
- package/dist/indexer/validatorIndex.d.ts.map +1 -0
- package/dist/indexer/validatorIndex.js +14 -0
- package/dist/indexer/validatorIndex.js.map +1 -0
- package/dist/lib/redis.d.ts +3 -0
- package/dist/lib/redis.d.ts.map +1 -0
- package/dist/lib/redis.js +7 -0
- package/dist/lib/redis.js.map +1 -0
- package/dist/lib/supabase.d.ts +2 -0
- package/dist/lib/supabase.d.ts.map +1 -0
- package/dist/lib/supabase.js +4 -0
- package/dist/lib/supabase.js.map +1 -0
- package/dist/logging/genStatus.service.d.ts +14 -0
- package/dist/logging/genStatus.service.d.ts.map +1 -0
- package/dist/logging/genStatus.service.js +36 -0
- package/dist/logging/genStatus.service.js.map +1 -0
- package/dist/logging/logging.utils.d.ts +12 -0
- package/dist/logging/logging.utils.d.ts.map +1 -0
- package/dist/logging/logging.utils.js +15 -0
- package/dist/logging/logging.utils.js.map +1 -0
- package/dist/logging/redis.service.d.ts +11 -0
- package/dist/logging/redis.service.d.ts.map +1 -0
- package/dist/logging/redis.service.js +26 -0
- package/dist/logging/redis.service.js.map +1 -0
- package/dist/repository/context.repository.d.ts +8 -0
- package/dist/repository/context.repository.d.ts.map +1 -0
- package/dist/repository/context.repository.js +59 -0
- package/dist/repository/context.repository.js.map +1 -0
- package/dist/repository/genStatus.repository.d.ts +13 -0
- package/dist/repository/genStatus.repository.d.ts.map +1 -0
- package/dist/repository/genStatus.repository.js +18 -0
- package/dist/repository/genStatus.repository.js.map +1 -0
- package/dist/repository/planTasks.repository.d.ts +9 -0
- package/dist/repository/planTasks.repository.d.ts.map +1 -0
- package/dist/repository/planTasks.repository.js +24 -0
- package/dist/repository/planTasks.repository.js.map +1 -0
- package/dist/repository/repository.d.ts +5 -0
- package/dist/repository/repository.d.ts.map +1 -0
- package/dist/repository/repository.js +7 -0
- package/dist/repository/repository.js.map +1 -0
- package/dist/types/context.types.d.ts +64 -0
- package/dist/types/context.types.d.ts.map +1 -0
- package/dist/types/context.types.js +55 -0
- package/dist/types/context.types.js.map +1 -0
- package/dist/types/events.d.ts +16 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +14 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index/configs.types.d.ts +28 -0
- package/dist/types/index/configs.types.d.ts.map +1 -0
- package/dist/types/index/configs.types.js +2 -0
- package/dist/types/index/configs.types.js.map +1 -0
- package/dist/types/index/conventions.types.d.ts +40 -0
- package/dist/types/index/conventions.types.d.ts.map +1 -0
- package/dist/types/index/conventions.types.js +2 -0
- package/dist/types/index/conventions.types.js.map +1 -0
- package/dist/types/index/index.types.d.ts +16 -0
- package/dist/types/index/index.types.d.ts.map +1 -0
- package/dist/types/index/index.types.js +2 -0
- package/dist/types/index/index.types.js.map +1 -0
- package/dist/types/index/indexing.types.d.ts +9 -0
- package/dist/types/index/indexing.types.d.ts.map +1 -0
- package/dist/types/index/indexing.types.js +2 -0
- package/dist/types/index/indexing.types.js.map +1 -0
- package/dist/types/projectInfo.types.d.ts +16 -0
- package/dist/types/projectInfo.types.d.ts.map +1 -0
- package/dist/types/projectInfo.types.js +2 -0
- package/dist/types/projectInfo.types.js.map +1 -0
- package/dist/types/updatePlan.types.d.ts +34 -0
- package/dist/types/updatePlan.types.d.ts.map +1 -0
- package/dist/types/updatePlan.types.js +18 -0
- package/dist/types/updatePlan.types.js.map +1 -0
- package/dist/utils/utils.d.ts +2 -0
- package/dist/utils/utils.d.ts.map +1 -0
- package/dist/utils/utils.js +6 -0
- package/dist/utils/utils.js.map +1 -0
- package/dist/utils/workspace.d.ts +13 -0
- package/dist/utils/workspace.d.ts.map +1 -0
- package/dist/utils/workspace.js +92 -0
- package/dist/utils/workspace.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyPatch.helpers.test.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/applyPatch.helpers.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { parseApplyPatch } from "./applyPatch.helpers.js";
|
|
4
|
+
test("parseApplyPatch: tolerates leading indentation (dedent)", () => {
|
|
5
|
+
const patch = `
|
|
6
|
+
*** Begin Patch
|
|
7
|
+
*** Update File: a.txt
|
|
8
|
+
@@
|
|
9
|
+
-hello
|
|
10
|
+
+hi
|
|
11
|
+
*** End Patch
|
|
12
|
+
`;
|
|
13
|
+
const ops = parseApplyPatch(patch);
|
|
14
|
+
assert.equal(ops.length, 1);
|
|
15
|
+
assert.equal(ops[0]?.kind, "update");
|
|
16
|
+
assert.equal(ops[0]?.filePath, "a.txt");
|
|
17
|
+
});
|
|
18
|
+
test("parseApplyPatch: strips surrounding markdown code fences", () => {
|
|
19
|
+
const patch = `
|
|
20
|
+
\`\`\`diff
|
|
21
|
+
*** Begin Patch
|
|
22
|
+
*** Update File: a.txt
|
|
23
|
+
@@
|
|
24
|
+
-hello
|
|
25
|
+
+hi
|
|
26
|
+
*** End Patch
|
|
27
|
+
\`\`\`
|
|
28
|
+
`;
|
|
29
|
+
const ops = parseApplyPatch(patch);
|
|
30
|
+
assert.equal(ops.length, 1);
|
|
31
|
+
assert.equal(ops[0]?.kind, "update");
|
|
32
|
+
assert.equal(ops[0]?.filePath, "a.txt");
|
|
33
|
+
});
|
|
34
|
+
test('parseApplyPatch: supports "*** Move to:" after Update File', () => {
|
|
35
|
+
const patch = `
|
|
36
|
+
*** Begin Patch
|
|
37
|
+
*** Update File: a.txt
|
|
38
|
+
*** Move to: b.txt
|
|
39
|
+
@@
|
|
40
|
+
-hello
|
|
41
|
+
+hi
|
|
42
|
+
*** End Patch
|
|
43
|
+
`;
|
|
44
|
+
const ops = parseApplyPatch(patch);
|
|
45
|
+
assert.equal(ops.length, 1);
|
|
46
|
+
assert.equal(ops[0]?.kind, "update");
|
|
47
|
+
assert.equal(ops[0]?.filePath, "a.txt");
|
|
48
|
+
assert.equal(ops[0].moveTo, "b.txt");
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=applyPatch.helpers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyPatch.helpers.test.js","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/applyPatch.helpers.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,IAAI,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACnE,MAAM,KAAK,GAAG;;;;;;;GAOb,CAAC;IAEF,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0DAA0D,EAAE,GAAG,EAAE;IACpE,MAAM,KAAK,GAAG;;;;;;;;;CASf,CAAC;IAEA,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4DAA4D,EAAE,GAAG,EAAE;IACtE,MAAM,KAAK,GAAG;;;;;;;;CAQf,CAAC;IAEA,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,CAAE,GAAG,CAAC,CAAC,CAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC","sourcesContent":["import assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport { parseApplyPatch } from \"./applyPatch.helpers.js\";\n\ntest(\"parseApplyPatch: tolerates leading indentation (dedent)\", () => {\n const patch = `\n *** Begin Patch\n *** Update File: a.txt\n @@\n -hello\n +hi\n *** End Patch\n `;\n\n const ops = parseApplyPatch(patch);\n assert.equal(ops.length, 1);\n assert.equal(ops[0]?.kind, \"update\");\n assert.equal(ops[0]?.filePath, \"a.txt\");\n});\n\ntest(\"parseApplyPatch: strips surrounding markdown code fences\", () => {\n const patch = `\n\\`\\`\\`diff\n*** Begin Patch\n*** Update File: a.txt\n@@\n-hello\n+hi\n*** End Patch\n\\`\\`\\`\n`;\n\n const ops = parseApplyPatch(patch);\n assert.equal(ops.length, 1);\n assert.equal(ops[0]?.kind, \"update\");\n assert.equal(ops[0]?.filePath, \"a.txt\");\n});\n\ntest('parseApplyPatch: supports \"*** Move to:\" after Update File', () => {\n const patch = `\n*** Begin Patch\n*** Update File: a.txt\n*** Move to: b.txt\n@@\n-hello\n+hi\n*** End Patch\n`;\n\n const ops = parseApplyPatch(patch);\n assert.equal(ops.length, 1);\n assert.equal(ops[0]?.kind, \"update\");\n assert.equal(ops[0]?.filePath, \"a.txt\");\n assert.equal((ops[0] as any).moveTo, \"b.txt\");\n});\n\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileSystem.helpers.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/fileSystem.helpers.ts"],"names":[],"mappings":"AA6CA,eAAO,MAAM,eAAe,GAAI,eAAe,MAAM,EAAE,WAAW,MAAM,WAoBvE,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
const normalizeForPrefixCheck = (value) => value.replace(/\\/g, "/").replace(/\/+$/g, "");
|
|
3
|
+
const stripKnownWorkspacePrefix = (inputPath, workspaceRoot) => {
|
|
4
|
+
const inputNormalized = normalizeForPrefixCheck(inputPath);
|
|
5
|
+
const workspaceNormalized = normalizeForPrefixCheck(workspaceRoot);
|
|
6
|
+
const caseInsensitive = process.platform === "win32";
|
|
7
|
+
const inputCmp = caseInsensitive ? inputNormalized.toLowerCase() : inputNormalized;
|
|
8
|
+
const workspaceCmp = caseInsensitive
|
|
9
|
+
? workspaceNormalized.toLowerCase()
|
|
10
|
+
: workspaceNormalized;
|
|
11
|
+
if (inputCmp === workspaceCmp ||
|
|
12
|
+
inputCmp.startsWith(`${workspaceCmp}/`)) {
|
|
13
|
+
return inputNormalized.slice(workspaceNormalized.length);
|
|
14
|
+
}
|
|
15
|
+
const hardcodedWorkspace = "/tmp/workspace";
|
|
16
|
+
if (inputCmp === (caseInsensitive ? hardcodedWorkspace.toLowerCase() : hardcodedWorkspace) ||
|
|
17
|
+
inputCmp.startsWith(`${caseInsensitive ? hardcodedWorkspace.toLowerCase() : hardcodedWorkspace}/`)) {
|
|
18
|
+
return inputNormalized.slice(hardcodedWorkspace.length);
|
|
19
|
+
}
|
|
20
|
+
const hardcodedWorkspaceNoSlash = "tmp/workspace";
|
|
21
|
+
if (inputCmp ===
|
|
22
|
+
(caseInsensitive
|
|
23
|
+
? hardcodedWorkspaceNoSlash.toLowerCase()
|
|
24
|
+
: hardcodedWorkspaceNoSlash) ||
|
|
25
|
+
inputCmp.startsWith(`${caseInsensitive ? hardcodedWorkspaceNoSlash.toLowerCase() : hardcodedWorkspaceNoSlash}/`)) {
|
|
26
|
+
return inputNormalized.slice(hardcodedWorkspaceNoSlash.length);
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
};
|
|
30
|
+
export const toWorkspacePath = (workspaceRoot, inputPath) => {
|
|
31
|
+
const stripped = stripKnownWorkspacePrefix(inputPath, workspaceRoot);
|
|
32
|
+
const isAbsoluteInput = path.isAbsolute(inputPath);
|
|
33
|
+
if (stripped === null && isAbsoluteInput) {
|
|
34
|
+
throw new Error(`Path "${inputPath}" is absolute but not within workspace "${workspaceRoot}".`);
|
|
35
|
+
}
|
|
36
|
+
const relativePath = (stripped ?? inputPath).replace(/^[\/\\]+/, "");
|
|
37
|
+
const resolvedRoot = path.resolve(workspaceRoot);
|
|
38
|
+
const resolved = path.resolve(resolvedRoot, relativePath);
|
|
39
|
+
const rel = path.relative(resolvedRoot, resolved);
|
|
40
|
+
if (rel.startsWith("..") || path.isAbsolute(rel)) {
|
|
41
|
+
throw new Error(`Path "${inputPath}" resolves outside the workspace root.`);
|
|
42
|
+
}
|
|
43
|
+
return resolved;
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=fileSystem.helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileSystem.helpers.js","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/fileSystem.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\n\nconst normalizeForPrefixCheck = (value: string) =>\n value.replace(/\\\\/g, \"/\").replace(/\\/+$/g, \"\");\n\nconst stripKnownWorkspacePrefix = (inputPath: string, workspaceRoot: string) => {\n const inputNormalized = normalizeForPrefixCheck(inputPath);\n const workspaceNormalized = normalizeForPrefixCheck(workspaceRoot);\n const caseInsensitive = process.platform === \"win32\";\n const inputCmp = caseInsensitive ? inputNormalized.toLowerCase() : inputNormalized;\n const workspaceCmp = caseInsensitive\n ? workspaceNormalized.toLowerCase()\n : workspaceNormalized;\n\n if (\n inputCmp === workspaceCmp ||\n inputCmp.startsWith(`${workspaceCmp}/`)\n ) {\n return inputNormalized.slice(workspaceNormalized.length);\n }\n\n const hardcodedWorkspace = \"/tmp/workspace\";\n if (\n inputCmp === (caseInsensitive ? hardcodedWorkspace.toLowerCase() : hardcodedWorkspace) ||\n inputCmp.startsWith(`${caseInsensitive ? hardcodedWorkspace.toLowerCase() : hardcodedWorkspace}/`)\n ) {\n return inputNormalized.slice(hardcodedWorkspace.length);\n }\n\n const hardcodedWorkspaceNoSlash = \"tmp/workspace\";\n if (\n inputCmp ===\n (caseInsensitive\n ? hardcodedWorkspaceNoSlash.toLowerCase()\n : hardcodedWorkspaceNoSlash) ||\n inputCmp.startsWith(\n `${caseInsensitive ? hardcodedWorkspaceNoSlash.toLowerCase() : hardcodedWorkspaceNoSlash}/`,\n )\n ) {\n return inputNormalized.slice(hardcodedWorkspaceNoSlash.length);\n }\n\n return null;\n};\n\nexport const toWorkspacePath = (workspaceRoot: string, inputPath: string) => {\n const stripped = stripKnownWorkspacePrefix(inputPath, workspaceRoot);\n const isAbsoluteInput = path.isAbsolute(inputPath);\n\n if (stripped === null && isAbsoluteInput) {\n throw new Error(\n `Path \"${inputPath}\" is absolute but not within workspace \"${workspaceRoot}\".`,\n );\n }\n\n const relativePath = (stripped ?? inputPath).replace(/^[\\/\\\\]+/, \"\");\n const resolvedRoot = path.resolve(workspaceRoot);\n const resolved = path.resolve(resolvedRoot, relativePath);\n const rel = path.relative(resolvedRoot, resolved);\n\n if (rel.startsWith(\"..\") || path.isAbsolute(rel)) {\n throw new Error(`Path \"${inputPath}\" resolves outside the workspace root.`);\n }\n\n return resolved;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileSystem.helpers.test.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/fileSystem.helpers.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import test from "node:test";
|
|
4
|
+
import { toWorkspacePath } from "./fileSystem.helpers.js";
|
|
5
|
+
test("toWorkspacePath: tolerates case mismatch for absolute paths on Windows", () => {
|
|
6
|
+
if (process.platform !== "win32") {
|
|
7
|
+
assert.ok(true);
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const workspaceRoot = "C:\\Repo\\Workspace";
|
|
11
|
+
const input = "c:\\repo\\workspace\\src\\index.ts";
|
|
12
|
+
const resolved = toWorkspacePath(workspaceRoot, input);
|
|
13
|
+
assert.equal(resolved, path.resolve(workspaceRoot, "src", "index.ts"));
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=fileSystem.helpers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileSystem.helpers.test.js","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/fileSystem.helpers.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,IAAI,CAAC,wEAAwE,EAAE,GAAG,EAAE;IAClF,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,MAAM,aAAa,GAAG,qBAAqB,CAAC;IAC5C,MAAM,KAAK,GAAG,oCAAoC,CAAC;IACnD,MAAM,QAAQ,GAAG,eAAe,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IACvD,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC","sourcesContent":["import assert from \"node:assert/strict\";\nimport path from \"node:path\";\nimport test from \"node:test\";\nimport { toWorkspacePath } from \"./fileSystem.helpers.js\";\n\ntest(\"toWorkspacePath: tolerates case mismatch for absolute paths on Windows\", () => {\n if (process.platform !== \"win32\") {\n assert.ok(true);\n return;\n }\n\n const workspaceRoot = \"C:\\\\Repo\\\\Workspace\";\n const input = \"c:\\\\repo\\\\workspace\\\\src\\\\index.ts\";\n const resolved = toWorkspacePath(workspaceRoot, input);\n assert.equal(resolved, path.resolve(workspaceRoot, \"src\", \"index.ts\"));\n});\n\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.helpers.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/format.helpers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,GACvB,SAAS,MAAM,EACf,YAAY,MAAM,EAClB,UAAU,MAAM,WAkBjB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const sliceByLines = (content, startLine, endLine) => {
|
|
2
|
+
const normalized = content.replace(/\r\n/g, "\n");
|
|
3
|
+
const lines = normalized.split("\n");
|
|
4
|
+
const start = startLine === undefined || startLine === null
|
|
5
|
+
? 0
|
|
6
|
+
: startLine <= 1
|
|
7
|
+
? 0
|
|
8
|
+
: startLine - 1;
|
|
9
|
+
const endExclusive = endLine === undefined || endLine === null || endLine === -1
|
|
10
|
+
? lines.length
|
|
11
|
+
: Math.max(start, endLine);
|
|
12
|
+
return lines.slice(start, endExclusive).join("\n");
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=format.helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.helpers.js","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/format.helpers.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAe,EACf,SAAkB,EAClB,OAAgB,EAChB,EAAE;IACF,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAErC,MAAM,KAAK,GACT,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,IAAI;QAC3C,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,SAAS,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;IAEtB,MAAM,YAAY,GAChB,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,CAAC;QACzD,CAAC,CAAC,KAAK,CAAC,MAAM;QACd,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAE/B,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC,CAAC","sourcesContent":["export const sliceByLines = (\n content: string,\n startLine?: number,\n endLine?: number,\n) => {\n const normalized = content.replace(/\\r\\n/g, \"\\n\");\n const lines = normalized.split(\"\\n\");\n\n const start =\n startLine === undefined || startLine === null\n ? 0\n : startLine <= 1\n ? 0\n : startLine - 1;\n\n const endExclusive =\n endLine === undefined || endLine === null || endLine === -1\n ? lines.length\n : Math.max(start, endLine);\n\n return lines.slice(start, endExclusive).join(\"\\n\");\n};\n\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const ALLOWED_ROUTE_FILENAMES: Set<string>;
|
|
2
|
+
export declare const PAGE_TSX_TEMPLATE: string;
|
|
3
|
+
export declare const normalizeFsPathForPolicy: (p: string) => string;
|
|
4
|
+
export declare const isAllowedRouteFilePath: (p: string) => boolean;
|
|
5
|
+
export declare const isPageTsxPath: (p: string) => boolean;
|
|
6
|
+
export declare const isPageConfigPath: (p: string) => boolean;
|
|
7
|
+
export declare const matchesPageTsxTemplate: (content: string) => boolean;
|
|
8
|
+
//# sourceMappingURL=nextRouteFilePolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextRouteFilePolicy.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/nextRouteFilePolicy.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,aAA0C,CAAC;AAE/E,eAAO,MAAM,iBAAiB,QAQlB,CAAC;AAEb,eAAO,MAAM,wBAAwB,GAAI,GAAG,MAAM,WACN,CAAC;AAE7C,eAAO,MAAM,sBAAsB,GAAI,GAAG,MAAM,YAI/C,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,GAAG,MAAM,YAGtC,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,GAAG,MAAM,YAGzC,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,YACc,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const ALLOWED_ROUTE_FILENAMES = new Set(["page.tsx", "page.config.ts"]);
|
|
2
|
+
export const PAGE_TSX_TEMPLATE = [
|
|
3
|
+
'import { config } from "./page.config";',
|
|
4
|
+
'import { RenderElement } from "@/lib/renderer/RenderElement";',
|
|
5
|
+
"",
|
|
6
|
+
"export default function Page() {",
|
|
7
|
+
" return config.elements.map((el) => <RenderElement key={el.id} el={el} />);",
|
|
8
|
+
"}",
|
|
9
|
+
"",
|
|
10
|
+
].join("\n");
|
|
11
|
+
export const normalizeFsPathForPolicy = (p) => String(p ?? "").replace(/\\/g, "/").trim();
|
|
12
|
+
export const isAllowedRouteFilePath = (p) => {
|
|
13
|
+
const norm = normalizeFsPathForPolicy(p);
|
|
14
|
+
const filename = norm.split("/").pop() ?? "";
|
|
15
|
+
return ALLOWED_ROUTE_FILENAMES.has(filename);
|
|
16
|
+
};
|
|
17
|
+
export const isPageTsxPath = (p) => {
|
|
18
|
+
const norm = normalizeFsPathForPolicy(p);
|
|
19
|
+
return (norm.split("/").pop() ?? "") === "page.tsx";
|
|
20
|
+
};
|
|
21
|
+
export const isPageConfigPath = (p) => {
|
|
22
|
+
const norm = normalizeFsPathForPolicy(p);
|
|
23
|
+
return (norm.split("/").pop() ?? "") === "page.config.ts";
|
|
24
|
+
};
|
|
25
|
+
export const matchesPageTsxTemplate = (content) => String(content ?? "").replace(/\r\n/g, "\n") === PAGE_TSX_TEMPLATE;
|
|
26
|
+
//# sourceMappingURL=nextRouteFilePolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextRouteFilePolicy.js","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/nextRouteFilePolicy.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE/E,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,yCAAyC;IACzC,+DAA+D;IAC/D,EAAE;IACF,kCAAkC;IAClC,8EAA8E;IAC9E,GAAG;IACH,EAAE;CACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAS,EAAE,EAAE,CACpD,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAE7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAS,EAAE,EAAE;IAClD,MAAM,IAAI,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAC7C,OAAO,uBAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAS,EAAE,EAAE;IACzC,MAAM,IAAI,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,KAAK,UAAU,CAAC;AACtD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAS,EAAE,EAAE;IAC5C,MAAM,IAAI,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,KAAK,gBAAgB,CAAC;AAC5D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,EAAE,CACxD,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,iBAAiB,CAAC","sourcesContent":["export const ALLOWED_ROUTE_FILENAMES = new Set([\"page.tsx\", \"page.config.ts\"]);\n\nexport const PAGE_TSX_TEMPLATE = [\n 'import { config } from \"./page.config\";',\n 'import { RenderElement } from \"@/lib/renderer/RenderElement\";',\n \"\",\n \"export default function Page() {\",\n \" return config.elements.map((el) => <RenderElement key={el.id} el={el} />);\",\n \"}\",\n \"\",\n].join(\"\\n\");\n\nexport const normalizeFsPathForPolicy = (p: string) =>\n String(p ?? \"\").replace(/\\\\/g, \"/\").trim();\n\nexport const isAllowedRouteFilePath = (p: string) => {\n const norm = normalizeFsPathForPolicy(p);\n const filename = norm.split(\"/\").pop() ?? \"\";\n return ALLOWED_ROUTE_FILENAMES.has(filename);\n};\n\nexport const isPageTsxPath = (p: string) => {\n const norm = normalizeFsPathForPolicy(p);\n return (norm.split(\"/\").pop() ?? \"\") === \"page.tsx\";\n};\n\nexport const isPageConfigPath = (p: string) => {\n const norm = normalizeFsPathForPolicy(p);\n return (norm.split(\"/\").pop() ?? \"\") === \"page.config.ts\";\n};\n\nexport const matchesPageTsxTemplate = (content: string) =>\n String(content ?? \"\").replace(/\\r\\n/g, \"\\n\") === PAGE_TSX_TEMPLATE;\n\n"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type WorkspaceDeps } from "./workspaceDeps.js";
|
|
2
|
+
export declare const createApplyPatchImpl: (deps: WorkspaceDeps) => (patchString: string) => Promise<{
|
|
3
|
+
success: boolean;
|
|
4
|
+
rejected: boolean;
|
|
5
|
+
error: string;
|
|
6
|
+
allowed: string[];
|
|
7
|
+
rule?: undefined;
|
|
8
|
+
changed?: undefined;
|
|
9
|
+
warnings?: undefined;
|
|
10
|
+
debug?: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
success: boolean;
|
|
13
|
+
rejected: boolean;
|
|
14
|
+
error: string;
|
|
15
|
+
allowed?: undefined;
|
|
16
|
+
rule?: undefined;
|
|
17
|
+
changed?: undefined;
|
|
18
|
+
warnings?: undefined;
|
|
19
|
+
debug?: undefined;
|
|
20
|
+
} | {
|
|
21
|
+
success: boolean;
|
|
22
|
+
rejected: boolean;
|
|
23
|
+
error: string;
|
|
24
|
+
rule: string;
|
|
25
|
+
allowed?: undefined;
|
|
26
|
+
changed?: undefined;
|
|
27
|
+
warnings?: undefined;
|
|
28
|
+
debug?: undefined;
|
|
29
|
+
} | {
|
|
30
|
+
success: boolean;
|
|
31
|
+
changed: boolean;
|
|
32
|
+
warnings: string[] | undefined;
|
|
33
|
+
rejected?: undefined;
|
|
34
|
+
error?: undefined;
|
|
35
|
+
allowed?: undefined;
|
|
36
|
+
rule?: undefined;
|
|
37
|
+
debug?: undefined;
|
|
38
|
+
} | {
|
|
39
|
+
success: boolean;
|
|
40
|
+
error: string;
|
|
41
|
+
debug: {
|
|
42
|
+
files: {
|
|
43
|
+
path: string;
|
|
44
|
+
head: string;
|
|
45
|
+
}[];
|
|
46
|
+
} | undefined;
|
|
47
|
+
rejected?: undefined;
|
|
48
|
+
allowed?: undefined;
|
|
49
|
+
rule?: undefined;
|
|
50
|
+
changed?: undefined;
|
|
51
|
+
warnings?: undefined;
|
|
52
|
+
}>;
|
|
53
|
+
//# sourceMappingURL=applyPatch.impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyPatch.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/applyPatch.impl.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,eAAO,MAAM,oBAAoB,GAAI,MAAM,aAAa,MAGxC,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAEC,MAAM;kBAAQ,MAAM;;;;;;;;EA+PvD,CAAC"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { applyHunksToContent, isTextFilePath, parseApplyPatch } from "../helpers/applyPatch.helpers.js";
|
|
3
|
+
import { toWorkspacePath } from "../helpers/fileSystem.helpers.js";
|
|
4
|
+
import { isAllowedRouteFilePath, isPageTsxPath, matchesPageTsxTemplate, normalizeFsPathForPolicy, PAGE_TSX_TEMPLATE, } from "../helpers/nextRouteFilePolicy.js";
|
|
5
|
+
export const createApplyPatchImpl = (deps) => {
|
|
6
|
+
const { workspaceRoot, fs } = deps;
|
|
7
|
+
return async (patchString) => {
|
|
8
|
+
let parsedOps = null;
|
|
9
|
+
const debugFiles = [];
|
|
10
|
+
const HEAD_MAX_LINES = 80;
|
|
11
|
+
const headLines = (content) => content.replace(/\r\n/g, "\n").split("\n").slice(0, HEAD_MAX_LINES).join("\n");
|
|
12
|
+
const addDebugSnapshot = async (filePath, label) => {
|
|
13
|
+
if (!filePath)
|
|
14
|
+
return;
|
|
15
|
+
if (debugFiles.length >= 3)
|
|
16
|
+
return;
|
|
17
|
+
if (debugFiles.some((f) => f.path === filePath))
|
|
18
|
+
return;
|
|
19
|
+
try {
|
|
20
|
+
const absolute = toWorkspacePath(workspaceRoot, filePath);
|
|
21
|
+
try {
|
|
22
|
+
await fs.stat(absolute);
|
|
23
|
+
const content = await fs.readFile(absolute);
|
|
24
|
+
debugFiles.push({
|
|
25
|
+
path: filePath,
|
|
26
|
+
head: `${label ? `${label}\n` : ""}${headLines(content)}`,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const code = err?.code;
|
|
31
|
+
const suffix = code === "ENOENT" ? "(not found)" : "(unreadable)";
|
|
32
|
+
debugFiles.push({ path: filePath, head: `${label ? `${label} ` : ""}${suffix}` });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
debugFiles.push({ path: filePath, head: `${label ? `${label} ` : ""}(invalid path)` });
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const extractPatchPaths = (patch) => {
|
|
40
|
+
const out = [];
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
const normalized = (patch ?? "").replace(/\r\n/g, "\n");
|
|
43
|
+
for (const line of normalized.split("\n")) {
|
|
44
|
+
const match = /^\*\*\* (Update File|Add File|Delete File):\s+(.+)$/.exec(line.trim()) ??
|
|
45
|
+
/^\*\*\* Move to:\s+(.+)$/.exec(line.trim());
|
|
46
|
+
if (!match)
|
|
47
|
+
continue;
|
|
48
|
+
const p = (match[2] ?? match[1] ?? "").trim();
|
|
49
|
+
if (!p || seen.has(p))
|
|
50
|
+
continue;
|
|
51
|
+
seen.add(p);
|
|
52
|
+
out.push(p);
|
|
53
|
+
if (out.length >= 10)
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
return out;
|
|
57
|
+
};
|
|
58
|
+
try {
|
|
59
|
+
const operations = parseApplyPatch(patchString);
|
|
60
|
+
parsedOps = operations;
|
|
61
|
+
for (const op of operations) {
|
|
62
|
+
const opPath = normalizeFsPathForPolicy(op.filePath);
|
|
63
|
+
if (!isAllowedRouteFilePath(opPath)) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
rejected: true,
|
|
67
|
+
error: `apply_patch rejected: only route files named "page.tsx" or "page.config.ts" may be modified.\n` +
|
|
68
|
+
`Found operation on: "${opPath}"`,
|
|
69
|
+
allowed: Array.from(["page.tsx", "page.config.ts"]),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (op.kind === "update" && op.moveTo && op.moveTo !== op.filePath) {
|
|
73
|
+
const moveToPath = normalizeFsPathForPolicy(op.moveTo);
|
|
74
|
+
if (!isAllowedRouteFilePath(moveToPath)) {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
rejected: true,
|
|
78
|
+
error: `apply_patch rejected: move target must be a route file named "page.tsx" or "page.config.ts".\n` +
|
|
79
|
+
`From: "${opPath}"\n` +
|
|
80
|
+
`To: "${moveToPath}"`,
|
|
81
|
+
allowed: Array.from(["page.tsx", "page.config.ts"]),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const fromName = opPath.split("/").pop() ?? "";
|
|
85
|
+
const toName = moveToPath.split("/").pop() ?? "";
|
|
86
|
+
if (fromName !== toName) {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
rejected: true,
|
|
90
|
+
error: `apply_patch rejected: renaming between route file types is not allowed.\n` +
|
|
91
|
+
`From: "${opPath}"\n` +
|
|
92
|
+
`To: "${moveToPath}"`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (isPageTsxPath(opPath)) {
|
|
97
|
+
if (op.kind === "update") {
|
|
98
|
+
return {
|
|
99
|
+
success: false,
|
|
100
|
+
rejected: true,
|
|
101
|
+
error: `apply_patch rejected: updates to "page.tsx" are not allowed for any route. ` +
|
|
102
|
+
`Only Add File (create) or Delete File is allowed.\n` +
|
|
103
|
+
`Path: "${opPath}"`,
|
|
104
|
+
rule: "page.tsx is immutable after creation",
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (op.kind === "add") {
|
|
108
|
+
const { content: after } = applyHunksToContent("", op.hunks);
|
|
109
|
+
if (!matchesPageTsxTemplate(after)) {
|
|
110
|
+
return {
|
|
111
|
+
success: false,
|
|
112
|
+
rejected: true,
|
|
113
|
+
error: `apply_patch rejected: new "page.tsx" must match the exact required template (byte-for-byte).\n` +
|
|
114
|
+
`Path: "${opPath}"\n` +
|
|
115
|
+
`Expected:\n${PAGE_TSX_TEMPLATE}`,
|
|
116
|
+
rule: "page.tsx must match template on creation",
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
let changed = false;
|
|
123
|
+
const warnings = [];
|
|
124
|
+
for (const op of operations) {
|
|
125
|
+
if (!isTextFilePath(op.filePath)) {
|
|
126
|
+
throw new Error(`Binary or unsupported file type in patch: "${op.filePath}"`);
|
|
127
|
+
}
|
|
128
|
+
if (op.kind === "update" && op.moveTo && !isTextFilePath(op.moveTo)) {
|
|
129
|
+
throw new Error(`Binary or unsupported file type in patch: "${op.moveTo}"`);
|
|
130
|
+
}
|
|
131
|
+
const fullPath = toWorkspacePath(workspaceRoot, op.filePath);
|
|
132
|
+
if (op.kind === "delete") {
|
|
133
|
+
console.log("Tool apply_patch (delete)", { path: fullPath });
|
|
134
|
+
try {
|
|
135
|
+
await fs.rmFile(fullPath);
|
|
136
|
+
changed = true;
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
140
|
+
throw new Error(`Delete File failed for "${op.filePath}": ${message}`);
|
|
141
|
+
}
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (op.kind === "add") {
|
|
145
|
+
console.log("Tool apply_patch (add)", { path: fullPath });
|
|
146
|
+
try {
|
|
147
|
+
const { content: after, changed: opChanged } = applyHunksToContent("", op.hunks);
|
|
148
|
+
await fs.mkdirp(path.dirname(fullPath));
|
|
149
|
+
await fs.writeFile(fullPath, after);
|
|
150
|
+
if (!opChanged)
|
|
151
|
+
warnings.push(`Add File produced no changes for "${op.filePath}".`);
|
|
152
|
+
changed = changed || opChanged;
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
156
|
+
throw new Error(`Add File failed for "${op.filePath}": ${message}`);
|
|
157
|
+
}
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (op.kind === "update") {
|
|
161
|
+
console.log("Tool apply_patch (update)", { path: fullPath });
|
|
162
|
+
try {
|
|
163
|
+
try {
|
|
164
|
+
await fs.stat(fullPath);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
const code = err?.code;
|
|
168
|
+
if (code === "ENOENT") {
|
|
169
|
+
throw new Error(`"${op.filePath}" not found.`);
|
|
170
|
+
}
|
|
171
|
+
throw err;
|
|
172
|
+
}
|
|
173
|
+
const before = await fs.readFile(fullPath);
|
|
174
|
+
await addDebugSnapshot(op.filePath, `BEFORE (${op.filePath}):`);
|
|
175
|
+
const { content: after, changed: contentChanged } = applyHunksToContent(before, op.hunks);
|
|
176
|
+
if (op.moveTo && op.moveTo !== op.filePath) {
|
|
177
|
+
const moveToPath = toWorkspacePath(workspaceRoot, op.moveTo);
|
|
178
|
+
console.log("Tool apply_patch (move)", {
|
|
179
|
+
from: fullPath,
|
|
180
|
+
to: moveToPath,
|
|
181
|
+
});
|
|
182
|
+
await fs.mkdirp(path.dirname(moveToPath));
|
|
183
|
+
await fs.writeFile(moveToPath, after);
|
|
184
|
+
await fs.rmFile(fullPath);
|
|
185
|
+
changed = true;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (!contentChanged) {
|
|
189
|
+
warnings.push(`Update File made no changes for "${op.filePath}".`);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
await fs.mkdirp(path.dirname(fullPath));
|
|
193
|
+
await fs.writeFile(fullPath, after);
|
|
194
|
+
changed = true;
|
|
195
|
+
}
|
|
196
|
+
catch (err) {
|
|
197
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
198
|
+
throw new Error(`Update File failed for "${op.filePath}": ${message}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return { success: true, changed, warnings: warnings.length > 0 ? warnings : undefined };
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
206
|
+
console.log("Tool apply_patch failed", err, { message });
|
|
207
|
+
try {
|
|
208
|
+
if (debugFiles.length < 3) {
|
|
209
|
+
const paths = parsedOps
|
|
210
|
+
? parsedOps.flatMap((op) => op.kind === "update" && op.moveTo
|
|
211
|
+
? [op.filePath, op.moveTo]
|
|
212
|
+
: [op.filePath])
|
|
213
|
+
: extractPatchPaths(patchString);
|
|
214
|
+
for (const p of paths) {
|
|
215
|
+
if (debugFiles.length >= 3)
|
|
216
|
+
break;
|
|
217
|
+
await addDebugSnapshot(p);
|
|
218
|
+
}
|
|
219
|
+
if (debugFiles.length < 3 && parsedOps) {
|
|
220
|
+
for (const op of parsedOps) {
|
|
221
|
+
if (debugFiles.length >= 3)
|
|
222
|
+
break;
|
|
223
|
+
if (op.kind === "add")
|
|
224
|
+
debugFiles.push({ path: op.filePath, head: "(new file)" });
|
|
225
|
+
if (op.kind === "delete")
|
|
226
|
+
debugFiles.push({ path: op.filePath, head: "(deleted)" });
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// best-effort only
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
success: false,
|
|
236
|
+
error: message,
|
|
237
|
+
debug: debugFiles.length > 0 ? { files: debugFiles.slice(0, 3) } : undefined,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
//# sourceMappingURL=applyPatch.impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyPatch.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/applyPatch.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport { applyHunksToContent, isTextFilePath, parseApplyPatch } from \"../helpers/applyPatch.helpers.js\";\nimport { toWorkspacePath } from \"../helpers/fileSystem.helpers.js\";\nimport {\n isAllowedRouteFilePath,\n isPageTsxPath,\n matchesPageTsxTemplate,\n normalizeFsPathForPolicy,\n PAGE_TSX_TEMPLATE,\n} from \"../helpers/nextRouteFilePolicy.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nexport const createApplyPatchImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (patchString: string) => {\n let parsedOps: ReturnType<typeof parseApplyPatch> | null = null;\n const debugFiles: Array<{ path: string; head: string }> = [];\n\n const HEAD_MAX_LINES = 80;\n\n const headLines = (content: string) =>\n content.replace(/\\r\\n/g, \"\\n\").split(\"\\n\").slice(0, HEAD_MAX_LINES).join(\"\\n\");\n\n const addDebugSnapshot = async (filePath: string, label?: string) => {\n if (!filePath) return;\n if (debugFiles.length >= 3) return;\n if (debugFiles.some((f) => f.path === filePath)) return;\n\n try {\n const absolute = toWorkspacePath(workspaceRoot, filePath);\n try {\n await fs.stat(absolute);\n const content = await fs.readFile(absolute);\n debugFiles.push({\n path: filePath,\n head: `${label ? `${label}\\n` : \"\"}${headLines(content)}`,\n });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n const suffix = code === \"ENOENT\" ? \"(not found)\" : \"(unreadable)\";\n debugFiles.push({ path: filePath, head: `${label ? `${label} ` : \"\"}${suffix}` });\n }\n } catch {\n debugFiles.push({ path: filePath, head: `${label ? `${label} ` : \"\"}(invalid path)` });\n }\n };\n\n const extractPatchPaths = (patch: string) => {\n const out: string[] = [];\n const seen = new Set<string>();\n const normalized = (patch ?? \"\").replace(/\\r\\n/g, \"\\n\");\n for (const line of normalized.split(\"\\n\")) {\n const match =\n /^\\*\\*\\* (Update File|Add File|Delete File):\\s+(.+)$/.exec(line.trim()) ??\n /^\\*\\*\\* Move to:\\s+(.+)$/.exec(line.trim());\n if (!match) continue;\n const p = (match[2] ?? match[1] ?? \"\").trim();\n if (!p || seen.has(p)) continue;\n seen.add(p);\n out.push(p);\n if (out.length >= 10) break;\n }\n return out;\n };\n\n try {\n const operations = parseApplyPatch(patchString);\n parsedOps = operations;\n\n for (const op of operations) {\n const opPath = normalizeFsPathForPolicy(op.filePath);\n if (!isAllowedRouteFilePath(opPath)) {\n return {\n success: false,\n rejected: true,\n error:\n `apply_patch rejected: only route files named \"page.tsx\" or \"page.config.ts\" may be modified.\\n` +\n `Found operation on: \"${opPath}\"`,\n allowed: Array.from([\"page.tsx\", \"page.config.ts\"]),\n };\n }\n\n if (op.kind === \"update\" && op.moveTo && op.moveTo !== op.filePath) {\n const moveToPath = normalizeFsPathForPolicy(op.moveTo);\n if (!isAllowedRouteFilePath(moveToPath)) {\n return {\n success: false,\n rejected: true,\n error:\n `apply_patch rejected: move target must be a route file named \"page.tsx\" or \"page.config.ts\".\\n` +\n `From: \"${opPath}\"\\n` +\n `To: \"${moveToPath}\"`,\n allowed: Array.from([\"page.tsx\", \"page.config.ts\"]),\n };\n }\n\n const fromName = opPath.split(\"/\").pop() ?? \"\";\n const toName = moveToPath.split(\"/\").pop() ?? \"\";\n if (fromName !== toName) {\n return {\n success: false,\n rejected: true,\n error:\n `apply_patch rejected: renaming between route file types is not allowed.\\n` +\n `From: \"${opPath}\"\\n` +\n `To: \"${moveToPath}\"`,\n };\n }\n }\n\n if (isPageTsxPath(opPath)) {\n if (op.kind === \"update\") {\n return {\n success: false,\n rejected: true,\n error:\n `apply_patch rejected: updates to \"page.tsx\" are not allowed for any route. ` +\n `Only Add File (create) or Delete File is allowed.\\n` +\n `Path: \"${opPath}\"`,\n rule: \"page.tsx is immutable after creation\",\n };\n }\n\n if (op.kind === \"add\") {\n const { content: after } = applyHunksToContent(\"\", op.hunks);\n if (!matchesPageTsxTemplate(after)) {\n return {\n success: false,\n rejected: true,\n error:\n `apply_patch rejected: new \"page.tsx\" must match the exact required template (byte-for-byte).\\n` +\n `Path: \"${opPath}\"\\n` +\n `Expected:\\n${PAGE_TSX_TEMPLATE}`,\n rule: \"page.tsx must match template on creation\",\n };\n }\n }\n }\n }\n\n let changed = false;\n const warnings: string[] = [];\n\n for (const op of operations) {\n if (!isTextFilePath(op.filePath)) {\n throw new Error(`Binary or unsupported file type in patch: \"${op.filePath}\"`);\n }\n if (op.kind === \"update\" && op.moveTo && !isTextFilePath(op.moveTo)) {\n throw new Error(`Binary or unsupported file type in patch: \"${op.moveTo}\"`);\n }\n\n const fullPath = toWorkspacePath(workspaceRoot, op.filePath);\n\n if (op.kind === \"delete\") {\n console.log(\"Tool apply_patch (delete)\", { path: fullPath });\n try {\n await fs.rmFile(fullPath);\n changed = true;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Delete File failed for \"${op.filePath}\": ${message}`);\n }\n continue;\n }\n\n if (op.kind === \"add\") {\n console.log(\"Tool apply_patch (add)\", { path: fullPath });\n try {\n const { content: after, changed: opChanged } = applyHunksToContent(\n \"\",\n op.hunks,\n );\n await fs.mkdirp(path.dirname(fullPath));\n await fs.writeFile(fullPath, after);\n if (!opChanged) warnings.push(`Add File produced no changes for \"${op.filePath}\".`);\n changed = changed || opChanged;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Add File failed for \"${op.filePath}\": ${message}`);\n }\n continue;\n }\n\n if (op.kind === \"update\") {\n console.log(\"Tool apply_patch (update)\", { path: fullPath });\n try {\n try {\n await fs.stat(fullPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") {\n throw new Error(`\"${op.filePath}\" not found.`);\n }\n throw err;\n }\n\n const before = await fs.readFile(fullPath);\n await addDebugSnapshot(op.filePath, `BEFORE (${op.filePath}):`);\n\n const { content: after, changed: contentChanged } = applyHunksToContent(\n before,\n op.hunks,\n );\n\n if (op.moveTo && op.moveTo !== op.filePath) {\n const moveToPath = toWorkspacePath(workspaceRoot, op.moveTo);\n console.log(\"Tool apply_patch (move)\", {\n from: fullPath,\n to: moveToPath,\n });\n await fs.mkdirp(path.dirname(moveToPath));\n await fs.writeFile(moveToPath, after);\n await fs.rmFile(fullPath);\n changed = true;\n continue;\n }\n\n if (!contentChanged) {\n warnings.push(`Update File made no changes for \"${op.filePath}\".`);\n continue;\n }\n\n await fs.mkdirp(path.dirname(fullPath));\n await fs.writeFile(fullPath, after);\n changed = true;\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Update File failed for \"${op.filePath}\": ${message}`);\n }\n }\n }\n\n return { success: true, changed, warnings: warnings.length > 0 ? warnings : undefined };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(\"Tool apply_patch failed\", err, { message });\n\n try {\n if (debugFiles.length < 3) {\n const paths = parsedOps\n ? parsedOps.flatMap((op) =>\n op.kind === \"update\" && op.moveTo\n ? [op.filePath, op.moveTo]\n : [op.filePath],\n )\n : extractPatchPaths(patchString);\n\n for (const p of paths) {\n if (debugFiles.length >= 3) break;\n await addDebugSnapshot(p);\n }\n\n if (debugFiles.length < 3 && parsedOps) {\n for (const op of parsedOps) {\n if (debugFiles.length >= 3) break;\n if (op.kind === \"add\") debugFiles.push({ path: op.filePath, head: \"(new file)\" });\n if (op.kind === \"delete\") debugFiles.push({ path: op.filePath, head: \"(deleted)\" });\n }\n }\n }\n } catch {\n // best-effort only\n }\n\n return {\n success: false,\n error: message,\n debug: debugFiles.length > 0 ? { files: debugFiles.slice(0, 3) } : undefined,\n };\n }\n };\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyPatch.impl.test.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/applyPatch.impl.test.ts"],"names":[],"mappings":""}
|