codexslimedit 0.7.4-dev.29700855995.1 → 0.7.4-dev.29702371652.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/mcp.js +71 -19
- package/package.json +1 -1
package/dist/mcp.js
CHANGED
|
@@ -4523,6 +4523,7 @@ async function readWorkspaceFile(input) {
|
|
|
4523
4523
|
async function editWorkspaceFile(input) {
|
|
4524
4524
|
const target = await resolveWorkspaceFile(input);
|
|
4525
4525
|
const nextContent = replaceContent(await readUtf8Text(target.absolutePath), input.oldString, input.newString);
|
|
4526
|
+
validateText(nextContent);
|
|
4526
4527
|
await atomicWrite(target.absolutePath, nextContent);
|
|
4527
4528
|
return {
|
|
4528
4529
|
path: target.relativePath,
|
|
@@ -4562,6 +4563,15 @@ async function createWorkspaceFile(input) {
|
|
|
4562
4563
|
content: input.content
|
|
4563
4564
|
};
|
|
4564
4565
|
}
|
|
4566
|
+
/** Validates a new workspace file without modifying the workspace. */
|
|
4567
|
+
async function prepareWorkspaceFileCreation(input) {
|
|
4568
|
+
const target = await resolveNewWorkspaceFile(input, false);
|
|
4569
|
+
validateText(input.content);
|
|
4570
|
+
return {
|
|
4571
|
+
path: target.relativePath,
|
|
4572
|
+
content: input.content
|
|
4573
|
+
};
|
|
4574
|
+
}
|
|
4565
4575
|
/** Deletes one existing regular workspace file. */
|
|
4566
4576
|
async function deleteWorkspaceFile(input) {
|
|
4567
4577
|
const target = await resolveWorkspaceFile(input);
|
|
@@ -4587,7 +4597,7 @@ async function resolveWorkspaceFile(input) {
|
|
|
4587
4597
|
relativePath: relative(rootPath, resolvedCandidate).split(sep).join("/")
|
|
4588
4598
|
};
|
|
4589
4599
|
}
|
|
4590
|
-
async function resolveNewWorkspaceFile(input) {
|
|
4600
|
+
async function resolveNewWorkspaceFile(input, createParent = true) {
|
|
4591
4601
|
const rootPath = await existingDirectory(input.root);
|
|
4592
4602
|
const candidate = resolve(rootPath, normalizeSeparators(input.filePath));
|
|
4593
4603
|
if (!isInside(rootPath, candidate)) throw new WorkspaceFileError("PATH_OUTSIDE_ROOT", "filePath must remain inside the workspace root.");
|
|
@@ -4597,13 +4607,13 @@ async function resolveNewWorkspaceFile(input) {
|
|
|
4597
4607
|
} catch (error) {
|
|
4598
4608
|
if (error instanceof WorkspaceFileError) throw error;
|
|
4599
4609
|
}
|
|
4600
|
-
const absolutePath = resolve(await
|
|
4610
|
+
const absolutePath = resolve(await safeParent(rootPath, dirname(candidate), createParent), basename(candidate));
|
|
4601
4611
|
return {
|
|
4602
4612
|
absolutePath,
|
|
4603
4613
|
relativePath: relative(rootPath, absolutePath).split(sep).join("/")
|
|
4604
4614
|
};
|
|
4605
4615
|
}
|
|
4606
|
-
async function
|
|
4616
|
+
async function safeParent(rootPath, requestedParent, createParent) {
|
|
4607
4617
|
const missingDirectories = [];
|
|
4608
4618
|
let existingParent = requestedParent;
|
|
4609
4619
|
while (true) try {
|
|
@@ -4616,7 +4626,7 @@ async function createSafeParent(rootPath, requestedParent) {
|
|
|
4616
4626
|
}
|
|
4617
4627
|
if (existingParent !== rootPath && !isInside(rootPath, existingParent)) throw new WorkspaceFileError("PATH_OUTSIDE_ROOT", "filePath parent resolves outside the workspace root through a symlink.");
|
|
4618
4628
|
const parentPath = resolve(existingParent, ...missingDirectories.reverse());
|
|
4619
|
-
await mkdir(parentPath, { recursive: true });
|
|
4629
|
+
if (createParent) await mkdir(parentPath, { recursive: true });
|
|
4620
4630
|
return parentPath;
|
|
4621
4631
|
}
|
|
4622
4632
|
async function existingDirectory(root) {
|
|
@@ -4765,38 +4775,69 @@ function message(error) {
|
|
|
4765
4775
|
/** Applies Codex add, update, and delete patch operations inside a workspace. */
|
|
4766
4776
|
async function applyWorkspacePatch(input) {
|
|
4767
4777
|
const operations = parsePatch(input.patch);
|
|
4778
|
+
const planned = await planOperations(input.root, operations);
|
|
4768
4779
|
const paths = [];
|
|
4769
|
-
for (const operation of
|
|
4780
|
+
for (const { operation, path, content } of planned) {
|
|
4770
4781
|
if (operation.kind === "add") {
|
|
4771
|
-
|
|
4782
|
+
await createWorkspaceFile({
|
|
4772
4783
|
root: input.root,
|
|
4773
4784
|
filePath: operation.filePath,
|
|
4774
4785
|
content: operation.content
|
|
4775
4786
|
});
|
|
4776
|
-
paths.push(
|
|
4787
|
+
paths.push(path);
|
|
4777
4788
|
continue;
|
|
4778
4789
|
}
|
|
4779
4790
|
if (operation.kind === "delete") {
|
|
4780
|
-
|
|
4791
|
+
await deleteWorkspaceFile({
|
|
4781
4792
|
root: input.root,
|
|
4782
4793
|
filePath: operation.filePath
|
|
4783
4794
|
});
|
|
4784
|
-
paths.push(
|
|
4795
|
+
paths.push(path);
|
|
4785
4796
|
continue;
|
|
4786
4797
|
}
|
|
4787
|
-
|
|
4788
|
-
root: input.root,
|
|
4789
|
-
filePath: operation.filePath
|
|
4790
|
-
});
|
|
4791
|
-
const result = await writeWorkspaceFile({
|
|
4798
|
+
await writeWorkspaceFile({
|
|
4792
4799
|
root: input.root,
|
|
4793
4800
|
filePath: operation.filePath,
|
|
4794
|
-
content:
|
|
4801
|
+
content: content ?? ""
|
|
4795
4802
|
});
|
|
4796
|
-
paths.push(
|
|
4803
|
+
paths.push(path);
|
|
4797
4804
|
}
|
|
4798
4805
|
return { paths };
|
|
4799
4806
|
}
|
|
4807
|
+
async function planOperations(root, operations) {
|
|
4808
|
+
const planned = [];
|
|
4809
|
+
const paths = /* @__PURE__ */ new Set();
|
|
4810
|
+
for (const operation of operations) {
|
|
4811
|
+
if (operation.kind === "add") {
|
|
4812
|
+
const result = await prepareWorkspaceFileCreation({
|
|
4813
|
+
root,
|
|
4814
|
+
filePath: operation.filePath,
|
|
4815
|
+
content: operation.content
|
|
4816
|
+
});
|
|
4817
|
+
assertUniquePath(paths, result.path);
|
|
4818
|
+
planned.push({
|
|
4819
|
+
operation,
|
|
4820
|
+
path: result.path
|
|
4821
|
+
});
|
|
4822
|
+
continue;
|
|
4823
|
+
}
|
|
4824
|
+
const current = await readWorkspaceFile({
|
|
4825
|
+
root,
|
|
4826
|
+
filePath: operation.filePath
|
|
4827
|
+
});
|
|
4828
|
+
assertUniquePath(paths, current.path);
|
|
4829
|
+
planned.push({
|
|
4830
|
+
operation,
|
|
4831
|
+
path: current.path,
|
|
4832
|
+
content: operation.kind === "update" ? applyUpdateHunks(current.content, operation.hunks) : void 0
|
|
4833
|
+
});
|
|
4834
|
+
}
|
|
4835
|
+
return planned;
|
|
4836
|
+
}
|
|
4837
|
+
function assertUniquePath(paths, path) {
|
|
4838
|
+
if (paths.has(path)) invalidPatch(`Patch contains multiple operations for ${path}.`);
|
|
4839
|
+
paths.add(path);
|
|
4840
|
+
}
|
|
4800
4841
|
function parsePatch(patch) {
|
|
4801
4842
|
const lines = patch.replace(/\r\n|\r/g, "\n").split("\n");
|
|
4802
4843
|
while (lines.at(-1) === "") lines.pop();
|
|
@@ -4811,8 +4852,12 @@ function parsePatch(patch) {
|
|
|
4811
4852
|
index += 1;
|
|
4812
4853
|
if (addPath !== void 0) {
|
|
4813
4854
|
const contentLines = [];
|
|
4814
|
-
while (index < lines.length - 1 && !lines[index]
|
|
4855
|
+
while (index < lines.length - 1 && !isOperationHeader(lines[index])) {
|
|
4815
4856
|
const line = lines[index];
|
|
4857
|
+
if (line === "*** End of File") {
|
|
4858
|
+
index += 1;
|
|
4859
|
+
break;
|
|
4860
|
+
}
|
|
4816
4861
|
if (!line?.startsWith("+")) invalidPatch("Add File lines must start with `+`.");
|
|
4817
4862
|
contentLines.push(line.slice(1));
|
|
4818
4863
|
index += 1;
|
|
@@ -4835,8 +4880,12 @@ function parsePatch(patch) {
|
|
|
4835
4880
|
const hunks = [];
|
|
4836
4881
|
let oldLines;
|
|
4837
4882
|
let newLines;
|
|
4838
|
-
while (index < lines.length - 1 && !lines[index]
|
|
4883
|
+
while (index < lines.length - 1 && !isOperationHeader(lines[index])) {
|
|
4839
4884
|
const line = lines[index];
|
|
4885
|
+
if (line === "*** End of File") {
|
|
4886
|
+
index += 1;
|
|
4887
|
+
break;
|
|
4888
|
+
}
|
|
4840
4889
|
if (line?.startsWith("@@")) {
|
|
4841
4890
|
if (oldLines !== void 0 && newLines !== void 0) hunks.push(validHunk(oldLines, newLines));
|
|
4842
4891
|
oldLines = [];
|
|
@@ -4866,6 +4915,9 @@ function parsePatch(patch) {
|
|
|
4866
4915
|
if (operations.length === 0) invalidPatch("Patch must contain at least one file operation.");
|
|
4867
4916
|
return operations;
|
|
4868
4917
|
}
|
|
4918
|
+
function isOperationHeader(line) {
|
|
4919
|
+
return /^\*\*\* (?:Add|Update|Delete) File: /.test(line ?? "");
|
|
4920
|
+
}
|
|
4869
4921
|
function validHunk(oldLines, newLines) {
|
|
4870
4922
|
if (oldLines.length === 0) invalidPatch("Update hunks require old or context lines for deterministic placement.");
|
|
4871
4923
|
return {
|
|
@@ -4906,7 +4958,7 @@ function invalidPatch(message) {
|
|
|
4906
4958
|
//#endregion
|
|
4907
4959
|
//#region src/version.ts
|
|
4908
4960
|
/** Current independent codexslimedit package version. */
|
|
4909
|
-
var CODEX_SLIM_EDIT_VERSION = "0.7.4-dev.
|
|
4961
|
+
var CODEX_SLIM_EDIT_VERSION = "0.7.4-dev.29702371652.1";
|
|
4910
4962
|
/** Returns whether command-line arguments request the package version. */
|
|
4911
4963
|
function isVersionRequest(args) {
|
|
4912
4964
|
return args.includes("--version");
|