codexslimedit 0.7.4-dev.29700855995.1 → 0.7.4-dev.29702567006.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/index.d.ts +1 -1
- package/dist/mcp.js +76 -20
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Readable, Writable } from "node:stream";
|
|
2
2
|
|
|
3
3
|
/** Current independent codexslimedit package version. */
|
|
4
|
-
export declare const CODEX_SLIM_EDIT_VERSION = "0.1
|
|
4
|
+
export declare const CODEX_SLIM_EDIT_VERSION = "0.7.4-dev.29702567006.1";
|
|
5
5
|
|
|
6
6
|
/** Returns whether command-line arguments request the package version. */
|
|
7
7
|
export declare function isVersionRequest(args: readonly string[]): boolean;
|
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,9 +4563,19 @@ 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);
|
|
4578
|
+
if ((await lstat(resolve(await existingDirectory(input.root), normalizeSeparators(input.filePath)))).isSymbolicLink()) throw new WorkspaceFileError("NOT_A_FILE", "Deleting symbolic links is not supported.");
|
|
4568
4579
|
const content = await readUtf8Text(target.absolutePath);
|
|
4569
4580
|
try {
|
|
4570
4581
|
await rm(target.absolutePath);
|
|
@@ -4587,7 +4598,7 @@ async function resolveWorkspaceFile(input) {
|
|
|
4587
4598
|
relativePath: relative(rootPath, resolvedCandidate).split(sep).join("/")
|
|
4588
4599
|
};
|
|
4589
4600
|
}
|
|
4590
|
-
async function resolveNewWorkspaceFile(input) {
|
|
4601
|
+
async function resolveNewWorkspaceFile(input, createParent = true) {
|
|
4591
4602
|
const rootPath = await existingDirectory(input.root);
|
|
4592
4603
|
const candidate = resolve(rootPath, normalizeSeparators(input.filePath));
|
|
4593
4604
|
if (!isInside(rootPath, candidate)) throw new WorkspaceFileError("PATH_OUTSIDE_ROOT", "filePath must remain inside the workspace root.");
|
|
@@ -4597,13 +4608,13 @@ async function resolveNewWorkspaceFile(input) {
|
|
|
4597
4608
|
} catch (error) {
|
|
4598
4609
|
if (error instanceof WorkspaceFileError) throw error;
|
|
4599
4610
|
}
|
|
4600
|
-
const absolutePath = resolve(await
|
|
4611
|
+
const absolutePath = resolve(await safeParent(rootPath, dirname(candidate), createParent), basename(candidate));
|
|
4601
4612
|
return {
|
|
4602
4613
|
absolutePath,
|
|
4603
4614
|
relativePath: relative(rootPath, absolutePath).split(sep).join("/")
|
|
4604
4615
|
};
|
|
4605
4616
|
}
|
|
4606
|
-
async function
|
|
4617
|
+
async function safeParent(rootPath, requestedParent, createParent) {
|
|
4607
4618
|
const missingDirectories = [];
|
|
4608
4619
|
let existingParent = requestedParent;
|
|
4609
4620
|
while (true) try {
|
|
@@ -4616,7 +4627,7 @@ async function createSafeParent(rootPath, requestedParent) {
|
|
|
4616
4627
|
}
|
|
4617
4628
|
if (existingParent !== rootPath && !isInside(rootPath, existingParent)) throw new WorkspaceFileError("PATH_OUTSIDE_ROOT", "filePath parent resolves outside the workspace root through a symlink.");
|
|
4618
4629
|
const parentPath = resolve(existingParent, ...missingDirectories.reverse());
|
|
4619
|
-
await mkdir(parentPath, { recursive: true });
|
|
4630
|
+
if (createParent) await mkdir(parentPath, { recursive: true });
|
|
4620
4631
|
return parentPath;
|
|
4621
4632
|
}
|
|
4622
4633
|
async function existingDirectory(root) {
|
|
@@ -4654,7 +4665,10 @@ async function readUtf8Text(path) {
|
|
|
4654
4665
|
throw new WorkspaceFileError("UNREADABLE_FILE", "filePath could not be read.");
|
|
4655
4666
|
}
|
|
4656
4667
|
try {
|
|
4657
|
-
const content = new TextDecoder("utf-8", {
|
|
4668
|
+
const content = new TextDecoder("utf-8", {
|
|
4669
|
+
fatal: true,
|
|
4670
|
+
ignoreBOM: true
|
|
4671
|
+
}).decode(bytes);
|
|
4658
4672
|
validateText(content);
|
|
4659
4673
|
return content;
|
|
4660
4674
|
} catch {
|
|
@@ -4765,38 +4779,69 @@ function message(error) {
|
|
|
4765
4779
|
/** Applies Codex add, update, and delete patch operations inside a workspace. */
|
|
4766
4780
|
async function applyWorkspacePatch(input) {
|
|
4767
4781
|
const operations = parsePatch(input.patch);
|
|
4782
|
+
const planned = await planOperations(input.root, operations);
|
|
4768
4783
|
const paths = [];
|
|
4769
|
-
for (const operation of
|
|
4784
|
+
for (const { operation, path, content } of planned) {
|
|
4770
4785
|
if (operation.kind === "add") {
|
|
4771
|
-
|
|
4786
|
+
await createWorkspaceFile({
|
|
4772
4787
|
root: input.root,
|
|
4773
4788
|
filePath: operation.filePath,
|
|
4774
4789
|
content: operation.content
|
|
4775
4790
|
});
|
|
4776
|
-
paths.push(
|
|
4791
|
+
paths.push(path);
|
|
4777
4792
|
continue;
|
|
4778
4793
|
}
|
|
4779
4794
|
if (operation.kind === "delete") {
|
|
4780
|
-
|
|
4795
|
+
await deleteWorkspaceFile({
|
|
4781
4796
|
root: input.root,
|
|
4782
4797
|
filePath: operation.filePath
|
|
4783
4798
|
});
|
|
4784
|
-
paths.push(
|
|
4799
|
+
paths.push(path);
|
|
4785
4800
|
continue;
|
|
4786
4801
|
}
|
|
4787
|
-
|
|
4788
|
-
root: input.root,
|
|
4789
|
-
filePath: operation.filePath
|
|
4790
|
-
});
|
|
4791
|
-
const result = await writeWorkspaceFile({
|
|
4802
|
+
await writeWorkspaceFile({
|
|
4792
4803
|
root: input.root,
|
|
4793
4804
|
filePath: operation.filePath,
|
|
4794
|
-
content:
|
|
4805
|
+
content: content ?? ""
|
|
4795
4806
|
});
|
|
4796
|
-
paths.push(
|
|
4807
|
+
paths.push(path);
|
|
4797
4808
|
}
|
|
4798
4809
|
return { paths };
|
|
4799
4810
|
}
|
|
4811
|
+
async function planOperations(root, operations) {
|
|
4812
|
+
const planned = [];
|
|
4813
|
+
const paths = /* @__PURE__ */ new Set();
|
|
4814
|
+
for (const operation of operations) {
|
|
4815
|
+
if (operation.kind === "add") {
|
|
4816
|
+
const result = await prepareWorkspaceFileCreation({
|
|
4817
|
+
root,
|
|
4818
|
+
filePath: operation.filePath,
|
|
4819
|
+
content: operation.content
|
|
4820
|
+
});
|
|
4821
|
+
assertUniquePath(paths, result.path);
|
|
4822
|
+
planned.push({
|
|
4823
|
+
operation,
|
|
4824
|
+
path: result.path
|
|
4825
|
+
});
|
|
4826
|
+
continue;
|
|
4827
|
+
}
|
|
4828
|
+
const current = await readWorkspaceFile({
|
|
4829
|
+
root,
|
|
4830
|
+
filePath: operation.filePath
|
|
4831
|
+
});
|
|
4832
|
+
assertUniquePath(paths, current.path);
|
|
4833
|
+
planned.push({
|
|
4834
|
+
operation,
|
|
4835
|
+
path: current.path,
|
|
4836
|
+
content: operation.kind === "update" ? applyUpdateHunks(current.content, operation.hunks) : void 0
|
|
4837
|
+
});
|
|
4838
|
+
}
|
|
4839
|
+
return planned;
|
|
4840
|
+
}
|
|
4841
|
+
function assertUniquePath(paths, path) {
|
|
4842
|
+
if (paths.has(path)) invalidPatch(`Patch contains multiple operations for ${path}.`);
|
|
4843
|
+
paths.add(path);
|
|
4844
|
+
}
|
|
4800
4845
|
function parsePatch(patch) {
|
|
4801
4846
|
const lines = patch.replace(/\r\n|\r/g, "\n").split("\n");
|
|
4802
4847
|
while (lines.at(-1) === "") lines.pop();
|
|
@@ -4811,8 +4856,12 @@ function parsePatch(patch) {
|
|
|
4811
4856
|
index += 1;
|
|
4812
4857
|
if (addPath !== void 0) {
|
|
4813
4858
|
const contentLines = [];
|
|
4814
|
-
while (index < lines.length - 1 && !lines[index]
|
|
4859
|
+
while (index < lines.length - 1 && !isOperationHeader(lines[index])) {
|
|
4815
4860
|
const line = lines[index];
|
|
4861
|
+
if (line === "*** End of File") {
|
|
4862
|
+
index += 1;
|
|
4863
|
+
break;
|
|
4864
|
+
}
|
|
4816
4865
|
if (!line?.startsWith("+")) invalidPatch("Add File lines must start with `+`.");
|
|
4817
4866
|
contentLines.push(line.slice(1));
|
|
4818
4867
|
index += 1;
|
|
@@ -4835,8 +4884,12 @@ function parsePatch(patch) {
|
|
|
4835
4884
|
const hunks = [];
|
|
4836
4885
|
let oldLines;
|
|
4837
4886
|
let newLines;
|
|
4838
|
-
while (index < lines.length - 1 && !lines[index]
|
|
4887
|
+
while (index < lines.length - 1 && !isOperationHeader(lines[index])) {
|
|
4839
4888
|
const line = lines[index];
|
|
4889
|
+
if (line === "*** End of File") {
|
|
4890
|
+
index += 1;
|
|
4891
|
+
break;
|
|
4892
|
+
}
|
|
4840
4893
|
if (line?.startsWith("@@")) {
|
|
4841
4894
|
if (oldLines !== void 0 && newLines !== void 0) hunks.push(validHunk(oldLines, newLines));
|
|
4842
4895
|
oldLines = [];
|
|
@@ -4866,6 +4919,9 @@ function parsePatch(patch) {
|
|
|
4866
4919
|
if (operations.length === 0) invalidPatch("Patch must contain at least one file operation.");
|
|
4867
4920
|
return operations;
|
|
4868
4921
|
}
|
|
4922
|
+
function isOperationHeader(line) {
|
|
4923
|
+
return /^\*\*\* (?:Add|Update|Delete) File: /.test(line ?? "");
|
|
4924
|
+
}
|
|
4869
4925
|
function validHunk(oldLines, newLines) {
|
|
4870
4926
|
if (oldLines.length === 0) invalidPatch("Update hunks require old or context lines for deterministic placement.");
|
|
4871
4927
|
return {
|
|
@@ -4906,7 +4962,7 @@ function invalidPatch(message) {
|
|
|
4906
4962
|
//#endregion
|
|
4907
4963
|
//#region src/version.ts
|
|
4908
4964
|
/** Current independent codexslimedit package version. */
|
|
4909
|
-
var CODEX_SLIM_EDIT_VERSION = "0.7.4-dev.
|
|
4965
|
+
var CODEX_SLIM_EDIT_VERSION = "0.7.4-dev.29702567006.1";
|
|
4910
4966
|
/** Returns whether command-line arguments request the package version. */
|
|
4911
4967
|
function isVersionRequest(args) {
|
|
4912
4968
|
return args.includes("--version");
|