Skip to content

fix: replace legacy unmarked OpenWiki section instead of appending a duplicate - #914

Merged
Colin Francis (colifran) merged 4 commits into
langchain-ai:mainfrom
drakeo338:claude/fix-361-legacy-openwiki-section
Sep 21, 2026
Merged

Colin Francis (colifran) merged 4 commits into
langchain-ai:mainfrom
drakeo338:claude/fix-361-legacy-openwiki-section

Conversation

@drakeo338

Copy link
Copy Markdown
Contributor

Fixes #361.

OpenWiki 0.0.x had the agent write its own ## OpenWiki section into AGENTS.md and CLAUDE.md, before the managed markers existed. Code mode sees no markers in a file like that and appends the managed block underneath, and after that it only ever refreshes the block, so the old section never goes away. The root AGENTS.md and CLAUDE.md in this repo have both copies right now.

This builds on Wenyu Chiou (@WenyuChiou)'s #362, which took the same approach and was closed without a comment, along with 15 other PRs in the same hour. It also no longer applies to current main, where the file has moved to src/ingestion/. I rewrote it against main and kept Wenyu as co-author on the commit.

With this change, prepareCodeModeAgentSnippet looks for the old section before it looks for markers. If there are no markers, the managed block goes where the old section was. If a marked block already exists, the old section is removed and the block is refreshed the same way it is now. The malformed-marker error is unchanged, and marker validation now runs on the content that actually gets written.

I went back and forth on what counts as the old section. Matching the heading alone would delete a ## OpenWiki section someone wrote by hand, and that's worse than the duplicate. So a heading only counts when the next non-blank line is the sentence every released 0.0.x template opened with: "This repository has documentation located in the /openwiki directory." #362 keyed on openwiki/quickstart.md instead. I didn't, because someone pointing their team at the wiki could easily link the quickstart, while that sentence only ever came from our prompt. Headings inside a fenced code block are skipped, so a README-style quote of the old snippet stays put.

My first version ran the old section to the next #/## heading. That silently deleted whatever a user had put underneath it, like a ### subsection, a paragraph, a setext heading or another tool's <!-- ... --> block. Now only lines from the old template are removed: the heading, that sentence, "Start here:", the quickstart link, the "OpenWiki includes..." and "When working in this repository..." lines, and blank lines between them. Every one of those is matched exactly, not by prefix, so a line someone appended their own text to no longer looks like the template and stops the removal like any other line. It stops at the first line that isn't one of those. The trade-off is that if someone edited a line inside the old section, the removal stops there and their edited line and anything after it stay. If they only added lines after it, those stay too. Either way nothing is lost, but a heavily edited old section may be only partly cleaned up.

For a CLAUDE.md that is just @AGENTS.md plus an old section, I remove the old section and leave only the import, since AGENTS.md carries the managed block. A CLAUDE.md that is only the import is still left byte-for-byte alone.

I added sixteen tests to test/ingestion/code-mode.test.ts:

  • the in-place replacement, including that a second run changes nothing
  • user content after the old section surviving in four variants (a ### subsection, a plain paragraph, a setext heading and an Nx-style comment block)
  • an old section at the end of the file
  • CRLF line endings
  • two old sections
  • an old section beside a marked block, and one after a marked block
  • the @AGENTS.md CLAUDE.md, and that reducing it to the import is idempotent
  • a template line the user appended text to, which halts removal with its addition intact
  • a fenced quote of the old snippet
  • a ``` fence that itself contains a ~~~ line, so the nested delimiter doesn't close the outer fence
  • a hand-written ## OpenWiki without the sentence

Thirteen of them fail on main because main leaves the duplicate. The two fenced-quote tests and the hand-written one pass on main, since main never deletes anything; they're there to keep this fix from deleting too much. lint:check, format:check and typecheck are clean.

#723 edits lines right next to this change in the same file, so whichever of the two lands second will have a small conflict.

It includes a patch changeset.

A repository set up by a pre-marker (0.0.x) release has a bare
`## OpenWiki` section that OpenWiki wrote directly into AGENTS.md and
CLAUDE.md, before the managed `<!-- OPENWIKI:START/END -->` markers
existed. Code mode finds no markers in that file, appends a fresh
managed block, and from then on only ever refreshes the block, so the
old section is never reconciled and the two sit side by side as two
`## OpenWiki` headings. This repo's own root AGENTS.md and CLAUDE.md are
in exactly that state.

prepareCodeModeAgentSnippet now looks for the legacy section before it
looks for markers. A heading counts as the legacy section only when the
next non-blank line is the sentence every 0.0.x template opened with, so
a `## OpenWiki` section someone wrote by hand is left alone, and a
heading quoted inside a fenced code block is skipped. Only the known
template lines are removed, stopping at the first line that is not one of
them, so hand-edited content below the old section survives. When there
are no markers the managed block is placed where the old section was;
when a marked block already exists the old section is removed and the
block is refreshed as before. Marker validation now runs on the content
that actually gets written, and the malformed-marker error path is
unchanged.

Co-Authored-By: Wenyu <[email protected]>
@changeset-bot

changeset-bot Bot commented Sep 19, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 707dbbe

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openwiki Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@colifran Colin Francis (colifran) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@colifran
Colin Francis (colifran) merged commit 812cb48 into langchain-ai:main Sep 21, 2026
11 checks passed
@github-actions github-actions Bot mentioned this pull request Sep 21, 2026
myleo198 pushed a commit to myleo198/openwiki that referenced this pull request Sep 27, 2026
…duplicate (langchain-ai#914)

* fix: replace legacy unmarked OpenWiki section instead of duplicating it

A repository set up by a pre-marker (0.0.x) release has a bare
`## OpenWiki` section that OpenWiki wrote directly into AGENTS.md and
CLAUDE.md, before the managed `<!-- OPENWIKI:START/END -->` markers
existed. Code mode finds no markers in that file, appends a fresh
managed block, and from then on only ever refreshes the block, so the
old section is never reconciled and the two sit side by side as two
`## OpenWiki` headings. This repo's own root AGENTS.md and CLAUDE.md are
in exactly that state.

prepareCodeModeAgentSnippet now looks for the legacy section before it
looks for markers. A heading counts as the legacy section only when the
next non-blank line is the sentence every 0.0.x template opened with, so
a `## OpenWiki` section someone wrote by hand is left alone, and a
heading quoted inside a fenced code block is skipped. Only the known
template lines are removed, stopping at the first line that is not one of
them, so hand-edited content below the old section survives. When there
are no markers the managed block is placed where the old section was;
when a marked block already exists the old section is removed and the
block is refreshed as before. Marker validation now runs on the content
that actually gets written, and the malformed-marker error path is
unchanged.

Co-Authored-By: Wenyu <[email protected]>

* fix: preserve customized legacy OpenWiki sections

* docs: align changeset with PR title

---------

Co-authored-by: Wenyu <[email protected]>
Co-authored-by: Colin Francis <[email protected]>
Co-authored-by: Colin Francis <[email protected]>
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.

bug: code mode appends a duplicate "## OpenWiki" section when a legacy unmarked section exists

2 participants