From e619b80e1654ad08b9db27eb2d2f3b05cca5d6ca Mon Sep 17 00:00:00 2001 From: Rayan-and-beyond <263488867+Rayan-and-beyond@users.noreply.github.com> Date: Tue, 15 Sep 2026 20:06:57 +0000 Subject: [PATCH 1/2] fix: repair orphan managed end markers --- CHANGELOG.md | 6 ++++++ package.json | 2 +- src/ignore.js | 4 ++++ test/ctxtrim.test.js | 8 ++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9cb818..b993593 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project are documented here, following [Keep a Changelog](https://keepachangelog.com/) and semantic versioning. +## [0.1.10] - 2026-09-15 + +### Fixed + +- Repair orphan managed-block end markers instead of duplicating them. + ## [0.1.9] - 2026-09-12 ### Fixed diff --git a/package.json b/package.json index 3f9e1ad..7bea5cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ctxtrim", - "version": "0.1.9", + "version": "0.1.10", "description": "Trim what bloats your AI coding context. Scan a repo, find the high-cost/low-value files ballooning your Claude Code / Cursor / Codex context, and write ignore files to cut token cost. Zero dependencies.", "type": "module", "bin": { diff --git a/src/ignore.js b/src/ignore.js index 5d3b89a..a266e50 100644 --- a/src/ignore.js +++ b/src/ignore.js @@ -30,6 +30,10 @@ export function merge(existing, patterns) { const base = existing.slice(0, startIndex).trim(); return (base ? base + "\n\n" : "") + b + "\n"; } + if (endIndex !== -1) { + const base = (existing.slice(0, endIndex) + existing.slice(endIndex + END.length)).trim(); + return (base ? base + "\n\n" : "") + b + "\n"; + } const base = existing.trim(); return (base ? base + "\n\n" : "") + b + "\n"; } diff --git a/test/ctxtrim.test.js b/test/ctxtrim.test.js index da50d9f..9e432ca 100644 --- a/test/ctxtrim.test.js +++ b/test/ctxtrim.test.js @@ -147,6 +147,14 @@ test("ignore merge repairs a managed block with no end marker", () => { assert.equal((repaired.match(/ctxtrim \(managed\)/g) || []).length, 2); }); +test("ignore merge repairs an orphan end marker", () => { + const existing = "# my own rule\n# <<< ctxtrim (managed) <<<\n"; + const repaired = merge(existing, ["dist/"]); + assert.equal((repaired.match(/ctxtrim \(managed\)/g) || []).length, 2); + assert.ok(repaired.includes("# my own rule")); + assert.ok(repaired.includes(block(["dist/"]))); +}); + test("clean repo (only source) reports nothing to trim", () => { // scanning the src subdir alone = only source const s = scanRepo(join(repo, "src")); From ff3e1b563e754a3b0e1e592bb285ba82d33337c0 Mon Sep 17 00:00:00 2001 From: Rayan-and-beyond <263488867+Rayan-and-beyond@users.noreply.github.com> Date: Tue, 15 Sep 2026 20:07:25 +0000 Subject: [PATCH 2/2] fix: detect orphan end marker from start --- src/ignore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ignore.js b/src/ignore.js index a266e50..9d19e8c 100644 --- a/src/ignore.js +++ b/src/ignore.js @@ -22,7 +22,7 @@ export function block(patterns) { export function merge(existing, patterns) { const b = block(patterns); const startIndex = existing.indexOf(START); - const endIndex = existing.indexOf(END, startIndex + START.length); + const endIndex = existing.indexOf(END, startIndex === -1 ? 0 : startIndex + START.length); if (startIndex !== -1 && endIndex !== -1) { return existing.replace(new RegExp(escape(START) + "[\\s\\S]*?" + escape(END)), b).trimEnd() + "\n"; }