encoding-aware-fs 0.1.2 → 0.1.4
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.js +146 -17
- package/dist/server.js +35 -3
- package/package.json +1 -1
- package/skills/claude-code/RULE.md +3 -0
- package/skills/opencode/RULE.md +3 -0
- package/.encoding-converter.json +0 -5
- package/.mcp.json +0 -15
- package/opencode.jsonc +0 -15
package/dist/index.js
CHANGED
|
@@ -25813,6 +25813,36 @@ var init_read_file = __esm({
|
|
|
25813
25813
|
}
|
|
25814
25814
|
});
|
|
25815
25815
|
|
|
25816
|
+
// src/encoding/line-endings.ts
|
|
25817
|
+
function detectLineEnding(buffer) {
|
|
25818
|
+
let crlf = 0;
|
|
25819
|
+
let lf = 0;
|
|
25820
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
25821
|
+
if (buffer[i] === 13 && i + 1 < buffer.length && buffer[i + 1] === 10) {
|
|
25822
|
+
crlf++;
|
|
25823
|
+
i++;
|
|
25824
|
+
} else if (buffer[i] === 10) {
|
|
25825
|
+
lf++;
|
|
25826
|
+
}
|
|
25827
|
+
}
|
|
25828
|
+
if (crlf === 0 && lf === 0) {
|
|
25829
|
+
return process.platform === "win32" ? "CRLF" : "LF";
|
|
25830
|
+
}
|
|
25831
|
+
return crlf >= lf ? "CRLF" : "LF";
|
|
25832
|
+
}
|
|
25833
|
+
function restoreLineEndings(text, style) {
|
|
25834
|
+
const normalized = text.replace(/\r\n/g, "\n");
|
|
25835
|
+
if (style === "CRLF") {
|
|
25836
|
+
return normalized.replace(/\n/g, "\r\n");
|
|
25837
|
+
}
|
|
25838
|
+
return normalized;
|
|
25839
|
+
}
|
|
25840
|
+
var init_line_endings = __esm({
|
|
25841
|
+
"src/encoding/line-endings.ts"() {
|
|
25842
|
+
"use strict";
|
|
25843
|
+
}
|
|
25844
|
+
});
|
|
25845
|
+
|
|
25816
25846
|
// src/tools/write-file.ts
|
|
25817
25847
|
function registerWriteFile(server2, config3, allowedDirectories) {
|
|
25818
25848
|
server2.registerTool(
|
|
@@ -25829,8 +25859,10 @@ function registerWriteFile(server2, config3, allowedDirectories) {
|
|
|
25829
25859
|
async (args) => {
|
|
25830
25860
|
const validPath = await validatePath(args.path, allowedDirectories);
|
|
25831
25861
|
let targetEncoding = config3.sourceEncoding || "GB18030";
|
|
25862
|
+
let lineEndingStyle = process.platform === "win32" ? "CRLF" : "LF";
|
|
25832
25863
|
try {
|
|
25833
|
-
await fs5.
|
|
25864
|
+
const existingBuffer = await fs5.readFile(validPath);
|
|
25865
|
+
lineEndingStyle = detectLineEnding(existingBuffer);
|
|
25834
25866
|
const detection = await detectEncoding(validPath);
|
|
25835
25867
|
if (detection.encoding && isUtf8Encoding(detection.encoding)) {
|
|
25836
25868
|
targetEncoding = "UTF-8";
|
|
@@ -25839,7 +25871,8 @@ function registerWriteFile(server2, config3, allowedDirectories) {
|
|
|
25839
25871
|
}
|
|
25840
25872
|
} catch {
|
|
25841
25873
|
}
|
|
25842
|
-
const
|
|
25874
|
+
const finalContent = restoreLineEndings(args.content, lineEndingStyle);
|
|
25875
|
+
const encoded = encodeFromUtf8(finalContent, targetEncoding);
|
|
25843
25876
|
try {
|
|
25844
25877
|
await fs5.writeFile(validPath, encoded, { flag: "wx" });
|
|
25845
25878
|
} catch (error2) {
|
|
@@ -25875,6 +25908,7 @@ var init_write_file = __esm({
|
|
|
25875
25908
|
init_path_validation();
|
|
25876
25909
|
init_detector();
|
|
25877
25910
|
init_converter();
|
|
25911
|
+
init_line_endings();
|
|
25878
25912
|
}
|
|
25879
25913
|
});
|
|
25880
25914
|
|
|
@@ -26400,6 +26434,7 @@ function registerEditFile(server2, config3, allowedDirectories) {
|
|
|
26400
26434
|
async (args) => {
|
|
26401
26435
|
const validPath = await validatePath(args.path, allowedDirectories);
|
|
26402
26436
|
const buffer = await fs6.readFile(validPath);
|
|
26437
|
+
const originalLineEnding = detectLineEnding(buffer);
|
|
26403
26438
|
const detection = await detectEncoding(validPath);
|
|
26404
26439
|
let originalEncoding = "UTF-8";
|
|
26405
26440
|
if (detection.encoding && detection.confidence >= config3.confidenceThreshold && isGBEncoding(detection.encoding)) {
|
|
@@ -26411,7 +26446,8 @@ function registerEditFile(server2, config3, allowedDirectories) {
|
|
|
26411
26446
|
const modifiedContent = applyEditsToContent(utf8Content, args.edits);
|
|
26412
26447
|
const diff = createUnifiedDiff(utf8Content, modifiedContent, args.path);
|
|
26413
26448
|
if (!args.dryRun) {
|
|
26414
|
-
const
|
|
26449
|
+
const finalContent = restoreLineEndings(modifiedContent, originalLineEnding);
|
|
26450
|
+
const encoded = isGBEncoding(originalEncoding) ? encodeFromUtf8(finalContent, originalEncoding) : Buffer.from(finalContent, "utf-8");
|
|
26415
26451
|
const tempPath = `${validPath}.${(0, import_crypto2.randomBytes)(16).toString("hex")}.tmp`;
|
|
26416
26452
|
try {
|
|
26417
26453
|
await fs6.writeFile(tempPath, encoded);
|
|
@@ -26441,6 +26477,7 @@ var init_edit_file = __esm({
|
|
|
26441
26477
|
init_path_validation();
|
|
26442
26478
|
init_detector();
|
|
26443
26479
|
init_converter();
|
|
26480
|
+
init_line_endings();
|
|
26444
26481
|
}
|
|
26445
26482
|
});
|
|
26446
26483
|
|
|
@@ -26539,6 +26576,10 @@ var init_config_io = __esm({
|
|
|
26539
26576
|
// src/uninstaller.ts
|
|
26540
26577
|
var uninstaller_exports = {};
|
|
26541
26578
|
__export(uninstaller_exports, {
|
|
26579
|
+
detectInstalled: () => detectInstalled,
|
|
26580
|
+
isOpenCodeJsoncEmpty: () => isOpenCodeJsoncEmpty,
|
|
26581
|
+
removeOpenCodeConfig: () => removeOpenCodeConfig,
|
|
26582
|
+
removeRuleFile: () => removeRuleFile,
|
|
26542
26583
|
runUninstaller: () => runUninstaller
|
|
26543
26584
|
});
|
|
26544
26585
|
async function fileExists(filePath) {
|
|
@@ -26561,8 +26602,18 @@ async function removeDirIfEmpty(dirPath) {
|
|
|
26561
26602
|
function isEmptyMcpJson(data) {
|
|
26562
26603
|
return data && typeof data === "object" && data.mcpServers && typeof data.mcpServers === "object" && Object.keys(data.mcpServers).length === 0 && Object.keys(data).length === 1;
|
|
26563
26604
|
}
|
|
26564
|
-
function
|
|
26565
|
-
|
|
26605
|
+
function isOpenCodeJsoncEmpty(data) {
|
|
26606
|
+
if (!data || typeof data !== "object")
|
|
26607
|
+
return false;
|
|
26608
|
+
const keys = Object.keys(data);
|
|
26609
|
+
return keys.every((key) => {
|
|
26610
|
+
const val = data[key];
|
|
26611
|
+
if (Array.isArray(val))
|
|
26612
|
+
return val.length === 0;
|
|
26613
|
+
if (typeof val === "object" && val !== null)
|
|
26614
|
+
return Object.keys(val).length === 0;
|
|
26615
|
+
return false;
|
|
26616
|
+
});
|
|
26566
26617
|
}
|
|
26567
26618
|
async function detectInstalled(cwd) {
|
|
26568
26619
|
const found = [];
|
|
@@ -26570,24 +26621,31 @@ async function detectInstalled(cwd) {
|
|
|
26570
26621
|
const mcpJson = await readJsonFile(mcpJsonPath);
|
|
26571
26622
|
const claudeSkillPath = path5.join(cwd, ".claude", "skills", "encoding-aware-fs", "SKILL.md");
|
|
26572
26623
|
const hasClaudeSkill = await fileExists(claudeSkillPath);
|
|
26573
|
-
|
|
26624
|
+
const claudeRulePath = path5.join(cwd, ".claude", "rules", "encoding-aware-fs.md");
|
|
26625
|
+
const hasClaudeRule = await fileExists(claudeRulePath);
|
|
26626
|
+
if (mcpJson?.mcpServers?.["encoding-aware-fs"] || hasClaudeSkill || hasClaudeRule) {
|
|
26574
26627
|
found.push({
|
|
26575
26628
|
type: "claude-code",
|
|
26576
26629
|
name: "Claude Code (.mcp.json)",
|
|
26577
26630
|
configPath: mcpJsonPath,
|
|
26578
|
-
skillPath: hasClaudeSkill ? claudeSkillPath : void 0
|
|
26631
|
+
skillPath: hasClaudeSkill ? claudeSkillPath : void 0,
|
|
26632
|
+
rulePath: hasClaudeRule ? claudeRulePath : void 0
|
|
26579
26633
|
});
|
|
26580
26634
|
}
|
|
26581
26635
|
const openCodePath = path5.join(cwd, "opencode.jsonc");
|
|
26582
26636
|
const openCode = await readJsonFile(openCodePath);
|
|
26583
26637
|
const openCodeSkillPath = path5.join(cwd, ".agents", "skills", "encoding-aware-fs", "SKILL.md");
|
|
26584
26638
|
const hasOpenCodeSkill = await fileExists(openCodeSkillPath);
|
|
26585
|
-
|
|
26639
|
+
const openCodeRulePath = path5.join(cwd, ".agents", "rules", "encoding-aware-fs.md");
|
|
26640
|
+
const hasOpenCodeRule = await fileExists(openCodeRulePath);
|
|
26641
|
+
const hasOpenCodeInstructions = Array.isArray(openCode?.instructions) && openCode.instructions.includes(".agents/rules/encoding-aware-fs.md");
|
|
26642
|
+
if (openCode?.mcp?.["encoding-aware-fs"] || hasOpenCodeSkill || hasOpenCodeRule || hasOpenCodeInstructions) {
|
|
26586
26643
|
found.push({
|
|
26587
26644
|
type: "opencode",
|
|
26588
26645
|
name: "OpenCode (opencode.jsonc)",
|
|
26589
26646
|
configPath: openCodePath,
|
|
26590
|
-
skillPath: hasOpenCodeSkill ? openCodeSkillPath : void 0
|
|
26647
|
+
skillPath: hasOpenCodeSkill ? openCodeSkillPath : void 0,
|
|
26648
|
+
rulePath: hasOpenCodeRule ? openCodeRulePath : void 0
|
|
26591
26649
|
});
|
|
26592
26650
|
}
|
|
26593
26651
|
return found;
|
|
@@ -26605,17 +26663,28 @@ async function removeClaudeCodeEntry(configPath) {
|
|
|
26605
26663
|
console.log(` \u2713 Removed encoding-aware-fs entry from ${configPath}`);
|
|
26606
26664
|
}
|
|
26607
26665
|
}
|
|
26608
|
-
async function
|
|
26666
|
+
async function removeOpenCodeConfig(configPath) {
|
|
26609
26667
|
const data = await readJsonFile(configPath);
|
|
26610
|
-
if (!data
|
|
26668
|
+
if (!data)
|
|
26611
26669
|
return;
|
|
26612
|
-
|
|
26613
|
-
|
|
26670
|
+
if (data.mcp?.["encoding-aware-fs"]) {
|
|
26671
|
+
delete data.mcp["encoding-aware-fs"];
|
|
26672
|
+
if (Object.keys(data.mcp).length === 0)
|
|
26673
|
+
delete data.mcp;
|
|
26674
|
+
}
|
|
26675
|
+
if (Array.isArray(data.instructions)) {
|
|
26676
|
+
data.instructions = data.instructions.filter(
|
|
26677
|
+
(i) => i !== ".agents/rules/encoding-aware-fs.md"
|
|
26678
|
+
);
|
|
26679
|
+
if (data.instructions.length === 0)
|
|
26680
|
+
delete data.instructions;
|
|
26681
|
+
}
|
|
26682
|
+
if (isOpenCodeJsoncEmpty(data) || Object.keys(data).length === 0) {
|
|
26614
26683
|
await fs9.unlink(configPath);
|
|
26615
26684
|
console.log(` \u2713 Removed ${configPath} (was empty after cleanup)`);
|
|
26616
26685
|
} else {
|
|
26617
26686
|
await writeJsonFile(configPath, data);
|
|
26618
|
-
console.log(` \u2713 Removed encoding-aware-fs
|
|
26687
|
+
console.log(` \u2713 Removed encoding-aware-fs entries from ${configPath}`);
|
|
26619
26688
|
}
|
|
26620
26689
|
}
|
|
26621
26690
|
async function removeSkillFiles(platform) {
|
|
@@ -26636,6 +26705,22 @@ async function removeSkillFiles(platform) {
|
|
|
26636
26705
|
const parentDir = path5.dirname(skillsDir);
|
|
26637
26706
|
await removeDirIfEmpty(parentDir);
|
|
26638
26707
|
}
|
|
26708
|
+
async function removeRuleFile(platform) {
|
|
26709
|
+
if (!platform.rulePath)
|
|
26710
|
+
return;
|
|
26711
|
+
try {
|
|
26712
|
+
await fs9.unlink(platform.rulePath);
|
|
26713
|
+
console.log(` \u2713 Removed ${platform.rulePath}`);
|
|
26714
|
+
} catch (err) {
|
|
26715
|
+
if (err.code !== "ENOENT")
|
|
26716
|
+
throw err;
|
|
26717
|
+
return;
|
|
26718
|
+
}
|
|
26719
|
+
const ruleDir = path5.dirname(platform.rulePath);
|
|
26720
|
+
await removeDirIfEmpty(ruleDir);
|
|
26721
|
+
const parentDir = path5.dirname(ruleDir);
|
|
26722
|
+
await removeDirIfEmpty(parentDir);
|
|
26723
|
+
}
|
|
26639
26724
|
async function runUninstaller() {
|
|
26640
26725
|
const cwd = process.cwd();
|
|
26641
26726
|
console.log();
|
|
@@ -26655,10 +26740,13 @@ async function runUninstaller() {
|
|
|
26655
26740
|
if (p.skillPath) {
|
|
26656
26741
|
console.log(` + Skill file: ${p.skillPath}`);
|
|
26657
26742
|
}
|
|
26743
|
+
if (p.rulePath) {
|
|
26744
|
+
console.log(` + Rule file: ${p.rulePath}`);
|
|
26745
|
+
}
|
|
26658
26746
|
}
|
|
26659
26747
|
console.log();
|
|
26660
26748
|
const proceed = await (0, import_prompts.confirm)({
|
|
26661
|
-
message: "Remove encoding-aware-fs MCP config entries and
|
|
26749
|
+
message: "Remove encoding-aware-fs MCP config entries, skill files, and rule files?",
|
|
26662
26750
|
default: false
|
|
26663
26751
|
});
|
|
26664
26752
|
if (!proceed) {
|
|
@@ -26670,12 +26758,15 @@ async function runUninstaller() {
|
|
|
26670
26758
|
if (p.type === "claude-code") {
|
|
26671
26759
|
await removeClaudeCodeEntry(p.configPath);
|
|
26672
26760
|
} else if (p.type === "opencode") {
|
|
26673
|
-
await
|
|
26761
|
+
await removeOpenCodeConfig(p.configPath);
|
|
26674
26762
|
}
|
|
26675
26763
|
}
|
|
26676
26764
|
for (const p of installed) {
|
|
26677
26765
|
await removeSkillFiles(p);
|
|
26678
26766
|
}
|
|
26767
|
+
for (const p of installed) {
|
|
26768
|
+
await removeRuleFile(p);
|
|
26769
|
+
}
|
|
26679
26770
|
const encodingConfigPath = path5.join(cwd, ".encoding-converter.json");
|
|
26680
26771
|
try {
|
|
26681
26772
|
await fs9.access(encodingConfigPath);
|
|
@@ -26700,6 +26791,8 @@ var init_uninstaller = __esm({
|
|
|
26700
26791
|
// src/installer.ts
|
|
26701
26792
|
var installer_exports = {};
|
|
26702
26793
|
__export(installer_exports, {
|
|
26794
|
+
addOpenCodeInstructions: () => addOpenCodeInstructions,
|
|
26795
|
+
copyRuleFile: () => copyRuleFile,
|
|
26703
26796
|
runInstaller: () => runInstaller
|
|
26704
26797
|
});
|
|
26705
26798
|
function checkNodeVersion() {
|
|
@@ -26765,6 +26858,33 @@ async function copySkillFile(cwd, platform) {
|
|
|
26765
26858
|
await fs10.copyFile(sourcePath, targetPath);
|
|
26766
26859
|
console.log(` \u2713 Installed skill \u2192 ${targetPath}`);
|
|
26767
26860
|
}
|
|
26861
|
+
async function copyRuleFile(cwd, platform) {
|
|
26862
|
+
const sourcePath = path6.join(path6.resolve(__dirname, ".."), "skills", platform, "RULE.md");
|
|
26863
|
+
try {
|
|
26864
|
+
await fs10.access(sourcePath);
|
|
26865
|
+
} catch {
|
|
26866
|
+
console.log(` \u26A0 Rule file template not found, skipping`);
|
|
26867
|
+
return;
|
|
26868
|
+
}
|
|
26869
|
+
const ruleDir = platform === "claude-code" ? path6.join(cwd, ".claude", "rules") : path6.join(cwd, ".agents", "rules");
|
|
26870
|
+
const rulePath = path6.join(ruleDir, "encoding-aware-fs.md");
|
|
26871
|
+
await fs10.mkdir(ruleDir, { recursive: true });
|
|
26872
|
+
await fs10.copyFile(sourcePath, rulePath);
|
|
26873
|
+
console.log(` \u2713 Installed rule \u2192 ${rulePath}`);
|
|
26874
|
+
}
|
|
26875
|
+
async function addOpenCodeInstructions(cwd) {
|
|
26876
|
+
const configPath = path6.join(cwd, "opencode.jsonc");
|
|
26877
|
+
const existing = await readJsonFile(configPath);
|
|
26878
|
+
const merged = existing ?? {};
|
|
26879
|
+
if (!merged.instructions) {
|
|
26880
|
+
merged.instructions = [];
|
|
26881
|
+
}
|
|
26882
|
+
const rulePath = ".agents/rules/encoding-aware-fs.md";
|
|
26883
|
+
if (!merged.instructions.includes(rulePath)) {
|
|
26884
|
+
merged.instructions.push(rulePath);
|
|
26885
|
+
}
|
|
26886
|
+
await writeJsonFile(configPath, merged);
|
|
26887
|
+
}
|
|
26768
26888
|
async function ensureEncodingConfig(cwd) {
|
|
26769
26889
|
const configPath = path6.join(cwd, ".encoding-converter.json");
|
|
26770
26890
|
try {
|
|
@@ -26828,6 +26948,15 @@ async function runInstaller() {
|
|
|
26828
26948
|
for (const platform of platforms) {
|
|
26829
26949
|
await copySkillFile(cwd, platform);
|
|
26830
26950
|
}
|
|
26951
|
+
console.log();
|
|
26952
|
+
console.log("Rule files:");
|
|
26953
|
+
for (const platform of platforms) {
|
|
26954
|
+
await copyRuleFile(cwd, platform);
|
|
26955
|
+
}
|
|
26956
|
+
if (platforms.includes("opencode")) {
|
|
26957
|
+
await addOpenCodeInstructions(cwd);
|
|
26958
|
+
console.log(" \u2713 Added rule to opencode.jsonc instructions");
|
|
26959
|
+
}
|
|
26831
26960
|
await ensureEncodingConfig(cwd);
|
|
26832
26961
|
console.log();
|
|
26833
26962
|
console.log("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
|
|
@@ -26840,7 +26969,7 @@ async function runInstaller() {
|
|
|
26840
26969
|
console.log("\u2502 OpenCode: restart opencode \u2502");
|
|
26841
26970
|
}
|
|
26842
26971
|
console.log("\u2502 \u2502");
|
|
26843
|
-
console.log("\u2502 Skill files installed for AI
|
|
26972
|
+
console.log("\u2502 Rule + Skill files installed for AI. \u2502");
|
|
26844
26973
|
console.log("\u2502 The MCP server will start automatically \u2502");
|
|
26845
26974
|
console.log("\u2502 when your AI tool connects. \u2502");
|
|
26846
26975
|
console.log("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
|
package/dist/server.js
CHANGED
|
@@ -25050,6 +25050,33 @@ function registerReadFile(server2, config3, allowedDirectories) {
|
|
|
25050
25050
|
// src/tools/write-file.ts
|
|
25051
25051
|
var fs5 = __toESM(require("fs/promises"));
|
|
25052
25052
|
var import_crypto = require("crypto");
|
|
25053
|
+
|
|
25054
|
+
// src/encoding/line-endings.ts
|
|
25055
|
+
function detectLineEnding(buffer) {
|
|
25056
|
+
let crlf = 0;
|
|
25057
|
+
let lf = 0;
|
|
25058
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
25059
|
+
if (buffer[i] === 13 && i + 1 < buffer.length && buffer[i + 1] === 10) {
|
|
25060
|
+
crlf++;
|
|
25061
|
+
i++;
|
|
25062
|
+
} else if (buffer[i] === 10) {
|
|
25063
|
+
lf++;
|
|
25064
|
+
}
|
|
25065
|
+
}
|
|
25066
|
+
if (crlf === 0 && lf === 0) {
|
|
25067
|
+
return process.platform === "win32" ? "CRLF" : "LF";
|
|
25068
|
+
}
|
|
25069
|
+
return crlf >= lf ? "CRLF" : "LF";
|
|
25070
|
+
}
|
|
25071
|
+
function restoreLineEndings(text, style) {
|
|
25072
|
+
const normalized = text.replace(/\r\n/g, "\n");
|
|
25073
|
+
if (style === "CRLF") {
|
|
25074
|
+
return normalized.replace(/\n/g, "\r\n");
|
|
25075
|
+
}
|
|
25076
|
+
return normalized;
|
|
25077
|
+
}
|
|
25078
|
+
|
|
25079
|
+
// src/tools/write-file.ts
|
|
25053
25080
|
function registerWriteFile(server2, config3, allowedDirectories) {
|
|
25054
25081
|
server2.registerTool(
|
|
25055
25082
|
"write_file",
|
|
@@ -25065,8 +25092,10 @@ function registerWriteFile(server2, config3, allowedDirectories) {
|
|
|
25065
25092
|
async (args) => {
|
|
25066
25093
|
const validPath = await validatePath(args.path, allowedDirectories);
|
|
25067
25094
|
let targetEncoding = config3.sourceEncoding || "GB18030";
|
|
25095
|
+
let lineEndingStyle = process.platform === "win32" ? "CRLF" : "LF";
|
|
25068
25096
|
try {
|
|
25069
|
-
await fs5.
|
|
25097
|
+
const existingBuffer = await fs5.readFile(validPath);
|
|
25098
|
+
lineEndingStyle = detectLineEnding(existingBuffer);
|
|
25070
25099
|
const detection = await detectEncoding(validPath);
|
|
25071
25100
|
if (detection.encoding && isUtf8Encoding(detection.encoding)) {
|
|
25072
25101
|
targetEncoding = "UTF-8";
|
|
@@ -25075,7 +25104,8 @@ function registerWriteFile(server2, config3, allowedDirectories) {
|
|
|
25075
25104
|
}
|
|
25076
25105
|
} catch {
|
|
25077
25106
|
}
|
|
25078
|
-
const
|
|
25107
|
+
const finalContent = restoreLineEndings(args.content, lineEndingStyle);
|
|
25108
|
+
const encoded = encodeFromUtf8(finalContent, targetEncoding);
|
|
25079
25109
|
try {
|
|
25080
25110
|
await fs5.writeFile(validPath, encoded, { flag: "wx" });
|
|
25081
25111
|
} catch (error2) {
|
|
@@ -25604,6 +25634,7 @@ function registerEditFile(server2, config3, allowedDirectories) {
|
|
|
25604
25634
|
async (args) => {
|
|
25605
25635
|
const validPath = await validatePath(args.path, allowedDirectories);
|
|
25606
25636
|
const buffer = await fs6.readFile(validPath);
|
|
25637
|
+
const originalLineEnding = detectLineEnding(buffer);
|
|
25607
25638
|
const detection = await detectEncoding(validPath);
|
|
25608
25639
|
let originalEncoding = "UTF-8";
|
|
25609
25640
|
if (detection.encoding && detection.confidence >= config3.confidenceThreshold && isGBEncoding(detection.encoding)) {
|
|
@@ -25615,7 +25646,8 @@ function registerEditFile(server2, config3, allowedDirectories) {
|
|
|
25615
25646
|
const modifiedContent = applyEditsToContent(utf8Content, args.edits);
|
|
25616
25647
|
const diff = createUnifiedDiff(utf8Content, modifiedContent, args.path);
|
|
25617
25648
|
if (!args.dryRun) {
|
|
25618
|
-
const
|
|
25649
|
+
const finalContent = restoreLineEndings(modifiedContent, originalLineEnding);
|
|
25650
|
+
const encoded = isGBEncoding(originalEncoding) ? encodeFromUtf8(finalContent, originalEncoding) : Buffer.from(finalContent, "utf-8");
|
|
25619
25651
|
const tempPath = `${validPath}.${(0, import_crypto2.randomBytes)(16).toString("hex")}.tmp`;
|
|
25620
25652
|
try {
|
|
25621
25653
|
await fs6.writeFile(tempPath, encoded);
|
package/package.json
CHANGED
package/.encoding-converter.json
DELETED
package/.mcp.json
DELETED