Skip to content

fix(plugin): codexRemove drops header-only bili block with no trailing newline - #187

Merged
ranxianglei merged 1 commit into
masterfrom
fix/codex-remove-header-only
Aug 22, 2026
Merged

fix(plugin): codexRemove drops header-only bili block with no trailing newline#187
ranxianglei merged 1 commit into
masterfrom
fix/codex-remove-header-only

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

Bug

codexRemove() in src/plugin-install.ts leaves the [mcp_servers.bili] header line behind when the table is header-only (no keys) and sits as the final line with no trailing newline.

Root cause:

const nextTable = after.slice(after.indexOf("\n") + 1).search(/^[ \t]*\[/m);
const end = nextTable >= 0 ? start + after.indexOf("\n") + 1 + nextTable : text.length;

When after.indexOf("\n") is -1 (no newline in the block), after.slice(0) still includes the header itself, so the next-table search matches the header at index 0. end collapses to start and the header line survives the removal.

Reproduced: a config ending in ...[mcp_servers.bili] (no trailing \n) still contains mcp_servers.bili after pluginRemove("codex").

Fix

Compute firstNewline once and treat a missing newline as "block runs to EOF":

const firstNewline = after.indexOf("\n");
const nextTable = firstNewline < 0 ? -1 : after.slice(firstNewline + 1).search(/^[ \t]*\[/m);
const end = nextTable >= 0 ? start + firstNewline + 1 + nextTable : text.length;

Notes

  • Very low real-world likelihood: codexInstall always writes command/args/env keys, so a header-only block only arises from manual editing, and it additionally requires a missing trailing newline. Fixing it anyway since the removal path should be total.
  • Adds a regression test in tests/plugin-agent.test.ts covering the header-only, no-trailing-newline case. Verified the test fails on the old code (header survives) and passes with the fix.
  • Full suite: 512 pass / 0 fail.

…g newline

When the [mcp_servers.bili] table was header-only (no keys) and sat as the
final line with no trailing newline, after.indexOf('\n') was -1, so the
next-table search ran over a slice that still included the header itself and
matched it at index 0. end collapsed to start and the header line survived
the removal.

Compute firstNewline once and treat a missing newline as 'block runs to EOF'
so end = text.length. Adds a regression test covering the header-only,
no-trailing-newline case.
@ranxianglei
ranxianglei merged commit b581f34 into master Aug 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant